LCOV - code coverage report
Current view: top level - lib - packets.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 550 625 88.0 %
Date: 2016-09-14 01:02:56 Functions: 66 68 97.1 %
Branches: 198 289 68.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <config.h>
      18                 :            : #include "packets.h"
      19                 :            : #include <arpa/inet.h>
      20                 :            : #include <sys/socket.h>
      21                 :            : #include <netinet/in.h>
      22                 :            : #include <netinet/ip6.h>
      23                 :            : #include <netinet/icmp6.h>
      24                 :            : #include <stdlib.h>
      25                 :            : #include "byte-order.h"
      26                 :            : #include "csum.h"
      27                 :            : #include "crc32c.h"
      28                 :            : #include "flow.h"
      29                 :            : #include "openvswitch/hmap.h"
      30                 :            : #include "openvswitch/dynamic-string.h"
      31                 :            : #include "ovs-thread.h"
      32                 :            : #include "odp-util.h"
      33                 :            : #include "dp-packet.h"
      34                 :            : #include "unaligned.h"
      35                 :            : 
      36                 :            : const struct in6_addr in6addr_exact = IN6ADDR_EXACT_INIT;
      37                 :            : const struct in6_addr in6addr_all_hosts = IN6ADDR_ALL_HOSTS_INIT;
      38                 :            : 
      39                 :            : struct in6_addr
      40                 :      97247 : flow_tnl_dst(const struct flow_tnl *tnl)
      41                 :            : {
      42         [ +  + ]:      97247 :     return tnl->ip_dst ? in6_addr_mapped_ipv4(tnl->ip_dst) : tnl->ipv6_dst;
      43                 :            : }
      44                 :            : 
      45                 :            : struct in6_addr
      46                 :       9245 : flow_tnl_src(const struct flow_tnl *tnl)
      47                 :            : {
      48         [ +  + ]:       9245 :     return tnl->ip_src ? in6_addr_mapped_ipv4(tnl->ip_src) : tnl->ipv6_src;
      49                 :            : }
      50                 :            : 
      51                 :            : /* Parses 's' as a 16-digit hexadecimal number representing a datapath ID.  On
      52                 :            :  * success stores the dpid into '*dpidp' and returns true, on failure stores 0
      53                 :            :  * into '*dpidp' and returns false.
      54                 :            :  *
      55                 :            :  * Rejects an all-zeros dpid as invalid. */
      56                 :            : bool
      57                 :       4700 : dpid_from_string(const char *s, uint64_t *dpidp)
      58                 :            : {
      59 [ +  + ][ +  - ]:       4700 :     *dpidp = (strlen(s) == 16 && strspn(s, "0123456789abcdefABCDEF") == 16
      60                 :            :               ? strtoull(s, NULL, 16)
      61                 :            :               : 0);
      62                 :       4700 :     return *dpidp != 0;
      63                 :            : }
      64                 :            : 
      65                 :            : /* Returns true if 'ea' is a reserved address, that a bridge must never
      66                 :            :  * forward, false otherwise.
      67                 :            :  *
      68                 :            :  * If you change this function's behavior, please update corresponding
      69                 :            :  * documentation in vswitch.xml at the same time. */
      70                 :            : bool
      71                 :      30443 : eth_addr_is_reserved(const struct eth_addr ea)
      72                 :            : {
      73                 :            :     struct eth_addr_node {
      74                 :            :         struct hmap_node hmap_node;
      75                 :            :         const uint64_t ea64;
      76                 :            :     };
      77                 :            : 
      78                 :            :     static struct eth_addr_node nodes[] = {
      79                 :            :         /* STP, IEEE pause frames, and other reserved protocols. */
      80                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000000ULL },
      81                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000001ULL },
      82                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000002ULL },
      83                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000003ULL },
      84                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000004ULL },
      85                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000005ULL },
      86                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000006ULL },
      87                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000007ULL },
      88                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000008ULL },
      89                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c2000009ULL },
      90                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000aULL },
      91                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000bULL },
      92                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000cULL },
      93                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000dULL },
      94                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000eULL },
      95                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x0180c200000fULL },
      96                 :            : 
      97                 :            :         /* Extreme protocols. */
      98                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000000ULL }, /* EDP. */
      99                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000004ULL }, /* EAPS. */
     100                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x00e02b000006ULL }, /* EAPS. */
     101                 :            : 
     102                 :            :         /* Cisco protocols. */
     103                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000c000000ULL }, /* ISL. */
     104                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccccULL }, /* PAgP, UDLD, CDP,
     105                 :            :                                                             * DTP, VTP. */
     106                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000ccccccdULL }, /* PVST+. */
     107                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000ccdcdcdULL }, /* STP Uplink Fast,
     108                 :            :                                                             * FlexLink. */
     109                 :            : 
     110                 :            :         /* Cisco CFM. */
     111                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc0ULL },
     112                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc1ULL },
     113                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc2ULL },
     114                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc3ULL },
     115                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc4ULL },
     116                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc5ULL },
     117                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc6ULL },
     118                 :            :         { HMAP_NODE_NULL_INITIALIZER, 0x01000cccccc7ULL },
     119                 :            :     };
     120                 :            : 
     121                 :            :     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
     122                 :            :     struct eth_addr_node *node;
     123                 :            :     static struct hmap addrs;
     124                 :            :     uint64_t ea64;
     125                 :            : 
     126         [ +  + ]:      30443 :     if (ovsthread_once_start(&once)) {
     127                 :        170 :         hmap_init(&addrs);
     128         [ +  + ]:       5440 :         for (node = nodes; node < &nodes[ARRAY_SIZE(nodes)]; node++) {
     129                 :       5270 :             hmap_insert(&addrs, &node->hmap_node, hash_uint64(node->ea64));
     130                 :            :         }
     131                 :        170 :         ovsthread_once_done(&once);
     132                 :            :     }
     133                 :            : 
     134                 :      30443 :     ea64 = eth_addr_to_uint64(ea);
     135 [ +  + ][ -  + ]:     116162 :     HMAP_FOR_EACH_IN_BUCKET (node, hmap_node, hash_uint64(ea64), &addrs) {
     136         [ -  + ]:      85719 :         if (node->ea64 == ea64) {
     137                 :          0 :             return true;
     138                 :            :         }
     139                 :            :     }
     140                 :      30443 :     return false;
     141                 :            : }
     142                 :            : 
     143                 :            : /* Attempts to parse 's' as an Ethernet address.  If successful, stores the
     144                 :            :  * address in 'ea' and returns true, otherwise zeros 'ea' and returns
     145                 :            :  * false.  */
     146                 :            : bool
     147                 :     159151 : eth_addr_from_string(const char *s, struct eth_addr *ea)
     148                 :            : {
     149         [ +  + ]:     159151 :     if (ovs_scan(s, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(*ea))) {
     150                 :      92179 :         return true;
     151                 :            :     } else {
     152                 :      66972 :         *ea = eth_addr_zero;
     153                 :      66972 :         return false;
     154                 :            :     }
     155                 :            : }
     156                 :            : 
     157                 :            : /* Fills 'b' with a Reverse ARP packet with Ethernet source address 'eth_src'.
     158                 :            :  * This function is used by Open vSwitch to compose packets in cases where
     159                 :            :  * context is important but content doesn't (or shouldn't) matter.
     160                 :            :  *
     161                 :            :  * The returned packet has enough headroom to insert an 802.1Q VLAN header if
     162                 :            :  * desired. */
     163                 :            : void
     164                 :          2 : compose_rarp(struct dp_packet *b, const struct eth_addr eth_src)
     165                 :            : {
     166                 :            :     struct eth_header *eth;
     167                 :            :     struct arp_eth_header *arp;
     168                 :            : 
     169                 :          2 :     dp_packet_clear(b);
     170                 :          2 :     dp_packet_prealloc_tailroom(b, 2 + ETH_HEADER_LEN + VLAN_HEADER_LEN
     171                 :            :                              + ARP_ETH_HEADER_LEN);
     172                 :          2 :     dp_packet_reserve(b, 2 + VLAN_HEADER_LEN);
     173                 :          2 :     eth = dp_packet_put_uninit(b, sizeof *eth);
     174                 :          2 :     eth->eth_dst = eth_addr_broadcast;
     175                 :          2 :     eth->eth_src = eth_src;
     176                 :          2 :     eth->eth_type = htons(ETH_TYPE_RARP);
     177                 :            : 
     178                 :          2 :     arp = dp_packet_put_uninit(b, sizeof *arp);
     179                 :          2 :     arp->ar_hrd = htons(ARP_HRD_ETHERNET);
     180                 :          2 :     arp->ar_pro = htons(ARP_PRO_IP);
     181                 :          2 :     arp->ar_hln = sizeof arp->ar_sha;
     182                 :          2 :     arp->ar_pln = sizeof arp->ar_spa;
     183                 :          2 :     arp->ar_op = htons(ARP_OP_RARP);
     184                 :          2 :     arp->ar_sha = eth_src;
     185                 :          2 :     put_16aligned_be32(&arp->ar_spa, htonl(0));
     186                 :          2 :     arp->ar_tha = eth_src;
     187                 :          2 :     put_16aligned_be32(&arp->ar_tpa, htonl(0));
     188                 :            : 
     189                 :          2 :     dp_packet_reset_offsets(b);
     190                 :          2 :     dp_packet_set_l3(b, arp);
     191                 :          2 : }
     192                 :            : 
     193                 :            : /* Insert VLAN header according to given TCI. Packet passed must be Ethernet
     194                 :            :  * packet.  Ignores the CFI bit of 'tci' using 0 instead.
     195                 :            :  *
     196                 :            :  * Also adjusts the layer offsets accordingly. */
     197                 :            : void
     198                 :        248 : eth_push_vlan(struct dp_packet *packet, ovs_be16 tpid, ovs_be16 tci)
     199                 :            : {
     200                 :            :     struct vlan_eth_header *veh;
     201                 :            : 
     202                 :            :     /* Insert new 802.1Q header. */
     203                 :        248 :     veh = dp_packet_resize_l2(packet, VLAN_HEADER_LEN);
     204                 :        248 :     memmove(veh, (char *)veh + VLAN_HEADER_LEN, 2 * ETH_ADDR_LEN);
     205                 :        248 :     veh->veth_type = tpid;
     206                 :        248 :     veh->veth_tci = tci & htons(~VLAN_CFI);
     207                 :        248 : }
     208                 :            : 
     209                 :            : /* Removes outermost VLAN header (if any is present) from 'packet'.
     210                 :            :  *
     211                 :            :  * 'packet->l2_5' should initially point to 'packet''s outer-most VLAN header
     212                 :            :  * or may be NULL if there are no VLAN headers. */
     213                 :            : void
     214                 :         38 : eth_pop_vlan(struct dp_packet *packet)
     215                 :            : {
     216                 :         38 :     struct vlan_eth_header *veh = dp_packet_l2(packet);
     217                 :            : 
     218 [ +  - ][ +  - ]:         38 :     if (veh && dp_packet_size(packet) >= sizeof *veh
     219         [ +  - ]:         38 :         && eth_type_vlan(veh->veth_type)) {
     220                 :            : 
     221                 :         38 :         memmove((char *)veh + VLAN_HEADER_LEN, veh, 2 * ETH_ADDR_LEN);
     222                 :         38 :         dp_packet_resize_l2(packet, -VLAN_HEADER_LEN);
     223                 :            :     }
     224                 :         38 : }
     225                 :            : 
     226                 :            : /* Set ethertype of the packet. */
     227                 :            : static void
     228                 :       3618 : set_ethertype(struct dp_packet *packet, ovs_be16 eth_type)
     229                 :            : {
     230                 :       3618 :     struct eth_header *eh = dp_packet_l2(packet);
     231                 :            : 
     232         [ -  + ]:       3618 :     if (!eh) {
     233                 :          0 :         return;
     234                 :            :     }
     235                 :            : 
     236         [ +  + ]:       3618 :     if (eth_type_vlan(eh->eth_type)) {
     237                 :            :         ovs_be16 *p;
     238                 :         54 :         char *l2_5 = dp_packet_l2_5(packet);
     239                 :            : 
     240         [ +  - ]:         54 :         p = ALIGNED_CAST(ovs_be16 *,
     241                 :            :                          (l2_5 ? l2_5 : (char *)dp_packet_l3(packet)) - 2);
     242                 :         54 :         *p = eth_type;
     243                 :            :     } else {
     244                 :       3564 :         eh->eth_type = eth_type;
     245                 :            :     }
     246                 :            : }
     247                 :            : 
     248                 :       3660 : static bool is_mpls(struct dp_packet *packet)
     249                 :            : {
     250                 :       3660 :     return packet->l2_5_ofs != UINT16_MAX;
     251                 :            : }
     252                 :            : 
     253                 :            : /* Set time to live (TTL) of an MPLS label stack entry (LSE). */
     254                 :            : void
     255                 :        242 : set_mpls_lse_ttl(ovs_be32 *lse, uint8_t ttl)
     256                 :            : {
     257                 :        242 :     *lse &= ~htonl(MPLS_TTL_MASK);
     258                 :        242 :     *lse |= htonl((ttl << MPLS_TTL_SHIFT) & MPLS_TTL_MASK);
     259                 :        242 : }
     260                 :            : 
     261                 :            : /* Set traffic class (TC) of an MPLS label stack entry (LSE). */
     262                 :            : void
     263                 :        263 : set_mpls_lse_tc(ovs_be32 *lse, uint8_t tc)
     264                 :            : {
     265                 :        263 :     *lse &= ~htonl(MPLS_TC_MASK);
     266                 :        263 :     *lse |= htonl((tc << MPLS_TC_SHIFT) & MPLS_TC_MASK);
     267                 :        263 : }
     268                 :            : 
     269                 :            : /* Set label of an MPLS label stack entry (LSE). */
     270                 :            : void
     271                 :        381 : set_mpls_lse_label(ovs_be32 *lse, ovs_be32 label)
     272                 :            : {
     273                 :        381 :     *lse &= ~htonl(MPLS_LABEL_MASK);
     274                 :        381 :     *lse |= htonl((ntohl(label) << MPLS_LABEL_SHIFT) & MPLS_LABEL_MASK);
     275                 :        381 : }
     276                 :            : 
     277                 :            : /* Set bottom of stack (BoS) bit of an MPLS label stack entry (LSE). */
     278                 :            : void
     279                 :       1959 : set_mpls_lse_bos(ovs_be32 *lse, uint8_t bos)
     280                 :            : {
     281                 :       1959 :     *lse &= ~htonl(MPLS_BOS_MASK);
     282                 :       1959 :     *lse |= htonl((bos << MPLS_BOS_SHIFT) & MPLS_BOS_MASK);
     283                 :       1959 : }
     284                 :            : 
     285                 :            : /* Compose an MPLS label stack entry (LSE) from its components:
     286                 :            :  * label, traffic class (TC), time to live (TTL) and
     287                 :            :  * bottom of stack (BoS) bit. */
     288                 :            : ovs_be32
     289                 :        178 : set_mpls_lse_values(uint8_t ttl, uint8_t tc, uint8_t bos, ovs_be32 label)
     290                 :            : {
     291                 :        178 :     ovs_be32 lse = htonl(0);
     292                 :        178 :     set_mpls_lse_ttl(&lse, ttl);
     293                 :        178 :     set_mpls_lse_tc(&lse, tc);
     294                 :        178 :     set_mpls_lse_bos(&lse, bos);
     295                 :        178 :     set_mpls_lse_label(&lse, label);
     296                 :        178 :     return lse;
     297                 :            : }
     298                 :            : 
     299                 :            : /* Set MPLS label stack entry to outermost MPLS header.*/
     300                 :            : void
     301                 :         42 : set_mpls_lse(struct dp_packet *packet, ovs_be32 mpls_lse)
     302                 :            : {
     303                 :            :     /* Packet type should be MPLS to set label stack entry. */
     304         [ +  - ]:         42 :     if (is_mpls(packet)) {
     305                 :         42 :         struct mpls_hdr *mh = dp_packet_l2_5(packet);
     306                 :            : 
     307                 :            :         /* Update mpls label stack entry. */
     308                 :         42 :         put_16aligned_be32(&mh->mpls_lse, mpls_lse);
     309                 :            :     }
     310                 :         42 : }
     311                 :            : 
     312                 :            : /* Push MPLS label stack entry 'lse' onto 'packet' as the outermost MPLS
     313                 :            :  * header.  If 'packet' does not already have any MPLS labels, then its
     314                 :            :  * Ethertype is changed to 'ethtype' (which must be an MPLS Ethertype). */
     315                 :            : void
     316                 :       3481 : push_mpls(struct dp_packet *packet, ovs_be16 ethtype, ovs_be32 lse)
     317                 :            : {
     318                 :            :     char * header;
     319                 :            :     size_t len;
     320                 :            : 
     321         [ -  + ]:       3481 :     if (!eth_type_mpls(ethtype)) {
     322                 :          0 :         return;
     323                 :            :     }
     324                 :            : 
     325         [ +  + ]:       3481 :     if (!is_mpls(packet)) {
     326                 :            :         /* Set MPLS label stack offset. */
     327                 :        127 :         packet->l2_5_ofs = packet->l3_ofs;
     328                 :            :     }
     329                 :            : 
     330                 :       3481 :     set_ethertype(packet, ethtype);
     331                 :            : 
     332                 :            :     /* Push new MPLS shim header onto packet. */
     333                 :       3481 :     len = packet->l2_5_ofs;
     334                 :       3481 :     header = dp_packet_resize_l2_5(packet, MPLS_HLEN);
     335                 :       3481 :     memmove(header, header + MPLS_HLEN, len);
     336                 :       3481 :     memcpy(header + len, &lse, sizeof lse);
     337                 :            : }
     338                 :            : 
     339                 :            : /* If 'packet' is an MPLS packet, removes its outermost MPLS label stack entry.
     340                 :            :  * If the label that was removed was the only MPLS label, changes 'packet''s
     341                 :            :  * Ethertype to 'ethtype' (which ordinarily should not be an MPLS
     342                 :            :  * Ethertype). */
     343                 :            : void
     344                 :        137 : pop_mpls(struct dp_packet *packet, ovs_be16 ethtype)
     345                 :            : {
     346         [ +  - ]:        137 :     if (is_mpls(packet)) {
     347                 :        137 :         struct mpls_hdr *mh = dp_packet_l2_5(packet);
     348                 :        137 :         size_t len = packet->l2_5_ofs;
     349                 :            : 
     350                 :        137 :         set_ethertype(packet, ethtype);
     351         [ +  + ]:        137 :         if (get_16aligned_be32(&mh->mpls_lse) & htonl(MPLS_BOS_MASK)) {
     352                 :         67 :             dp_packet_set_l2_5(packet, NULL);
     353                 :            :         }
     354                 :            :         /* Shift the l2 header forward. */
     355                 :        137 :         memmove((char*)dp_packet_data(packet) + MPLS_HLEN, dp_packet_data(packet), len);
     356                 :        137 :         dp_packet_resize_l2_5(packet, -MPLS_HLEN);
     357                 :            :     }
     358                 :        137 : }
     359                 :            : 
     360                 :            : /* Converts hex digits in 'hex' to an Ethernet packet in '*packetp'.  The
     361                 :            :  * caller must free '*packetp'.  On success, returns NULL.  On failure, returns
     362                 :            :  * an error message and stores NULL in '*packetp'.
     363                 :            :  *
     364                 :            :  * Aligns the L3 header of '*packetp' on a 32-bit boundary. */
     365                 :            : const char *
     366                 :       6051 : eth_from_hex(const char *hex, struct dp_packet **packetp)
     367                 :            : {
     368                 :            :     struct dp_packet *packet;
     369                 :            : 
     370                 :            :     /* Use 2 bytes of headroom to 32-bit align the L3 header. */
     371                 :       6051 :     packet = *packetp = dp_packet_new_with_headroom(strlen(hex) / 2, 2);
     372                 :            : 
     373         [ +  + ]:       6051 :     if (dp_packet_put_hex(packet, hex, NULL)[0] != '\0') {
     374                 :       1975 :         dp_packet_delete(packet);
     375                 :       1975 :         *packetp = NULL;
     376                 :       1975 :         return "Trailing garbage in packet data";
     377                 :            :     }
     378                 :            : 
     379         [ -  + ]:       4076 :     if (dp_packet_size(packet) < ETH_HEADER_LEN) {
     380                 :          0 :         dp_packet_delete(packet);
     381                 :          0 :         *packetp = NULL;
     382                 :          0 :         return "Packet data too short for Ethernet";
     383                 :            :     }
     384                 :            : 
     385                 :       4076 :     return NULL;
     386                 :            : }
     387                 :            : 
     388                 :            : void
     389                 :      28641 : eth_format_masked(const struct eth_addr eth,
     390                 :            :                   const struct eth_addr *mask, struct ds *s)
     391                 :            : {
     392                 :      28641 :     ds_put_format(s, ETH_ADDR_FMT, ETH_ADDR_ARGS(eth));
     393 [ +  + ][ +  + ]:      28641 :     if (mask && !eth_mask_is_exact(*mask)) {
     394                 :       1866 :         ds_put_format(s, "/"ETH_ADDR_FMT, ETH_ADDR_ARGS(*mask));
     395                 :            :     }
     396                 :      28641 : }
     397                 :            : 
     398                 :            : /* Given the IP netmask 'netmask', returns the number of bits of the IP address
     399                 :            :  * that it specifies, that is, the number of 1-bits in 'netmask'.
     400                 :            :  *
     401                 :            :  * If 'netmask' is not a CIDR netmask (see ip_is_cidr()), the return value will
     402                 :            :  * still be in the valid range but isn't otherwise meaningful. */
     403                 :            : int
     404                 :      51042 : ip_count_cidr_bits(ovs_be32 netmask)
     405                 :            : {
     406                 :      51042 :     return 32 - ctz32(ntohl(netmask));
     407                 :            : }
     408                 :            : 
     409                 :            : void
     410                 :      17546 : ip_format_masked(ovs_be32 ip, ovs_be32 mask, struct ds *s)
     411                 :            : {
     412                 :      17546 :     ds_put_format(s, IP_FMT, IP_ARGS(ip));
     413         [ +  + ]:      17546 :     if (mask != OVS_BE32_MAX) {
     414         [ +  + ]:       1968 :         if (ip_is_cidr(mask)) {
     415                 :       1960 :             ds_put_format(s, "/%d", ip_count_cidr_bits(mask));
     416                 :            :         } else {
     417                 :          8 :             ds_put_format(s, "/"IP_FMT, IP_ARGS(mask));
     418                 :            :         }
     419                 :            :     }
     420                 :      17546 : }
     421                 :            : 
     422                 :            : /* Parses string 's', which must be an IP address.  Stores the IP address into
     423                 :            :  * '*ip'.  Returns true if successful, otherwise false. */
     424                 :            : bool
     425                 :     502092 : ip_parse(const char *s, ovs_be32 *ip)
     426                 :            : {
     427                 :     502092 :     return inet_pton(AF_INET, s, ip) == 1;
     428                 :            : }
     429                 :            : 
     430                 :            : /* Parses string 's', which must be an IP address with an optional netmask or
     431                 :            :  * CIDR prefix length.  Stores the IP address into '*ip', netmask into '*mask',
     432                 :            :  * (255.255.255.255, if 's' lacks a netmask), and number of scanned characters
     433                 :            :  * into '*n'.
     434                 :            :  *
     435                 :            :  * Returns NULL if successful, otherwise an error message that the caller must
     436                 :            :  * free(). */
     437                 :            : char * OVS_WARN_UNUSED_RESULT
     438                 :      44863 : ip_parse_masked_len(const char *s, int *n, ovs_be32 *ip,
     439                 :            :                     ovs_be32 *mask)
     440                 :            : {
     441                 :            :     int prefix;
     442                 :            : 
     443         [ +  + ]:      44863 :     if (ovs_scan_len(s, n, IP_SCAN_FMT"/"IP_SCAN_FMT,
     444                 :            :                  IP_SCAN_ARGS(ip), IP_SCAN_ARGS(mask))) {
     445                 :            :         /* OK. */
     446         [ +  + ]:      44850 :     } else if (ovs_scan_len(s, n, IP_SCAN_FMT"/%d",
     447                 :            :                             IP_SCAN_ARGS(ip), &prefix)) {
     448 [ +  - ][ -  + ]:      11336 :         if (prefix < 0 || prefix > 32) {
     449                 :          0 :             return xasprintf("%s: IPv4 network prefix bits not between 0 and "
     450                 :            :                               "32, inclusive", s);
     451                 :            :         }
     452                 :      11336 :         *mask = be32_prefix_mask(prefix);
     453         [ +  + ]:      33514 :     } else if (ovs_scan_len(s, n, IP_SCAN_FMT, IP_SCAN_ARGS(ip))) {
     454                 :      32229 :         *mask = OVS_BE32_MAX;
     455                 :            :     } else {
     456                 :       1285 :         return xasprintf("%s: invalid IP address", s);
     457                 :            :     }
     458                 :      44863 :     return NULL;
     459                 :            : }
     460                 :            : 
     461                 :            : /* This function is similar to ip_parse_masked_len(), but doesn't return the
     462                 :            :  * number of scanned characters and expects 's' to end after the ip/(optional)
     463                 :            :  * mask.
     464                 :            :  *
     465                 :            :  * Returns NULL if successful, otherwise an error message that the caller must
     466                 :            :  * free(). */
     467                 :            : char * OVS_WARN_UNUSED_RESULT
     468                 :       1941 : ip_parse_masked(const char *s, ovs_be32 *ip, ovs_be32 *mask)
     469                 :            : {
     470                 :       1941 :     int n = 0;
     471                 :            : 
     472                 :       1941 :     char *error = ip_parse_masked_len(s, &n, ip, mask);
     473 [ +  - ][ -  + ]:       1941 :     if (!error && s[n]) {
     474                 :          0 :         return xasprintf("%s: invalid IP address", s);
     475                 :            :     }
     476                 :       1941 :     return error;
     477                 :            : }
     478                 :            : 
     479                 :            : /* Similar to ip_parse_masked_len(), but the mask, if present, must be a CIDR
     480                 :            :  * mask and is returned as a prefix len in '*plen'. */
     481                 :            : char * OVS_WARN_UNUSED_RESULT
     482                 :      42922 : ip_parse_cidr_len(const char *s, int *n, ovs_be32 *ip, unsigned int *plen)
     483                 :            : {
     484                 :            :     ovs_be32 mask;
     485                 :            :     char *error;
     486                 :            : 
     487                 :      42922 :     error = ip_parse_masked_len(s, n, ip, &mask);
     488         [ +  + ]:      42922 :     if (error) {
     489                 :       1285 :         return error;
     490                 :            :     }
     491                 :            : 
     492         [ -  + ]:      41637 :     if (!ip_is_cidr(mask)) {
     493                 :          0 :         return xasprintf("%s: CIDR network required", s);
     494                 :            :     }
     495                 :      41637 :     *plen = ip_count_cidr_bits(mask);
     496                 :      42922 :     return NULL;
     497                 :            : }
     498                 :            : 
     499                 :            : /* Similar to ip_parse_cidr_len(), but doesn't return the number of scanned
     500                 :            :  * characters and expects 's' to be NULL terminated at the end of the
     501                 :            :  * ip/(optional) cidr. */
     502                 :            : char * OVS_WARN_UNUSED_RESULT
     503                 :      11671 : ip_parse_cidr(const char *s, ovs_be32 *ip, unsigned int *plen)
     504                 :            : {
     505                 :      11671 :     int n = 0;
     506                 :            : 
     507                 :      11671 :     char *error = ip_parse_cidr_len(s, &n, ip, plen);
     508 [ +  + ][ -  + ]:      11671 :     if (!error && s[n]) {
     509                 :          0 :         return xasprintf("%s: invalid IP address", s);
     510                 :            :     }
     511                 :      11671 :     return error;
     512                 :            : }
     513                 :            : 
     514                 :            : /* Parses string 's', which must be an IPv6 address.  Stores the IPv6 address
     515                 :            :  * into '*ip'.  Returns true if successful, otherwise false. */
     516                 :            : bool
     517                 :     161664 : ipv6_parse(const char *s, struct in6_addr *ip)
     518                 :            : {
     519                 :     161664 :     return inet_pton(AF_INET6, s, ip) == 1;
     520                 :            : }
     521                 :            : 
     522                 :            : /* Parses string 's', which must be an IPv6 address with an optional netmask or
     523                 :            :  * CIDR prefix length.  Stores the IPv6 address into '*ip' and the netmask into
     524                 :            :  * '*mask' (if 's' does not contain a netmask, all-one-bits is assumed), and
     525                 :            :  * number of scanned characters into '*n'.
     526                 :            :  *
     527                 :            :  * Returns NULL if successful, otherwise an error message that the caller must
     528                 :            :  * free(). */
     529                 :            : char * OVS_WARN_UNUSED_RESULT
     530                 :       1403 : ipv6_parse_masked_len(const char *s, int *n, struct in6_addr *ip,
     531                 :            :                       struct in6_addr *mask)
     532                 :            : {
     533                 :            :     char ipv6_s[IPV6_SCAN_LEN + 1];
     534                 :            :     int prefix;
     535                 :            : 
     536         [ +  + ]:       1403 :     if (ovs_scan_len(s, n, " "IPV6_SCAN_FMT, ipv6_s)
     537         [ +  - ]:       1371 :         && ipv6_parse(ipv6_s, ip)) {
     538         [ +  + ]:       1371 :         if (ovs_scan_len(s, n, "/%d", &prefix)) {
     539 [ +  - ][ -  + ]:        397 :             if (prefix < 0 || prefix > 128) {
     540                 :          0 :                 return xasprintf("%s: IPv6 network prefix bits not between 0 "
     541                 :            :                                  "and 128, inclusive", s);
     542                 :            :             }
     543                 :        397 :             *mask = ipv6_create_mask(prefix);
     544         [ +  + ]:        974 :         } else if (ovs_scan_len(s, n, "/"IPV6_SCAN_FMT, ipv6_s)) {
     545         [ -  + ]:          3 :              if (!ipv6_parse(ipv6_s, mask)) {
     546                 :          0 :                  return xasprintf("%s: Invalid IPv6 mask", s);
     547                 :            :              }
     548                 :            :             /* OK. */
     549                 :            :         } else {
     550                 :            :             /* OK. No mask. */
     551                 :        971 :             *mask = in6addr_exact;
     552                 :            :         }
     553                 :       1371 :         return NULL;
     554                 :            :     }
     555                 :       1403 :     return xasprintf("%s: invalid IPv6 address", s);
     556                 :            : }
     557                 :            : 
     558                 :            : /* This function is similar to ipv6_parse_masked_len(), but doesn't return the
     559                 :            :  * number of scanned characters and expects 's' to end following the
     560                 :            :  * ipv6/(optional) mask. */
     561                 :            : char * OVS_WARN_UNUSED_RESULT
     562                 :        116 : ipv6_parse_masked(const char *s, struct in6_addr *ip, struct in6_addr *mask)
     563                 :            : {
     564                 :        116 :     int n = 0;
     565                 :            : 
     566                 :        116 :     char *error = ipv6_parse_masked_len(s, &n, ip, mask);
     567 [ +  - ][ -  + ]:        116 :     if (!error && s[n]) {
     568                 :          0 :         return xasprintf("%s: invalid IPv6 address", s);
     569                 :            :     }
     570                 :        116 :     return error;
     571                 :            : }
     572                 :            : 
     573                 :            : /* Similar to ipv6_parse_masked_len(), but the mask, if present, must be a CIDR
     574                 :            :  * mask and is returned as a prefix length in '*plen'. */
     575                 :            : char * OVS_WARN_UNUSED_RESULT
     576                 :       1287 : ipv6_parse_cidr_len(const char *s, int *n, struct in6_addr *ip,
     577                 :            :                     unsigned int *plen)
     578                 :            : {
     579                 :            :     struct in6_addr mask;
     580                 :            :     char *error;
     581                 :            : 
     582                 :       1287 :     error = ipv6_parse_masked_len(s, n, ip, &mask);
     583         [ +  + ]:       1287 :     if (error) {
     584                 :         32 :         return error;
     585                 :            :     }
     586                 :            : 
     587         [ -  + ]:       1255 :     if (!ipv6_is_cidr(&mask)) {
     588                 :          0 :         return xasprintf("%s: IPv6 CIDR network required", s);
     589                 :            :     }
     590                 :       1255 :     *plen = ipv6_count_cidr_bits(&mask);
     591                 :       1287 :     return NULL;
     592                 :            : }
     593                 :            : 
     594                 :            : /* Similar to ipv6_parse_cidr_len(), but doesn't return the number of scanned
     595                 :            :  * characters and expects 's' to end after the ipv6/(optional) cidr. */
     596                 :            : char * OVS_WARN_UNUSED_RESULT
     597                 :         48 : ipv6_parse_cidr(const char *s, struct in6_addr *ip, unsigned int *plen)
     598                 :            : {
     599                 :         48 :     int n = 0;
     600                 :            : 
     601                 :         48 :     char *error = ipv6_parse_cidr_len(s, &n, ip, plen);
     602 [ +  - ][ -  + ]:         48 :     if (!error && s[n]) {
     603                 :          0 :         return xasprintf("%s: invalid IPv6 address", s);
     604                 :            :     }
     605                 :         48 :     return error;
     606                 :            : }
     607                 :            : 
     608                 :            : /* Stores the string representation of the IPv6 address 'addr' into the
     609                 :            :  * character array 'addr_str', which must be at least INET6_ADDRSTRLEN
     610                 :            :  * bytes long. */
     611                 :            : void
     612                 :       3505 : ipv6_format_addr(const struct in6_addr *addr, struct ds *s)
     613                 :            : {
     614                 :            :     char *dst;
     615                 :            : 
     616                 :       3505 :     ds_reserve(s, s->length + INET6_ADDRSTRLEN);
     617                 :            : 
     618                 :       3505 :     dst = s->string + s->length;
     619                 :       3505 :     inet_ntop(AF_INET6, addr, dst, INET6_ADDRSTRLEN);
     620                 :       3505 :     s->length += strlen(dst);
     621                 :       3505 : }
     622                 :            : 
     623                 :            : /* Same as print_ipv6_addr, but optionally encloses the address in square
     624                 :            :  * brackets. */
     625                 :            : void
     626                 :         18 : ipv6_format_addr_bracket(const struct in6_addr *addr, struct ds *s,
     627                 :            :                          bool bracket)
     628                 :            : {
     629         [ +  + ]:         18 :     if (bracket) {
     630                 :          6 :         ds_put_char(s, '[');
     631                 :            :     }
     632                 :         18 :     ipv6_format_addr(addr, s);
     633         [ +  + ]:         18 :     if (bracket) {
     634                 :          6 :         ds_put_char(s, ']');
     635                 :            :     }
     636                 :         18 : }
     637                 :            : 
     638                 :            : void
     639                 :          6 : ipv6_format_mapped(const struct in6_addr *addr, struct ds *s)
     640                 :            : {
     641 [ +  + ][ +  - ]:          6 :     if (IN6_IS_ADDR_V4MAPPED(addr)) {
         [ +  + ][ +  + ]
     642                 :          3 :         ds_put_format(s, IP_FMT, addr->s6_addr[12], addr->s6_addr[13],
     643                 :          6 :                                  addr->s6_addr[14], addr->s6_addr[15]);
     644                 :            :     } else {
     645                 :          3 :         ipv6_format_addr(addr, s);
     646                 :            :     }
     647                 :          6 : }
     648                 :            : 
     649                 :            : void
     650                 :       3404 : ipv6_format_masked(const struct in6_addr *addr, const struct in6_addr *mask,
     651                 :            :                    struct ds *s)
     652                 :            : {
     653                 :       3404 :     ipv6_format_addr(addr, s);
     654 [ +  + ][ +  + ]:       3404 :     if (mask && !ipv6_mask_is_exact(mask)) {
     655         [ +  + ]:        421 :         if (ipv6_is_cidr(mask)) {
     656                 :        419 :             int cidr_bits = ipv6_count_cidr_bits(mask);
     657                 :        419 :             ds_put_format(s, "/%d", cidr_bits);
     658                 :            :         } else {
     659                 :          2 :             ds_put_char(s, '/');
     660                 :          2 :             ipv6_format_addr(mask, s);
     661                 :            :         }
     662                 :            :     }
     663                 :       3404 : }
     664                 :            : 
     665                 :            : /* Stores the string representation of the IPv6 address 'addr' into the
     666                 :            :  * character array 'addr_str', which must be at least INET6_ADDRSTRLEN
     667                 :            :  * bytes long. If addr is IPv4-mapped, store an IPv4 dotted-decimal string. */
     668                 :            : const char *
     669                 :       6762 : ipv6_string_mapped(char *addr_str, const struct in6_addr *addr)
     670                 :            : {
     671                 :            :     ovs_be32 ip;
     672                 :       6762 :     ip = in6_addr_get_mapped_ipv4(addr);
     673         [ +  + ]:       6762 :     if (ip) {
     674                 :       4827 :         return inet_ntop(AF_INET, &ip, addr_str, INET6_ADDRSTRLEN);
     675                 :            :     } else {
     676                 :       6762 :         return inet_ntop(AF_INET6, addr, addr_str, INET6_ADDRSTRLEN);
     677                 :            :     }
     678                 :            : }
     679                 :            : 
     680                 :            : #ifdef s6_addr32
     681                 :            : #define s6_addrX s6_addr32
     682                 :            : #define IPV6_FOR_EACH(VAR) for (int VAR = 0; VAR < 4; VAR++)
     683                 :            : #else
     684                 :            : #define s6_addrX s6_addr
     685                 :            : #define IPV6_FOR_EACH(VAR) for (int VAR = 0; VAR < 16; VAR++)
     686                 :            : #endif
     687                 :            : 
     688                 :            : struct in6_addr
     689                 :     130751 : ipv6_addr_bitand(const struct in6_addr *a, const struct in6_addr *b)
     690                 :            : {
     691                 :            :    struct in6_addr dst;
     692         [ +  + ]:     653755 :    IPV6_FOR_EACH (i) {
     693                 :     523004 :        dst.s6_addrX[i] = a->s6_addrX[i] & b->s6_addrX[i];
     694                 :            :    }
     695                 :     130751 :    return dst;
     696                 :            : }
     697                 :            : 
     698                 :            : struct in6_addr
     699                 :         70 : ipv6_addr_bitxor(const struct in6_addr *a, const struct in6_addr *b)
     700                 :            : {
     701                 :            :    struct in6_addr dst;
     702         [ +  + ]:        350 :    IPV6_FOR_EACH (i) {
     703                 :        280 :        dst.s6_addrX[i] = a->s6_addrX[i] ^ b->s6_addrX[i];
     704                 :            :    }
     705                 :         70 :    return dst;
     706                 :            : }
     707                 :            : 
     708                 :            : bool
     709                 :          0 : ipv6_is_zero(const struct in6_addr *a)
     710                 :            : {
     711         [ #  # ]:          0 :    IPV6_FOR_EACH (i) {
     712         [ #  # ]:          0 :        if (a->s6_addrX[i]) {
     713                 :          0 :            return false;
     714                 :            :        }
     715                 :            :    }
     716                 :          0 :    return true;
     717                 :            : }
     718                 :            : 
     719                 :            : /* Returns an in6_addr consisting of 'mask' high-order 1-bits and 128-N
     720                 :            :  * low-order 0-bits. */
     721                 :            : struct in6_addr
     722                 :      53362 : ipv6_create_mask(int mask)
     723                 :            : {
     724                 :            :     struct in6_addr netmask;
     725                 :      53362 :     uint8_t *netmaskp = &netmask.s6_addr[0];
     726                 :            : 
     727                 :      53362 :     memset(&netmask, 0, sizeof netmask);
     728         [ +  + ]:     519191 :     while (mask > 8) {
     729                 :     465829 :         *netmaskp = 0xff;
     730                 :     465829 :         netmaskp++;
     731                 :     465829 :         mask -= 8;
     732                 :            :     }
     733                 :            : 
     734         [ +  + ]:      53362 :     if (mask) {
     735                 :      53339 :         *netmaskp = 0xff << (8 - mask);
     736                 :            :     }
     737                 :            : 
     738                 :      53362 :     return netmask;
     739                 :            : }
     740                 :            : 
     741                 :            : /* Given the IPv6 netmask 'netmask', returns the number of bits of the IPv6
     742                 :            :  * address that it specifies, that is, the number of 1-bits in 'netmask'.
     743                 :            :  * 'netmask' must be a CIDR netmask (see ipv6_is_cidr()).
     744                 :            :  *
     745                 :            :  * If 'netmask' is not a CIDR netmask (see ipv6_is_cidr()), the return value
     746                 :            :  * will still be in the valid range but isn't otherwise meaningful. */
     747                 :            : int
     748                 :       1696 : ipv6_count_cidr_bits(const struct in6_addr *netmask)
     749                 :            : {
     750                 :            :     int i;
     751                 :       1696 :     int count = 0;
     752                 :       1696 :     const uint8_t *netmaskp = &netmask->s6_addr[0];
     753                 :            : 
     754         [ +  + ]:      21605 :     for (i=0; i<16; i++) {
     755         [ +  + ]:      20665 :         if (netmaskp[i] == 0xff) {
     756                 :      19909 :             count += 8;
     757                 :            :         } else {
     758                 :            :             uint8_t nm;
     759                 :            : 
     760         [ +  + ]:        801 :             for(nm = netmaskp[i]; nm; nm <<= 1) {
     761                 :         45 :                 count++;
     762                 :            :             }
     763                 :        756 :             break;
     764                 :            :         }
     765                 :            : 
     766                 :            :     }
     767                 :            : 
     768                 :       1696 :     return count;
     769                 :            : }
     770                 :            : 
     771                 :            : /* Returns true if 'netmask' is a CIDR netmask, that is, if it consists of N
     772                 :            :  * high-order 1-bits and 128-N low-order 0-bits. */
     773                 :            : bool
     774                 :       1694 : ipv6_is_cidr(const struct in6_addr *netmask)
     775                 :            : {
     776                 :       1694 :     const uint8_t *netmaskp = &netmask->s6_addr[0];
     777                 :            :     int i;
     778                 :            : 
     779         [ +  + ]:      22314 :     for (i=0; i<16; i++) {
     780         [ +  + ]:      20625 :         if (netmaskp[i] != 0xff) {
     781                 :        756 :             uint8_t x = ~netmaskp[i];
     782         [ +  + ]:        756 :             if (x & (x + 1)) {
     783                 :          1 :                 return false;
     784                 :            :             }
     785         [ +  + ]:       7223 :             while (++i < 16) {
     786         [ +  + ]:       6472 :                 if (netmaskp[i]) {
     787                 :          4 :                     return false;
     788                 :            :                 }
     789                 :            :             }
     790                 :            :         }
     791                 :            :     }
     792                 :            : 
     793                 :       1689 :     return true;
     794                 :            : }
     795                 :            : 
     796                 :            : /* Populates 'b' with an Ethernet II packet headed with the given 'eth_dst',
     797                 :            :  * 'eth_src' and 'eth_type' parameters.  A payload of 'size' bytes is allocated
     798                 :            :  * in 'b' and returned.  This payload may be populated with appropriate
     799                 :            :  * information by the caller.  Sets 'b''s 'frame' pointer and 'l3' offset to
     800                 :            :  * the Ethernet header and payload respectively.  Aligns b->l3 on a 32-bit
     801                 :            :  * boundary.
     802                 :            :  *
     803                 :            :  * The returned packet has enough headroom to insert an 802.1Q VLAN header if
     804                 :            :  * desired. */
     805                 :            : void *
     806                 :       7905 : eth_compose(struct dp_packet *b, const struct eth_addr eth_dst,
     807                 :            :             const struct eth_addr eth_src, uint16_t eth_type,
     808                 :            :             size_t size)
     809                 :            : {
     810                 :            :     void *data;
     811                 :            :     struct eth_header *eth;
     812                 :            : 
     813                 :       7905 :     dp_packet_clear(b);
     814                 :            : 
     815                 :            :     /* The magic 2 here ensures that the L3 header (when it is added later)
     816                 :            :      * will be 32-bit aligned. */
     817                 :       7905 :     dp_packet_prealloc_tailroom(b, 2 + ETH_HEADER_LEN + VLAN_HEADER_LEN + size);
     818                 :       7905 :     dp_packet_reserve(b, 2 + VLAN_HEADER_LEN);
     819                 :       7905 :     eth = dp_packet_put_uninit(b, ETH_HEADER_LEN);
     820                 :       7905 :     data = dp_packet_put_zeros(b, size);
     821                 :            : 
     822                 :       7905 :     eth->eth_dst = eth_dst;
     823                 :       7905 :     eth->eth_src = eth_src;
     824                 :       7905 :     eth->eth_type = htons(eth_type);
     825                 :            : 
     826                 :       7905 :     dp_packet_reset_offsets(b);
     827                 :       7905 :     dp_packet_set_l3(b, data);
     828                 :            : 
     829                 :       7905 :     return data;
     830                 :            : }
     831                 :            : 
     832                 :            : static void
     833                 :         88 : packet_set_ipv4_addr(struct dp_packet *packet,
     834                 :            :                      ovs_16aligned_be32 *addr, ovs_be32 new_addr)
     835                 :            : {
     836                 :         88 :     struct ip_header *nh = dp_packet_l3(packet);
     837                 :         88 :     ovs_be32 old_addr = get_16aligned_be32(addr);
     838                 :         88 :     size_t l4_size = dp_packet_l4_size(packet);
     839                 :            : 
     840 [ +  + ][ +  - ]:        141 :     if (nh->ip_proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) {
     841                 :         53 :         struct tcp_header *th = dp_packet_l4(packet);
     842                 :            : 
     843                 :         53 :         th->tcp_csum = recalc_csum32(th->tcp_csum, old_addr, new_addr);
     844 [ +  + ][ +  - ]:         35 :     } else if (nh->ip_proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN ) {
     845                 :         15 :         struct udp_header *uh = dp_packet_l4(packet);
     846                 :            : 
     847         [ +  + ]:         15 :         if (uh->udp_csum) {
     848                 :         11 :             uh->udp_csum = recalc_csum32(uh->udp_csum, old_addr, new_addr);
     849         [ -  + ]:         11 :             if (!uh->udp_csum) {
     850                 :          0 :                 uh->udp_csum = htons(0xffff);
     851                 :            :             }
     852                 :            :         }
     853                 :            :     }
     854                 :         88 :     nh->ip_csum = recalc_csum32(nh->ip_csum, old_addr, new_addr);
     855                 :         88 :     put_16aligned_be32(addr, new_addr);
     856                 :         88 : }
     857                 :            : 
     858                 :            : /* Returns true, if packet contains at least one routing header where
     859                 :            :  * segements_left > 0.
     860                 :            :  *
     861                 :            :  * This function assumes that L3 and L4 offsets are set in the packet. */
     862                 :            : static bool
     863                 :          6 : packet_rh_present(struct dp_packet *packet, uint8_t *nexthdr)
     864                 :            : {
     865                 :            :     const struct ovs_16aligned_ip6_hdr *nh;
     866                 :            :     size_t len;
     867                 :            :     size_t remaining;
     868                 :          6 :     uint8_t *data = dp_packet_l3(packet);
     869                 :            : 
     870                 :          6 :     remaining = packet->l4_ofs - packet->l3_ofs;
     871         [ -  + ]:          6 :     if (remaining < sizeof *nh) {
     872                 :          0 :         return false;
     873                 :            :     }
     874                 :          6 :     nh = ALIGNED_CAST(struct ovs_16aligned_ip6_hdr *, data);
     875                 :          6 :     data += sizeof *nh;
     876                 :          6 :     remaining -= sizeof *nh;
     877                 :          6 :     *nexthdr = nh->ip6_nxt;
     878                 :            : 
     879                 :            :     while (1) {
     880         [ +  - ]:          6 :         if ((*nexthdr != IPPROTO_HOPOPTS)
     881         [ +  - ]:          6 :                 && (*nexthdr != IPPROTO_ROUTING)
     882         [ +  - ]:          6 :                 && (*nexthdr != IPPROTO_DSTOPTS)
     883         [ +  - ]:          6 :                 && (*nexthdr != IPPROTO_AH)
     884         [ +  - ]:          6 :                 && (*nexthdr != IPPROTO_FRAGMENT)) {
     885                 :            :             /* It's either a terminal header (e.g., TCP, UDP) or one we
     886                 :            :              * don't understand.  In either case, we're done with the
     887                 :            :              * packet, so use it to fill in 'nw_proto'. */
     888                 :          6 :             break;
     889                 :            :         }
     890                 :            : 
     891                 :            :         /* We only verify that at least 8 bytes of the next header are
     892                 :            :          * available, but many of these headers are longer.  Ensure that
     893                 :            :          * accesses within the extension header are within those first 8
     894                 :            :          * bytes. All extension headers are required to be at least 8
     895                 :            :          * bytes. */
     896         [ #  # ]:          0 :         if (remaining < 8) {
     897                 :          0 :             return false;
     898                 :            :         }
     899                 :            : 
     900         [ #  # ]:          0 :         if (*nexthdr == IPPROTO_AH) {
     901                 :            :             /* A standard AH definition isn't available, but the fields
     902                 :            :              * we care about are in the same location as the generic
     903                 :            :              * option header--only the header length is calculated
     904                 :            :              * differently. */
     905                 :          0 :             const struct ip6_ext *ext_hdr = (struct ip6_ext *)data;
     906                 :            : 
     907                 :          0 :             *nexthdr = ext_hdr->ip6e_nxt;
     908                 :          0 :             len = (ext_hdr->ip6e_len + 2) * 4;
     909         [ #  # ]:          0 :         } else if (*nexthdr == IPPROTO_FRAGMENT) {
     910                 :          0 :             const struct ovs_16aligned_ip6_frag *frag_hdr
     911                 :            :                 = ALIGNED_CAST(struct ovs_16aligned_ip6_frag *, data);
     912                 :            : 
     913                 :          0 :             *nexthdr = frag_hdr->ip6f_nxt;
     914                 :          0 :             len = sizeof *frag_hdr;
     915         [ #  # ]:          0 :         } else if (*nexthdr == IPPROTO_ROUTING) {
     916                 :          0 :             const struct ip6_rthdr *rh = (struct ip6_rthdr *)data;
     917                 :            : 
     918         [ #  # ]:          0 :             if (rh->ip6r_segleft > 0) {
     919                 :          0 :                 return true;
     920                 :            :             }
     921                 :            : 
     922                 :          0 :             *nexthdr = rh->ip6r_nxt;
     923                 :          0 :             len = (rh->ip6r_len + 1) * 8;
     924                 :            :         } else {
     925                 :          0 :             const struct ip6_ext *ext_hdr = (struct ip6_ext *)data;
     926                 :            : 
     927                 :          0 :             *nexthdr = ext_hdr->ip6e_nxt;
     928                 :          0 :             len = (ext_hdr->ip6e_len + 1) * 8;
     929                 :            :         }
     930                 :            : 
     931         [ #  # ]:          0 :         if (remaining < len) {
     932                 :          0 :             return false;
     933                 :            :         }
     934                 :          0 :         remaining -= len;
     935                 :          0 :         data += len;
     936                 :          0 :     }
     937                 :            : 
     938                 :          6 :     return false;
     939                 :            : }
     940                 :            : 
     941                 :            : static void
     942                 :         19 : packet_update_csum128(struct dp_packet *packet, uint8_t proto,
     943                 :            :                      ovs_16aligned_be32 addr[4], const ovs_be32 new_addr[4])
     944                 :            : {
     945                 :         19 :     size_t l4_size = dp_packet_l4_size(packet);
     946                 :            : 
     947 [ -  + ][ #  # ]:         19 :     if (proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) {
     948                 :          0 :         struct tcp_header *th = dp_packet_l4(packet);
     949                 :            : 
     950                 :          0 :         th->tcp_csum = recalc_csum128(th->tcp_csum, addr, new_addr);
     951 [ +  + ][ +  - ]:         21 :     } else if (proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN) {
     952                 :          2 :         struct udp_header *uh = dp_packet_l4(packet);
     953                 :            : 
     954         [ +  - ]:          2 :         if (uh->udp_csum) {
     955                 :          2 :             uh->udp_csum = recalc_csum128(uh->udp_csum, addr, new_addr);
     956         [ -  + ]:          2 :             if (!uh->udp_csum) {
     957                 :          0 :                 uh->udp_csum = htons(0xffff);
     958                 :            :             }
     959                 :            :         }
     960 [ +  - ][ +  - ]:         17 :     } else if (proto == IPPROTO_ICMPV6 &&
     961                 :            :                l4_size >= sizeof(struct icmp6_header)) {
     962                 :         17 :         struct icmp6_header *icmp = dp_packet_l4(packet);
     963                 :            : 
     964                 :         17 :         icmp->icmp6_cksum = recalc_csum128(icmp->icmp6_cksum, addr, new_addr);
     965                 :            :     }
     966                 :         19 : }
     967                 :            : 
     968                 :            : static void
     969                 :         19 : packet_set_ipv6_addr(struct dp_packet *packet, uint8_t proto,
     970                 :            :                      ovs_16aligned_be32 addr[4], const ovs_be32 new_addr[4],
     971                 :            :                      bool recalculate_csum)
     972                 :            : {
     973         [ +  - ]:         19 :     if (recalculate_csum) {
     974                 :         19 :         packet_update_csum128(packet, proto, addr, new_addr);
     975                 :            :     }
     976                 :         19 :     memcpy(addr, new_addr, sizeof(ovs_be32[4]));
     977                 :         19 : }
     978                 :            : 
     979                 :            : static void
     980                 :          6 : packet_set_ipv6_flow_label(ovs_16aligned_be32 *flow_label, ovs_be32 flow_key)
     981                 :            : {
     982                 :          6 :     ovs_be32 old_label = get_16aligned_be32(flow_label);
     983                 :          6 :     ovs_be32 new_label = (old_label & htonl(~IPV6_LABEL_MASK)) | flow_key;
     984                 :          6 :     put_16aligned_be32(flow_label, new_label);
     985                 :          6 : }
     986                 :            : 
     987                 :            : static void
     988                 :          6 : packet_set_ipv6_tc(ovs_16aligned_be32 *flow_label, uint8_t tc)
     989                 :            : {
     990                 :          6 :     ovs_be32 old_label = get_16aligned_be32(flow_label);
     991                 :          6 :     ovs_be32 new_label = (old_label & htonl(0xF00FFFFF)) | htonl(tc << 20);
     992                 :          6 :     put_16aligned_be32(flow_label, new_label);
     993                 :          6 : }
     994                 :            : 
     995                 :            : /* Modifies the IPv4 header fields of 'packet' to be consistent with 'src',
     996                 :            :  * 'dst', 'tos', and 'ttl'.  Updates 'packet''s L4 checksums as appropriate.
     997                 :            :  * 'packet' must contain a valid IPv4 packet with correctly populated l[347]
     998                 :            :  * markers. */
     999                 :            : void
    1000                 :       1269 : packet_set_ipv4(struct dp_packet *packet, ovs_be32 src, ovs_be32 dst,
    1001                 :            :                 uint8_t tos, uint8_t ttl)
    1002                 :            : {
    1003                 :       1269 :     struct ip_header *nh = dp_packet_l3(packet);
    1004                 :            : 
    1005         [ +  + ]:       1269 :     if (get_16aligned_be32(&nh->ip_src) != src) {
    1006                 :         55 :         packet_set_ipv4_addr(packet, &nh->ip_src, src);
    1007                 :            :     }
    1008                 :            : 
    1009         [ +  + ]:       1269 :     if (get_16aligned_be32(&nh->ip_dst) != dst) {
    1010                 :         33 :         packet_set_ipv4_addr(packet, &nh->ip_dst, dst);
    1011                 :            :     }
    1012                 :            : 
    1013         [ +  + ]:       1269 :     if (nh->ip_tos != tos) {
    1014                 :          6 :         uint8_t *field = &nh->ip_tos;
    1015                 :            : 
    1016                 :          6 :         nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t) *field),
    1017                 :          6 :                                     htons((uint16_t) tos));
    1018                 :          6 :         *field = tos;
    1019                 :            :     }
    1020                 :            : 
    1021         [ +  + ]:       1269 :     if (nh->ip_ttl != ttl) {
    1022                 :       1185 :         uint8_t *field = &nh->ip_ttl;
    1023                 :            : 
    1024                 :       1185 :         nh->ip_csum = recalc_csum16(nh->ip_csum, htons(*field << 8),
    1025                 :       1185 :                                     htons(ttl << 8));
    1026                 :       1185 :         *field = ttl;
    1027                 :            :     }
    1028                 :       1269 : }
    1029                 :            : 
    1030                 :            : /* Modifies the IPv6 header fields of 'packet' to be consistent with 'src',
    1031                 :            :  * 'dst', 'traffic class', and 'next hop'.  Updates 'packet''s L4 checksums as
    1032                 :            :  * appropriate. 'packet' must contain a valid IPv6 packet with correctly
    1033                 :            :  * populated l[34] offsets. */
    1034                 :            : void
    1035                 :          6 : packet_set_ipv6(struct dp_packet *packet, const ovs_be32 src[4],
    1036                 :            :                 const ovs_be32 dst[4], uint8_t key_tc, ovs_be32 key_fl,
    1037                 :            :                 uint8_t key_hl)
    1038                 :            : {
    1039                 :          6 :     struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet);
    1040                 :          6 :     uint8_t proto = 0;
    1041                 :            :     bool rh_present;
    1042                 :            : 
    1043                 :          6 :     rh_present = packet_rh_present(packet, &proto);
    1044                 :            : 
    1045         [ +  - ]:          6 :     if (memcmp(&nh->ip6_src, src, sizeof(ovs_be32[4]))) {
    1046                 :          6 :         packet_set_ipv6_addr(packet, proto, nh->ip6_src.be32, src, true);
    1047                 :            :     }
    1048                 :            : 
    1049         [ +  - ]:          6 :     if (memcmp(&nh->ip6_dst, dst, sizeof(ovs_be32[4]))) {
    1050                 :          6 :         packet_set_ipv6_addr(packet, proto, nh->ip6_dst.be32, dst,
    1051                 :            :                              !rh_present);
    1052                 :            :     }
    1053                 :            : 
    1054                 :          6 :     packet_set_ipv6_tc(&nh->ip6_flow, key_tc);
    1055                 :          6 :     packet_set_ipv6_flow_label(&nh->ip6_flow, key_fl);
    1056                 :          6 :     nh->ip6_hlim = key_hl;
    1057                 :          6 : }
    1058                 :            : 
    1059                 :            : static void
    1060                 :         44 : packet_set_port(ovs_be16 *port, ovs_be16 new_port, ovs_be16 *csum)
    1061                 :            : {
    1062         [ +  + ]:         44 :     if (*port != new_port) {
    1063                 :         23 :         *csum = recalc_csum16(*csum, *port, new_port);
    1064                 :         23 :         *port = new_port;
    1065                 :            :     }
    1066                 :         44 : }
    1067                 :            : 
    1068                 :            : /* Sets the TCP source and destination port ('src' and 'dst' respectively) of
    1069                 :            :  * the TCP header contained in 'packet'.  'packet' must be a valid TCP packet
    1070                 :            :  * with its l4 offset properly populated. */
    1071                 :            : void
    1072                 :         14 : packet_set_tcp_port(struct dp_packet *packet, ovs_be16 src, ovs_be16 dst)
    1073                 :            : {
    1074                 :         14 :     struct tcp_header *th = dp_packet_l4(packet);
    1075                 :            : 
    1076                 :         14 :     packet_set_port(&th->tcp_src, src, &th->tcp_csum);
    1077                 :         14 :     packet_set_port(&th->tcp_dst, dst, &th->tcp_csum);
    1078                 :         14 : }
    1079                 :            : 
    1080                 :            : /* Sets the UDP source and destination port ('src' and 'dst' respectively) of
    1081                 :            :  * the UDP header contained in 'packet'.  'packet' must be a valid UDP packet
    1082                 :            :  * with its l4 offset properly populated. */
    1083                 :            : void
    1084                 :         10 : packet_set_udp_port(struct dp_packet *packet, ovs_be16 src, ovs_be16 dst)
    1085                 :            : {
    1086                 :         10 :     struct udp_header *uh = dp_packet_l4(packet);
    1087                 :            : 
    1088         [ +  + ]:         10 :     if (uh->udp_csum) {
    1089                 :          8 :         packet_set_port(&uh->udp_src, src, &uh->udp_csum);
    1090                 :          8 :         packet_set_port(&uh->udp_dst, dst, &uh->udp_csum);
    1091                 :            : 
    1092         [ -  + ]:          8 :         if (!uh->udp_csum) {
    1093                 :          8 :             uh->udp_csum = htons(0xffff);
    1094                 :            :         }
    1095                 :            :     } else {
    1096                 :          2 :         uh->udp_src = src;
    1097                 :          2 :         uh->udp_dst = dst;
    1098                 :            :     }
    1099                 :         10 : }
    1100                 :            : 
    1101                 :            : /* Sets the SCTP source and destination port ('src' and 'dst' respectively) of
    1102                 :            :  * the SCTP header contained in 'packet'.  'packet' must be a valid SCTP packet
    1103                 :            :  * with its l4 offset properly populated. */
    1104                 :            : void
    1105                 :          7 : packet_set_sctp_port(struct dp_packet *packet, ovs_be16 src, ovs_be16 dst)
    1106                 :            : {
    1107                 :          7 :     struct sctp_header *sh = dp_packet_l4(packet);
    1108                 :            :     ovs_be32 old_csum, old_correct_csum, new_csum;
    1109                 :          7 :     uint16_t tp_len = dp_packet_l4_size(packet);
    1110                 :            : 
    1111                 :          7 :     old_csum = get_16aligned_be32(&sh->sctp_csum);
    1112                 :          7 :     put_16aligned_be32(&sh->sctp_csum, 0);
    1113                 :          7 :     old_correct_csum = crc32c((void *)sh, tp_len);
    1114                 :            : 
    1115                 :          7 :     sh->sctp_src = src;
    1116                 :          7 :     sh->sctp_dst = dst;
    1117                 :            : 
    1118                 :          7 :     new_csum = crc32c((void *)sh, tp_len);
    1119                 :          7 :     put_16aligned_be32(&sh->sctp_csum, old_csum ^ old_correct_csum ^ new_csum);
    1120                 :          7 : }
    1121                 :            : 
    1122                 :            : /* Sets the ICMP type and code of the ICMP header contained in 'packet'.
    1123                 :            :  * 'packet' must be a valid ICMP packet with its l4 offset properly
    1124                 :            :  * populated. */
    1125                 :            : void
    1126                 :          4 : packet_set_icmp(struct dp_packet *packet, uint8_t type, uint8_t code)
    1127                 :            : {
    1128                 :          4 :     struct icmp_header *ih = dp_packet_l4(packet);
    1129                 :          4 :     ovs_be16 orig_tc = htons(ih->icmp_type << 8 | ih->icmp_code);
    1130                 :          4 :     ovs_be16 new_tc = htons(type << 8 | code);
    1131                 :            : 
    1132         [ +  - ]:          4 :     if (orig_tc != new_tc) {
    1133                 :          4 :         ih->icmp_type = type;
    1134                 :          4 :         ih->icmp_code = code;
    1135                 :            : 
    1136                 :          4 :         ih->icmp_csum = recalc_csum16(ih->icmp_csum, orig_tc, new_tc);
    1137                 :            :     }
    1138                 :          4 : }
    1139                 :            : 
    1140                 :            : void
    1141                 :          8 : packet_set_nd(struct dp_packet *packet, const ovs_be32 target[4],
    1142                 :            :               const struct eth_addr sll, const struct eth_addr tll)
    1143                 :            : {
    1144                 :            :     struct ovs_nd_msg *ns;
    1145                 :            :     struct ovs_nd_opt *nd_opt;
    1146                 :          8 :     int bytes_remain = dp_packet_l4_size(packet);
    1147                 :            : 
    1148         [ -  + ]:          8 :     if (OVS_UNLIKELY(bytes_remain < sizeof(*ns))) {
    1149                 :          0 :         return;
    1150                 :            :     }
    1151                 :            : 
    1152                 :          8 :     ns = dp_packet_l4(packet);
    1153                 :          8 :     nd_opt = &ns->options[0];
    1154                 :          8 :     bytes_remain -= sizeof(*ns);
    1155                 :            : 
    1156         [ +  + ]:          8 :     if (memcmp(&ns->target, target, sizeof(ovs_be32[4]))) {
    1157                 :          7 :         packet_set_ipv6_addr(packet, IPPROTO_ICMPV6,
    1158                 :          7 :                              ns->target.be32,
    1159                 :            :                              target, true);
    1160                 :            :     }
    1161                 :            : 
    1162 [ +  - ][ +  - ]:          8 :     while (bytes_remain >= ND_OPT_LEN && nd_opt->nd_opt_len != 0) {
    1163         [ +  + ]:          8 :         if (nd_opt->nd_opt_type == ND_OPT_SOURCE_LINKADDR
    1164         [ +  - ]:          6 :             && nd_opt->nd_opt_len == 1) {
    1165         [ +  - ]:          6 :             if (!eth_addr_equals(nd_opt->nd_opt_mac, sll)) {
    1166                 :          6 :                 ovs_be16 *csum = &(ns->icmph.icmp6_cksum);
    1167                 :            : 
    1168                 :          6 :                 *csum = recalc_csum48(*csum, nd_opt->nd_opt_mac, sll);
    1169                 :          6 :                 nd_opt->nd_opt_mac = sll;
    1170                 :            :             }
    1171                 :            : 
    1172                 :            :             /* A packet can only contain one SLL or TLL option */
    1173                 :          6 :             break;
    1174         [ +  - ]:          2 :         } else if (nd_opt->nd_opt_type == ND_OPT_TARGET_LINKADDR
    1175         [ +  - ]:          2 :                    && nd_opt->nd_opt_len == 1) {
    1176         [ +  - ]:          2 :             if (!eth_addr_equals(nd_opt->nd_opt_mac, tll)) {
    1177                 :          2 :                 ovs_be16 *csum = &(ns->icmph.icmp6_cksum);
    1178                 :            : 
    1179                 :          2 :                 *csum = recalc_csum48(*csum, nd_opt->nd_opt_mac, tll);
    1180                 :          2 :                 nd_opt->nd_opt_mac = tll;
    1181                 :            :             }
    1182                 :            : 
    1183                 :            :             /* A packet can only contain one SLL or TLL option */
    1184                 :          2 :             break;
    1185                 :            :         }
    1186                 :            : 
    1187                 :          0 :         nd_opt += nd_opt->nd_opt_len;
    1188                 :          0 :         bytes_remain -= nd_opt->nd_opt_len * ND_OPT_LEN;
    1189                 :            :     }
    1190                 :            : }
    1191                 :            : 
    1192                 :            : const char *
    1193                 :       2455 : packet_tcp_flag_to_string(uint32_t flag)
    1194                 :            : {
    1195   [ +  +  +  +  :       2455 :     switch (flag) {
          +  +  +  +  +  
             +  +  +  + ]
    1196                 :            :     case TCP_FIN:
    1197                 :        309 :         return "fin";
    1198                 :            :     case TCP_SYN:
    1199                 :        381 :         return "syn";
    1200                 :            :     case TCP_RST:
    1201                 :        293 :         return "rst";
    1202                 :            :     case TCP_PSH:
    1203                 :        268 :         return "psh";
    1204                 :            :     case TCP_ACK:
    1205                 :       1105 :         return "ack";
    1206                 :            :     case TCP_URG:
    1207                 :         13 :         return "urg";
    1208                 :            :     case TCP_ECE:
    1209                 :          4 :         return "ece";
    1210                 :            :     case TCP_CWR:
    1211                 :          4 :         return "cwr";
    1212                 :            :     case TCP_NS:
    1213                 :          6 :         return "ns";
    1214                 :            :     case 0x200:
    1215                 :          4 :         return "[200]";
    1216                 :            :     case 0x400:
    1217                 :          4 :         return "[400]";
    1218                 :            :     case 0x800:
    1219                 :          4 :         return "[800]";
    1220                 :            :     default:
    1221                 :         60 :         return NULL;
    1222                 :            :     }
    1223                 :            : }
    1224                 :            : 
    1225                 :            : /* Appends a string representation of the TCP flags value 'tcp_flags'
    1226                 :            :  * (e.g. from struct flow.tcp_flags or obtained via TCP_FLAGS) to 's', in the
    1227                 :            :  * format used by tcpdump. */
    1228                 :            : void
    1229                 :         54 : packet_format_tcp_flags(struct ds *s, uint16_t tcp_flags)
    1230                 :            : {
    1231         [ -  + ]:         54 :     if (!tcp_flags) {
    1232                 :          0 :         ds_put_cstr(s, "none");
    1233                 :          0 :         return;
    1234                 :            :     }
    1235                 :            : 
    1236         [ +  + ]:         54 :     if (tcp_flags & TCP_SYN) {
    1237                 :         24 :         ds_put_char(s, 'S');
    1238                 :            :     }
    1239         [ +  - ]:         54 :     if (tcp_flags & TCP_FIN) {
    1240                 :         54 :         ds_put_char(s, 'F');
    1241                 :            :     }
    1242         [ +  - ]:         54 :     if (tcp_flags & TCP_PSH) {
    1243                 :         54 :         ds_put_char(s, 'P');
    1244                 :            :     }
    1245         [ -  + ]:         54 :     if (tcp_flags & TCP_RST) {
    1246                 :          0 :         ds_put_char(s, 'R');
    1247                 :            :     }
    1248         [ -  + ]:         54 :     if (tcp_flags & TCP_URG) {
    1249                 :          0 :         ds_put_char(s, 'U');
    1250                 :            :     }
    1251         [ +  - ]:         54 :     if (tcp_flags & TCP_ACK) {
    1252                 :         54 :         ds_put_char(s, '.');
    1253                 :            :     }
    1254         [ -  + ]:         54 :     if (tcp_flags & TCP_ECE) {
    1255                 :          0 :         ds_put_cstr(s, "E");
    1256                 :            :     }
    1257         [ -  + ]:         54 :     if (tcp_flags & TCP_CWR) {
    1258                 :          0 :         ds_put_cstr(s, "C");
    1259                 :            :     }
    1260         [ -  + ]:         54 :     if (tcp_flags & TCP_NS) {
    1261                 :          0 :         ds_put_cstr(s, "N");
    1262                 :            :     }
    1263         [ -  + ]:         54 :     if (tcp_flags & 0x200) {
    1264                 :          0 :         ds_put_cstr(s, "[200]");
    1265                 :            :     }
    1266         [ -  + ]:         54 :     if (tcp_flags & 0x400) {
    1267                 :          0 :         ds_put_cstr(s, "[400]");
    1268                 :            :     }
    1269         [ -  + ]:         54 :     if (tcp_flags & 0x800) {
    1270                 :          0 :         ds_put_cstr(s, "[800]");
    1271                 :            :     }
    1272                 :            : }
    1273                 :            : 
    1274                 :            : #define ARP_PACKET_SIZE  (2 + ETH_HEADER_LEN + VLAN_HEADER_LEN + \
    1275                 :            :                           ARP_ETH_HEADER_LEN)
    1276                 :            : 
    1277                 :            : /* Clears 'b' and replaces its contents by an ARP frame with the specified
    1278                 :            :  * 'arp_op', 'arp_sha', 'arp_tha', 'arp_spa', and 'arp_tpa'.  The outer
    1279                 :            :  * Ethernet frame is initialized with Ethernet source 'arp_sha' and destination
    1280                 :            :  * 'arp_tha', except that destination ff:ff:ff:ff:ff:ff is used instead if
    1281                 :            :  * 'broadcast' is true.  Points the L3 header to the ARP header. */
    1282                 :            : void
    1283                 :          9 : compose_arp(struct dp_packet *b, uint16_t arp_op,
    1284                 :            :             const struct eth_addr arp_sha, const struct eth_addr arp_tha,
    1285                 :            :             bool broadcast, ovs_be32 arp_spa, ovs_be32 arp_tpa)
    1286                 :            : {
    1287                 :          9 :     compose_arp__(b);
    1288                 :            : 
    1289                 :          9 :     struct eth_header *eth = dp_packet_l2(b);
    1290         [ +  - ]:          9 :     eth->eth_dst = broadcast ? eth_addr_broadcast : arp_tha;
    1291                 :          9 :     eth->eth_src = arp_sha;
    1292                 :            : 
    1293                 :          9 :     struct arp_eth_header *arp = dp_packet_l3(b);
    1294                 :          9 :     arp->ar_op = htons(arp_op);
    1295                 :          9 :     arp->ar_sha = arp_sha;
    1296                 :          9 :     arp->ar_tha = arp_tha;
    1297                 :          9 :     put_16aligned_be32(&arp->ar_spa, arp_spa);
    1298                 :          9 :     put_16aligned_be32(&arp->ar_tpa, arp_tpa);
    1299                 :          9 : }
    1300                 :            : 
    1301                 :            : /* Clears 'b' and replaces its contents by an ARP frame.  Sets the fields in
    1302                 :            :  * the Ethernet and ARP headers that are fixed for ARP frames to those fixed
    1303                 :            :  * values, and zeroes the other fields.  Points the L3 header to the ARP
    1304                 :            :  * header. */
    1305                 :            : void
    1306                 :        226 : compose_arp__(struct dp_packet *b)
    1307                 :            : {
    1308                 :        226 :     dp_packet_clear(b);
    1309                 :        226 :     dp_packet_prealloc_tailroom(b, ARP_PACKET_SIZE);
    1310                 :        226 :     dp_packet_reserve(b, 2 + VLAN_HEADER_LEN);
    1311                 :            : 
    1312                 :        226 :     struct eth_header *eth = dp_packet_put_zeros(b, sizeof *eth);
    1313                 :        226 :     eth->eth_type = htons(ETH_TYPE_ARP);
    1314                 :            : 
    1315                 :        226 :     struct arp_eth_header *arp = dp_packet_put_zeros(b, sizeof *arp);
    1316                 :        226 :     arp->ar_hrd = htons(ARP_HRD_ETHERNET);
    1317                 :        226 :     arp->ar_pro = htons(ARP_PRO_IP);
    1318                 :        226 :     arp->ar_hln = sizeof arp->ar_sha;
    1319                 :        226 :     arp->ar_pln = sizeof arp->ar_spa;
    1320                 :            : 
    1321                 :        226 :     dp_packet_reset_offsets(b);
    1322                 :        226 :     dp_packet_set_l3(b, arp);
    1323                 :        226 : }
    1324                 :            : 
    1325                 :            : /* This function expects packet with ethernet header with correct
    1326                 :            :  * l3 pointer set. */
    1327                 :            : static void *
    1328                 :          5 : compose_ipv6(struct dp_packet *packet, uint8_t proto,
    1329                 :            :              const struct in6_addr *src, const struct in6_addr *dst,
    1330                 :            :              uint8_t key_tc, ovs_be32 key_fl, uint8_t key_hl, int size)
    1331                 :            : {
    1332                 :            :     struct ip6_hdr *nh;
    1333                 :            :     void *data;
    1334                 :            : 
    1335                 :            :     /* Copy 'src' and 'dst' to temporary buffers to prevent misaligned
    1336                 :            :      * accesses. */
    1337                 :            :     ovs_be32 sbuf[4], dbuf[4];
    1338                 :          5 :     memcpy(sbuf, src, sizeof sbuf);
    1339                 :          5 :     memcpy(dbuf, dst, sizeof dbuf);
    1340                 :            : 
    1341                 :          5 :     nh = dp_packet_l3(packet);
    1342                 :          5 :     nh->ip6_vfc = 0x60;
    1343                 :          5 :     nh->ip6_nxt = proto;
    1344                 :          5 :     nh->ip6_plen = htons(size);
    1345                 :          5 :     data = dp_packet_put_zeros(packet, size);
    1346                 :          5 :     dp_packet_set_l4(packet, data);
    1347                 :          5 :     packet_set_ipv6(packet, sbuf, dbuf, key_tc, key_fl, key_hl);
    1348                 :          5 :     return data;
    1349                 :            : }
    1350                 :            : 
    1351                 :            : /* Compose an IPv6 Neighbor Discovery Neighbor Solicitation message. */
    1352                 :            : void
    1353                 :          4 : compose_nd_ns(struct dp_packet *b, const struct eth_addr eth_src,
    1354                 :            :               const struct in6_addr *ipv6_src, const struct in6_addr *ipv6_dst)
    1355                 :            : {
    1356                 :            :     struct in6_addr sn_addr;
    1357                 :            :     struct eth_addr eth_dst;
    1358                 :            :     struct ovs_nd_msg *ns;
    1359                 :            :     struct ovs_nd_opt *nd_opt;
    1360                 :            :     uint32_t icmp_csum;
    1361                 :            : 
    1362                 :          4 :     in6_addr_solicited_node(&sn_addr, ipv6_dst);
    1363                 :          4 :     ipv6_multicast_to_ethernet(&eth_dst, &sn_addr);
    1364                 :            : 
    1365                 :          4 :     eth_compose(b, eth_dst, eth_src, ETH_TYPE_IPV6, IPV6_HEADER_LEN);
    1366                 :          4 :     ns = compose_ipv6(b, IPPROTO_ICMPV6, ipv6_src, &sn_addr,
    1367                 :            :                       0, 0, 255, ND_MSG_LEN + ND_OPT_LEN);
    1368                 :            : 
    1369                 :          4 :     ns->icmph.icmp6_type = ND_NEIGHBOR_SOLICIT;
    1370                 :          4 :     ns->icmph.icmp6_code = 0;
    1371                 :          4 :     put_16aligned_be32(&ns->rso_flags, htonl(0));
    1372                 :            : 
    1373                 :          4 :     nd_opt = &ns->options[0];
    1374                 :          4 :     nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
    1375                 :          4 :     nd_opt->nd_opt_len = 1;
    1376                 :            : 
    1377                 :            :     /* Copy target address to temp buffer to prevent misaligned access. */
    1378                 :            :     ovs_be32 tbuf[4];
    1379                 :          4 :     memcpy(tbuf, ipv6_dst->s6_addr, sizeof tbuf);
    1380                 :          4 :     packet_set_nd(b, tbuf, eth_src, eth_addr_zero);
    1381                 :            : 
    1382                 :          4 :     ns->icmph.icmp6_cksum = 0;
    1383                 :          4 :     icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b));
    1384                 :          4 :     ns->icmph.icmp6_cksum = csum_finish(csum_continue(icmp_csum, ns,
    1385                 :            :                                                       ND_MSG_LEN + ND_OPT_LEN));
    1386                 :          4 : }
    1387                 :            : 
    1388                 :            : /* Compose an IPv6 Neighbor Discovery Neighbor Advertisement message. */
    1389                 :            : void
    1390                 :          1 : compose_nd_na(struct dp_packet *b,
    1391                 :            :               const struct eth_addr eth_src, const struct eth_addr eth_dst,
    1392                 :            :               const struct in6_addr *ipv6_src, const struct in6_addr *ipv6_dst,
    1393                 :            :               ovs_be32 rso_flags)
    1394                 :            : {
    1395                 :            :     struct ovs_nd_msg *na;
    1396                 :            :     struct ovs_nd_opt *nd_opt;
    1397                 :            :     uint32_t icmp_csum;
    1398                 :            : 
    1399                 :          1 :     eth_compose(b, eth_dst, eth_src, ETH_TYPE_IPV6, IPV6_HEADER_LEN);
    1400                 :          1 :     na = compose_ipv6(b, IPPROTO_ICMPV6, ipv6_src, ipv6_dst,
    1401                 :            :                       0, 0, 255, ND_MSG_LEN + ND_OPT_LEN);
    1402                 :            : 
    1403                 :          1 :     na->icmph.icmp6_type = ND_NEIGHBOR_ADVERT;
    1404                 :          1 :     na->icmph.icmp6_code = 0;
    1405                 :          1 :     put_16aligned_be32(&na->rso_flags, rso_flags);
    1406                 :            : 
    1407                 :          1 :     nd_opt = &na->options[0];
    1408                 :          1 :     nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
    1409                 :          1 :     nd_opt->nd_opt_len = 1;
    1410                 :            : 
    1411                 :            :     /* Copy target address to temp buffer to prevent misaligned access. */
    1412                 :            :     ovs_be32 tbuf[4];
    1413                 :          1 :     memcpy(tbuf, ipv6_src->s6_addr, sizeof tbuf);
    1414                 :          1 :     packet_set_nd(b, tbuf, eth_addr_zero, eth_src);
    1415                 :            : 
    1416                 :          1 :     na->icmph.icmp6_cksum = 0;
    1417                 :          1 :     icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b));
    1418                 :          1 :     na->icmph.icmp6_cksum = csum_finish(csum_continue(icmp_csum, na,
    1419                 :            :                                                       ND_MSG_LEN + ND_OPT_LEN));
    1420                 :          1 : }
    1421                 :            : 
    1422                 :            : uint32_t
    1423                 :       5688 : packet_csum_pseudoheader(const struct ip_header *ip)
    1424                 :            : {
    1425                 :       5688 :     uint32_t partial = 0;
    1426                 :            : 
    1427                 :       5688 :     partial = csum_add32(partial, get_16aligned_be32(&ip->ip_src));
    1428                 :       5688 :     partial = csum_add32(partial, get_16aligned_be32(&ip->ip_dst));
    1429                 :       5688 :     partial = csum_add16(partial, htons(ip->ip_proto));
    1430                 :       5688 :     partial = csum_add16(partial, htons(ntohs(ip->ip_tot_len) -
    1431                 :       5688 :                                         IP_IHL(ip->ip_ihl_ver) * 4));
    1432                 :            : 
    1433                 :       5688 :     return partial;
    1434                 :            : }
    1435                 :            : 
    1436                 :            : #ifndef __CHECKER__
    1437                 :            : uint32_t
    1438                 :        118 : packet_csum_pseudoheader6(const struct ovs_16aligned_ip6_hdr *ip6)
    1439                 :            : {
    1440                 :        118 :     uint32_t partial = 0;
    1441                 :            : 
    1442                 :        118 :     partial = csum_add32(partial, get_16aligned_be32(&(ip6->ip6_src.be32[0])));
    1443                 :        118 :     partial = csum_add32(partial, get_16aligned_be32(&(ip6->ip6_src.be32[1])));
    1444                 :        118 :     partial = csum_add32(partial, get_16aligned_be32(&(ip6->ip6_src.be32[2])));
    1445                 :        118 :     partial = csum_add32(partial, get_16aligned_be32(&(ip6->ip6_src.be32[3])));
    1446                 :            : 
    1447                 :        118 :     partial = csum_add32(partial, get_16aligned_be32(&(ip6->ip6_dst.be32[0])));
    1448                 :        118 :     partial = csum_add32(partial, get_16aligned_be32(&(ip6->ip6_dst.be32[1])));
    1449                 :        118 :     partial = csum_add32(partial, get_16aligned_be32(&(ip6->ip6_dst.be32[2])));
    1450                 :        118 :     partial = csum_add32(partial, get_16aligned_be32(&(ip6->ip6_dst.be32[3])));
    1451                 :            : 
    1452                 :        118 :     partial = csum_add16(partial, htons(ip6->ip6_nxt));
    1453                 :        118 :     partial = csum_add16(partial, ip6->ip6_plen);
    1454                 :            : 
    1455                 :        118 :     return partial;
    1456                 :            : }
    1457                 :            : #endif
    1458                 :            : 
    1459                 :            : void
    1460                 :          0 : IP_ECN_set_ce(struct dp_packet *pkt, bool is_ipv6)
    1461                 :            : {
    1462         [ #  # ]:          0 :     if (is_ipv6) {
    1463                 :          0 :         ovs_16aligned_be32 *ip6 = dp_packet_l3(pkt);
    1464                 :            : 
    1465                 :          0 :         put_16aligned_be32(ip6, get_16aligned_be32(ip6) |
    1466                 :          0 :                                 htonl(IP_ECN_CE << 20));
    1467                 :            :     } else {
    1468                 :          0 :         struct ip_header *nh = dp_packet_l3(pkt);
    1469                 :          0 :         uint8_t tos = nh->ip_tos;
    1470                 :            : 
    1471                 :          0 :         tos |= IP_ECN_CE;
    1472         [ #  # ]:          0 :         if (nh->ip_tos != tos) {
    1473                 :          0 :             nh->ip_csum = recalc_csum16(nh->ip_csum, htons(nh->ip_tos),
    1474                 :          0 :                                         htons((uint16_t) tos));
    1475                 :          0 :             nh->ip_tos = tos;
    1476                 :            :         }
    1477                 :            :     }
    1478                 :          0 : }

Generated by: LCOV version 1.12