[ovs-dev] [PATCH v3 3/6] userspace: Handling of versatile tunnel ports
Zoltán Balogh
zoltan.balogh at ericsson.com
Fri Jun 2 16:29:00 UTC 2017
From: Jan Scheurich <jan.scheurich at ericsson.com>
In netdev_gre_build_header(), GRE protocol and VXLAN next_potocol is set based
on packet_type of flow. If it's about an Ethernet packet, it is set to
ETP_TYPE_TEB. Otherwise, if the name space is OFPHTN_ETHERNET, it is set
according to the name space type.
Signed-off-by: Jan Scheurich <jan.scheurich at ericsson.com>
---
lib/netdev-native-tnl.c | 20 ++++++++++++++------
ofproto/ofproto-dpif-xlate.c | 2 +-
ofproto/tunnel.c | 24 ++++++++++++++++++++----
ofproto/tunnel.h | 2 +-
4 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c
index c7a299345..658c87101 100644
--- a/lib/netdev-native-tnl.c
+++ b/lib/netdev-native-tnl.c
@@ -463,10 +463,12 @@ netdev_gre_build_header(const struct netdev *netdev,
greh = netdev_tnl_ip_build_header(data, params, IPPROTO_GRE);
- if (tnl_cfg->is_layer3) {
- greh->protocol = params->flow->dl_type;
- } else {
+ if (params->flow->packet_type == htonl(PT_ETH)) {
greh->protocol = htons(ETH_TYPE_TEB);
+ } else if (pt_ns(params->flow->packet_type) == OFPHTN_ETHERTYPE) {
+ greh->protocol = pt_ns_type_be(params->flow->packet_type);
+ } else {
+ return 1;
}
greh->flags = 0;
@@ -575,8 +577,10 @@ netdev_vxlan_build_header(const struct netdev *netdev,
put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS | VXLAN_HF_GPE));
put_16aligned_be32(&vxh->vx_vni,
htonl(ntohll(params->flow->tunnel.tun_id) << 8));
- if (tnl_cfg->is_layer3) {
- switch (ntohs(params->flow->dl_type)) {
+ if (params->flow->packet_type == htonl(PT_ETH)) {
+ vxh->vx_gpe.next_protocol = VXLAN_GPE_NP_ETHERNET;
+ } else if (pt_ns(params->flow->packet_type) == OFPHTN_ETHERTYPE){
+ switch (pt_ns_type(params->flow->packet_type)) {
case ETH_TYPE_IP:
vxh->vx_gpe.next_protocol = VXLAN_GPE_NP_IPV4;
break;
@@ -586,9 +590,13 @@ netdev_vxlan_build_header(const struct netdev *netdev,
case ETH_TYPE_TEB:
vxh->vx_gpe.next_protocol = VXLAN_GPE_NP_ETHERNET;
break;
+ default:
+ /* Drop packet. */
+ return 1;
+ break;
}
} else {
- vxh->vx_gpe.next_protocol = VXLAN_GPE_NP_ETHERNET;
+ return 1;
}
} else {
put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS));
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 63b9d5c1c..c22647289 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -6152,7 +6152,7 @@ xlate_wc_init(struct xlate_ctx *ctx)
netflow_mask_wc(&ctx->xin->flow, ctx->wc);
}
- tnl_wc_init(&ctx->xin->flow, ctx->wc);
+ tnl_wc_init(&ctx->xin->flow, ctx->wc, ctx->xbridge->packet_type_aware);
}
static void
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index e27a9fb75..caf01be5f 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -361,7 +361,8 @@ tnl_process_ecn(struct flow *flow)
}
void
-tnl_wc_init(struct flow *flow, struct flow_wildcards *wc)
+tnl_wc_init(struct flow *flow, struct flow_wildcards *wc,
+ bool packet_type_aware)
{
if (tnl_port_should_receive(flow)) {
wc->masks.tunnel.tun_id = OVS_BE64_MAX;
@@ -386,8 +387,10 @@ tnl_wc_init(struct flow *flow, struct flow_wildcards *wc)
&& IP_ECN_is_ce(flow->tunnel.ip_tos)) {
wc->masks.nw_tos |= IP_ECN_MASK;
}
- /* Match on packet_type for tunneled packets.*/
- wc->masks.packet_type = OVS_BE32_MAX;
+ if (!packet_type_aware) {
+ /* Match on packet_type for tunneled packets.*/
+ wc->masks.packet_type = OVS_BE32_MAX;
+ }
}
}
@@ -566,8 +569,21 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock)
match.in_key_flow = in_key_flow;
match.ip_dst_flow = ip_dst_flow;
match.ip_src_flow = ip_src == IP_SRC_FLOW;
- match.is_layer3 = flow->packet_type != htonl(PT_ETH);
+ /* If it's about a Non-ethernet packet then we look for a
+ * layer3 tunnel port first, as it would be attached to a
+ * non-PTAP bridge. Then for a versatile tunnel port as it
+ * would be attached to a PTAP bridge. */
+ if (pt_ns(flow->packet_type) == OFPHTN_ETHERTYPE) {
+ /* Try to find a layer3 port first. */
+ match.is_layer3 = true;
+ tnl_port = tnl_find_exact(&match, map);
+ if (tnl_port) {
+ return tnl_port;
+ }
+ }
+ /* Check for a non-layer3 or versatile tunnel port. */
+ match.is_layer3 = false;
tnl_port = tnl_find_exact(&match, map);
if (tnl_port) {
return tnl_port;
diff --git a/ofproto/tunnel.h b/ofproto/tunnel.h
index b0ec67c2b..dc004cc18 100644
--- a/ofproto/tunnel.h
+++ b/ofproto/tunnel.h
@@ -39,7 +39,7 @@ int tnl_port_add(const struct ofport_dpif *, const struct netdev *,
void tnl_port_del(const struct ofport_dpif *);
const struct ofport_dpif *tnl_port_receive(const struct flow *);
-void tnl_wc_init(struct flow *, struct flow_wildcards *);
+void tnl_wc_init(struct flow *, struct flow_wildcards *, bool);
bool tnl_process_ecn(struct flow *);
odp_port_t tnl_port_send(const struct ofport_dpif *, struct flow *,
struct flow_wildcards *wc);
--
2.11.0
More information about the dev
mailing list