]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ip link gre: create interfaces in external mode correctly
authorJiri Benc <jbenc@redhat.com>
Wed, 27 Apr 2016 14:11:13 +0000 (16:11 +0200)
committerStephen Hemminger <shemming@brocade.com>
Fri, 6 May 2016 18:49:08 +0000 (11:49 -0700)
For GRE interfaces in 'external' mode, the kernel ignores all manual
settings like remote IP address or TTL. However, for some of those
attributes, kernel checks their value and does not allow them to be zero
(even though they're ignored later).

Currently, 'ip link' always includes all attributes in the netlink message.
This leads to problem with creating interfaces in 'external' mode. For
example, this command does not work:

ip link add gre1 type gretap external

and needs a bogus remote IP address to be specified, as the kernel enforces
remote IP address to be either not present, or not null.

Ignore the parameters that do not make sense in 'external' mode.
Unfortunately, we cannot error out, as there may be existing deployments
that workarounded the bug by specifying bogus values.

Fixes: 926b39e1feffd ("gre: add support for collect metadata flag")
Signed-off-by: Jiri Benc <jbenc@redhat.com>
ip/link_gre.c

index bcf003aaa5d7ae68e032bdef660acab0513fd52c..36ce1252675b4dd58b9da60ffe4cb86ed8252ca5 100644 (file)
@@ -315,24 +315,26 @@ get_failed:
                return -1;
        }
 
-       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, &saddr, 4);
-       addattr_l(n, 1024, IFLA_GRE_REMOTE, &daddr, 4);
-       addattr_l(n, 1024, IFLA_GRE_PMTUDISC, &pmtudisc, 1);
-       if (link)
-               addattr32(n, 1024, IFLA_GRE_LINK, link);
-       addattr_l(n, 1024, IFLA_GRE_TTL, &ttl, 1);
-       addattr_l(n, 1024, IFLA_GRE_TOS, &tos, 1);
+       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, &saddr, 4);
+               addattr_l(n, 1024, IFLA_GRE_REMOTE, &daddr, 4);
+               addattr_l(n, 1024, IFLA_GRE_PMTUDISC, &pmtudisc, 1);
+               if (link)
+                       addattr32(n, 1024, IFLA_GRE_LINK, link);
+               addattr_l(n, 1024, IFLA_GRE_TTL, &ttl, 1);
+               addattr_l(n, 1024, IFLA_GRE_TOS, &tos, 1);
+       } else {
+               addattr_l(n, 1024, IFLA_GRE_COLLECT_METADATA, NULL, 0);
+       }
 
        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)
-               addattr_l(n, 1024, IFLA_GRE_COLLECT_METADATA, NULL, 0);
 
        return 0;
 }