improve lwtunnel route support
Subsystems (2)
Paolo Abeni
maintainerv3 cover improve lwtunnel route support
This patch series try to improve the current route based lwtunnel support in iproute2, namely adding support for the COLLECT_METADATA flag in vxlan and gre link, and for ip6 encap type in lwtunnel.
Tunnel devices need to have the COLLECT_METADATA flag set in order to be used for route based lwtunnel.
Changes from V1:
- the COLLECT_METADATA flag is now controlled via the 'external' keyword
- 'vni' and 'external' arguments are mutually exclusive for the vxlan link
Changes from V2:
- rebased
Paolo Abeni (3):
vxlan: add support for collect metadata flag
gre: add support for collect metadata flag
lwtunnel: implement support for ip6 encap
ip/iplink_vxlan.c | 19 +++++++++-- ip/iproute_lwtunnel.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++- ip/link_gre.c | 11 ++++++ 3 files changed, 119 insertions(+), 3 deletions(-)
Signature · 1 line
1.8.3.1
Paolo Abeni
maintainerPATCH v3 1/3 vxlan: add support for collect metadata flag
This patch add support for IFLA_VXLAN_COLLECT_METADATA via the 'external' keyword to the vxlan link.
Also enforce mutual exclusion between 'vni' and 'external'.
--- ip/iplink_vxlan.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
ip/iplink_vxlan.c +17 -2
@@ -31,7 +31,7 @@ static void print_explain(FILE *f)fprintf (f," [ ageing SECONDS ] [ maxaddress NUMBER ]\n" );fprintf (f," [ [no]udpcsum ] [ [no]udp6zerocsumtx ] [ [no]udp6zerocsumrx ]\n" );fprintf (f," [ [no]remcsumtx ] [ [no]remcsumrx ]\n" ); -fprintf (f," [ gbp ]\n" ); +fprintf (f," [ [no]external ] [ gbp ]\n" );fprintf (f,"\n" );fprintf (f,"Where: VNI := 0-16777215\n" );fprintf (f," ADDR := { IP_ADDRESS | any }\n" );
@@ -72,6 +72,7 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,__u8 udp6zerocsumrx =0 ;__u8 remcsumtx =0 ;__u8 remcsumrx =0 ; +__u8 metadata =0 ;__u8 gbp =0 ;int dst_port_set =0 ;struct ifla_vxlan_port_range range = {0 ,0 };
@@ -210,6 +211,10 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, remcsumrx =1 ; }else if (!matches (*argv,"noremcsumrx" )) { remcsumrx =0 ; + }else if (!matches (*argv,"external" )) { + metadata =1 ; + }else if (!matches (*argv,"noexternal" )) { + metadata =0 ; }else if (!matches (*argv,"gbp" )) { gbp =1 ; }else if (matches (*argv,"help" ) ==0 ) {
@@ -223,7 +228,12 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, argc--, argv++; } -if (!vni_set) { +if (metadata && vni_set) { +fprintf (stderr,"vxlan: both 'external' and vni cannot be specified\n" ); +return -1 ; + } + +if (!metadata && !vni_set) {fprintf (stderr,"vxlan: missing virtual network identifier\n" );return -1 ; }
@@ -272,6 +282,7 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,addattr8 (n,1024 ,IFLA_VXLAN_UDP_ZERO_CSUM6_RX , udp6zerocsumrx);addattr8 (n,1024 ,IFLA_VXLAN_REMCSUM_TX , remcsumtx);addattr8 (n,1024 ,IFLA_VXLAN_REMCSUM_RX , remcsumrx); +addattr8 (n,1024 ,IFLA_VXLAN_COLLECT_METADATA , metadata);if (noage)addattr32 (n,1024 ,IFLA_VXLAN_AGEING ,0 );
@@ -428,6 +439,10 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_RX]))fputs ("remcsumrx " , f); +if (tb[IFLA_VXLAN_COLLECT_METADATA ] && +rta_getattr_u8 (tb[IFLA_VXLAN_COLLECT_METADATA ])) +fputs ("external " , f); +if (tb[IFLA_VXLAN_GBP ])fputs ("gbp " , f); }
Signature · 1 line
1.8.3.1
Paolo Abeni
maintainerPATCH v3 2/3 gre: add support for collect metadata flag
In reply to Paolo AbeniThis patch add support for IFLA_GRE_COLLECT_METADATA via the 'external' keyword to the gre link.
--- ip/link_gre.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
ip/link_gre.c +11 -0
@@ -74,6 +74,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,__u16 encapflags =0 ;__u16 encapsport =0 ;__u16 encapdport =0 ; +__u8 metadata =0 ;if (!(n->nlmsg_flags &NLM_F_CREATE )) {memset (&req,0 ,sizeof (req));
@@ -148,6 +149,9 @@ get_failed: encapsport =rta_getattr_u16 (greinfo[IFLA_GRE_ENCAP_SPORT ]);if (greinfo[IFLA_GRE_ENCAP_DPORT ]) encapdport =rta_getattr_u16 (greinfo[IFLA_GRE_ENCAP_DPORT ]); + +if (greinfo[IFLA_GRE_COLLECT_METADATA ]) + metadata =1 ; }while (argc >0 ) {
@@ -291,6 +295,8 @@ get_failed: encapflags |=TUNNEL_ENCAP_FLAG_REMCSUM ; }else if (strcmp (*argv,"noencap-remcsum" ) ==0 ) { encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM ; + }else if (strcmp (*argv,"external" ) ==0 ) { + metadata =1 ; }else usage (); argc--; argv++;
@@ -325,6 +331,8 @@ get_failed:addattr16 (n,1024 ,IFLA_GRE_ENCAP_FLAGS , encapflags);addattr16 (n,1024 ,IFLA_GRE_ENCAP_SPORT ,htons (encapsport));addattr16 (n,1024 ,IFLA_GRE_ENCAP_DPORT ,htons (encapdport)); +if (metadata) +addattr_l (n,1024 ,IFLA_GRE_COLLECT_METADATA ,NULL ,0 );return 0 ; }
@@ -413,6 +421,9 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])if (oflags &GRE_CSUM )fputs ("ocsum " , f); +if (tb[IFLA_GRE_COLLECT_METADATA ]) +fputs ("external " , f); +if (tb[IFLA_GRE_ENCAP_TYPE ] && *(__u16 *)RTA_DATA (tb[IFLA_GRE_ENCAP_TYPE ]) !=TUNNEL_ENCAP_NONE ) {__u16 type =rta_getattr_u16 (tb[IFLA_GRE_ENCAP_TYPE ]);
Signature · 1 line
1.8.3.1
Paolo Abeni
maintainerPATCH v3 3/3 lwtunnel: implement support for ip6 encap
In reply to Paolo AbeniCurrently ip6 encap support for lwtunnel is missing. This patch implement it, mostly duplicating the ipv4 parts.
Also be sure to insert a space after the encap type, when showing lwtunnel, to avoid the tunnel type and the following argument being merged into a single word.
--- ip/iproute_lwtunnel.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-)
ip/iproute_lwtunnel.c +91 -1
@@ -115,6 +115,37 @@ static void print_encap_ila(FILE *fp, struct rtattr *encap) } } +static void print_encap_ip6 (FILE *fp,struct rtattr *encap) +{ +struct rtattr *tb[LWTUNNEL_IP6_MAX +1 ]; +char abuf[256 ]; + +parse_rtattr_nested (tb,LWTUNNEL_IP6_MAX , encap); + +if (tb[LWTUNNEL_IP6_ID ]) +fprintf (fp,"id %llu " ,ntohll (rta_getattr_u64 (tb[LWTUNNEL_IP6_ID ]))); + +if (tb[LWTUNNEL_IP6_SRC ]) +fprintf (fp,"src %s " , +rt_addr_n2a (AF_INET6 , +RTA_PAYLOAD (tb[LWTUNNEL_IP6_SRC ]), +RTA_DATA (tb[LWTUNNEL_IP6_SRC ]), + abuf,sizeof (abuf))); + +if (tb[LWTUNNEL_IP6_DST ]) +fprintf (fp,"dst %s " , +rt_addr_n2a (AF_INET6 , +RTA_PAYLOAD (tb[LWTUNNEL_IP6_DST ]), +RTA_DATA (tb[LWTUNNEL_IP6_DST ]), + abuf,sizeof (abuf))); + +if (tb[LWTUNNEL_IP6_HOPLIMIT ]) +fprintf (fp,"hoplimit %d " ,rta_getattr_u8 (tb[LWTUNNEL_IP6_HOPLIMIT ])); + +if (tb[LWTUNNEL_IP6_TC ]) +fprintf (fp,"tc %d " ,rta_getattr_u8 (tb[LWTUNNEL_IP6_TC ])); +} +void lwt_print_encap (FILE *fp,struct rtattr *encap_type,struct rtattr *encap) {
@@ -125,7 +156,7 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type, et =rta_getattr_u16 (encap_type); -fprintf (fp," encap %s" ,format_encap_type (et)); +fprintf (fp," encap %s " ,format_encap_type (et));switch (et) {case LWTUNNEL_ENCAP_MPLS :
@@ -137,6 +168,9 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type,case LWTUNNEL_ENCAP_ILA :print_encap_ila (fp, encap);break ; +case LWTUNNEL_ENCAP_IP6 : +print_encap_ip6 (fp, encap); +break ; } }
@@ -233,6 +267,59 @@ static int parse_encap_ila(struct rtattr *rta, size_t len,return 0 ; } +static int parse_encap_ip6 (struct rtattr *rta,size_t len,int *argcp,char ***argvp) +{ +int id_ok =0 , dst_ok =0 , tos_ok =0 , ttl_ok =0 ; +char **argv = *argvp; +int argc = *argcp; + +while (argc >0 ) { +if (strcmp (*argv,"id" ) ==0 ) { +__u64 id; +NEXT_ARG (); +if (id_ok++) +duparg2 ("id" , *argv); +if (get_u64 (&id, *argv,0 )) +invarg ("\"id\" value is invalid\n" , *argv); +rta_addattr64 (rta, len,LWTUNNEL_IP6_ID ,htonll (id)); + }else if (strcmp (*argv,"dst" ) ==0 ) { +inet_prefix addr; +NEXT_ARG (); +if (dst_ok++) +duparg2 ("dst" , *argv); +get_addr (&addr, *argv,AF_INET6 ); +rta_addattr_l (rta, len,LWTUNNEL_IP6_DST , &addr.data, addr.bytelen); + }else if (strcmp (*argv,"tc" ) ==0 ) { +__u32 tc; +NEXT_ARG (); +if (tos_ok++) +duparg2 ("tc" , *argv); +if (rtnl_dsfield_a2n (&tc, *argv)) +invarg ("\"tc\" value is invalid\n" , *argv); +rta_addattr8 (rta, len,LWTUNNEL_IP6_TC , tc); + }else if (strcmp (*argv,"hoplimit" ) ==0 ) { +__u8 hoplimit; +NEXT_ARG (); +if (ttl_ok++) +duparg2 ("hoplimit" , *argv); +if (get_u8 (&hoplimit, *argv,0 )) +invarg ("\"hoplimit\" value is invalid\n" , *argv); +rta_addattr8 (rta, len,LWTUNNEL_IP6_HOPLIMIT , hoplimit); + }else { +break ; + } + argc--; argv++; + } + +/* argv is currently the first unparsed argument, +* but the lwt_parse_encap() caller will move to the next, +* so step back */ + *argcp = argc +1 ; + *argvp = argv -1 ; + +return 0 ; +} +int lwt_parse_encap (struct rtattr *rta,size_t len,int *argcp,char ***argvp) {struct rtattr *nest;
@@ -262,6 +349,9 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp)case LWTUNNEL_ENCAP_ILA :parse_encap_ila (rta, len, &argc, &argv);break ; +case LWTUNNEL_ENCAP_IP6 : +parse_encap_ip6 (rta, len, &argc, &argv); +break ;default :fprintf (stderr,"Error: unsupported encap type\n" );break ;
Signature · 1 line
1.8.3.1
Quoted 20 lines · On Fri, 18 Dec 2015 10:50:35 +0100 Paolo Abeni <[email protected]> wrote:
This patch series try to improve the current route based lwtunnel support in iproute2, namely adding support for the
COLLECT_METADATAflag in vxlan and gre link, and for ip6 encap type in lwtunnel.Tunnel devices need to have the
COLLECT_METADATAflag set in order to be used for route based lwtunnel.Changes from V1:
- theCOLLECT_METADATAflag is now controlled via the 'external' keyword
- 'vni' and 'external' arguments are mutually exclusive for the vxlan linkChanges from V2:
- rebasedPaolo Abeni (3):
vxlan: add support for collect metadata flag
gre: add support for collect metadata flag
lwtunnel: implement support for ip6 encap
Quoted 5 lines
ip/iplink_vxlan.c | 19 +++++++++-- ip/iproute_lwtunnel.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++- ip/link_gre.c | 11 ++++++ 3 files changed, 119 insertions(+), 3 deletions(-)
Applied thanks.