On Wed, Jul 01, 2020 at 09:45:04PM +0200, Guillaume Nault wrote: > Bareudp devices provide a generic L3 encapsulation for tunnelling > different protocols like MPLS, IP, NSH, etc. inside a UDP tunnel. > > This patch is based on original work from Martin Varghese: > https://lore.kernel.org/netdev/1570532361-15163-1-git-send-email-martinvargheseno...@gmail.com/ > > Examples: > > - ip link add dev bareudp0 type bareudp dstport 6635 ethertype mpls_uc > > This creates a bareudp tunnel device which tunnels L3 traffic with > ethertype 0x8847 (unicast MPLS traffic). The destination port of the > UDP header will be set to 6635. The device will listen on UDP port 6635 > to receive traffic. > > - ip link add dev bareudp0 type bareudp dstport 6635 ethertype ipv4 > multiproto > > Same as the MPLS example, but for IPv4. The "multiproto" keyword allows > the device to also tunnel IPv6 traffic. > > Signed-off-by: Guillaume Nault <gna...@redhat.com> > --- > ip/Makefile | 2 +- > ip/iplink.c | 2 +- > ip/iplink_bareudp.c | 150 ++++++++++++++++++++++++++++++++++++++++++ > man/man8/ip-link.8.in | 44 +++++++++++++ > 4 files changed, 196 insertions(+), 2 deletions(-) > create mode 100644 ip/iplink_bareudp.c > > diff --git a/ip/Makefile b/ip/Makefile > index 8735b8e4..4cad619c 100644 > --- a/ip/Makefile > +++ b/ip/Makefile > @@ -11,7 +11,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o > ipnetns.o \ > iplink_bridge.o iplink_bridge_slave.o ipfou.o iplink_ipvlan.o \ > iplink_geneve.o iplink_vrf.o iproute_lwtunnel.o ipmacsec.o ipila.o \ > ipvrf.o iplink_xstats.o ipseg6.o iplink_netdevsim.o iplink_rmnet.o \ > - ipnexthop.o ipmptcp.o > + ipnexthop.o ipmptcp.o iplink_bareudp.o > > RTMONOBJ=rtmon.o > > diff --git a/ip/iplink.c b/ip/iplink.c > index 47f73988..7d4b244d 100644 > --- a/ip/iplink.c > +++ b/ip/iplink.c > @@ -124,7 +124,7 @@ void iplink_usage(void) > " bridge | bond | team | ipoib | ip6tnl | ipip > | sit | vxlan |\n" > " gre | gretap | erspan | ip6gre | ip6gretap | > ip6erspan |\n" > " vti | nlmon | team_slave | bond_slave | > bridge_slave |\n" > - " ipvlan | ipvtap | geneve | vrf | macsec | > netdevsim | rmnet |\n" > + " ipvlan | ipvtap | geneve | bareudp | vrf | > macsec | netdevsim | rmnet |\n" > " xfrm }\n"); > } > exit(-1); > diff --git a/ip/iplink_bareudp.c b/ip/iplink_bareudp.c > new file mode 100644 > index 00000000..885e1110 > --- /dev/null > +++ b/ip/iplink_bareudp.c > @@ -0,0 +1,150 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > + > +#include <stdio.h> > + > +#include "libnetlink.h" > +#include "linux/if_ether.h" > +#include "linux/if_link.h" > +#include "linux/netlink.h" > +#include "linux/rtnetlink.h" > +#include "rt_names.h" > +#include "utils.h" > +#include "ip_common.h" > +#include "json_print.h" > + > +#define BAREUDP_ATTRSET(attrs, type) (((attrs) & (1L << (type))) != 0) > + > +static void print_explain(FILE *f) > +{ > + fprintf(f, > + "Usage: ... bareudp dstport PORT\n" > + " ethertype PROTO\n" > + " [ srcportmin PORT ]\n" > + " [ [no]multiproto ]\n" > + "\n" > + "Where: PORT := 0-65535\n" > + " PROTO := NUMBER | ip | mpls\n" > + " SRCPORTMIN := 0-65535\n" > + ); > +} > + > +static void explain(void) > +{ > + print_explain(stderr); > +} > + > +static void check_duparg(__u64 *attrs, int type, const char *key, > + const char *argv) > +{ > + if (!BAREUDP_ATTRSET(*attrs, type)) { > + *attrs |= (1L << type); > + return; > + } > + duparg2(key, argv); > +} > + > +static int bareudp_parse_opt(struct link_util *lu, int argc, char **argv, > + struct nlmsghdr *n) > +{ > + bool multiproto = false; > + __u16 srcportmin = 0; > + __be16 ethertype = 0; > + __be16 dstport = 0; > + __u64 attrs = 0; > + > + while (argc > 0) { > + if (matches(*argv, "dstport") == 0) { > + NEXT_ARG(); > + check_duparg(&attrs, IFLA_BAREUDP_PORT, "dstport", > + *argv); > + if (get_be16(&dstport, *argv, 0)) > + invarg("dstport", *argv); > + } else if (matches(*argv, "ethertype") == 0) { > + NEXT_ARG(); > + check_duparg(&attrs, IFLA_BAREUDP_ETHERTYPE, > + "ethertype", *argv); > + if (ll_proto_a2n(ðertype, *argv)) > + invarg("ethertype", *argv); > + } else if (matches(*argv, "srcportmin") == 0) { > + NEXT_ARG(); > + check_duparg(&attrs, IFLA_BAREUDP_SRCPORT_MIN, > + "srcportmin", *argv); > + if (get_u16(&srcportmin, *argv, 0)) > + invarg("srcportmin", *argv); > + } else if (matches(*argv, "multiproto") == 0) { > + check_duparg(&attrs, IFLA_BAREUDP_MULTIPROTO_MODE, > + *argv, *argv); > + multiproto = true; > + } else if (matches(*argv, "nomultiproto") == 0) { > + check_duparg(&attrs, IFLA_BAREUDP_MULTIPROTO_MODE, > + *argv, *argv); > + multiproto = false; > + } else if (matches(*argv, "help") == 0) { > + explain(); > + return -1; > + } else { > + fprintf(stderr, "bareudp: unknown command \"%s\"?\n", > + *argv); > + explain(); > + return -1; > + } > + argc--, argv++; > + } > + > + if (!BAREUDP_ATTRSET(attrs, IFLA_BAREUDP_PORT)) > + missarg("dstport"); > + if (!BAREUDP_ATTRSET(attrs, IFLA_BAREUDP_ETHERTYPE)) > + missarg("ethertype"); > + > + addattr16(n, 1024, IFLA_BAREUDP_PORT, dstport); > + addattr16(n, 1024, IFLA_BAREUDP_ETHERTYPE, ethertype); > + if (BAREUDP_ATTRSET(attrs, IFLA_BAREUDP_SRCPORT_MIN)) > + addattr16(n, 1024, IFLA_BAREUDP_SRCPORT_MIN, srcportmin); > + if (multiproto) > + addattr(n, 1024, IFLA_BAREUDP_MULTIPROTO_MODE); > + > + return 0; > +} > + > +static void bareudp_print_opt(struct link_util *lu, FILE *f, > + struct rtattr *tb[]) > +{ > + if (!tb) > + return; > + > + if (tb[IFLA_BAREUDP_PORT]) > + print_uint(PRINT_ANY, "dstport", "dstport %u ", > + rta_getattr_be16(tb[IFLA_BAREUDP_PORT])); > + > + if (tb[IFLA_BAREUDP_ETHERTYPE]) { > + struct rtattr *attr = tb[IFLA_BAREUDP_ETHERTYPE]; > + SPRINT_BUF(ethertype); > + > + print_string(PRINT_ANY, "ethertype", "ethertype %s ", > + ll_proto_n2a(rta_getattr_u16(attr), > + ethertype, sizeof(ethertype))); > + } > + > + if (tb[IFLA_BAREUDP_SRCPORT_MIN]) > + print_uint(PRINT_ANY, "srcportmin", "srcportmin %u ", > + rta_getattr_u16(tb[IFLA_BAREUDP_SRCPORT_MIN])); > + > + if (tb[IFLA_BAREUDP_MULTIPROTO_MODE]) > + print_bool(PRINT_ANY, "multiproto", "multiproto ", true); > + else > + print_bool(PRINT_ANY, "multiproto", "nomultiproto ", false); > +} > + > +static void bareudp_print_help(struct link_util *lu, int argc, char **argv, > + FILE *f) > +{ > + print_explain(f); > +} > + > +struct link_util bareudp_link_util = { > + .id = "bareudp", > + .maxattr = IFLA_BAREUDP_MAX, > + .parse_opt = bareudp_parse_opt, > + .print_opt = bareudp_print_opt, > + .print_help = bareudp_print_help, > +}; > diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in > index e8a25451..c6bd2c53 100644 > --- a/man/man8/ip-link.8.in > +++ b/man/man8/ip-link.8.in > @@ -223,6 +223,7 @@ ip-link \- network device configuration > .BR ipvtap " |" > .BR lowpan " |" > .BR geneve " |" > +.BR bareudp " |" > .BR vrf " |" > .BR macsec " |" > .BR netdevsim " |" > @@ -356,6 +357,9 @@ Link types: > .BR geneve > - GEneric NEtwork Virtualization Encapsulation > .sp > +.BR bareudp > +- Bare UDP L3 encapsulation support > +.sp > .BR macsec > - Interface for IEEE 802.1AE MAC Security (MACsec) > .sp > @@ -1293,6 +1297,46 @@ options. > > .in -8 > > +.TP > +Bareudp Type Support > +For a link of type > +.I Bareudp > +the following additional arguments are supported: > + > +.BI "ip link add " DEVICE > +.BI type " bareudp " dstport " PORT " ethertype " ETHERTYPE" > +[ > +.BI srcportmin " SRCPORTMIN " > +] [ > +.RB [ no ] multiproto > +] > + > +.in +8 > +.sp > +.BI dstport " PORT" > +- specifies the destination port for the UDP tunnel. > + > +.sp > +.BI ethertype " ETHERTYPE" > +- specifies the ethertype of the L3 protocol being tunnelled. > + > +.sp > +.BI srcportmin " SRCPORTMIN" > +- selects the lowest value of the UDP tunnel source port range. > + > +.sp > +.RB [ no ] multiproto > +- activates support for protocols similar to the one > +.RB "specified by " ethertype . > +When > +.I ETHERTYPE > +is "mpls_uc" (that is, unicast MPLS), this allows the tunnel to also handle > +multicast MPLS. > +When > +.I ETHERTYPE > +is "ipv4", this allows the tunnel to also handle IPv6. This option is > disabled > +by default. > + > .TP > MACVLAN and MACVTAP Type Support > For a link of type > --
I couldnt apply the patch to master.Could you please confirm if it was rebased to the master > 2.21.3 >