lib/flow: add dp_hash and recirc_id to struct flow
[sliver-openvswitch.git] / lib / flow.c
index 06ba036..f6ec135 100644 (file)
@@ -35,6 +35,7 @@
 #include "ofpbuf.h"
 #include "openflow/openflow.h"
 #include "packets.h"
+#include "odp-util.h"
 #include "random.h"
 #include "unaligned.h"
 
@@ -361,8 +362,7 @@ invalid:
 
 }
 
-/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
- * 'in_port'.
+/* Initializes 'flow' members from 'packet' and 'md'
  *
  * Initializes 'packet' header pointers as follows:
  *
@@ -381,8 +381,7 @@ invalid:
  *      present and has a correct length, and otherwise NULL.
  */
 void
-flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark,
-             const struct flow_tnl *tnl, const union flow_in_port *in_port,
+flow_extract(struct ofpbuf *packet, const struct pkt_metadata *md,
              struct flow *flow)
 {
     struct ofpbuf b = *packet;
@@ -392,15 +391,12 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark,
 
     memset(flow, 0, sizeof *flow);
 
-    if (tnl) {
-        ovs_assert(tnl != &flow->tunnel);
-        flow->tunnel = *tnl;
+    if (md) {
+        flow->tunnel = md->tunnel;
+        flow->in_port = md->in_port;
+        flow->skb_priority = md->skb_priority;
+        flow->pkt_mark = md->pkt_mark;
     }
-    if (in_port) {
-        flow->in_port = *in_port;
-    }
-    flow->skb_priority = skb_priority;
-    flow->pkt_mark = pkt_mark;
 
     packet->l2   = b.data;
     packet->l2_5 = NULL;
@@ -534,8 +530,10 @@ flow_unwildcard_tp_ports(const struct flow *flow, struct flow_wildcards *wc)
 void
 flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
 {
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 24);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 25);
 
+    fmd->dp_hash = flow->dp_hash;
+    fmd->recirc_id = flow->recirc_id;
     fmd->tun_id = flow->tunnel.tun_id;
     fmd->tun_src = flow->tunnel.ip_src;
     fmd->tun_dst = flow->tunnel.ip_dst;
@@ -822,6 +820,25 @@ flow_wildcards_set_reg_mask(struct flow_wildcards *wc, int idx, uint32_t mask)
     wc->masks.regs[idx] = mask;
 }
 
+/* Calculates the 5-tuple hash from the given flow. */
+uint32_t
+flow_hash_5tuple(const struct flow *flow, uint32_t basis)
+{
+    uint32_t hash = 0;
+
+    if (!flow) {
+        return 0;
+    }
+
+    hash = mhash_add(basis, (OVS_FORCE uint32_t) flow->nw_src);
+    hash = mhash_add(hash, (OVS_FORCE uint32_t) flow->nw_dst);
+    hash = mhash_add(hash, ((OVS_FORCE uint32_t) flow->tp_src << 16)
+                           | (OVS_FORCE uint32_t) flow->tp_dst);
+    hash = mhash_add(hash, flow->nw_proto);
+
+    return mhash_finish(hash, 13);
+}
+
 /* Hashes 'flow' based on its L2 through L4 protocol information. */
 uint32_t
 flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
@@ -1130,7 +1147,7 @@ flow_count_common_mpls_labels(const struct flow *a, int an,
  * If the new label is the second or label MPLS label in 'flow', it is
  * generated as;
  *
- *     - label: 0.
+ *     - label: Copied from outer label.
  *
  *     - TTL: Copied from outer label.
  *
@@ -1156,7 +1173,7 @@ flow_push_mpls(struct flow *flow, int n, ovs_be16 mpls_eth_type,
             flow->mpls_lse[i] = flow->mpls_lse[i - 1];
         }
         flow->mpls_lse[0] = (flow->mpls_lse[1]
-                             & htonl(MPLS_TTL_MASK | MPLS_TC_MASK));
+                             & htonl(~MPLS_BOS_MASK));
     } else {
         int label = 0;          /* IPv4 Explicit Null. */
         int tc = 0;
@@ -1179,7 +1196,7 @@ flow_push_mpls(struct flow *flow, int n, ovs_be16 mpls_eth_type,
         flow->mpls_lse[0] = set_mpls_lse_values(ttl, tc, 1, htonl(label));
 
         /* Clear all L3 and L4 fields. */
-        BUILD_ASSERT(FLOW_WC_SEQ == 24);
+        BUILD_ASSERT(FLOW_WC_SEQ == 25);
         memset((char *) flow + FLOW_SEGMENT_2_ENDS_AT, 0,
                sizeof(struct flow) - FLOW_SEGMENT_2_ENDS_AT);
     }