diff options
author | Martin Varghese <martin.varghese@nokia.com> | 2020-12-17 12:48:41 +0530 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2020-12-22 12:51:22 +0100 |
commit | ebe0e518b0489aafbe385ba90133f6bacba33353 (patch) | |
tree | 73972f43dc33161d91cb93684f153da5919b0290 /lib/dpif-netlink-rtnl.c | |
parent | 55f2b065acd477a6810d5279fcace8b42bd594f5 (diff) | |
download | openvswitch-ebe0e518b0489aafbe385ba90133f6bacba33353.tar.gz |
tunnel: Bareudp Tunnel Support.
There are various L3 encapsulation standards using UDP being discussed to
leverage the UDP based load balancing capability of different networks.
MPLSoUDP (__ https://tools.ietf.org/html/rfc7510) is one among them.
The Bareudp tunnel provides a generic L3 encapsulation support for
tunnelling different L3 protocols like MPLS, IP, NSH etc. inside a UDP
tunnel.
An example to create bareudp device to tunnel MPLS traffic is
given
$ ovs-vsctl add-port br_mpls udp_port -- set interface udp_port \
type=bareudp options:remote_ip=2.1.1.3
options:local_ip=2.1.1.2 \
options:payload_type=0x8847 options:dst_port=6635
The bareudp device supports special handling for MPLS & IP as
they can have multiple ethertypes. MPLS procotcol can have ethertypes
ETH_P_MPLS_UC (unicast) & ETH_P_MPLS_MC (multicast). IP protocol can have
ethertypes ETH_P_IP (v4) & ETH_P_IPV6 (v6).
The bareudp device to tunnel L3 traffic with multiple ethertypes
(MPLS & IP) can be created by passing the L3 protocol name as string in
the field payload_type. An example to create bareudp device to tunnel
MPLS unicast & multicast traffic is given below.::
$ ovs-vsctl add-port br_mpls udp_port -- set interface
udp_port \
type=bareudp options:remote_ip=2.1.1.3
options:local_ip=2.1.1.2 \
options:payload_type=mpls options:dst_port=6635
Signed-off-by: Martin Varghese <martin.varghese@nokia.com>
Acked-By: Greg Rose <gvrose8192@gmail.com>
Tested-by: Greg Rose <gvrose8192@gmail.com>
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'lib/dpif-netlink-rtnl.c')
-rw-r--r-- | lib/dpif-netlink-rtnl.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/dpif-netlink-rtnl.c b/lib/dpif-netlink-rtnl.c index fd157ce2d..4fc42daed 100644 --- a/lib/dpif-netlink-rtnl.c +++ b/lib/dpif-netlink-rtnl.c @@ -58,6 +58,18 @@ VLOG_DEFINE_THIS_MODULE(dpif_netlink_rtnl); #define IFLA_GENEVE_UDP_ZERO_CSUM6_RX 10 #endif +#ifndef IFLA_BAREUDP_MAX +#define IFLA_BAREUDP_MAX 0 +#endif +#if IFLA_BAREUDP_MAX < 4 +#define IFLA_BAREUDP_PORT 1 +#define IFLA_BAREUDP_ETHERTYPE 2 +#define IFLA_BAREUDP_SRCPORT_MIN 3 +#define IFLA_BAREUDP_MULTIPROTO_MODE 4 +#endif + +#define BAREUDP_SRCPORT_MIN 49153 + static const struct nl_policy rtlink_policy[] = { [IFLA_LINKINFO] = { .type = NL_A_NESTED }, }; @@ -81,6 +93,10 @@ static const struct nl_policy geneve_policy[] = { [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NL_A_U8 }, [IFLA_GENEVE_PORT] = { .type = NL_A_U16 }, }; +static const struct nl_policy bareudp_policy[] = { + [IFLA_BAREUDP_PORT] = { .type = NL_A_U16 }, + [IFLA_BAREUDP_ETHERTYPE] = { .type = NL_A_U16 }, +}; static const char * vport_type_to_kind(enum ovs_vport_type type, @@ -113,6 +129,8 @@ vport_type_to_kind(enum ovs_vport_type type, } case OVS_VPORT_TYPE_GTPU: return NULL; + case OVS_VPORT_TYPE_BAREUDP: + return "bareudp"; case OVS_VPORT_TYPE_NETDEV: case OVS_VPORT_TYPE_INTERNAL: case OVS_VPORT_TYPE_LISP: @@ -243,6 +261,24 @@ dpif_netlink_rtnl_geneve_verify(const struct netdev_tunnel_config *tnl_cfg, return err; } +static int +dpif_netlink_rtnl_bareudp_verify(const struct netdev_tunnel_config *tnl_cfg, + const char *kind, struct ofpbuf *reply) +{ + struct nlattr *bareudp[ARRAY_SIZE(bareudp_policy)]; + int err; + + err = rtnl_policy_parse(kind, reply, bareudp_policy, bareudp, + ARRAY_SIZE(bareudp_policy)); + if (!err) { + if ((tnl_cfg->dst_port != nl_attr_get_be16(bareudp[IFLA_BAREUDP_PORT])) + || (tnl_cfg->payload_ethertype + != nl_attr_get_be16(bareudp[IFLA_BAREUDP_ETHERTYPE]))) { + err = EINVAL; + } + } + return err; +} static int dpif_netlink_rtnl_verify(const struct netdev_tunnel_config *tnl_cfg, @@ -275,6 +311,9 @@ dpif_netlink_rtnl_verify(const struct netdev_tunnel_config *tnl_cfg, case OVS_VPORT_TYPE_GENEVE: err = dpif_netlink_rtnl_geneve_verify(tnl_cfg, kind, reply); break; + case OVS_VPORT_TYPE_BAREUDP: + err = dpif_netlink_rtnl_bareudp_verify(tnl_cfg, kind, reply); + break; case OVS_VPORT_TYPE_NETDEV: case OVS_VPORT_TYPE_INTERNAL: case OVS_VPORT_TYPE_LISP: @@ -357,6 +396,16 @@ dpif_netlink_rtnl_create(const struct netdev_tunnel_config *tnl_cfg, nl_msg_put_u8(&request, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, 1); nl_msg_put_be16(&request, IFLA_GENEVE_PORT, tnl_cfg->dst_port); break; + case OVS_VPORT_TYPE_BAREUDP: + nl_msg_put_be16(&request, IFLA_BAREUDP_ETHERTYPE, + tnl_cfg->payload_ethertype); + nl_msg_put_u16(&request, IFLA_BAREUDP_SRCPORT_MIN, + BAREUDP_SRCPORT_MIN); + nl_msg_put_be16(&request, IFLA_BAREUDP_PORT, tnl_cfg->dst_port); + if (tnl_cfg->exts & (1 << OVS_BAREUDP_EXT_MULTIPROTO_MODE)) { + nl_msg_put_flag(&request, IFLA_BAREUDP_MULTIPROTO_MODE); + } + break; case OVS_VPORT_TYPE_NETDEV: case OVS_VPORT_TYPE_INTERNAL: case OVS_VPORT_TYPE_LISP: @@ -470,6 +519,7 @@ dpif_netlink_rtnl_port_destroy(const char *name, const char *type) case OVS_VPORT_TYPE_ERSPAN: case OVS_VPORT_TYPE_IP6ERSPAN: case OVS_VPORT_TYPE_IP6GRE: + case OVS_VPORT_TYPE_BAREUDP: return dpif_netlink_rtnl_destroy(name); case OVS_VPORT_TYPE_NETDEV: case OVS_VPORT_TYPE_INTERNAL: |