This will be used to both avoid the need to recalculate the length for each
packet in the datapath and to allow clamping the MSS of packets to the PMTU

Cc: Kyle Mestery <kmest...@cisco.com>
Signed-of-by: Simon Horman <ho...@verge.net.au>

---

v5
* Initial post
---
 include/linux/openvswitch.h |  3 ++-
 lib/flow.h                  |  3 ++-
 ofproto/ofproto-dpif.c      | 50 ++++++++++++++++++++++++++++++++++++++-------
 ofproto/ofproto.h           |  1 +
 4 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
index c5c7cb5..7f067ce 100644
--- a/include/linux/openvswitch.h
+++ b/include/linux/openvswitch.h
@@ -368,7 +368,8 @@ struct ovs_key_ipv4_tunnel {
        __be32 ipv4_dst;
        __u8   ipv4_tos;
        __u8   ipv4_ttl;
-       __u8   pad[2];
+       __u8   tun_hdr_len;
+       __u8   pad;
 };
 
 /**
diff --git a/lib/flow.h b/lib/flow.h
index 18396f3..ea808da 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -59,7 +59,8 @@ struct flow_tun_key {
     ovs_be32 ipv4_dst;
     uint8_t  ipv4_tos;
     uint8_t  ipv4_ttl;
-    uint8_t  pad[2];
+    uint8_t  tun_hdr_len;
+    uint8_t  pad;
 };
 
 struct flow {
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index eb8a6a4..595c50c 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -479,6 +479,7 @@ static bool facet_is_controller_flow(struct facet *);
 struct ofport_dpif_tun {
     struct tunnel_settings s;
     uint16_t tundev_ofp_port;
+    uint8_t hdr_len;
     struct hmap_node tundev_node;
     struct ofport_dpif *ofport;  /* Containing ofport_dpif */
 };
@@ -4928,6 +4929,7 @@ compose_output_action__(struct action_xlate_ctx *ctx, 
uint16_t ofp_port,
             ctx->flow.tun_key.ipv4_dst = ofport->tun->s.daddr;
             ctx->flow.tun_key.ipv4_tos = ofport->tun->s.tos;
             ctx->flow.tun_key.ipv4_ttl = ofport->tun->s.ttl;
+            ctx->flow.tun_key.tun_hdr_len = ofport->tun->hdr_len;
         } else {
             ctx->flow.vlan_tci = htons(0);
         }
@@ -7199,17 +7201,45 @@ tun_add(struct ofport_dpif *ofport)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
 
-    /* Only add if the saddr is non-zero, in which case ofport is a
-     * realdev. Otherwise it is a tundev */
-    if (ofport->tun->s.daddr == htonl(0)) {
-        return;
-    }
-
     (*tun_port_pool(&ofport->tun->s))++;
     hmap_insert(&ofproto->tundev_map, &ofport->tun->tundev_node,
                 hash_int(ofport->tun->tundev_ofp_port, 0));
 }
 
+#define GRE_HEADER_SECTION 4
+
+#define CAPWAP_MIN_HLEN    16 /* UDP header    (8 bytes) +
+                               * CAPWAP header (8 bytes)
+                               */
+#define CAPWAP_KEY_HLEN    12 /* CAPWAP WSI     (4 bytes) +
+                               * CAPWAP WSI Key (8 bytes)
+                               */
+
+static uint8_t tun_hdr_len(const struct tunnel_settings *s)
+{
+     uint8_t hdr_len = 0;
+
+     switch(s->type & TNL_T_PROTO_MASK) {
+     case TNL_T_PROTO_GRE:
+        hdr_len = GRE_HEADER_SECTION;
+        if (s->flags & TNL_F_CSUM) {
+            hdr_len += GRE_HEADER_SECTION;
+        }
+        if (s->flags & TNL_F_OUT_KEY) {
+            hdr_len += GRE_HEADER_SECTION;
+        }
+        break;
+     case TNL_T_PROTO_CAPWAP:
+        hdr_len = CAPWAP_MIN_HLEN;
+        if (s->flags & TNL_F_OUT_KEY) {
+            hdr_len += CAPWAP_KEY_HLEN;
+        }
+        break;
+     }
+
+     return hdr_len;
+}
+
 static int
 set_tunnelling(struct ofport *ofport_, uint16_t tundev_ofp_port,
                const struct tunnel_settings *s)
@@ -7241,7 +7271,13 @@ set_tunnelling(struct ofport *ofport_, uint16_t 
tundev_ofp_port,
 
     ofport->tun->s = *s;
     ofport->tun->tundev_ofp_port = tundev_ofp_port;
-    tun_add(ofport);
+
+    /* Only add and set the hdr_len if the saddr is non-zero,
+     * in which case ofport is a realdev. Otherwise it is a tundev */
+    if (ofport->tun->s.daddr != htonl(0)) {
+        ofport->tun->hdr_len = tun_hdr_len(s);
+        tun_add(ofport);
+    }
 
     return 0;
 }
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index d9afd9c..2c0643a 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -382,6 +382,7 @@ int ofproto_port_set_realdev(struct ofproto *, uint16_t 
vlandev_ofp_port,
 
 #define TNL_T_PROTO_GRE     0
 #define TNL_T_PROTO_CAPWAP  1
+#define TNL_T_PROTO_MASK    0x1f
 
 #define TNL_T_KEY_EXACT     (1 << 6)
 #define TNL_T_KEY_MATCH     (1 << 7)
-- 
1.7.10.2.484.gcd07cc5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to