flow: Extend struct flow to contain tunnel outer header.
[sliver-openvswitch.git] / lib / flow.c
index e517a03..93bd9b2 100644 (file)
@@ -316,7 +316,7 @@ invalid:
 
 }
 
-/* Initializes 'flow' members from 'packet', 'skb_priority', 'tun_id', and
+/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
  * 'ofp_in_port'.
  *
  * Initializes 'packet' header pointers as follows:
@@ -334,8 +334,9 @@ invalid:
  *      present and has a correct length, and otherwise NULL.
  */
 void
-flow_extract(struct ofpbuf *packet, uint32_t skb_priority, ovs_be64 tun_id,
-             uint16_t ofp_in_port, struct flow *flow)
+flow_extract(struct ofpbuf *packet, uint32_t skb_priority,
+             const struct flow_tnl *tnl, uint16_t ofp_in_port,
+             struct flow *flow)
 {
     struct ofpbuf b = *packet;
     struct eth_header *eth;
@@ -343,7 +344,10 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, ovs_be64 tun_id,
     COVERAGE_INC(flow_extract);
 
     memset(flow, 0, sizeof *flow);
-    flow->tun_id = tun_id;
+
+    if (tnl) {
+        flow->tunnel = *tnl;
+    }
     flow->in_port = ofp_in_port;
     flow->skb_priority = skb_priority;
 
@@ -460,7 +464,7 @@ flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
 {
     BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
 
-    fmd->tun_id = flow->tun_id;
+    fmd->tun_id = flow->tunnel.tun_id;
     fmd->metadata = flow->metadata;
     memcpy(fmd->regs, flow->regs, sizeof fmd->regs);
     fmd->in_port = flow->in_port;
@@ -474,15 +478,46 @@ flow_to_string(const struct flow *flow)
     return ds_cstr(&ds);
 }
 
+static void format_tunnel_flags(uint16_t flags, struct ds *ds)
+{
+    flags &= ~FLOW_TNL_F_KEY;
+
+    if (flags & FLOW_TNL_F_DONT_FRAGMENT) {
+        ds_put_cstr(ds, ",df");
+        flags &= ~FLOW_TNL_F_DONT_FRAGMENT;
+    }
+
+    if (flags & FLOW_TNL_F_CSUM) {
+        ds_put_cstr(ds, ",csum");
+        flags &= ~FLOW_TNL_F_CSUM;
+    }
+
+    if (flags) {
+        ds_put_format(ds, ",flags:%#"PRIx16, flags);
+    }
+}
+
 void
 flow_format(struct ds *ds, const struct flow *flow)
 {
-    ds_put_format(ds, "priority:%"PRIu32
-                      ",tunnel:%#"PRIx64
-                      ",metadata:%#"PRIx64
+    ds_put_format(ds, "priority:%"PRIu32, flow->skb_priority);
+
+    if (flow->tunnel.ip_dst || flow->tunnel.tun_id) {
+        ds_put_cstr(ds, ",tunnel(");
+        ds_put_format(ds, IP_FMT"->"IP_FMT, IP_ARGS(&flow->tunnel.ip_src),
+                                            IP_ARGS(&flow->tunnel.ip_dst));
+
+        if (flow->tunnel.flags & FLOW_TNL_F_KEY) {
+            ds_put_format(ds, ",key:%#"PRIx64, ntohll(flow->tunnel.tun_id));
+        }
+        ds_put_format(ds, ",tos:%#"PRIx8",ttl:%"PRIu8, flow->tunnel.ip_tos,
+                                                       flow->tunnel.ip_ttl);
+        format_tunnel_flags(flow->tunnel.flags, ds);
+        ds_put_char(ds, ')');
+    }
+
+    ds_put_format(ds, ",metadata:%#"PRIx64
                       ",in_port:%04"PRIx16,
-                      flow->skb_priority,
-                      ntohll(flow->tun_id),
                       ntohll(flow->metadata),
                       flow->in_port);