Don't overload IP TOS with the frag matching bits.
authorJustin Pettit <jpettit@nicira.com>
Thu, 3 Nov 2011 01:17:36 +0000 (18:17 -0700)
committerJustin Pettit <jpettit@nicira.com>
Wed, 9 Nov 2011 18:37:57 +0000 (10:37 -0800)
This will be useful later when we add support for matching the ECN bits
within the TOS field.

Signed-off-by: Justin Pettit <jpettit@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
14 files changed:
datapath/datapath.c
datapath/flow.c
datapath/flow.h
lib/classifier.c
lib/flow.c
lib/flow.h
lib/meta-flow.c
lib/nx-match.c
lib/odp-util.c
lib/odp-util.h
lib/ofp-util.c
ofproto/netflow.c
ofproto/ofproto-dpif.c
tests/test-classifier.c

index 9a22aab8cc4be32e3719eedef61bc0187f0a87a2..21efd02f321bbb2c742763c6f3975cf48f08b53d 100644 (file)
@@ -423,8 +423,7 @@ static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
                         * properly mark later fragments.
                         */
                        later_key = *upcall_info->key;
-                       later_key.ip.tos_frag &= ~OVS_FRAG_TYPE_MASK;
-                       later_key.ip.tos_frag |= OVS_FRAG_TYPE_LATER;
+                       later_key.ip.frag = OVS_FRAG_TYPE_LATER;
 
                        later_info = *upcall_info;
                        later_info.key = &later_key;
@@ -593,8 +592,7 @@ static int validate_action_key(const struct nlattr *a,
                if (ipv4_key->ipv4_tos & INET_ECN_MASK)
                        return -EINVAL;
 
-               if (ipv4_key->ipv4_frag !=
-                   (flow_key->ip.tos_frag & OVS_FRAG_TYPE_MASK))
+               if (ipv4_key->ipv4_frag != flow_key->ip.frag)
                        return -EINVAL;
 
                break;
index a7832a4354e2fc8ec1ba3d34d503ca939aa218f5..5080ee90d8ae646eec04c0cd1e0c2eafcb84c696 100644 (file)
@@ -126,10 +126,10 @@ u64 flow_used_time(unsigned long flow_jiffies)
  * @nexthdrp: Initially, points to the type of the extension header at @start.
  * This function updates it to point to the extension header at the final
  * offset.
- * @tos_frag: Points to the @tos_frag member in a &struct sw_flow_key.  This
+ * @frag: Points to the @frag member in a &struct sw_flow_key.  This
  * function sets an appropriate %OVS_FRAG_TYPE_* value.
  *
- * This is based on ipv6_skip_exthdr() but adds the updates to *@tos_frag.
+ * This is based on ipv6_skip_exthdr() but adds the updates to *@frag.
  *
  * When there is more than one fragment header, this version reports whether
  * the final fragment header that it examines is a first fragment.
@@ -137,7 +137,7 @@ u64 flow_used_time(unsigned long flow_jiffies)
  * Returns the final payload offset, or -1 on error.
  */
 static int skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp,
-                      u8 *tos_frag)
+                      u8 *frag)
 {
        u8 nexthdr = *nexthdrp;
 
@@ -160,12 +160,11 @@ static int skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp,
                        if (fp == NULL)
                                return -1;
 
-                       *tos_frag &= ~OVS_FRAG_TYPE_MASK;
                        if (ntohs(*fp) & ~0x7) {
-                               *tos_frag |= OVS_FRAG_TYPE_LATER;
+                               *frag = OVS_FRAG_TYPE_LATER;
                                break;
                        }
-                       *tos_frag |= OVS_FRAG_TYPE_FIRST;
+                       *frag = OVS_FRAG_TYPE_FIRST;
                        hdrlen = 8;
                } else if (nexthdr == NEXTHDR_AUTH)
                        hdrlen = (hp->hdrlen+2)<<2;
@@ -201,13 +200,12 @@ static int parse_ipv6hdr(struct sk_buff *skb, struct sw_flow_key *key,
        payload_ofs = (u8 *)(nh + 1) - skb->data;
 
        key->ip.proto = NEXTHDR_NONE;
-       key->ip.tos_frag = ipv6_get_dsfield(nh) & ~INET_ECN_MASK;
+       key->ip.tos = ipv6_get_dsfield(nh) & ~INET_ECN_MASK;
        key->ipv6.label = *(__be32 *)nh & htonl(IPV6_FLOWINFO_FLOWLABEL);
        ipv6_addr_copy(&key->ipv6.addr.src, &nh->saddr);
        ipv6_addr_copy(&key->ipv6.addr.dst, &nh->daddr);
 
-       payload_ofs = skip_exthdr(skb, payload_ofs,
-                                 &nexthdr, &key->ip.tos_frag);
+       payload_ofs = skip_exthdr(skb, payload_ofs, &nexthdr, &key->ip.frag);
        if (unlikely(payload_ofs < 0))
                return -EINVAL;
 
@@ -691,16 +689,16 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
                key->ipv4.addr.dst = nh->daddr;
 
                key->ip.proto = nh->protocol;
-               key->ip.tos_frag = nh->tos & ~INET_ECN_MASK;
+               key->ip.tos = nh->tos & ~INET_ECN_MASK;
 
                offset = nh->frag_off & htons(IP_OFFSET);
                if (offset) {
-                       key->ip.tos_frag |= OVS_FRAG_TYPE_LATER;
+                       key->ip.frag = OVS_FRAG_TYPE_LATER;
                        goto out;
                }
                if (nh->frag_off & htons(IP_MF) ||
                         skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
-                       key->ip.tos_frag |= OVS_FRAG_TYPE_FIRST;
+                       key->ip.frag = OVS_FRAG_TYPE_FIRST;
 
                /* Transport layer. */
                if (key->ip.proto == IPPROTO_TCP) {
@@ -764,10 +762,10 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
                        goto out;
                }
 
-               if ((key->ip.tos_frag & OVS_FRAG_TYPE_MASK) == OVS_FRAG_TYPE_LATER)
+               if (key->ip.frag == OVS_FRAG_TYPE_LATER)
                        goto out;
                if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
-                       key->ip.tos_frag |= OVS_FRAG_TYPE_FIRST;
+                       key->ip.frag = OVS_FRAG_TYPE_FIRST;
 
                /* Transport layer. */
                if (key->ip.proto == NEXTHDR_TCP) {
@@ -843,15 +841,6 @@ void flow_tbl_remove(struct flow_table *table, struct sw_flow *flow)
        }
 }
 
-static int parse_tos_frag(struct sw_flow_key *swkey, u8 tos, u8 frag)
-{
-       if (tos & INET_ECN_MASK || frag > OVS_FRAG_TYPE_MAX)
-               return -EINVAL;
-
-       swkey->ip.tos_frag = tos | frag;
-       return 0;
-}
-
 /* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute.  */
 const u32 ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
        [OVS_KEY_ATTR_PRIORITY] = 4,
@@ -890,7 +879,6 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
                      const struct nlattr *attr)
 {
        int error = 0;
-       enum ovs_frag_type frag_type;
        const struct nlattr *nla;
        u16 prev_type;
        int rem;
@@ -970,10 +958,13 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
                        if (swkey->eth.type != htons(ETH_P_IP))
                                goto invalid;
                        ipv4_key = nla_data(nla);
-                       swkey->ip.proto = ipv4_key->ipv4_proto;
-                       if (parse_tos_frag(swkey, ipv4_key->ipv4_tos,
-                                          ipv4_key->ipv4_frag))
+                       if (ipv4_key->ipv4_tos & INET_ECN_MASK)
+                               goto invalid;
+                       if (ipv4_key->ipv4_frag > OVS_FRAG_TYPE_MAX)
                                goto invalid;
+                       swkey->ip.proto = ipv4_key->ipv4_proto;
+                       swkey->ip.tos = ipv4_key->ipv4_tos;
+                       swkey->ip.frag = ipv4_key->ipv4_frag;
                        swkey->ipv4.addr.src = ipv4_key->ipv4_src;
                        swkey->ipv4.addr.dst = ipv4_key->ipv4_dst;
                        break;
@@ -983,11 +974,14 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
                        if (swkey->eth.type != htons(ETH_P_IPV6))
                                goto invalid;
                        ipv6_key = nla_data(nla);
+                       if (ipv6_key->ipv6_tos & INET_ECN_MASK)
+                               goto invalid;
+                       if (ipv6_key->ipv6_frag > OVS_FRAG_TYPE_MAX)
+                               goto invalid;
                        swkey->ipv6.label = ipv6_key->ipv6_label;
                        swkey->ip.proto = ipv6_key->ipv6_proto;
-                       if (parse_tos_frag(swkey, ipv6_key->ipv6_tos,
-                                          ipv6_key->ipv6_frag))
-                               goto invalid;
+                       swkey->ip.tos = ipv6_key->ipv6_tos;
+                       swkey->ip.frag = ipv6_key->ipv6_frag;
                        memcpy(&swkey->ipv6.addr.src, ipv6_key->ipv6_src,
                                        sizeof(swkey->ipv6.addr.src));
                        memcpy(&swkey->ipv6.addr.dst, ipv6_key->ipv6_dst,
@@ -1083,7 +1077,6 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
        if (rem)
                goto invalid;
 
-       frag_type = swkey->ip.tos_frag & OVS_FRAG_TYPE_MASK;
        switch (prev_type) {
        case OVS_KEY_ATTR_UNSPEC:
                goto invalid;
@@ -1105,7 +1098,7 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
                goto ok;
 
        case OVS_KEY_ATTR_IPV4:
-               if (frag_type == OVS_FRAG_TYPE_LATER)
+               if (swkey->ip.frag == OVS_FRAG_TYPE_LATER)
                        goto ok;
                if (swkey->ip.proto == IPPROTO_TCP ||
                    swkey->ip.proto == IPPROTO_UDP ||
@@ -1114,7 +1107,7 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
                goto ok;
 
        case OVS_KEY_ATTR_IPV6:
-               if (frag_type == OVS_FRAG_TYPE_LATER)
+               if (swkey->ip.frag == OVS_FRAG_TYPE_LATER)
                        goto ok;
                if (swkey->ip.proto == IPPROTO_TCP ||
                    swkey->ip.proto == IPPROTO_UDP ||
@@ -1125,7 +1118,7 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
        case OVS_KEY_ATTR_ICMPV6:
                if (swkey->ipv6.tp.src == htons(NDISC_NEIGHBOUR_SOLICITATION) ||
                    swkey->ipv6.tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT) ||
-                   frag_type == OVS_FRAG_TYPE_LATER)
+                   swkey->ip.frag == OVS_FRAG_TYPE_LATER)
                        goto invalid;
                goto ok;
 
@@ -1133,7 +1126,7 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
        case OVS_KEY_ATTR_UDP:
        case OVS_KEY_ATTR_ICMP:
        case OVS_KEY_ATTR_ND:
-               if (frag_type == OVS_FRAG_TYPE_LATER)
+               if (swkey->ip.frag == OVS_FRAG_TYPE_LATER)
                        goto invalid;
                goto ok;
 
@@ -1256,8 +1249,8 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
                ipv4_key->ipv4_src = swkey->ipv4.addr.src;
                ipv4_key->ipv4_dst = swkey->ipv4.addr.dst;
                ipv4_key->ipv4_proto = swkey->ip.proto;
-               ipv4_key->ipv4_tos = swkey->ip.tos_frag & ~INET_ECN_MASK;
-               ipv4_key->ipv4_frag = swkey->ip.tos_frag & OVS_FRAG_TYPE_MASK;
+               ipv4_key->ipv4_tos = swkey->ip.tos & ~INET_ECN_MASK;
+               ipv4_key->ipv4_frag = swkey->ip.frag;
        } else if (swkey->eth.type == htons(ETH_P_IPV6)) {
                struct ovs_key_ipv6 *ipv6_key;
 
@@ -1272,8 +1265,8 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
                                sizeof(ipv6_key->ipv6_dst));
                ipv6_key->ipv6_label = swkey->ipv6.label;
                ipv6_key->ipv6_proto = swkey->ip.proto;
-               ipv6_key->ipv6_tos = swkey->ip.tos_frag & ~INET_ECN_MASK;
-               ipv6_key->ipv6_frag = swkey->ip.tos_frag & OVS_FRAG_TYPE_MASK;
+               ipv6_key->ipv6_tos = swkey->ip.tos & ~INET_ECN_MASK;
+               ipv6_key->ipv6_frag = swkey->ip.frag;
        } else if (swkey->eth.type == htons(ETH_P_ARP)) {
                struct ovs_key_arp *arp_key;
 
@@ -1291,7 +1284,7 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 
        if ((swkey->eth.type == htons(ETH_P_IP) ||
             swkey->eth.type == htons(ETH_P_IPV6)) &&
-           (swkey->ip.tos_frag & OVS_FRAG_TYPE_MASK) != OVS_FRAG_TYPE_LATER) {
+            swkey->ip.frag != OVS_FRAG_TYPE_LATER) {
 
                if (swkey->ip.proto == IPPROTO_TCP) {
                        struct ovs_key_tcp *tcp_key;
index 0471cfc567ccfe661dbb71203047014b3277a8a2..1604cd5dbd9e1b3d3d66b8d0efe1ddc9c384f722 100644 (file)
@@ -30,10 +30,6 @@ struct sw_flow_actions {
        struct nlattr actions[];
 };
 
-/* Mask for the OVS_FRAG_TYPE_* value in the low 2 bits of ip.tos_frag in
- * struct sw_flow_key. */
-#define OVS_FRAG_TYPE_MASK INET_ECN_MASK
-
 struct sw_flow_key {
        struct {
                __be64  tun_id;         /* Encapsulating tunnel ID. */
@@ -48,8 +44,8 @@ struct sw_flow_key {
        } eth;
        struct {
                u8     proto;           /* IP protocol or lower 8 bits of ARP opcode. */
-               u8     tos_frag;        /* IP ToS DSCP in high 6 bits,
-                                        * OVS_FRAG_TYPE_* in low 2 bits. */
+               u8     tos;         /* IP ToS DSCP in high 6 bits. */
+               u8     frag;        /* One of OVS_FRAG_TYPE_*. */
        } ip;
        union {
                struct {
@@ -147,7 +143,7 @@ u64 flow_used_time(unsigned long flow_jiffies);
  *  OVS_KEY_ATTR_ETHERNET     12    --     4     16
  *  OVS_KEY_ATTR_8021Q         4    --     4      8
  *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8
- *  OVS_KEY_ATTR_IPV6         38     2     4     44
+ *  OVS_KEY_ATTR_IPV6         39     1     4     44
  *  OVS_KEY_ATTR_ICMPV6        2     2     4      8
  *  OVS_KEY_ATTR_ND           28    --     4     32
  *  -------------------------------------------------
index 7d7a449825d19f3126a479b1c1cd425e9a88cfee..53ef03a06c21264b096a92888794218cbd26e213 100644 (file)
@@ -320,26 +320,23 @@ cls_rule_set_nw_dst_masked(struct cls_rule *rule, ovs_be32 ip, ovs_be32 mask)
 void
 cls_rule_set_nw_tos(struct cls_rule *rule, uint8_t nw_tos)
 {
-    rule->wc.tos_frag_mask |= IP_DSCP_MASK;
-    rule->flow.tos_frag &= ~IP_DSCP_MASK;
-    rule->flow.tos_frag |= nw_tos & IP_DSCP_MASK;
+    rule->wc.tos_mask |= IP_DSCP_MASK;
+    rule->flow.tos &= ~IP_DSCP_MASK;
+    rule->flow.tos |= nw_tos & IP_DSCP_MASK;
 }
 
 void
 cls_rule_set_frag(struct cls_rule *rule, uint8_t frag)
 {
-    rule->wc.tos_frag_mask |= FLOW_FRAG_MASK;
-    rule->flow.tos_frag &= ~FLOW_FRAG_MASK;
-    rule->flow.tos_frag |= frag & FLOW_FRAG_MASK;
+    rule->wc.frag_mask |= FLOW_FRAG_MASK;
+    rule->flow.frag = frag;
 }
 
 void
 cls_rule_set_frag_masked(struct cls_rule *rule, uint8_t frag, uint8_t mask)
 {
-    mask &= FLOW_FRAG_MASK;
-    frag &= mask;
-    rule->wc.tos_frag_mask = (rule->wc.tos_frag_mask & ~FLOW_FRAG_MASK) | mask;
-    rule->flow.tos_frag = (rule->flow.tos_frag & ~FLOW_FRAG_MASK) | frag;
+    rule->flow.frag = frag & mask;
+    rule->wc.frag_mask = mask;
 }
 
 void
@@ -475,7 +472,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
 
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     if (rule->priority != OFP_DEFAULT_PRIORITY) {
         ds_put_format(s, "priority=%d,", rule->priority);
@@ -620,25 +617,25 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
                     ETH_ADDR_ARGS(f->arp_tha));
         }
     }
-    if (wc->tos_frag_mask & IP_DSCP_MASK) {
-        ds_put_format(s, "nw_tos=%"PRIu8",", f->tos_frag & IP_DSCP_MASK);
+    if (wc->tos_mask & IP_DSCP_MASK) {
+        ds_put_format(s, "nw_tos=%"PRIu8",", f->tos & IP_DSCP_MASK);
     }
-    switch (wc->tos_frag_mask & FLOW_FRAG_MASK) {
+    switch (wc->frag_mask) {
     case FLOW_FRAG_ANY | FLOW_FRAG_LATER:
         ds_put_format(s, "frag=%s,",
-                      f->tos_frag & FLOW_FRAG_ANY
-                      ? (f->tos_frag & FLOW_FRAG_LATER ? "later" : "first")
-                      : (f->tos_frag & FLOW_FRAG_LATER ? "<error>" : "no"));
+                      f->frag & FLOW_FRAG_ANY
+                      ? (f->frag & FLOW_FRAG_LATER ? "later" : "first")
+                      : (f->frag & FLOW_FRAG_LATER ? "<error>" : "no"));
         break;
 
     case FLOW_FRAG_ANY:
         ds_put_format(s, "frag=%s,",
-                      f->tos_frag & FLOW_FRAG_ANY ? "yes" : "no");
+                      f->frag & FLOW_FRAG_ANY ? "yes" : "no");
         break;
 
     case FLOW_FRAG_LATER:
         ds_put_format(s, "frag=%s,",
-                      f->tos_frag & FLOW_FRAG_LATER ? "later" : "not_later");
+                      f->frag & FLOW_FRAG_LATER ? "later" : "not_later");
         break;
     }
     if (f->nw_proto == IPPROTO_ICMP) {
@@ -1169,7 +1166,7 @@ flow_equal_except(const struct flow *a, const struct flow *b,
     const flow_wildcards_t wc = wildcards->wildcards;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     for (i = 0; i < FLOW_N_REGS; i++) {
         if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
@@ -1196,7 +1193,8 @@ flow_equal_except(const struct flow *a, const struct flow *b,
             && (wc & FWW_ETH_MCAST
                 || !((a->dl_dst[0] ^ b->dl_dst[0]) & 0x01))
             && (wc & FWW_NW_PROTO || a->nw_proto == b->nw_proto)
-            && !((a->tos_frag ^ b->tos_frag) & wildcards->tos_frag_mask)
+            && !((a->tos ^ b->tos) & wildcards->tos_mask)
+            && !((a->frag ^ b->frag) & wildcards->frag_mask)
             && (wc & FWW_ARP_SHA || eth_addr_equals(a->arp_sha, b->arp_sha))
             && (wc & FWW_ARP_THA || eth_addr_equals(a->arp_tha, b->arp_tha))
             && (wc & FWW_IPV6_LABEL || a->ipv6_label == b->ipv6_label)
index 9323aae70eba02b2c098cb32e9593e30bdec1cf6..99cef1e04b1816417b2df427676af4f6f7666ca4 100644 (file)
@@ -148,7 +148,7 @@ parse_ipv6(struct ofpbuf *packet, struct flow *flow)
     flow->ipv6_dst = nh->ip6_dst;
 
     tc_flow = get_unaligned_be32(&nh->ip6_flow);
-    flow->tos_frag = (ntohl(tc_flow) >> 4) & IP_DSCP_MASK;
+    flow->tos = (ntohl(tc_flow) >> 4) & IP_DSCP_MASK;
     flow->ipv6_label = tc_flow & htonl(IPV6_LABEL_MASK);
     flow->nw_proto = IPPROTO_NONE;
 
@@ -202,10 +202,9 @@ parse_ipv6(struct ofpbuf *packet, struct flow *flow)
             }
 
             /* We only process the first fragment. */
-            flow->tos_frag &= ~FLOW_FRAG_MASK;
-            flow->tos_frag |= FLOW_FRAG_ANY;
+            flow->frag = FLOW_FRAG_ANY;
             if ((frag_hdr->ip6f_offlg & IP6F_OFF_MASK) != htons(0)) {
-                flow->tos_frag |= FLOW_FRAG_LATER;
+                flow->frag |= FLOW_FRAG_LATER;
                 nexthdr = IPPROTO_FRAGMENT;
                 break;
             }
@@ -370,11 +369,11 @@ flow_extract(struct ofpbuf *packet, uint32_t priority, ovs_be64 tun_id,
             flow->nw_dst = get_unaligned_be32(&nh->ip_dst);
             flow->nw_proto = nh->ip_proto;
 
-            flow->tos_frag = nh->ip_tos & IP_DSCP_MASK;
+            flow->tos = nh->ip_tos & IP_DSCP_MASK;
             if (IP_IS_FRAGMENT(nh->ip_frag_off)) {
-                flow->tos_frag |= FLOW_FRAG_ANY;
+                flow->frag = FLOW_FRAG_ANY;
                 if (nh->ip_frag_off & htons(IP_FRAG_OFF_MASK)) {
-                    flow->tos_frag |= FLOW_FRAG_LATER;
+                    flow->frag |= FLOW_FRAG_LATER;
                 }
             }
 
@@ -438,7 +437,7 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
     const flow_wildcards_t wc = wildcards->wildcards;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     for (i = 0; i < FLOW_N_REGS; i++) {
         flow->regs[i] &= wildcards->reg_masks[i];
@@ -475,7 +474,8 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
     if (wc & FWW_IPV6_LABEL) {
         flow->ipv6_label = htonl(0);
     }
-    flow->tos_frag &= wildcards->tos_frag_mask;
+    flow->tos &= wildcards->tos_mask;
+    flow->frag &= wildcards->frag_mask;
     if (wc & FWW_ARP_SHA) {
         memset(flow->arp_sha, 0, sizeof flow->arp_sha);
     }
@@ -503,8 +503,6 @@ flow_to_string(const struct flow *flow)
 void
 flow_format(struct ds *ds, const struct flow *flow)
 {
-    int frag;
-
     ds_put_format(ds, "priority%"PRIu32
                       ":tunnel%#"PRIx64
                       ":in_port%04"PRIx16,
@@ -529,7 +527,7 @@ flow_format(struct ds *ds, const struct flow *flow)
     if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
         ds_put_format(ds, " label%#"PRIx32" proto%"PRIu8" tos%"PRIu8" ipv6",
                       ntohl(flow->ipv6_label), flow->nw_proto,
-                      flow->tos_frag & IP_DSCP_MASK);
+                      flow->tos & IP_DSCP_MASK);
         print_ipv6_addr(ds, &flow->ipv6_src);
         ds_put_cstr(ds, "->");
         print_ipv6_addr(ds, &flow->ipv6_dst);
@@ -539,16 +537,15 @@ flow_format(struct ds *ds, const struct flow *flow)
                           " tos%"PRIu8
                           " ip"IP_FMT"->"IP_FMT,
                       flow->nw_proto,
-                      flow->tos_frag & IP_DSCP_MASK,
+                      flow->tos & IP_DSCP_MASK,
                       IP_ARGS(&flow->nw_src),
                       IP_ARGS(&flow->nw_dst));
     }
-    frag = flow->tos_frag & FLOW_FRAG_MASK;
-    if (frag) {
+    if (flow->frag) {
         ds_put_format(ds, " frag(%s)",
-                      frag == FLOW_FRAG_ANY ? "first"
-                      : frag == (FLOW_FRAG_ANY | FLOW_FRAG_LATER) ? "later"
-                      : "<error>");
+                      flow->frag == FLOW_FRAG_ANY ? "first"
+                      : flow->frag == (FLOW_FRAG_ANY | FLOW_FRAG_LATER)
+                      ? "later" : "<error>");
     }
     if (flow->tp_src || flow->tp_dst) {
         ds_put_format(ds, " port%"PRIu16"->%"PRIu16,
@@ -575,7 +572,7 @@ flow_print(FILE *stream, const struct flow *flow)
 void
 flow_wildcards_init_catchall(struct flow_wildcards *wc)
 {
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     wc->wildcards = FWW_ALL;
     wc->tun_id_mask = htonll(0);
@@ -585,7 +582,8 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc)
     wc->ipv6_dst_mask = in6addr_any;
     memset(wc->reg_masks, 0, sizeof wc->reg_masks);
     wc->vlan_tci_mask = htons(0);
-    wc->tos_frag_mask = 0;
+    wc->tos_mask = 0;
+    wc->frag_mask = 0;
     memset(wc->zeros, 0, sizeof wc->zeros);
 }
 
@@ -594,7 +592,7 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc)
 void
 flow_wildcards_init_exact(struct flow_wildcards *wc)
 {
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     wc->wildcards = 0;
     wc->tun_id_mask = htonll(UINT64_MAX);
@@ -604,7 +602,8 @@ flow_wildcards_init_exact(struct flow_wildcards *wc)
     wc->ipv6_dst_mask = in6addr_exact;
     memset(wc->reg_masks, 0xff, sizeof wc->reg_masks);
     wc->vlan_tci_mask = htons(UINT16_MAX);
-    wc->tos_frag_mask = UINT8_MAX;
+    wc->tos_mask = UINT8_MAX;
+    wc->frag_mask = UINT8_MAX;
     memset(wc->zeros, 0, sizeof wc->zeros);
 }
 
@@ -615,7 +614,7 @@ flow_wildcards_is_exact(const struct flow_wildcards *wc)
 {
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     if (wc->wildcards
         || wc->tun_id_mask != htonll(UINT64_MAX)
@@ -624,7 +623,8 @@ flow_wildcards_is_exact(const struct flow_wildcards *wc)
         || wc->vlan_tci_mask != htons(UINT16_MAX)
         || !ipv6_mask_is_exact(&wc->ipv6_src_mask)
         || !ipv6_mask_is_exact(&wc->ipv6_dst_mask)
-        || wc->tos_frag_mask != UINT8_MAX) {
+        || wc->tos_mask != UINT8_MAX
+        || wc->frag_mask != UINT8_MAX) {
         return false;
     }
 
@@ -644,7 +644,7 @@ flow_wildcards_is_catchall(const struct flow_wildcards *wc)
 {
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     if (wc->wildcards != FWW_ALL
         || wc->tun_id_mask != htonll(0)
@@ -653,7 +653,8 @@ flow_wildcards_is_catchall(const struct flow_wildcards *wc)
         || wc->vlan_tci_mask != htons(0)
         || !ipv6_mask_is_any(&wc->ipv6_src_mask)
         || !ipv6_mask_is_any(&wc->ipv6_dst_mask)
-        || wc->tos_frag_mask != 0) {
+        || wc->tos_mask != 0
+        || wc->frag_mask != 0) {
         return false;
     }
 
@@ -1015,19 +1016,19 @@ 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->tos_frag & IP_DSCP_MASK;
+        ip->ip_tos = flow->tos & IP_DSCP_MASK;
         ip->ip_proto = flow->nw_proto;
         ip->ip_src = flow->nw_src;
         ip->ip_dst = flow->nw_dst;
 
-        if (flow->tos_frag & FLOW_FRAG_ANY) {
+        if (flow->frag & FLOW_FRAG_ANY) {
             ip->ip_frag_off |= htons(IP_MORE_FRAGMENTS);
-            if (flow->tos_frag & FLOW_FRAG_LATER) {
+            if (flow->frag & FLOW_FRAG_LATER) {
                 ip->ip_frag_off |= htons(100);
             }
         }
-        if (!(flow->tos_frag & FLOW_FRAG_ANY)
-            || !(flow->tos_frag & FLOW_FRAG_LATER)) {
+        if (!(flow->frag & FLOW_FRAG_ANY)
+            || !(flow->frag & FLOW_FRAG_LATER)) {
             if (flow->nw_proto == IPPROTO_TCP) {
                 struct tcp_header *tcp;
 
index c451073712e51fd52d234cb0da03a78664dbc1ea..af634fb966054f75f00611ba41707e28eaa4f448 100644 (file)
@@ -35,7 +35,7 @@ struct ofpbuf;
 /* This sequence number should be incremented whenever anything involving flows
  * or the wildcarding of flows changes.  This will cause build assertion
  * failures in places which likely need to be updated. */
-#define FLOW_WC_SEQ 4
+#define FLOW_WC_SEQ 5
 
 #define FLOW_N_REGS 5
 BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS);
@@ -70,21 +70,23 @@ struct flow {
     uint8_t dl_src[6];          /* Ethernet source address. */
     uint8_t dl_dst[6];          /* Ethernet destination address. */
     uint8_t nw_proto;           /* IP protocol or low 8 bits of ARP opcode. */
-    uint8_t tos_frag;           /* IP ToS in top bits, FLOW_FRAG_* in low. */
+    uint8_t tos;                /* IP ToS. */
     uint8_t arp_sha[6];         /* ARP/ND source hardware address. */
     uint8_t arp_tha[6];         /* ARP/ND target hardware address. */
+    uint8_t frag;               /* FLOW_FRAG_* flags. */
+    uint8_t reserved[7];        /* Reserved for 64-bit packing. */
 };
 
 /* Assert that there are FLOW_SIG_SIZE bytes of significant data in "struct
  * flow", followed by FLOW_PAD_SIZE bytes of padding. */
-#define FLOW_SIG_SIZE (108 + FLOW_N_REGS * 4)
-#define FLOW_PAD_SIZE 0
-BUILD_ASSERT_DECL(offsetof(struct flow, arp_tha) == FLOW_SIG_SIZE - 6);
-BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->arp_tha) == 6);
+#define FLOW_SIG_SIZE (109 + FLOW_N_REGS * 4)
+#define FLOW_PAD_SIZE 7
+BUILD_ASSERT_DECL(offsetof(struct flow, frag) == FLOW_SIG_SIZE - 1);
+BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->frag) == 1);
 BUILD_ASSERT_DECL(sizeof(struct flow) == FLOW_SIG_SIZE + FLOW_PAD_SIZE);
 
 /* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
-BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 128 && FLOW_WC_SEQ == 4);
+BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 129 && FLOW_WC_SEQ == 5);
 
 void flow_extract(struct ofpbuf *, uint32_t priority, ovs_be64 tun_id,
                   uint16_t in_port, struct flow *);
@@ -144,7 +146,7 @@ typedef unsigned int OVS_BITWISE flow_wildcards_t;
 #define FWW_ALL         ((OVS_FORCE flow_wildcards_t) (((1 << 12)) - 1))
 
 /* Remember to update FLOW_WC_SEQ when adding or removing FWW_*. */
-BUILD_ASSERT_DECL(FWW_ALL == ((1 << 12) - 1) && FLOW_WC_SEQ == 4);
+BUILD_ASSERT_DECL(FWW_ALL == ((1 << 12) - 1) && FLOW_WC_SEQ == 5);
 
 /* Information on wildcards for a flow, as a supplement to "struct flow".
  *
@@ -159,12 +161,13 @@ struct flow_wildcards {
     struct in6_addr ipv6_src_mask; /* 1-bit in each signficant ipv6_src bit. */
     struct in6_addr ipv6_dst_mask; /* 1-bit in each signficant ipv6_dst bit. */
     ovs_be16 vlan_tci_mask;     /* 1-bit in each significant vlan_tci bit. */
-    uint8_t tos_frag_mask;      /* 1-bit in each significant tos_frag bit. */
-    uint8_t zeros[5];           /* Padding field set to zero. */
+    uint8_t tos_mask;           /* 1-bit in each significant tos bit. */
+    uint8_t frag_mask;          /* 1-bit in each significant frag bit. */
+    uint8_t zeros[4];           /* Padding field set to zero. */
 };
 
 /* Remember to update FLOW_WC_SEQ when updating struct flow_wildcards. */
-BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) == 80 && FLOW_WC_SEQ == 4);
+BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) == 80 && FLOW_WC_SEQ == 5);
 
 void flow_wildcards_init_catchall(struct flow_wildcards *);
 void flow_wildcards_init_exact(struct flow_wildcards *);
index 4bf6039f18eaf14b1d931e114d9ff874f7c9c6c5..a823c3048aa3fab6a099ab4da4afbefb7c3b3635 100644 (file)
@@ -423,9 +423,9 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
         return ipv6_mask_is_any(&wc->ipv6_dst_mask);
 
     case MFF_IP_TOS:
-        return !(wc->tos_frag_mask & IP_DSCP_MASK);
+        return !(wc->tos_mask & IP_DSCP_MASK);
     case MFF_IP_FRAG:
-        return !(wc->tos_frag_mask & FLOW_FRAG_MASK);
+        return !(wc->frag_mask & FLOW_FRAG_MASK);
 
     case MFF_ARP_SPA:
         return !wc->nw_src_mask;
@@ -525,10 +525,10 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
         break;
 
     case MFF_IP_TOS:
-        mask->u8 = wc->tos_frag_mask & IP_DSCP_MASK;
+        mask->u8 = wc->tos_mask & IP_DSCP_MASK;
         break;
     case MFF_IP_FRAG:
-        mask->u8 = wc->tos_frag_mask & FLOW_FRAG_MASK;
+        mask->u8 = wc->frag_mask & FLOW_FRAG_MASK;
         break;
 
     case MFF_ARP_SPA:
@@ -800,11 +800,11 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
         break;
 
     case MFF_IP_TOS:
-        value->u8 = flow->tos_frag & IP_DSCP_MASK;
+        value->u8 = flow->tos & IP_DSCP_MASK;
         break;
 
     case MFF_IP_FRAG:
-        value->u8 = flow->tos_frag & FLOW_FRAG_MASK;
+        value->u8 = flow->frag;
         break;
 
     case MFF_ARP_OP:
@@ -1118,13 +1118,13 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
         break;
 
     case MFF_IP_TOS:
-        rule->wc.tos_frag_mask |= IP_DSCP_MASK;
-        rule->flow.tos_frag &= ~IP_DSCP_MASK;
+        rule->wc.tos_mask |= IP_DSCP_MASK;
+        rule->flow.tos &= ~IP_DSCP_MASK;
         break;
 
     case MFF_IP_FRAG:
-        rule->wc.tos_frag_mask |= FLOW_FRAG_MASK;
-        rule->flow.tos_frag &= ~FLOW_FRAG_MASK;
+        rule->wc.frag_mask |= FLOW_FRAG_MASK;
+        rule->flow.frag &= ~FLOW_FRAG_MASK;
         break;
 
     case MFF_ARP_OP:
index e6259889b0bf5210f91ab34e29cc5adae8564f3b..98ed6a667a8d162ce545216ded5737bbd57842cf 100644 (file)
@@ -422,27 +422,21 @@ nxm_put_ipv6(struct ofpbuf *b, uint32_t header,
 }
 
 static void
-nxm_put_tos_frag(struct ofpbuf *b, const struct cls_rule *cr)
+nxm_put_frag(struct ofpbuf *b, const struct cls_rule *cr)
 {
-    uint8_t tos_frag = cr->flow.tos_frag;
-    uint8_t tos_frag_mask = cr->wc.tos_frag_mask;
+    uint8_t frag = cr->flow.frag;
+    uint8_t frag_mask = cr->wc.frag_mask;
 
-    if (tos_frag_mask & IP_DSCP_MASK) {
-        nxm_put_8(b, NXM_OF_IP_TOS, tos_frag & IP_DSCP_MASK);
-    }
-
-    switch (tos_frag_mask & FLOW_FRAG_MASK) {
+    switch (frag_mask) {
     case 0:
         break;
 
     case FLOW_FRAG_MASK:
-        /* Output it as exact-match even though only the low 2 bits matter. */
-        nxm_put_8(b, NXM_NX_IP_FRAG, tos_frag & FLOW_FRAG_MASK);
+        nxm_put_8(b, NXM_NX_IP_FRAG, frag);
         break;
 
     default:
-        nxm_put_8m(b, NXM_NX_IP_FRAG, tos_frag & FLOW_FRAG_MASK,
-                   tos_frag_mask & FLOW_FRAG_MASK);
+        nxm_put_8m(b, NXM_NX_IP_FRAG, frag, frag_mask & FLOW_FRAG_MASK);
         break;
     }
 }
@@ -466,7 +460,7 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr)
     int match_len;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     /* Metadata. */
     if (!(wc & FWW_IN_PORT)) {
@@ -490,9 +484,13 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr)
     /* L3. */
     if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_IP)) {
         /* IP. */
-        nxm_put_tos_frag(b, cr);
         nxm_put_32m(b, NXM_OF_IP_SRC, flow->nw_src, cr->wc.nw_src_mask);
         nxm_put_32m(b, NXM_OF_IP_DST, flow->nw_dst, cr->wc.nw_dst_mask);
+        nxm_put_frag(b, cr);
+
+        if (cr->wc.tos_mask & IP_DSCP_MASK) {
+            nxm_put_8(b, NXM_OF_IP_TOS, flow->tos & IP_DSCP_MASK);
+        }
 
         if (!(wc & FWW_NW_PROTO)) {
             nxm_put_8(b, NXM_OF_IP_PROTO, flow->nw_proto);
@@ -530,15 +528,20 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr)
         }
     } else if (!(wc & FWW_DL_TYPE) && flow->dl_type == htons(ETH_TYPE_IPV6)) {
         /* IPv6. */
-        nxm_put_tos_frag(b, cr);
         nxm_put_ipv6(b, NXM_NX_IPV6_SRC, &flow->ipv6_src,
                 &cr->wc.ipv6_src_mask);
         nxm_put_ipv6(b, NXM_NX_IPV6_DST, &flow->ipv6_dst,
                 &cr->wc.ipv6_dst_mask);
+        nxm_put_frag(b, cr);
+
         if (!(wc & FWW_IPV6_LABEL)) {
             nxm_put_32(b, NXM_NX_IPV6_LABEL, flow->ipv6_label);
         }
 
+        if (cr->wc.tos_mask & IP_DSCP_MASK) {
+            nxm_put_8(b, NXM_OF_IP_TOS, flow->tos & IP_DSCP_MASK);
+        }
+
         if (!(wc & FWW_NW_PROTO)) {
             nxm_put_8(b, NXM_OF_IP_PROTO, flow->nw_proto);
             switch (flow->nw_proto) {
@@ -1042,10 +1045,10 @@ nxm_read_field(const struct nxm_field *src, const struct flow *flow)
         return ntohs(flow->vlan_tci);
 
     case NFI_NXM_OF_IP_TOS:
-        return flow->tos_frag & IP_DSCP_MASK;
+        return flow->tos & IP_DSCP_MASK;
 
     case NFI_NXM_NX_IP_FRAG:
-        return flow->tos_frag & FLOW_FRAG_MASK;
+        return flow->frag;
 
     case NFI_NXM_OF_IP_PROTO:
     case NFI_NXM_OF_ARP_OP:
@@ -1195,13 +1198,12 @@ nxm_write_field(const struct nxm_field *dst, struct flow *flow,
 #endif
 
     case NFI_NXM_OF_IP_TOS:
-        flow->tos_frag &= ~IP_DSCP_MASK;
-        flow->tos_frag |= new_value & IP_DSCP_MASK;
+        flow->tos &= ~IP_DSCP_MASK;
+        flow->tos |= new_value & IP_DSCP_MASK;
         break;
 
     case NFI_NXM_NX_IP_FRAG:
-        flow->tos_frag &= ~FLOW_FRAG_MASK;
-        flow->tos_frag |= new_value & FLOW_FRAG_MASK;
+        flow->frag = new_value;
         break;
 
     case NFI_NXM_OF_IP_SRC:
index 51cd001fac9283e5db953e13bbafe72655a94491..3c883d9a530161848d4d951a1f876a97c0d44980 100644 (file)
@@ -821,10 +821,10 @@ odp_flow_key_from_string(const char *s, struct ofpbuf *key)
 }
 
 static uint8_t
-tos_frag_to_odp_frag(uint8_t tos_frag)
+ovs_to_odp_frag(uint8_t ovs_frag)
 {
-    return (tos_frag & FLOW_FRAG_LATER ? OVS_FRAG_TYPE_LATER
-            : tos_frag & FLOW_FRAG_ANY ? OVS_FRAG_TYPE_FIRST
+    return (ovs_frag & FLOW_FRAG_LATER ? OVS_FRAG_TYPE_LATER
+            : ovs_frag & FLOW_FRAG_ANY ? OVS_FRAG_TYPE_FIRST
             : OVS_FRAG_TYPE_NONE);
 }
 
@@ -876,8 +876,8 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow)
         ipv4_key->ipv4_src = flow->nw_src;
         ipv4_key->ipv4_dst = flow->nw_dst;
         ipv4_key->ipv4_proto = flow->nw_proto;
-        ipv4_key->ipv4_tos = flow->tos_frag & IP_DSCP_MASK;
-        ipv4_key->ipv4_frag = tos_frag_to_odp_frag(flow->tos_frag);
+        ipv4_key->ipv4_tos = flow->tos & IP_DSCP_MASK;
+        ipv4_key->ipv4_frag = ovs_to_odp_frag(flow->frag);
     } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
         struct ovs_key_ipv6 *ipv6_key;
 
@@ -888,8 +888,8 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow)
         memcpy(ipv6_key->ipv6_dst, &flow->ipv6_dst, sizeof ipv6_key->ipv6_dst);
         ipv6_key->ipv6_label = flow->ipv6_label;
         ipv6_key->ipv6_proto = flow->nw_proto;
-        ipv6_key->ipv6_tos = flow->tos_frag & IP_DSCP_MASK;
-        ipv6_key->ipv6_frag = tos_frag_to_odp_frag(flow->tos_frag);
+        ipv6_key->ipv6_tos = flow->tos & IP_DSCP_MASK;
+        ipv6_key->ipv6_frag = ovs_to_odp_frag(flow->frag);
     } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {
         struct ovs_key_arp *arp_key;
 
@@ -905,7 +905,7 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow)
 
     if ((flow->dl_type == htons(ETH_TYPE_IP)
          || flow->dl_type == htons(ETH_TYPE_IPV6))
-        && !(flow->tos_frag & FLOW_FRAG_LATER)) {
+        && !(flow->frag & FLOW_FRAG_LATER)) {
 
         if (flow->nw_proto == IPPROTO_TCP) {
             struct ovs_key_tcp *tcp_key;
@@ -954,17 +954,16 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow)
 }
 
 static bool
-odp_to_tos_frag(uint8_t odp_tos, uint8_t odp_frag, struct flow *flow)
+odp_to_ovs_frag(uint8_t odp_frag, struct flow *flow)
 {
-    if (odp_tos & ~IP_DSCP_MASK || odp_frag > OVS_FRAG_TYPE_LATER) {
+    if (odp_frag > OVS_FRAG_TYPE_LATER) {
         return false;
     }
 
-    flow->tos_frag = odp_tos;
     if (odp_frag != OVS_FRAG_TYPE_NONE) {
-        flow->tos_frag |= FLOW_FRAG_ANY;
+        flow->frag |= FLOW_FRAG_ANY;
         if (odp_frag == OVS_FRAG_TYPE_LATER) {
-            flow->tos_frag |= FLOW_FRAG_LATER;
+            flow->frag |= FLOW_FRAG_LATER;
         }
     }
     return true;
@@ -1061,8 +1060,8 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
             flow->nw_src = ipv4_key->ipv4_src;
             flow->nw_dst = ipv4_key->ipv4_dst;
             flow->nw_proto = ipv4_key->ipv4_proto;
-            if (!odp_to_tos_frag(ipv4_key->ipv4_tos, ipv4_key->ipv4_frag,
-                                 flow)) {
+            flow->tos = ipv4_key->ipv4_tos;
+            if (!odp_to_ovs_frag(ipv4_key->ipv4_frag, flow)) {
                 return EINVAL;
             }
             break;
@@ -1076,8 +1075,8 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
             memcpy(&flow->ipv6_dst, ipv6_key->ipv6_dst, sizeof flow->ipv6_dst);
             flow->ipv6_label = ipv6_key->ipv6_label;
             flow->nw_proto = ipv6_key->ipv6_proto;
-            if (!odp_to_tos_frag(ipv6_key->ipv6_tos, ipv6_key->ipv6_frag,
-                                 flow)) {
+            flow->tos = ipv6_key->ipv6_tos;
+            if (!odp_to_ovs_frag(ipv6_key->ipv6_frag, flow)) {
                 return EINVAL;
             }
             break;
@@ -1178,7 +1177,7 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
         return 0;
 
     case OVS_KEY_ATTR_IPV4:
-        if (flow->tos_frag & FLOW_FRAG_LATER) {
+        if (flow->frag & FLOW_FRAG_LATER) {
             return 0;
         }
         if (flow->nw_proto == IPPROTO_TCP
@@ -1189,7 +1188,7 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
         return 0;
 
     case OVS_KEY_ATTR_IPV6:
-        if (flow->tos_frag & FLOW_FRAG_LATER) {
+        if (flow->frag & FLOW_FRAG_LATER) {
             return 0;
         }
         if (flow->nw_proto == IPPROTO_TCP
@@ -1202,7 +1201,7 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
     case OVS_KEY_ATTR_ICMPV6:
         if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)
             || flow->tp_src == htons(ND_NEIGHBOR_ADVERT)
-            || flow->tos_frag & FLOW_FRAG_LATER) {
+            || flow->frag & FLOW_FRAG_LATER) {
             return EINVAL;
         }
         return 0;
@@ -1211,7 +1210,7 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
     case OVS_KEY_ATTR_UDP:
     case OVS_KEY_ATTR_ICMP:
     case OVS_KEY_ATTR_ND:
-        if (flow->tos_frag & FLOW_FRAG_LATER) {
+        if (flow->frag & FLOW_FRAG_LATER) {
             return EINVAL;
         }
         return 0;
index 8a7fbc63b2bafd6e5dca15b1c4c40f4a0a58a3c0..73c3362ab0d71906e5e5c60dc6f6e33e1e30f378 100644 (file)
@@ -72,7 +72,7 @@ void format_odp_actions(struct ds *, const struct nlattr *odp_actions,
  *  OVS_KEY_ATTR_ETHERNET     12    --     4     16
  *  OVS_KEY_ATTR_8021Q         4    --     4      8
  *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8
- *  OVS_KEY_ATTR_IPV6         38     2     4     44
+ *  OVS_KEY_ATTR_IPV6         39     1     4     44
  *  OVS_KEY_ATTR_ICMPV6        2     2     4      8
  *  OVS_KEY_ATTR_ND           28    --     4     32
  *  -------------------------------------------------
index d8bee057ebde23d706125a2e35c873d607b740d5..5ef4e80fc122e9bb0a82f63cc15bf992057742ef 100644 (file)
@@ -101,7 +101,7 @@ static const flow_wildcards_t WC_INVARIANTS = 0
 void
 ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
 {
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     /* Initialize most of rule->wc. */
     flow_wildcards_init_catchall(wc);
@@ -112,7 +112,7 @@ ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
                       | FWW_IPV6_LABEL);
 
     if (!(ofpfw & OFPFW_NW_TOS)) {
-        wc->tos_frag_mask |= IP_DSCP_MASK;
+        wc->tos_mask |= IP_DSCP_MASK;
     }
 
     wc->nw_src_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW_NW_SRC_SHIFT);
@@ -155,7 +155,7 @@ ofputil_cls_rule_from_match(const struct ofp_match *match,
     rule->flow.tp_dst = match->tp_dst;
     memcpy(rule->flow.dl_src, match->dl_src, ETH_ADDR_LEN);
     memcpy(rule->flow.dl_dst, match->dl_dst, ETH_ADDR_LEN);
-    rule->flow.tos_frag = match->nw_tos & IP_DSCP_MASK;
+    rule->flow.tos = match->nw_tos & IP_DSCP_MASK;
     rule->flow.nw_proto = match->nw_proto;
 
     /* Translate VLANs. */
@@ -194,7 +194,7 @@ ofputil_cls_rule_to_match(const struct cls_rule *rule, struct ofp_match *match)
     ofpfw = (OVS_FORCE uint32_t) (wc->wildcards & WC_INVARIANTS);
     ofpfw |= ofputil_netmask_to_wcbits(wc->nw_src_mask) << OFPFW_NW_SRC_SHIFT;
     ofpfw |= ofputil_netmask_to_wcbits(wc->nw_dst_mask) << OFPFW_NW_DST_SHIFT;
-    if (!(wc->tos_frag_mask & IP_DSCP_MASK)) {
+    if (!(wc->tos_mask & IP_DSCP_MASK)) {
         ofpfw |= OFPFW_NW_TOS;
     }
 
@@ -228,7 +228,7 @@ ofputil_cls_rule_to_match(const struct cls_rule *rule, struct ofp_match *match)
     match->dl_type = ofputil_dl_type_to_openflow(rule->flow.dl_type);
     match->nw_src = rule->flow.nw_src;
     match->nw_dst = rule->flow.nw_dst;
-    match->nw_tos = rule->flow.tos_frag & IP_DSCP_MASK;
+    match->nw_tos = rule->flow.tos & IP_DSCP_MASK;
     match->nw_proto = rule->flow.nw_proto;
     match->tp_src = rule->flow.tp_src;
     match->tp_dst = rule->flow.tp_dst;
@@ -859,7 +859,7 @@ ofputil_min_flow_format(const struct cls_rule *rule)
 {
     const struct flow_wildcards *wc = &rule->wc;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 5);
 
     /* Only NXM supports separately wildcards the Ethernet multicast bit. */
     if (!(wc->wildcards & FWW_DL_DST) != !(wc->wildcards & FWW_ETH_MCAST)) {
@@ -888,7 +888,7 @@ ofputil_min_flow_format(const struct cls_rule *rule)
     }
 
     /* Only NXM supports matching fragments. */
-    if (wc->tos_frag_mask & FLOW_FRAG_MASK) {
+    if (wc->frag_mask) {
         return NXFF_NXM;
     }
 
@@ -2511,7 +2511,7 @@ ofputil_normalize_rule(struct cls_rule *rule, enum nx_flow_format flow_format)
         MAY_NW_ADDR     = 1 << 0, /* nw_src, nw_dst */
         MAY_TP_ADDR     = 1 << 1, /* tp_src, tp_dst */
         MAY_NW_PROTO    = 1 << 2, /* nw_proto */
-        MAY_TOS_FRAG    = 1 << 3, /* tos_frag */
+        MAY_IPVx        = 1 << 3, /* tos, frag */
         MAY_ARP_SHA     = 1 << 4, /* arp_sha */
         MAY_ARP_THA     = 1 << 5, /* arp_tha */
         MAY_IPV6_ADDR   = 1 << 6, /* ipv6_src, ipv6_dst */
@@ -2522,7 +2522,7 @@ ofputil_normalize_rule(struct cls_rule *rule, enum nx_flow_format flow_format)
 
     /* Figure out what fields may be matched. */
     if (rule->flow.dl_type == htons(ETH_TYPE_IP)) {
-        may_match = MAY_NW_PROTO | MAY_TOS_FRAG | MAY_NW_ADDR;
+        may_match = MAY_NW_PROTO | MAY_IPVx | MAY_NW_ADDR;
         if (rule->flow.nw_proto == IPPROTO_TCP ||
             rule->flow.nw_proto == IPPROTO_UDP ||
             rule->flow.nw_proto == IPPROTO_ICMP) {
@@ -2530,7 +2530,7 @@ ofputil_normalize_rule(struct cls_rule *rule, enum nx_flow_format flow_format)
         }
     } else if (rule->flow.dl_type == htons(ETH_TYPE_IPV6)
                && flow_format == NXFF_NXM) {
-        may_match = MAY_NW_PROTO | MAY_TOS_FRAG | MAY_IPV6_ADDR;
+        may_match = MAY_NW_PROTO | MAY_IPVx | MAY_IPV6_ADDR;
         if (rule->flow.nw_proto == IPPROTO_TCP ||
             rule->flow.nw_proto == IPPROTO_UDP) {
             may_match |= MAY_TP_ADDR;
@@ -2562,8 +2562,9 @@ ofputil_normalize_rule(struct cls_rule *rule, enum nx_flow_format flow_format)
     if (!(may_match & MAY_NW_PROTO)) {
         wc.wildcards |= FWW_NW_PROTO;
     }
-    if (!(may_match & MAY_TOS_FRAG)) {
-        wc.tos_frag_mask = 0;
+    if (!(may_match & MAY_IPVx)) {
+        wc.tos_mask = 0;
+        wc.frag_mask = 0;
     }
     if (!(may_match & MAY_ARP_SHA)) {
         wc.wildcards |= FWW_ARP_SHA;
index 9d9ef19809a7919f661f2dfe34a32726c5ffd79a..89ccb3b2f6505da4911b115f80f2b3787a32fae9 100644 (file)
@@ -160,7 +160,7 @@ gen_netflow_rec(struct netflow *nf, struct netflow_flow *nf_flow,
     }
     nf_rec->tcp_flags = nf_flow->tcp_flags;
     nf_rec->ip_proto = expired->flow.nw_proto;
-    nf_rec->ip_tos = expired->flow.tos_frag & IP_DSCP_MASK;
+    nf_rec->ip_tos = expired->flow.tos & IP_DSCP_MASK;
 
     /* NetFlow messages are limited to 30 records. */
     if (ntohs(nf_hdr->count) >= 30) {
index 0def71dd261bbcbd32fe421bb019a127e96d7432..3b637e122a6cba3a76e106102a81fa33bada1297 100644 (file)
@@ -3248,7 +3248,7 @@ rule_dpif_lookup(struct ofproto_dpif *ofproto, const struct flow *flow,
     }
 
     cls = &ofproto->up.tables[table_id];
-    if (flow->tos_frag & FLOW_FRAG_ANY
+    if (flow->frag & FLOW_FRAG_ANY
         && ofproto->up.frag_handling == OFPC_FRAG_NORMAL) {
         /* For OFPC_NORMAL frag_handling, we must pretend that transport ports
          * are unavailable. */
@@ -3661,7 +3661,6 @@ static void
 commit_set_nw_action(const struct flow *flow, struct flow *base,
                      struct ofpbuf *odp_actions)
 {
-    int frag = base->tos_frag & FLOW_FRAG_MASK;
     struct ovs_key_ipv4 ipv4_key;
 
     if (base->dl_type != htons(ETH_TYPE_IP) ||
@@ -3671,7 +3670,8 @@ commit_set_nw_action(const struct flow *flow, struct flow *base,
 
     if (base->nw_src == flow->nw_src &&
         base->nw_dst == flow->nw_dst &&
-        base->tos_frag == flow->tos_frag) {
+        base->tos == flow->tos &&
+        base->frag == flow->frag) {
         return;
     }
 
@@ -3680,9 +3680,9 @@ commit_set_nw_action(const struct flow *flow, struct flow *base,
     ipv4_key.ipv4_src = base->nw_src = flow->nw_src;
     ipv4_key.ipv4_dst = base->nw_dst = flow->nw_dst;
     ipv4_key.ipv4_proto = base->nw_proto;
-    ipv4_key.ipv4_tos = flow->tos_frag & IP_DSCP_MASK;
-    ipv4_key.ipv4_frag = (frag == 0 ? OVS_FRAG_TYPE_NONE
-                          : frag == FLOW_FRAG_ANY ? OVS_FRAG_TYPE_FIRST
+    ipv4_key.ipv4_tos = flow->tos & IP_DSCP_MASK;
+    ipv4_key.ipv4_frag = (base->frag == 0 ? OVS_FRAG_TYPE_NONE
+                          : base->frag == FLOW_FRAG_ANY ? OVS_FRAG_TYPE_FIRST
                           : OVS_FRAG_TYPE_LATER);
 
     commit_action__(odp_actions, OVS_ACTION_ATTR_SET,
@@ -4167,8 +4167,8 @@ do_xlate_actions(const union ofp_action *in, size_t n_in,
             break;
 
         case OFPUTIL_OFPAT_SET_NW_TOS:
-            ctx->flow.tos_frag &= ~IP_DSCP_MASK;
-            ctx->flow.tos_frag |= ia->nw_tos.nw_tos & IP_DSCP_MASK;
+            ctx->flow.tos &= ~IP_DSCP_MASK;
+            ctx->flow.tos |= ia->nw_tos.nw_tos & IP_DSCP_MASK;
             break;
 
         case OFPUTIL_OFPAT_SET_TP_SRC:
@@ -4309,7 +4309,7 @@ xlate_actions(struct action_xlate_ctx *ctx,
     ctx->table_id = 0;
     ctx->exit = false;
 
-    if (ctx->flow.tos_frag & FLOW_FRAG_ANY) {
+    if (ctx->flow.frag & FLOW_FRAG_ANY) {
         switch (ctx->ofproto->up.frag_handling) {
         case OFPC_FRAG_NORMAL:
             /* We must pretend that transport ports are unavailable. */
index 0e2b13f0afd9dff60e91a5c60bfca6f3fa6f1ba1..d66654bc72eb4ba113c67f55b885a933cc2782f9 100644 (file)
@@ -55,7 +55,7 @@
     CLS_FIELD(FWW_DL_SRC,                 dl_src,      DL_SRC)      \
     CLS_FIELD(FWW_DL_DST | FWW_ETH_MCAST, dl_dst,      DL_DST)      \
     CLS_FIELD(FWW_NW_PROTO,               nw_proto,    NW_PROTO)    \
-    CLS_FIELD(0,                          tos_frag,    TOS_FRAG)
+    CLS_FIELD(0,                          tos,         TOS)
 
 /* Field indexes.
  *
@@ -203,9 +203,9 @@ match(const struct cls_rule *wild, const struct flow *fixed)
                    & wild->wc.vlan_tci_mask);
         } else if (f_idx == CLS_F_IDX_TUN_ID) {
             eq = !((fixed->tun_id ^ wild->flow.tun_id) & wild->wc.tun_id_mask);
-        } else if (f_idx == CLS_F_IDX_TOS_FRAG) {
-            eq = !((fixed->tos_frag ^ wild->flow.tos_frag)
-                   & wild->wc.tos_frag_mask);
+        } else if (f_idx == CLS_F_IDX_TOS) {
+            eq = !((fixed->tos ^ wild->flow.tos)
+                   & wild->wc.tos_mask);
         } else {
             NOT_REACHED();
         }
@@ -266,7 +266,7 @@ static uint8_t dl_src_values[][6] = { { 0x00, 0x02, 0xe3, 0x0f, 0x80, 0xa4 },
 static uint8_t dl_dst_values[][6] = { { 0x4a, 0x27, 0x71, 0xae, 0x64, 0xc1 },
                                       { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
 static uint8_t nw_proto_values[] = { IPPROTO_TCP, IPPROTO_ICMP };
-static uint8_t tos_frag_values[] = { 48, 0 };
+static uint8_t tos_values[] = { 48, 0 };
 
 static void *values[CLS_N_FIELDS][2];
 
@@ -300,8 +300,8 @@ init_values(void)
     values[CLS_F_IDX_NW_PROTO][0] = &nw_proto_values[0];
     values[CLS_F_IDX_NW_PROTO][1] = &nw_proto_values[1];
 
-    values[CLS_F_IDX_TOS_FRAG][0] = &tos_frag_values[0];
-    values[CLS_F_IDX_TOS_FRAG][1] = &tos_frag_values[1];
+    values[CLS_F_IDX_TOS][0] = &tos_values[0];
+    values[CLS_F_IDX_TOS][1] = &tos_values[1];
 
     values[CLS_F_IDX_TP_SRC][0] = &tp_src_values[0];
     values[CLS_F_IDX_TP_SRC][1] = &tp_src_values[1];
@@ -321,7 +321,7 @@ init_values(void)
 #define N_DL_SRC_VALUES ARRAY_SIZE(dl_src_values)
 #define N_DL_DST_VALUES ARRAY_SIZE(dl_dst_values)
 #define N_NW_PROTO_VALUES ARRAY_SIZE(nw_proto_values)
-#define N_TOS_FRAG_VALUES ARRAY_SIZE(tos_frag_values)
+#define N_TOS_VALUES ARRAY_SIZE(tos_values)
 
 #define N_FLOW_VALUES (N_NW_SRC_VALUES *        \
                        N_NW_DST_VALUES *        \
@@ -334,7 +334,7 @@ init_values(void)
                        N_DL_SRC_VALUES *        \
                        N_DL_DST_VALUES *        \
                        N_NW_PROTO_VALUES *      \
-                       N_TOS_FRAG_VALUES)
+                       N_TOS_VALUES)
 
 static unsigned int
 get_value(unsigned int *x, unsigned n_values)
@@ -370,7 +370,7 @@ compare_classifiers(struct classifier *cls, struct tcls *tcls)
         memcpy(flow.dl_dst, dl_dst_values[get_value(&x, N_DL_DST_VALUES)],
                ETH_ADDR_LEN);
         flow.nw_proto = nw_proto_values[get_value(&x, N_NW_PROTO_VALUES)];
-        flow.tos_frag = tos_frag_values[get_value(&x, N_TOS_FRAG_VALUES)];
+        flow.tos = tos_values[get_value(&x, N_TOS_VALUES)];
 
         cr0 = classifier_lookup(cls, &flow);
         cr1 = tcls_lookup(tcls, &flow);
@@ -468,8 +468,8 @@ make_rule(int wc_fields, unsigned int priority, int value_pat)
             rule->cls_rule.wc.vlan_tci_mask = htons(UINT16_MAX);
         } else if (f_idx == CLS_F_IDX_TUN_ID) {
             rule->cls_rule.wc.tun_id_mask = htonll(UINT64_MAX);
-        } else if (f_idx == CLS_F_IDX_TOS_FRAG) {
-            rule->cls_rule.wc.tos_frag_mask = UINT8_MAX;
+        } else if (f_idx == CLS_F_IDX_TOS) {
+            rule->cls_rule.wc.tos_mask = UINT8_MAX;
         } else {
             NOT_REACHED();
         }