Process RARP packets with ethertype 0x8035 similar to ARP packets.
[openvswitch] / lib / flow.c
index 0c9aa3637559830c47638319390ce69f5ecbd2e5..7084079ea778da6dc310b9e242c9a2d0a5a9ea03 100644 (file)
@@ -424,7 +424,8 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority,
                 packet->l7 = b.data;
             }
         }
-    } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {
+    } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
+               flow->dl_type == htons(ETH_TYPE_RARP)) {
         const struct arp_eth_header *arp = pull_arp(&b);
         if (arp && arp->ar_hrd == htons(1)
             && arp->ar_pro == htons(ETH_TYPE_IP)
@@ -435,13 +436,10 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority,
                 flow->nw_proto = ntohs(arp->ar_op);
             }
 
-            if ((flow->nw_proto == ARP_OP_REQUEST)
-                || (flow->nw_proto == ARP_OP_REPLY)) {
-                flow->nw_src = arp->ar_spa;
-                flow->nw_dst = arp->ar_tpa;
-                memcpy(flow->arp_sha, arp->ar_sha, ETH_ADDR_LEN);
-                memcpy(flow->arp_tha, arp->ar_tha, ETH_ADDR_LEN);
-            }
+            flow->nw_src = arp->ar_spa;
+            flow->nw_dst = arp->ar_tpa;
+            memcpy(flow->arp_sha, arp->ar_sha, ETH_ADDR_LEN);
+            memcpy(flow->arp_tha, arp->ar_tha, ETH_ADDR_LEN);
         }
     }
 }
@@ -512,7 +510,6 @@ void
 flow_wildcards_init_exact(struct flow_wildcards *wc)
 {
     memset(&wc->masks, 0xff, sizeof wc->masks);
-    memset(wc->masks.zeros, 0, sizeof wc->masks.zeros);
 }
 
 /* Returns true if 'wc' matches every packet, false if 'wc' fixes any bits or
@@ -770,6 +767,7 @@ flow_compose(struct ofpbuf *b, const struct flow *flow)
         b->l3 = ip = ofpbuf_put_zeros(b, sizeof *ip);
         ip->ip_ihl_ver = IP_IHL_VER(5, 4);
         ip->ip_tos = flow->nw_tos;
+        ip->ip_ttl = flow->nw_ttl;
         ip->ip_proto = flow->nw_proto;
         ip->ip_src = flow->nw_src;
         ip->ip_dst = flow->nw_dst;
@@ -811,7 +809,8 @@ flow_compose(struct ofpbuf *b, const struct flow *flow)
         ip->ip_csum = csum(ip, sizeof *ip);
     } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
         /* XXX */
-    } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {
+    } else if (flow->dl_type == htons(ETH_TYPE_ARP) ||
+               flow->dl_type == htons(ETH_TYPE_RARP)) {
         struct arp_eth_header *arp;
 
         b->l3 = arp = ofpbuf_put_zeros(b, sizeof *arp);