ofproto-dpif.at: Add test for normal action with OFPP_NONE in_port.
[openvswitch] / lib / flow.c
index 3865e509dc85b32309f448c7230d681c926ebc7d..fa7ae4f178327fa681b05c5e37832037f313e5fd 100644 (file)
@@ -203,11 +203,14 @@ parse_ipv6(struct ofpbuf *packet, struct flow *flow)
             }
 
             /* We only process the first fragment. */
-            flow->nw_frag = FLOW_NW_FRAG_ANY;
-            if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) {
-                flow->nw_frag |= FLOW_NW_FRAG_LATER;
-                nexthdr = IPPROTO_FRAGMENT;
-                break;
+            if (frag_hdr->ip6f_offlg != htons(0)) {
+                if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) == htons(0)) {
+                    flow->nw_frag = FLOW_NW_FRAG_ANY;
+                } else {
+                    flow->nw_frag |= FLOW_NW_FRAG_LATER;
+                    nexthdr = IPPROTO_FRAGMENT;
+                    break;
+                }
             }
         }
     }
@@ -309,7 +312,9 @@ invalid:
 
 }
 
-/* Initializes 'flow' members from 'packet', 'tun_id', and 'ofp_in_port'.
+/* Initializes 'flow' members from 'packet', 'skb_priority', 'tun_id', and
+ * 'ofp_in_port'.
+ *
  * Initializes 'packet' header pointers as follows:
  *
  *    - packet->l2 to the start of the Ethernet header.
@@ -325,7 +330,7 @@ invalid:
  *      present and has a correct length, and otherwise NULL.
  */
 void
-flow_extract(struct ofpbuf *packet, uint32_t priority, ovs_be64 tun_id,
+flow_extract(struct ofpbuf *packet, uint32_t skb_priority, ovs_be64 tun_id,
              uint16_t ofp_in_port, struct flow *flow)
 {
     struct ofpbuf b = *packet;
@@ -336,7 +341,7 @@ flow_extract(struct ofpbuf *packet, uint32_t priority, ovs_be64 tun_id,
     memset(flow, 0, sizeof *flow);
     flow->tun_id = tun_id;
     flow->in_port = ofp_in_port;
-    flow->priority = priority;
+    flow->skb_priority = skb_priority;
 
     packet->l2 = b.data;
     packet->l3 = NULL;
@@ -499,7 +504,7 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
     if (wc & FWW_ND_TARGET) {
         memset(&flow->nd_target, 0, sizeof flow->nd_target);
     }
-    flow->priority = 0;
+    flow->skb_priority = 0;
 }
 
 char *
@@ -516,7 +521,7 @@ flow_format(struct ds *ds, const struct flow *flow)
     ds_put_format(ds, "priority%"PRIu32
                       ":tunnel%#"PRIx64
                       ":in_port%04"PRIx16,
-                      flow->priority,
+                      flow->skb_priority,
                       ntohll(flow->tun_id),
                       flow->in_port);
 
@@ -1017,6 +1022,7 @@ flow_compose(struct ofpbuf *b, const struct flow *flow)
                 b->l4 = tcp = ofpbuf_put_zeros(b, sizeof *tcp);
                 tcp->tcp_src = flow->tp_src;
                 tcp->tcp_dst = flow->tp_dst;
+                tcp->tcp_ctl = TCP_CTL(0, 5);
             } else if (flow->nw_proto == IPPROTO_UDP) {
                 struct udp_header *udp;
 
@@ -1031,6 +1037,9 @@ flow_compose(struct ofpbuf *b, const struct flow *flow)
                 icmp->icmp_code = ntohs(flow->tp_dst);
             }
         }
+
+        ip->ip_tot_len = htons((uint8_t *) b->data + b->size
+                               - (uint8_t *) b->l3);
     } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
         /* XXX */
     } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {