]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
gre6: add collect metadata support
authorWilliam Tu <u9012063@gmail.com>
Wed, 13 Dec 2017 02:22:52 +0000 (18:22 -0800)
committerStephen Hemminger <stephen@networkplumber.org>
Fri, 15 Dec 2017 05:19:49 +0000 (21:19 -0800)
The patch adds 'external' option to support collect metadata
gre6 tunnel.  The 'external' keyword is already used to set the
device into collect metadata mode such as vxlan, geneve, ipip,
etc.  This patch extends support for ipv6 gre and gretap.
Example of L3 and L2 gre device:
bash:~# ip link add dev ip6gre123 type ip6gre external
bash:~# ip link add dev ip6gretap123 type ip6gretap external

Signed-off-by: William Tu <u9012063@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
ip/link_gre6.c
man/man8/ip-link.8.in

index 0a82eaecf2cdd861b6b2401cbca3f36a293e8f00..2cb46ca116d0bb918de9482364c6e9559cb5e1b8 100644 (file)
@@ -105,6 +105,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
        __u16 encapflags = TUNNEL_ENCAP_FLAG_CSUM6;
        __u16 encapsport = 0;
        __u16 encapdport = 0;
+       __u8 metadata = 0;
        int len;
        __u32 fwmark = 0;
        __u32 erspan_idx = 0;
@@ -178,6 +179,9 @@ get_failed:
                if (greinfo[IFLA_GRE_ENCAP_SPORT])
                        encapsport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_SPORT]);
 
+               if (greinfo[IFLA_GRE_COLLECT_METADATA])
+                       metadata = 1;
+
                if (greinfo[IFLA_GRE_ENCAP_DPORT])
                        encapdport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_DPORT]);
 
@@ -355,6 +359,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 if (strcmp(*argv, "fwmark") == 0) {
                        NEXT_ARG();
                        if (strcmp(*argv, "inherit") == 0) {
@@ -388,26 +394,30 @@ get_failed:
                argc--; argv++;
        }
 
-       addattr32(n, 1024, IFLA_GRE_IKEY, ikey);
-       addattr32(n, 1024, IFLA_GRE_OKEY, okey);
-       addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
-       addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
-       addattr_l(n, 1024, IFLA_GRE_LOCAL, &laddr, sizeof(laddr));
-       addattr_l(n, 1024, IFLA_GRE_REMOTE, &raddr, sizeof(raddr));
-       if (link)
-               addattr32(n, 1024, IFLA_GRE_LINK, link);
-       addattr_l(n, 1024, IFLA_GRE_TTL, &hop_limit, 1);
-       addattr_l(n, 1024, IFLA_GRE_ENCAP_LIMIT, &encap_limit, 1);
-       addattr_l(n, 1024, IFLA_GRE_FLOWINFO, &flowinfo, 4);
-       addattr32(n, 1024, IFLA_GRE_FLAGS, flags);
-       addattr32(n, 1024, IFLA_GRE_FWMARK, fwmark);
-       if (erspan_idx != 0)
-               addattr32(n, 1024, IFLA_GRE_ERSPAN_INDEX, erspan_idx);
-
-       addattr16(n, 1024, IFLA_GRE_ENCAP_TYPE, encaptype);
-       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) {
+               addattr32(n, 1024, IFLA_GRE_IKEY, ikey);
+               addattr32(n, 1024, IFLA_GRE_OKEY, okey);
+               addattr_l(n, 1024, IFLA_GRE_IFLAGS, &iflags, 2);
+               addattr_l(n, 1024, IFLA_GRE_OFLAGS, &oflags, 2);
+               addattr_l(n, 1024, IFLA_GRE_LOCAL, &laddr, sizeof(laddr));
+               addattr_l(n, 1024, IFLA_GRE_REMOTE, &raddr, sizeof(raddr));
+               if (link)
+                       addattr32(n, 1024, IFLA_GRE_LINK, link);
+               addattr_l(n, 1024, IFLA_GRE_TTL, &hop_limit, 1);
+               addattr_l(n, 1024, IFLA_GRE_ENCAP_LIMIT, &encap_limit, 1);
+               addattr_l(n, 1024, IFLA_GRE_FLOWINFO, &flowinfo, 4);
+               addattr32(n, 1024, IFLA_GRE_FLAGS, flags);
+               addattr32(n, 1024, IFLA_GRE_FWMARK, fwmark);
+               if (erspan_idx != 0)
+                       addattr32(n, 1024, IFLA_GRE_ERSPAN_INDEX, erspan_idx);
+
+               addattr16(n, 1024, IFLA_GRE_ENCAP_TYPE, encaptype);
+               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));
+       } else {
+               addattr_l(n, 1024, IFLA_GRE_COLLECT_METADATA, NULL, 0);
+       }
 
        return 0;
 }
@@ -426,6 +436,11 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
        if (!tb)
                return;
 
+       if (tb[IFLA_GRE_COLLECT_METADATA]) {
+               print_bool(PRINT_ANY, "collect_metadata", "external", true);
+               return;
+       }
+
        if (tb[IFLA_GRE_FLAGS])
                flags = rta_getattr_u32(tb[IFLA_GRE_FLAGS]);
 
index 40f09b30ea3a0f2630e1ba15e649402abd3fde3a..9e9a5f0d2cefbe4e87f50175997befe98974a917 100644 (file)
@@ -768,6 +768,8 @@ the following additional arguments are supported:
 .BI "dscp inherit"
 ] [
 .BI dev " PHYS_DEV "
+] [
+.RB external
 ]
 
 .in +8
@@ -846,6 +848,21 @@ or
 .IR 00 ".." ff
 when tunneling non-IP packets. The default value is 00.
 
+.sp
+.RB external
+- make this tunnel externally controlled (or not, which is the default).
+In the kernel, this is referred to as collect metadata mode.  This flag is
+mutually exclusive with the
+.BR remote ,
+.BR local ,
+.BR seq ,
+.BR key,
+.BR csum,
+.BR hoplimit,
+.BR encaplimit,
+.BR flowlabel " and " tclass
+options.
+
 .in -8
 
 .TP