flow: Remove superfluous casts.
[openvswitch] / lib / flow.c
index 5ba3e10df435dfa569e6712d850c59456e3619a9..59158ac08430736d2d59c12b1e30318e922b38b0 100644 (file)
@@ -26,6 +26,7 @@
 #include <string.h>
 #include "byte-order.h"
 #include "coverage.h"
+#include "csum.h"
 #include "dynamic-string.h"
 #include "hash.h"
 #include "ofpbuf.h"
@@ -179,7 +180,7 @@ parse_ipv6(struct ofpbuf *packet, struct flow *flow)
                 || (nexthdr == IPPROTO_DSTOPTS)) {
             /* These headers, while different, have the fields we care about
              * in the same location and with the same interpretation. */
-            const struct ip6_ext *ext_hdr = (struct ip6_ext *)packet->data;
+            const struct ip6_ext *ext_hdr = packet->data;
             nexthdr = ext_hdr->ip6e_nxt;
             if (!ofpbuf_try_pull(packet, (ext_hdr->ip6e_len + 1) * 8)) {
                 return EINVAL;
@@ -189,13 +190,13 @@ parse_ipv6(struct ofpbuf *packet, struct flow *flow)
              * we care about are in the same location as the generic
              * option header--only the header length is calculated
              * differently. */
-            const struct ip6_ext *ext_hdr = (struct ip6_ext *)packet->data;
+            const struct ip6_ext *ext_hdr = packet->data;
             nexthdr = ext_hdr->ip6e_nxt;
             if (!ofpbuf_try_pull(packet, (ext_hdr->ip6e_len + 2) * 4)) {
                return EINVAL;
             }
         } else if (nexthdr == IPPROTO_FRAGMENT) {
-            const struct ip6_frag *frag_hdr = (struct ip6_frag *)packet->data;
+            const struct ip6_frag *frag_hdr = packet->data;
 
             nexthdr = frag_hdr->ip6f_nxt;
             if (!ofpbuf_try_pull(packet, sizeof *frag_hdr)) {
@@ -744,6 +745,7 @@ flow_wildcards_combine(struct flow_wildcards *dst,
     dst->vlan_tci_mask = src1->vlan_tci_mask & src2->vlan_tci_mask;
     dst->tp_src_mask = src1->tp_src_mask & src2->tp_src_mask;
     dst->tp_dst_mask = src1->tp_dst_mask & src2->tp_dst_mask;
+    dst->nw_frag_mask = src1->nw_frag_mask & src2->nw_frag_mask;
     eth_addr_bitand(src1->dl_src_mask, src2->dl_src_mask, dst->dl_src_mask);
     eth_addr_bitand(src1->dl_dst_mask, src2->dl_dst_mask, dst->dl_dst_mask);
     eth_addr_bitand(src1->arp_sha_mask, src2->arp_sha_mask, dst->arp_sha_mask);
@@ -783,6 +785,7 @@ flow_wildcards_equal(const struct flow_wildcards *a,
         || !ipv6_addr_equals(&a->nd_target_mask, &b->nd_target_mask)
         || a->tp_src_mask != b->tp_src_mask
         || a->tp_dst_mask != b->tp_dst_mask
+        || a->nw_frag_mask != b->nw_frag_mask
         || !eth_addr_equals(a->dl_src_mask, b->dl_src_mask)
         || !eth_addr_equals(a->dl_dst_mask, b->dl_dst_mask)
         || !eth_addr_equals(a->arp_sha_mask, b->arp_sha_mask)
@@ -860,7 +863,8 @@ flow_wildcards_has_extra(const struct flow_wildcards *a,
             || (a->vlan_tci_mask & b->vlan_tci_mask) != b->vlan_tci_mask
             || (a->metadata_mask & b->metadata_mask) != b->metadata_mask
             || (a->tp_src_mask & b->tp_src_mask) != b->tp_src_mask
-            || (a->tp_dst_mask & b->tp_dst_mask) != b->tp_dst_mask);
+            || (a->tp_dst_mask & b->tp_dst_mask) != b->tp_dst_mask
+            || (a->nw_frag_mask & b->nw_frag_mask) != b->nw_frag_mask);
 }
 
 /* Sets the wildcard mask for register 'idx' in 'wc' to 'mask'.
@@ -968,7 +972,7 @@ flow_hash_fields_valid(enum nx_hash_fields fields)
  *
  *      - Other values of 'vid' should not be used. */
 void
-flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
+flow_set_dl_vlan(struct flow *flow, ovs_be16 vid)
 {
     if (vid == htons(OFP10_VLAN_NONE)) {
         flow->vlan_tci = htons(0);
@@ -979,6 +983,17 @@ flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
     }
 }
 
+/* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
+ * OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
+ * plus CFI). */
+void
+flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
+{
+    ovs_be16 mask = htons(VLAN_VID_MASK | VLAN_CFI);
+    flow->vlan_tci &= ~mask;
+    flow->vlan_tci |= vid & mask;
+}
+
 /* Sets the VLAN PCP that 'flow' matches to 'pcp', which should be in the
  * range 0...7.
  *
@@ -998,7 +1013,7 @@ flow_set_vlan_pcp(struct flow *flow, uint8_t pcp)
  * 'flow'.
  *
  * (This is useful only for testing, obviously, and the packet isn't really
- * valid.  It hasn't got any checksums filled in, for one, and lots of fields
+ * valid. It hasn't got some checksums filled in, for one, and lots of fields
  * are just zeroed.) */
 void
 flow_compose(struct ofpbuf *b, const struct flow *flow)
@@ -1054,8 +1069,10 @@ flow_compose(struct ofpbuf *b, const struct flow *flow)
             }
         }
 
+        ip = b->l3;
         ip->ip_tot_len = htons((uint8_t *) b->data + b->size
                                - (uint8_t *) b->l3);
+        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)) {