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