From: wenxu <[email protected]>
There is currently no support for the multicast/broadcast aspects
of VXLAN in ovs. In the datapath flow the tun_dst must specific.
But in the IP_TUNNEL_INFO_BRIDGE mode the tun_dst can not be specific.
And the packet can forward through the fdb table of vxlan devcice. In
this mode the broadcast/multicast packet can be sent through the
following ways in ovs.
It adds an options allow_info_bridge for vxlan tunnel interface to
permit to enable this mode for this vxlan tunnel.
ovs-vsctl add-port br0 vxlan -- set in vxlan type=vxlan \
options:key=1000 options:remote_ip=flow
ovs-vsctl set in vxlan options:allow_info_bridge=true
ovs-ofctl add-flow br0 in_port=LOCAL,dl_dst=ff:ff:ff:ff:ff:ff, \
action=output:vxlan
bridge fdb append ff:ff:ff:ff:ff:ff dev vxlan_sys_4789 dst 172.168.0.1 \
src_vni 1000 vni 1000 self
bridge fdb append ff:ff:ff:ff:ff:ff dev vxlan_sys_4789 dst 172.168.0.2 \
src_vni 1000 vni 1000 self
Signed-off-by: wenxu <[email protected]>
Signed-off-by: Greg Rose <[email protected]>
---
include/openvswitch/packets.h | 3 ++-
lib/netdev-vport.c | 18 ++++++++++++++++++
lib/netdev.h | 2 ++
lib/odp-util.c | 21 ++++++++++++++++++---
lib/packets.h | 6 ++++++
ofproto/ofproto-dpif-xlate.c | 3 ++-
ofproto/tunnel.c | 5 +++++
vswitchd/vswitch.xml | 9 +++++++++
8 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/include/openvswitch/packets.h b/include/openvswitch/packets.h
index a65cb0d04..bf3774e84 100644
--- a/include/openvswitch/packets.h
+++ b/include/openvswitch/packets.h
@@ -43,9 +43,10 @@ struct flow_tnl {
uint32_t erspan_idx;
uint8_t erspan_dir;
uint8_t erspan_hwid;
+ uint8_t ipv4_info_bridge;
uint8_t gtpu_flags;
uint8_t gtpu_msgtype;
- uint8_t pad1[4]; /* Pad to 64 bits. */
+ uint8_t pad1[3]; /* Pad to 64 bits. */
struct tun_metadata metadata;
};
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 0252b61de..4cba7fe20 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -569,6 +569,7 @@ set_tunnel_config(struct netdev *dev_, const struct smap
*args, char **errp)
bool needs_dst_port, has_csum, has_seq;
uint16_t dst_proto = 0, src_proto = 0;
struct netdev_tunnel_config tnl_cfg;
+ bool allow_info_bridge = false;
struct smap_node *node;
int err;
@@ -745,12 +746,25 @@ set_tunnel_config(struct netdev *dev_, const struct smap
*args, char **errp)
goto out;
}
}
+ } else if (!strcmp(node->key, "allow_info_bridge")) {
+ if (!strcmp(node->value, "true")) {
+ allow_info_bridge = true;
+ }
} else {
ds_put_format(&errors, "%s: unknown %s argument '%s'\n", name,
type, node->key);
}
}
+ if (allow_info_bridge) {
+ if (!strcmp(type, "vxlan") && tnl_cfg.ip_dst_flow) {
+ tnl_cfg.allow_info_bridge = true;
+ } else {
+ ds_put_format(&errors, "%s: only work for vxlan in remote_ip=flow"
+ " mode\n", node->key);
+ }
+ }
+
enum tunnel_layers layers = tunnel_supported_layers(type, &tnl_cfg);
const char *full_type = (strcmp(type, "vxlan") ? type
: (tnl_cfg.exts & (1 << OVS_VXLAN_EXT_GPE)
@@ -983,6 +997,10 @@ get_tunnel_config(const struct netdev *dev, struct smap
*args)
}
}
+ if (!strcmp("vxlan", type) && tnl_cfg.allow_info_bridge) {
+ smap_add(args, "allow_info_bridge", "true");
+ }
+
return 0;
}
diff --git a/lib/netdev.h b/lib/netdev.h
index fb5073056..715a8af84 100644
--- a/lib/netdev.h
+++ b/lib/netdev.h
@@ -139,6 +139,8 @@ struct netdev_tunnel_config {
bool erspan_idx_flow;
bool erspan_dir_flow;
bool erspan_hwid_flow;
+
+ bool allow_info_bridge;
};
void netdev_run(void);
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 5989381e9..b43c599d6 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -2668,6 +2668,7 @@ static const struct attr_len_tbl
ovs_tun_key_attr_lens[OVS_TUNNEL_KEY_ATTR_MAX +
[OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = 16 },
[OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = 16 },
[OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = ATTR_LEN_VARIABLE },
+ [OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE] = { .len = 0 },
[OVS_TUNNEL_KEY_ATTR_GTPU_OPTS] = { .len = ATTR_LEN_VARIABLE },
};
@@ -3081,6 +3082,9 @@ odp_tun_key_from_attr__(const struct nlattr *attr, bool
is_mask,
tun->gtpu_msgtype = opts->msgtype;
break;
}
+ case OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE:
+ tun->ipv4_info_bridge = 1;
+ break;
default:
/* Allow this to show up as unexpected, if there are unknown
@@ -3128,6 +3132,11 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl
*tun_key,
if (tun_key->tun_id || tun_key->flags & FLOW_TNL_F_KEY) {
nl_msg_put_be64(a, OVS_TUNNEL_KEY_ATTR_ID, tun_key->tun_id);
}
+ if (tnl_type && !strcmp(tnl_type, "vxlan") &&
+ tun_key->ipv4_info_bridge) {
+ nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE);
+ goto out;
+ }
if (tun_key->ip_src) {
nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, tun_key->ip_src);
}
@@ -3204,6 +3213,8 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl
*tun_key,
nl_msg_put_unspec(a, OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS,
&opts, sizeof(opts));
}
+
+out:
nl_msg_end_nested(a, tun_key_ofs);
}
@@ -3973,6 +3984,9 @@ format_odp_tun_attr(const struct nlattr *attr, const
struct nlattr *mask_attr,
format_odp_tun_gtpu_opt(a, ma, ds, verbose);
ds_put_cstr(ds, ")");
break;
+ case OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE:
+ ds_put_cstr(ds, "ipv4_info_bridge,");
+ break;
case __OVS_TUNNEL_KEY_ATTR_MAX:
default:
format_unknown_key(ds, a, ma);
@@ -7687,9 +7701,10 @@ void
commit_odp_tunnel_action(const struct flow *flow, struct flow *base,
struct ofpbuf *odp_actions, const char *tnl_type)
{
- /* A valid IPV4_TUNNEL must have non-zero ip_dst; a valid IPv6 tunnel
- * must have non-zero ipv6_dst. */
- if (flow_tnl_dst_is_set(&flow->tunnel)) {
+ /* A valid IPV4_TUNNEL must have non-zero ip_dst or ipv4 info bridge mode;
+ * a valid IPv6 tunnel must have non-zero ipv6_dst. */
+ if (flow_tnl_dst_is_set(&flow->tunnel) ||
+ flow_tnl_ipv4_info_bridge(&flow->tunnel)) {
if (!memcmp(&base->tunnel, &flow->tunnel, sizeof base->tunnel)) {
return;
}
diff --git a/lib/packets.h b/lib/packets.h
index 395bc869e..9edf52113 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -58,6 +58,12 @@ flow_tnl_src_is_set(const struct flow_tnl *tnl)
return tnl->ip_src || ipv6_addr_is_set(&tnl->ipv6_src);
}
+static inline bool
+flow_tnl_ipv4_info_bridge(const struct flow_tnl *tnl)
+{
+ return tnl->ipv4_info_bridge;
+}
+
struct in6_addr flow_tnl_dst(const struct flow_tnl *tnl);
struct in6_addr flow_tnl_src(const struct flow_tnl *tnl);
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index e0ede2cab..fb26fb373 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4172,7 +4172,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t
ofp_port,
goto out; /* restore flow_nw_tos */
}
dst = flow_tnl_dst(&flow->tunnel);
- if (ipv6_addr_equals(&dst, &ctx->orig_tunnel_ipv6_dst)) {
+ if (!flow_tnl_ipv4_info_bridge(&flow->tunnel) &&
+ ipv6_addr_equals(&dst, &ctx->orig_tunnel_ipv6_dst)) {
xlate_report(ctx, OFT_WARN, "Not tunneling to our own address");
goto out; /* restore flow_nw_tos */
}
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index 3455ed233..18ec93655 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -488,6 +488,11 @@ tnl_port_send(const struct ofport_dpif *ofport, struct
flow *flow,
flow->tunnel.erspan_hwid = cfg->erspan_hwid;
}
+ if (cfg->allow_info_bridge && !flow_tnl_dst_is_set(&flow->tunnel) &&
+ !flow->tunnel.gbp_flags && !flow->tunnel.gbp_id) {
+ flow->tunnel.ipv4_info_bridge = 1;
+ }
+
if (pre_flow_str) {
char *post_flow_str = flow_to_string(flow, NULL);
char *tnl_str = tnl_port_to_string(tnl_port);
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 81c84927f..d9e8f4373 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -2944,6 +2944,15 @@
</li>
</ul>
</column>
+
+ <column name="options" key="allow_info_bridge"
+ type='{"type": "boolean"}'>
+ Optional. Only in remote_ip=flow mode can be enabled. If enabled,
+ the tunnel dst is not set in flow. It will ignore all other
+ parameters except VNI. It makes the packet forward through the fdb
+ of vxlan_sys_x device. Default is disable; set to <code>true</code>
+ to enable.
+ </column>
</group>
<group title="Tunnel Options: gre only">
--
2.17.1
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev