From d226fa19a89a5f8519cf7259ec304a399f70708e Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2016 06:06:31 +0000 Subject: import libnl3-3.2.28-2.el7 --- diff --git a/.gitignore b/.gitignore index 2d5e97d..eedebbe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/libnl-3.2.21.tar.gz -SOURCES/libnl-doc-3.2.21.tar.gz +SOURCES/libnl-3.2.28.tar.gz +SOURCES/libnl-doc-3.2.28.tar.gz diff --git a/.libnl3.metadata b/.libnl3.metadata index 09e10ef..83c0d1f 100644 --- a/.libnl3.metadata +++ b/.libnl3.metadata @@ -1,2 +1,2 @@ -7d680788902f1e839889b7c2611393595beba907 SOURCES/libnl-3.2.21.tar.gz -de52a546e233c09f3d859daf9eb06a7b4ec9b565 SOURCES/libnl-doc-3.2.21.tar.gz +7c6435ee248642940d022511629ab658a5aff260 SOURCES/libnl-3.2.28.tar.gz +deb56c054ef3cd82c306ebe9f85881e8b2e40b86 SOURCES/libnl-doc-3.2.28.tar.gz diff --git a/SOURCES/0001-compare-v4-addr-rh1370503.patch b/SOURCES/0001-compare-v4-addr-rh1370503.patch new file mode 100644 index 0000000..e630975 --- /dev/null +++ b/SOURCES/0001-compare-v4-addr-rh1370503.patch @@ -0,0 +1,103 @@ +From 2eab63bff2624d154891c949bd815c1fe7082f60 Mon Sep 17 00:00:00 2001 +From: Tobias Jungel +Date: Thu, 4 Aug 2016 10:01:43 +0200 +Subject: [PATCH 1/2] route/addr: address attributes based on object + +addr_id_attrs_get returned a fixed set of attributes for AF_INET. This +leads to an invalid cache in case the default cache manager is used. + +The error was cause by nl_object_identical, which checkes the ce_mask +of an object against the req_attrs. For route/addr objects the ce_mask +may contain the ADDR_ATTR_PEER, but the addr_id_attrs_get always +includes this attribute. Thus nl_object_identical fails always in case +no peer exists, which is the default for local addresses. + +Fixes: 83e851ca9c842ccb6dae411d3fff9c7e9561269a + +https://github.com/thom311/libnl/pull/105 + +Signed-off-by: Thomas Haller +(cherry picked from commit dfaba51b5b2b5ad7e3c4990c2af3f30acbe5f8d9) +--- + lib/route/addr.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/lib/route/addr.c b/lib/route/addr.c +index b699c64..7d3ff39 100644 +--- a/lib/route/addr.c ++++ b/lib/route/addr.c +@@ -467,12 +467,15 @@ static void addr_dump_stats(struct nl_object *obj, struct nl_dump_params *p) + static uint32_t addr_id_attrs_get(struct nl_object *obj) + { + struct rtnl_addr *addr = (struct rtnl_addr *)obj; ++ uint32_t rv; + + switch (addr->a_family) { + case AF_INET: +- return (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX | +- ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN | +- ADDR_ATTR_PEER); ++ rv = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX | ++ ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN); ++ if (addr->a_peer) ++ rv |= ADDR_ATTR_PEER; ++ return rv; + case AF_INET6: + return (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX | + ADDR_ATTR_LOCAL); +-- +2.7.4 + + +From f2ac27c8a513eaf6b838796aacf2ec444a2c1227 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Sun, 14 Aug 2016 11:05:48 +0200 +Subject: [PATCH 2/2] lib: capability NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX for + ID comparison of v4 addresses + +The ID attributes for IPv4 addresses were broken which causes wrong +nl_object_identical() and cache lookup. + +This capability shall indicate that the bug was fixed. + +Signed-off-by: Thomas Haller +(cherry picked from commit 99b1d8acf87bcb35efed49f412d54af682bf1738) +--- + include/netlink/utils.h | 7 +++++++ + lib/utils.c | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/include/netlink/utils.h b/include/netlink/utils.h +index 3b10340..1115bb4 100644 +--- a/include/netlink/utils.h ++++ b/include/netlink/utils.h +@@ -217,6 +217,13 @@ enum { + NL_CAPABILITY_VERSION_3_2_28 = 19, + #define NL_CAPABILITY_VERSION_3_2_28 NL_CAPABILITY_VERSION_3_2_28 + ++ /** ++ * After NL_CAPABILITY_RTNL_ADDR_PEER_FIX, a follow up regression to lookup ++ * IPv4 addresses in the cache was fixed (PR#105). ++ */ ++ NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX = 20, ++#define NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX ++ + __NL_CAPABILITY_MAX, + NL_CAPABILITY_MAX = (__NL_CAPABILITY_MAX - 1), + #define NL_CAPABILITY_MAX NL_CAPABILITY_MAX +diff --git a/lib/utils.c b/lib/utils.c +index 3399c03..0f2a252 100644 +--- a/lib/utils.c ++++ b/lib/utils.c +@@ -1164,7 +1164,7 @@ int nl_has_capability (int capability) + NL_CAPABILITY_XFRM_SA_KEY_SIZE, + NL_CAPABILITY_RTNL_ADDR_PEER_FIX, + NL_CAPABILITY_VERSION_3_2_28, +- 0, ++ NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX, + 0, + 0, + 0, +-- +2.7.4 + diff --git a/SOURCES/0004-add-nl_has_capability.patch b/SOURCES/0004-add-nl_has_capability.patch deleted file mode 100644 index eac636e..0000000 --- a/SOURCES/0004-add-nl_has_capability.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 02f989353861bca76e0bf228b89e3b2a38c851be Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 13 Mar 2014 13:16:05 +0100 -Subject: [PATCH 1/1] utils: add nl_has_capability() function - -Acked-by: Thomas Graf -Signed-off-by: Thomas Haller -(cherry picked from commit 68d6bd7f37dc9a0c004b4355770e9c475fb964cd) ---- - include/netlink/utils.h | 8 ++++++++ - lib/utils.c | 43 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 51 insertions(+) - -diff --git a/include/netlink/utils.h b/include/netlink/utils.h -index 502341a..da46a55 100644 ---- a/include/netlink/utils.h -+++ b/include/netlink/utils.h -@@ -79,6 +79,14 @@ extern void nl_new_line(struct nl_dump_params *); - extern void nl_dump(struct nl_dump_params *, const char *, ...); - extern void nl_dump_line(struct nl_dump_params *, const char *, ...); - -+enum { -+ NL_CAPABILITY_NONE, -+ -+ __NL_CAPABILITY_MAX -+#define NL_CAPABILITY_MAX (__NL_CAPABILITY_MAX - 1) -+}; -+int nl_has_capability (int capability); -+ - #ifdef __cplusplus - } - #endif -diff --git a/lib/utils.c b/lib/utils.c -index 3bfa604..7354956 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -1097,6 +1097,49 @@ void dump_from_ops(struct nl_object *obj, struct nl_dump_params *params) - obj->ce_ops->oo_dump[type](obj, params); - } - -+/** -+ * Check for library capabilities -+ * -+ * @arg capability capability identifier -+ * -+ * Check whether the loaded libnl library supports a certain capability. -+ * This is useful so that applications can workaround known issues of -+ * libnl that are fixed in newer library versions, without -+ * having a hard dependency on the new version. It is also useful, for -+ * capabilities that cannot easily be detected using autoconf tests. -+ * The capabilities are integer constants with name NL_CAPABILITY_*. -+ * -+ * As this function is intended to detect capabilities at runtime, -+ * you might not want to depend during compile time on the NL_CAPABILITY_* -+ * names. Instead you can use their numeric values which are guaranteed not to -+ * change meaning. -+ * -+ * @return non zero if libnl supports a certain capability, 0 otherwise. -+ **/ -+int nl_has_capability (int capability) -+{ -+ static const uint8_t caps[ ( NL_CAPABILITY_MAX + 7 ) / 8 ] = { -+#define _NL_ASSERT(expr) ( 0 * sizeof(struct { unsigned int x: ( (!!(expr)) ? 1 : -1 ); }) ) -+#define _NL_SETV(i, r, v) \ -+ ( _NL_ASSERT( (v) == 0 || (i) * 8 + (r) == (v) - 1 ) + \ -+ ( (v) == 0 ? 0 : (1 << (r)) ) ) -+#define _NL_SET(i, v0, v1, v2, v3, v4, v5, v6, v7) \ -+ [(i)] = ( \ -+ _NL_SETV((i), 0, (v0)) | _NL_SETV((i), 4, (v4)) | \ -+ _NL_SETV((i), 1, (v1)) | _NL_SETV((i), 5, (v5)) | \ -+ _NL_SETV((i), 2, (v2)) | _NL_SETV((i), 6, (v6)) | \ -+ _NL_SETV((i), 3, (v3)) | _NL_SETV((i), 7, (v7)) ) -+#undef _NL_SET -+#undef _NL_SETV -+#undef _NL_ASSERT -+ }; -+ -+ if (capability <= 0 || capability > NL_CAPABILITY_MAX) -+ return 0; -+ capability--; -+ return (caps[capability / 8] & (1 << (capability % 8))) != 0; -+} -+ - /** @endcond */ - - /** @} */ --- -1.8.5.3 - diff --git a/SOURCES/0005-rtnl_route_build_msg-set-scope.patch b/SOURCES/0005-rtnl_route_build_msg-set-scope.patch deleted file mode 100644 index 0db0e41..0000000 --- a/SOURCES/0005-rtnl_route_build_msg-set-scope.patch +++ /dev/null @@ -1,101 +0,0 @@ -From bead44cba8cb487d1dee88a7aff832c418657d64 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 13 Feb 2014 21:31:37 +0100 -Subject: [PATCH 1/2] route: rtnl_route_build_msg() should not overwrite the - route scope - -rtnl_route_build_msg() should allow the user to set the route scope -explicitly to RT_SCOPE_NOWHERE. - -This is useful for IPv4 routes, because when deleting a route, -the kernel requires the scope to match, unless the scope is set to -RT_SCOPE_NOWHERE. Thus by setting the scope to RT_SCOPE_NOWHERE, -the user can delete a route, even without knowing its scope. - -rtnl_route_build_msg() should only try to guess the scope, if it was -not explicitly specified. - -Signed-off-by: Thomas Haller -Acked-by: Thomas Graf -(cherry picked from commit 85ec9c7ad80c60f4f619472f2bb9d9595da93b26) ---- - lib/route/route_obj.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c -index 8f1e515..57b8f23 100644 ---- a/lib/route/route_obj.c -+++ b/lib/route/route_obj.c -@@ -1194,7 +1194,7 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route) - if (route->rt_src) - rtmsg.rtm_src_len = nl_addr_get_prefixlen(route->rt_src); - -- if (rtmsg.rtm_scope == RT_SCOPE_NOWHERE) -+ if (!(route->ce_mask & ROUTE_ATTR_SCOPE)) - rtmsg.rtm_scope = rtnl_route_guess_scope(route); - - if (rtnl_route_get_nnexthops(route) == 1) { --- -1.8.5.3 - - -From 5ee88135f410a9630321f10b8a2ea824c88b22ba Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 13 Mar 2014 13:16:51 +0100 -Subject: [PATCH 2/2] utils: indicate capability - NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE - -This capability indicates that libnl does no longer overwrites -the route scope in rtnl_route_build_msg(), as fixed by commit -85ec9c7ad80c60f4f619472f2bb9d9595da93b26. - -Acked-by: Thomas Graf -Signed-off-by: Thomas Haller -(cherry picked from commit 015c4ee59b786fec35118c2a963532b3e05ba5a2) ---- - include/netlink/utils.h | 8 ++++++++ - lib/utils.c | 9 +++++++++ - 2 files changed, 17 insertions(+) - -diff --git a/include/netlink/utils.h b/include/netlink/utils.h -index da46a55..2094bb4 100644 ---- a/include/netlink/utils.h -+++ b/include/netlink/utils.h -@@ -82,6 +82,14 @@ extern void nl_dump_line(struct nl_dump_params *, const char *, ...); - enum { - NL_CAPABILITY_NONE, - -+ /** -+ * rtnl_route_build_msg() no longer guesses the route scope -+ * if explicitly set to RT_SCOPE_NOWHERE. -+ * @ingroup utils -+ */ -+ NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE = 1, -+#define NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE -+ - __NL_CAPABILITY_MAX - #define NL_CAPABILITY_MAX (__NL_CAPABILITY_MAX - 1) - }; -diff --git a/lib/utils.c b/lib/utils.c -index 7354956..d7f6724 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -1129,6 +1129,15 @@ int nl_has_capability (int capability) - _NL_SETV((i), 1, (v1)) | _NL_SETV((i), 5, (v5)) | \ - _NL_SETV((i), 2, (v2)) | _NL_SETV((i), 6, (v6)) | \ - _NL_SETV((i), 3, (v3)) | _NL_SETV((i), 7, (v7)) ) -+ _NL_SET(0, -+ NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE, -+ 0, -+ 0, -+ 0, -+ 0, -+ 0, -+ 0, -+ 0), - #undef _NL_SET - #undef _NL_SETV - #undef _NL_ASSERT --- -1.8.5.3 - diff --git a/SOURCES/0006-nl_msec2str-fix.patch b/SOURCES/0006-nl_msec2str-fix.patch deleted file mode 100644 index dfe827a..0000000 --- a/SOURCES/0006-nl_msec2str-fix.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 4ea4090788fbd0cdfb9e4c1cf2f8c96842132cb1 Mon Sep 17 00:00:00 2001 -From: Joe Damato -Date: Thu, 18 Jul 2013 22:35:45 -0700 -Subject: [PATCH 1/2] Handle the case where nl_msec2str is passed 0 msecs - -(cherry picked from commit b3fb89f445108677d405c62865b25aeea209d10a) ---- - lib/utils.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/lib/utils.c b/lib/utils.c -index d7f6724..e04a7b7 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -552,6 +552,11 @@ char * nl_msec2str(uint64_t msec, char *buf, size_t len) - #undef _SPLIT - split[4] = msec; - -+ if (msec == 0) { -+ snprintf(buf, len, "0msec"); -+ return buf_orig; -+ } -+ - for (i = 0; i < ARRAY_SIZE(split) && len; i++) { - int l; - if (split[i] == 0) --- -1.8.5.3 - - -From 58c7f957ca301c3ca65a3788ecb7412b32469ae1 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 19 Feb 2014 19:22:13 +0100 -Subject: [PATCH 2/2] utils: fix nl_msec2str() which always returned '0msec' - for whole second durations - -If the duration was without subsecond part, the function always returned -'0msec', instead of giving the time in days, hours, minutes or seconds. - -Regression introduced by commit b3fb89f445108677d405c62865b25aeea209d10a. - -Signed-off-by: Thomas Haller -Acked-by: Thomas Graf -(cherry picked from commit 3fb0aae0bc37eafe868d28f0f12ee8803d7ad266) ---- - lib/utils.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/lib/utils.c b/lib/utils.c -index e04a7b7..44350c3 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -544,6 +544,11 @@ char * nl_msec2str(uint64_t msec, char *buf, size_t len) - static const char *units[5] = {"d", "h", "m", "s", "msec"}; - char * const buf_orig = buf; - -+ if (msec == 0) { -+ snprintf(buf, len, "0msec"); -+ return buf_orig; -+ } -+ - #define _SPLIT(idx, unit) if ((split[idx] = msec / unit)) msec %= unit - _SPLIT(0, 86400000); /* days */ - _SPLIT(1, 3600000); /* hours */ -@@ -552,11 +557,6 @@ char * nl_msec2str(uint64_t msec, char *buf, size_t len) - #undef _SPLIT - split[4] = msec; - -- if (msec == 0) { -- snprintf(buf, len, "0msec"); -- return buf_orig; -- } -- - for (i = 0; i < ARRAY_SIZE(split) && len; i++) { - int l; - if (split[i] == 0) --- -1.8.5.3 - diff --git a/SOURCES/0007-relax-parsing-protinfo.patch b/SOURCES/0007-relax-parsing-protinfo.patch deleted file mode 100644 index abea0b0..0000000 --- a/SOURCES/0007-relax-parsing-protinfo.patch +++ /dev/null @@ -1,532 +0,0 @@ -From b14cc1f2fb310e6ff00d3df867dc336d6b521f3f Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 20 Mar 2014 19:18:42 +0100 -Subject: [PATCH 1/3] route: don't enforce minlen in inet6_parse_protinfo() - (IFLA_PROTINFO) and inet_parse_af() (IFLA_AF_SPEC) - -Older kernel version might have fewer values defined, so they would send -netlink messages that got rejected. Only check that at least one value -got sent. - -This is especially grave as libnl uses an internal copy of the -kernel header files. Thus not only it is bound to the installed kernel -headers but to the libnl internal header copies that might easily be out -of sync with the kernel. - -This affects IFLA_PROTINFO, inet6_parse_protinfo(): - - tb[IFLA_INET6_CONF], expecting DEVCONF_MAX - - tb[IFLA_INET6_STATS], expecting __IPSTATS_MIB_MAX - - tb[IFLA_INET6_ICMP6STATS], expecting __ICMP6_MIB_MAX -and IFLA_AF_SPEC, inet_parse_af(): - - tb[IFLA_INET_CONF], expecting IPV4_DEVCONF_MAX - -https://bugzilla.redhat.com/show_bug.cgi?id=1062533 - -Acked-by: Thomas Graf -Signed-off-by: Thomas Haller -(cherry picked from commit dfd0a80ec845a800504fecb936c2b33d6918fc9c) ---- - lib/route/link/inet.c | 4 +++- - lib/route/link/inet6.c | 18 +++++++++++++----- - 2 files changed, 16 insertions(+), 6 deletions(-) - -diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c -index e2c867d..eb2e8ae 100644 ---- a/lib/route/link/inet.c -+++ b/lib/route/link/inet.c -@@ -92,7 +92,7 @@ static void inet_free(struct rtnl_link *link, void *data) - } - - static struct nla_policy inet_policy[IFLA_INET6_MAX+1] = { -- [IFLA_INET_CONF] = { .minlen = IPV4_DEVCONF_MAX * 4 }, -+ [IFLA_INET_CONF] = { .minlen = 4 }, - }; - - static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data) -@@ -104,6 +104,8 @@ static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data - err = nla_parse_nested(tb, IFLA_INET_MAX, attr, inet_policy); - if (err < 0) - return err; -+ if (tb[IFLA_INET_CONF] && nla_len(tb[IFLA_INET_CONF]) % 4) -+ return -EINVAL; - - if (tb[IFLA_INET_CONF]) - nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf)); -diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c -index 4c627bd..f171fed 100644 ---- a/lib/route/link/inet6.c -+++ b/lib/route/link/inet6.c -@@ -45,9 +45,9 @@ static void inet6_free(struct rtnl_link *link, void *data) - static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = { - [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, - [IFLA_INET6_CACHEINFO] = { .minlen = sizeof(struct ifla_cacheinfo) }, -- [IFLA_INET6_CONF] = { .minlen = DEVCONF_MAX * 4 }, -- [IFLA_INET6_STATS] = { .minlen = __IPSTATS_MIB_MAX * 8 }, -- [IFLA_INET6_ICMP6STATS] = { .minlen = __ICMP6_MIB_MAX * 8 }, -+ [IFLA_INET6_CONF] = { .minlen = 4 }, -+ [IFLA_INET6_STATS] = { .minlen = 8 }, -+ [IFLA_INET6_ICMP6STATS] = { .minlen = 8 }, - }; - - static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, -@@ -60,6 +60,12 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, - err = nla_parse_nested(tb, IFLA_INET6_MAX, attr, inet6_policy); - if (err < 0) - return err; -+ if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4) -+ return -EINVAL; -+ if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8) -+ return -EINVAL; -+ if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8) -+ return -EINVAL; - - if (tb[IFLA_INET6_FLAGS]) - i6->i6_flags = nla_get_u32(tb[IFLA_INET6_FLAGS]); -@@ -80,8 +86,9 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, - unsigned char *cnt = nla_data(tb[IFLA_INET6_STATS]); - uint64_t stat; - int i; -+ int len = min_t(int, __IPSTATS_MIB_MAX, nla_len(tb[IFLA_INET6_STATS]) / 8); - -- for (i = 1; i < __IPSTATS_MIB_MAX; i++) { -+ for (i = 1; i < len; i++) { - memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat)); - rtnl_link_set_stat(link, RTNL_LINK_IP6_INPKTS + i - 1, - stat); -@@ -92,8 +99,9 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, - unsigned char *cnt = nla_data(tb[IFLA_INET6_ICMP6STATS]); - uint64_t stat; - int i; -+ int len = min_t(int, __ICMP6_MIB_MAX, nla_len(tb[IFLA_INET6_ICMP6STATS]) / 8); - -- for (i = 1; i < __ICMP6_MIB_MAX; i++) { -+ for (i = 1; i < len; i++) { - memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat)); - rtnl_link_set_stat(link, RTNL_LINK_ICMP6_INMSGS + i - 1, - stat); --- -1.8.5.3 - - -From b104b959d0508d89be672d751b370ad92cb0dc72 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 20 Mar 2014 19:18:43 +0100 -Subject: [PATCH 2/3] route: detect missing cfgid in rtnl_link_inet_get_conf() - -If the netlink message for IFLA_INET_CONF contains less then -IPV4_DEVCONF_MAX entires, the last entries in i_conf are unset. -Modify rtnl_link_inet_get_conf() to return -EINVAL when accessing -an unset cfgid. - -Acked-by: Thomas Graf -Signed-off-by: Thomas Haller -(cherry picked from commit 3584a7ab55cb93225a0216385b62fbe5331388cd) ---- - lib/route/link/inet.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c -index eb2e8ae..2e61323 100644 ---- a/lib/route/link/inet.c -+++ b/lib/route/link/inet.c -@@ -107,8 +107,14 @@ static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data - if (tb[IFLA_INET_CONF] && nla_len(tb[IFLA_INET_CONF]) % 4) - return -EINVAL; - -- if (tb[IFLA_INET_CONF]) -+ if (tb[IFLA_INET_CONF]) { -+ int i; -+ int len = min_t(int, IPV4_DEVCONF_MAX, nla_len(tb[IFLA_INET_CONF]) / 4); -+ -+ for (i = 0; i < len; i++) -+ id->i_confset[i] = 1; - nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf)); -+ } - - return 0; - } -@@ -186,7 +192,7 @@ static void inet_dump_details(struct rtnl_link *link, - for (i = 0; i < IPV4_DEVCONF_MAX; i++) { - nl_dump_line(p, "%-19s %3u", - rtnl_link_inet_devconf2str(i+1, buf, sizeof(buf)), -- id->i_conf[i]); -+ id->i_confset[i] ? id->i_conf[i] : 0); - - if (++n == 3) { - nl_dump(p, "\n"); -@@ -222,6 +228,8 @@ static struct rtnl_link_af_ops inet_ops = { - * @return 0 on success or a negative error code. - * @return -NLE_RANGE cfgid is out of range, 1..IPV4_DEVCONF_MAX - * @return -NLE_NOATTR configuration setting not available -+ * @return -NLE_INVAL cfgid not set. If the link was received via netlink, -+ * it means that the cfgid is not supported. - */ - int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid, - uint32_t *res) -@@ -234,6 +242,8 @@ int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid, - if (!(id = rtnl_link_af_alloc(link, &inet_ops))) - return -NLE_NOATTR; - -+ if (!id->i_confset[cfgid - 1]) -+ return -NLE_INVAL; - *res = id->i_conf[cfgid - 1]; - - return 0; --- -1.8.5.3 - - -From 8421ae8b6bfa7a88cf9cdddf07fabd88362de963 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 20 Mar 2014 19:18:44 +0100 -Subject: [PATCH 3/3] route: update kernel header snmp.h and fix - inet6_parse_protinfo() after kernel API breakage - -Take 'include/uapi/linux/snmp.h' from current kernel v3.13 -(commit d8ec26d7f8287f5788a494f56e8814210f0e64be). - -The header file added new values for IPSTATS_MIB_* and ICMP6_MIB_*, but -more importantly, the kernel broke user space API by reordering enum values in -IPSTATS_MIB_*. Add a workaround when parsing IFLA_PROTINFO trying to -be compatible with both older and newer kernels. - -Note that this workaround might fail for some specific kernel versions by -assuming the old enum value mapping, although the kernel version already -contains the API change. In this case rtnl_link_get_stat() mixes up -values. - -Acked-by: Thomas Graf -Signed-off-by: Thomas Haller -(cherry picked from commit 5981a39583ab65dca230a8ee70625626d9ec9fc8) ---- - include/linux/snmp.h | 43 +++++++++++++--- - include/netlink/route/link.h | 6 +++ - lib/route/link.c | 6 +++ - lib/route/link/inet6.c | 117 +++++++++++++++++++++++++++++++++++++++---- - 4 files changed, 156 insertions(+), 16 deletions(-) - -diff --git a/include/linux/snmp.h b/include/linux/snmp.h -index 12b2b18..1bdb4a3 100644 ---- a/include/linux/snmp.h -+++ b/include/linux/snmp.h -@@ -18,7 +18,14 @@ - enum - { - IPSTATS_MIB_NUM = 0, -+/* frequently written fields in fast path, kept in same cache line */ - IPSTATS_MIB_INPKTS, /* InReceives */ -+ IPSTATS_MIB_INOCTETS, /* InOctets */ -+ IPSTATS_MIB_INDELIVERS, /* InDelivers */ -+ IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */ -+ IPSTATS_MIB_OUTPKTS, /* OutRequests */ -+ IPSTATS_MIB_OUTOCTETS, /* OutOctets */ -+/* other fields */ - IPSTATS_MIB_INHDRERRORS, /* InHdrErrors */ - IPSTATS_MIB_INTOOBIGERRORS, /* InTooBigErrors */ - IPSTATS_MIB_INNOROUTES, /* InNoRoutes */ -@@ -26,9 +33,6 @@ enum - IPSTATS_MIB_INUNKNOWNPROTOS, /* InUnknownProtos */ - IPSTATS_MIB_INTRUNCATEDPKTS, /* InTruncatedPkts */ - IPSTATS_MIB_INDISCARDS, /* InDiscards */ -- IPSTATS_MIB_INDELIVERS, /* InDelivers */ -- IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */ -- IPSTATS_MIB_OUTPKTS, /* OutRequests */ - IPSTATS_MIB_OUTDISCARDS, /* OutDiscards */ - IPSTATS_MIB_OUTNOROUTES, /* OutNoRoutes */ - IPSTATS_MIB_REASMTIMEOUT, /* ReasmTimeout */ -@@ -42,12 +46,15 @@ enum - IPSTATS_MIB_OUTMCASTPKTS, /* OutMcastPkts */ - IPSTATS_MIB_INBCASTPKTS, /* InBcastPkts */ - IPSTATS_MIB_OUTBCASTPKTS, /* OutBcastPkts */ -- IPSTATS_MIB_INOCTETS, /* InOctets */ -- IPSTATS_MIB_OUTOCTETS, /* OutOctets */ - IPSTATS_MIB_INMCASTOCTETS, /* InMcastOctets */ - IPSTATS_MIB_OUTMCASTOCTETS, /* OutMcastOctets */ - IPSTATS_MIB_INBCASTOCTETS, /* InBcastOctets */ - IPSTATS_MIB_OUTBCASTOCTETS, /* OutBcastOctets */ -+ IPSTATS_MIB_CSUMERRORS, /* InCsumErrors */ -+ IPSTATS_MIB_NOECTPKTS, /* InNoECTPkts */ -+ IPSTATS_MIB_ECT1PKTS, /* InECT1Pkts */ -+ IPSTATS_MIB_ECT0PKTS, /* InECT0Pkts */ -+ IPSTATS_MIB_CEPKTS, /* InCEPkts */ - __IPSTATS_MIB_MAX - }; - -@@ -85,6 +92,7 @@ enum - ICMP_MIB_OUTTIMESTAMPREPS, /* OutTimestampReps */ - ICMP_MIB_OUTADDRMASKS, /* OutAddrMasks */ - ICMP_MIB_OUTADDRMASKREPS, /* OutAddrMaskReps */ -+ ICMP_MIB_CSUMERRORS, /* InCsumErrors */ - __ICMP_MIB_MAX - }; - -@@ -101,6 +109,7 @@ enum - ICMP6_MIB_INERRORS, /* InErrors */ - ICMP6_MIB_OUTMSGS, /* OutMsgs */ - ICMP6_MIB_OUTERRORS, /* OutErrors */ -+ ICMP6_MIB_CSUMERRORS, /* InCsumErrors */ - __ICMP6_MIB_MAX - }; - -@@ -128,6 +137,7 @@ enum - TCP_MIB_RETRANSSEGS, /* RetransSegs */ - TCP_MIB_INERRS, /* InErrs */ - TCP_MIB_OUTRSTS, /* OutRsts */ -+ TCP_MIB_CSUMERRORS, /* InCsumErrors */ - __TCP_MIB_MAX - }; - -@@ -145,6 +155,7 @@ enum - UDP_MIB_OUTDATAGRAMS, /* OutDatagrams */ - UDP_MIB_RCVBUFERRORS, /* RcvbufErrors */ - UDP_MIB_SNDBUFERRORS, /* SndbufErrors */ -+ UDP_MIB_CSUMERRORS, /* InCsumErrors */ - __UDP_MIB_MAX - }; - -@@ -192,7 +203,6 @@ enum - LINUX_MIB_TCPPARTIALUNDO, /* TCPPartialUndo */ - LINUX_MIB_TCPDSACKUNDO, /* TCPDSACKUndo */ - LINUX_MIB_TCPLOSSUNDO, /* TCPLossUndo */ -- LINUX_MIB_TCPLOSS, /* TCPLoss */ - LINUX_MIB_TCPLOSTRETRANSMIT, /* TCPLostRetransmit */ - LINUX_MIB_TCPRENOFAILURES, /* TCPRenoFailures */ - LINUX_MIB_TCPSACKFAILURES, /* TCPSackFailures */ -@@ -201,6 +211,8 @@ enum - LINUX_MIB_TCPFORWARDRETRANS, /* TCPForwardRetrans */ - LINUX_MIB_TCPSLOWSTARTRETRANS, /* TCPSlowStartRetrans */ - LINUX_MIB_TCPTIMEOUTS, /* TCPTimeouts */ -+ LINUX_MIB_TCPLOSSPROBES, /* TCPLossProbes */ -+ LINUX_MIB_TCPLOSSPROBERECOVERY, /* TCPLossProbeRecovery */ - LINUX_MIB_TCPRENORECOVERYFAIL, /* TCPRenoRecoveryFail */ - LINUX_MIB_TCPSACKRECOVERYFAIL, /* TCPSackRecoveryFail */ - LINUX_MIB_TCPSCHEDULERFAILED, /* TCPSchedulerFailed */ -@@ -209,7 +221,6 @@ enum - LINUX_MIB_TCPDSACKOFOSENT, /* TCPDSACKOfoSent */ - LINUX_MIB_TCPDSACKRECV, /* TCPDSACKRecv */ - LINUX_MIB_TCPDSACKOFORECV, /* TCPDSACKOfoRecv */ -- LINUX_MIB_TCPABORTONSYN, /* TCPAbortOnSyn */ - LINUX_MIB_TCPABORTONDATA, /* TCPAbortOnData */ - LINUX_MIB_TCPABORTONCLOSE, /* TCPAbortOnClose */ - LINUX_MIB_TCPABORTONMEMORY, /* TCPAbortOnMemory */ -@@ -231,6 +242,22 @@ enum - LINUX_MIB_TCPDEFERACCEPTDROP, - LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ - LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */ -+ LINUX_MIB_TCPREQQFULLDOCOOKIES, /* TCPReqQFullDoCookies */ -+ LINUX_MIB_TCPREQQFULLDROP, /* TCPReqQFullDrop */ -+ LINUX_MIB_TCPRETRANSFAIL, /* TCPRetransFail */ -+ LINUX_MIB_TCPRCVCOALESCE, /* TCPRcvCoalesce */ -+ LINUX_MIB_TCPOFOQUEUE, /* TCPOFOQueue */ -+ LINUX_MIB_TCPOFODROP, /* TCPOFODrop */ -+ LINUX_MIB_TCPOFOMERGE, /* TCPOFOMerge */ -+ LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */ -+ LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */ -+ LINUX_MIB_TCPFASTOPENACTIVE, /* TCPFastOpenActive */ -+ LINUX_MIB_TCPFASTOPENPASSIVE, /* TCPFastOpenPassive*/ -+ LINUX_MIB_TCPFASTOPENPASSIVEFAIL, /* TCPFastOpenPassiveFail */ -+ LINUX_MIB_TCPFASTOPENLISTENOVERFLOW, /* TCPFastOpenListenOverflow */ -+ LINUX_MIB_TCPFASTOPENCOOKIEREQD, /* TCPFastOpenCookieReqd */ -+ LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES, /* TCPSpuriousRtxHostQueues */ -+ LINUX_MIB_BUSYPOLLRXPACKETS, /* BusyPollRxPackets */ - __LINUX_MIB_MAX - }; - -@@ -264,6 +291,8 @@ enum - LINUX_MIB_XFRMOUTPOLDEAD, /* XfrmOutPolDead */ - LINUX_MIB_XFRMOUTPOLERROR, /* XfrmOutPolError */ - LINUX_MIB_XFRMFWDHDRERROR, /* XfrmFwdHdrError*/ -+ LINUX_MIB_XFRMOUTSTATEINVALID, /* XfrmOutStateInvalid */ -+ LINUX_MIB_XFRMACQUIREERROR, /* XfrmAcquireError */ - __LINUX_MIB_XFRMMAX - }; - -diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h -index dbde72f..2d061be 100644 ---- a/include/netlink/route/link.h -+++ b/include/netlink/route/link.h -@@ -92,6 +92,12 @@ typedef enum { - RTNL_LINK_ICMP6_INERRORS, /*!< ICMPv6 SNMP InErrors */ - RTNL_LINK_ICMP6_OUTMSGS, /*!< ICMPv6 SNMP OutMsgs */ - RTNL_LINK_ICMP6_OUTERRORS, /*!< ICMPv6 SNMP OutErrors */ -+ RTNL_LINK_ICMP6_CSUMERRORS, /*!< ICMPv6 SNMP InCsumErrors */ -+ RTNL_LINK_IP6_CSUMERRORS, /*!< IPv6 SNMP InCsumErrors */ -+ RTNL_LINK_IP6_NOECTPKTS, /*!< IPv6 SNMP InNoECTPkts */ -+ RTNL_LINK_IP6_ECT1PKTS, /*!< IPv6 SNMP InECT1Pkts */ -+ RTNL_LINK_IP6_ECT0PKTS, /*!< IPv6 SNMP InECT0Pkts */ -+ RTNL_LINK_IP6_CEPKTS, /*!< IPv6 SNMP InCEPkts */ - __RTNL_LINK_STATS_MAX, - } rtnl_link_stat_id_t; - -diff --git a/lib/route/link.c b/lib/route/link.c -index 3171513..8fe3376 100644 ---- a/lib/route/link.c -+++ b/lib/route/link.c -@@ -2470,6 +2470,12 @@ static const struct trans_tbl link_stats[] = { - __ADD(RTNL_LINK_ICMP6_INERRORS, ICMP6_InErrors) - __ADD(RTNL_LINK_ICMP6_OUTMSGS, ICMP6_OutMsgs) - __ADD(RTNL_LINK_ICMP6_OUTERRORS, ICMP6_OutErrors) -+ __ADD(RTNL_LINK_ICMP6_CSUMERRORS, ICMP6_InCsumErrors) -+ __ADD(RTNL_LINK_IP6_CSUMERRORS, Ip6_InCsumErrors) -+ __ADD(RTNL_LINK_IP6_NOECTPKTS, Ip6_InNoECTPkts) -+ __ADD(RTNL_LINK_IP6_ECT1PKTS, Ip6_InECT1Pkts) -+ __ADD(RTNL_LINK_IP6_ECT0PKTS, Ip6_InECT0Pkts) -+ __ADD(RTNL_LINK_IP6_CEPKTS, Ip6_InCEPkts) - }; - - char *rtnl_link_stat2str(int st, char *buf, size_t len) -diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c -index f171fed..6fa2741 100644 ---- a/lib/route/link/inet6.c -+++ b/lib/route/link/inet6.c -@@ -50,6 +50,84 @@ static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = { - [IFLA_INET6_ICMP6STATS] = { .minlen = 8 }, - }; - -+static const uint8_t map_stat_id_from_IPSTATS_MIB_v1[__IPSTATS_MIB_MAX] = { -+ /* 14a196807482e6fc74f15fc03176d5c08880588f^:include/linux/snmp.h -+ * version before the API change in commit 14a196807482e6fc74f15fc03176d5c08880588f. -+ * This version was valid since commit edf391ff17232f097d72441c9ad467bcb3b5db18, which -+ * predates support for parsing IFLA_PROTINFO in libnl3. Such an even older meaning of -+ * the flags is not supported in libnl3. */ -+ [ 1] = RTNL_LINK_IP6_INPKTS, /* IPSTATS_MIB_INPKTS */ -+ [ 2] = RTNL_LINK_IP6_INHDRERRORS, /* IPSTATS_MIB_INHDRERRORS */ -+ [ 3] = RTNL_LINK_IP6_INTOOBIGERRORS, /* IPSTATS_MIB_INTOOBIGERRORS */ -+ [ 4] = RTNL_LINK_IP6_INNOROUTES, /* IPSTATS_MIB_INNOROUTES */ -+ [ 5] = RTNL_LINK_IP6_INADDRERRORS, /* IPSTATS_MIB_INADDRERRORS */ -+ [ 6] = RTNL_LINK_IP6_INUNKNOWNPROTOS, /* IPSTATS_MIB_INUNKNOWNPROTOS */ -+ [ 7] = RTNL_LINK_IP6_INTRUNCATEDPKTS, /* IPSTATS_MIB_INTRUNCATEDPKTS */ -+ [ 8] = RTNL_LINK_IP6_INDISCARDS, /* IPSTATS_MIB_INDISCARDS */ -+ [ 9] = RTNL_LINK_IP6_INDELIVERS, /* IPSTATS_MIB_INDELIVERS */ -+ [10] = RTNL_LINK_IP6_OUTFORWDATAGRAMS, /* IPSTATS_MIB_OUTFORWDATAGRAMS */ -+ [11] = RTNL_LINK_IP6_OUTPKTS, /* IPSTATS_MIB_OUTPKTS */ -+ [12] = RTNL_LINK_IP6_OUTDISCARDS, /* IPSTATS_MIB_OUTDISCARDS */ -+ [13] = RTNL_LINK_IP6_OUTNOROUTES, /* IPSTATS_MIB_OUTNOROUTES */ -+ [14] = RTNL_LINK_IP6_REASMTIMEOUT, /* IPSTATS_MIB_REASMTIMEOUT */ -+ [15] = RTNL_LINK_IP6_REASMREQDS, /* IPSTATS_MIB_REASMREQDS */ -+ [16] = RTNL_LINK_IP6_REASMOKS, /* IPSTATS_MIB_REASMOKS */ -+ [17] = RTNL_LINK_IP6_REASMFAILS, /* IPSTATS_MIB_REASMFAILS */ -+ [18] = RTNL_LINK_IP6_FRAGOKS, /* IPSTATS_MIB_FRAGOKS */ -+ [19] = RTNL_LINK_IP6_FRAGFAILS, /* IPSTATS_MIB_FRAGFAILS */ -+ [20] = RTNL_LINK_IP6_FRAGCREATES, /* IPSTATS_MIB_FRAGCREATES */ -+ [21] = RTNL_LINK_IP6_INMCASTPKTS, /* IPSTATS_MIB_INMCASTPKTS */ -+ [22] = RTNL_LINK_IP6_OUTMCASTPKTS, /* IPSTATS_MIB_OUTMCASTPKTS */ -+ [23] = RTNL_LINK_IP6_INBCASTPKTS, /* IPSTATS_MIB_INBCASTPKTS */ -+ [24] = RTNL_LINK_IP6_OUTBCASTPKTS, /* IPSTATS_MIB_OUTBCASTPKTS */ -+ [25] = RTNL_LINK_IP6_INOCTETS, /* IPSTATS_MIB_INOCTETS */ -+ [26] = RTNL_LINK_IP6_OUTOCTETS, /* IPSTATS_MIB_OUTOCTETS */ -+ [27] = RTNL_LINK_IP6_INMCASTOCTETS, /* IPSTATS_MIB_INMCASTOCTETS */ -+ [28] = RTNL_LINK_IP6_OUTMCASTOCTETS, /* IPSTATS_MIB_OUTMCASTOCTETS */ -+ [29] = RTNL_LINK_IP6_INBCASTOCTETS, /* IPSTATS_MIB_INBCASTOCTETS */ -+ [30] = RTNL_LINK_IP6_OUTBCASTOCTETS, /* IPSTATS_MIB_OUTBCASTOCTETS */ -+}; -+ -+static const uint8_t map_stat_id_from_IPSTATS_MIB_v2[__IPSTATS_MIB_MAX] = { -+ /* d8ec26d7f8287f5788a494f56e8814210f0e64be:include/uapi/linux/snmp.h -+ * version since the API change in commit 14a196807482e6fc74f15fc03176d5c08880588f */ -+ [ 1] = RTNL_LINK_IP6_INPKTS, /* IPSTATS_MIB_INPKTS */ -+ [ 2] = RTNL_LINK_IP6_INOCTETS, /* IPSTATS_MIB_INOCTETS */ -+ [ 3] = RTNL_LINK_IP6_INDELIVERS, /* IPSTATS_MIB_INDELIVERS */ -+ [ 4] = RTNL_LINK_IP6_OUTFORWDATAGRAMS, /* IPSTATS_MIB_OUTFORWDATAGRAMS */ -+ [ 5] = RTNL_LINK_IP6_OUTPKTS, /* IPSTATS_MIB_OUTPKTS */ -+ [ 6] = RTNL_LINK_IP6_OUTOCTETS, /* IPSTATS_MIB_OUTOCTETS */ -+ [ 7] = RTNL_LINK_IP6_INHDRERRORS, /* IPSTATS_MIB_INHDRERRORS */ -+ [ 8] = RTNL_LINK_IP6_INTOOBIGERRORS, /* IPSTATS_MIB_INTOOBIGERRORS */ -+ [ 9] = RTNL_LINK_IP6_INNOROUTES, /* IPSTATS_MIB_INNOROUTES */ -+ [10] = RTNL_LINK_IP6_INADDRERRORS, /* IPSTATS_MIB_INADDRERRORS */ -+ [11] = RTNL_LINK_IP6_INUNKNOWNPROTOS, /* IPSTATS_MIB_INUNKNOWNPROTOS */ -+ [12] = RTNL_LINK_IP6_INTRUNCATEDPKTS, /* IPSTATS_MIB_INTRUNCATEDPKTS */ -+ [13] = RTNL_LINK_IP6_INDISCARDS, /* IPSTATS_MIB_INDISCARDS */ -+ [14] = RTNL_LINK_IP6_OUTDISCARDS, /* IPSTATS_MIB_OUTDISCARDS */ -+ [15] = RTNL_LINK_IP6_OUTNOROUTES, /* IPSTATS_MIB_OUTNOROUTES */ -+ [16] = RTNL_LINK_IP6_REASMTIMEOUT, /* IPSTATS_MIB_REASMTIMEOUT */ -+ [17] = RTNL_LINK_IP6_REASMREQDS, /* IPSTATS_MIB_REASMREQDS */ -+ [18] = RTNL_LINK_IP6_REASMOKS, /* IPSTATS_MIB_REASMOKS */ -+ [19] = RTNL_LINK_IP6_REASMFAILS, /* IPSTATS_MIB_REASMFAILS */ -+ [20] = RTNL_LINK_IP6_FRAGOKS, /* IPSTATS_MIB_FRAGOKS */ -+ [21] = RTNL_LINK_IP6_FRAGFAILS, /* IPSTATS_MIB_FRAGFAILS */ -+ [22] = RTNL_LINK_IP6_FRAGCREATES, /* IPSTATS_MIB_FRAGCREATES */ -+ [23] = RTNL_LINK_IP6_INMCASTPKTS, /* IPSTATS_MIB_INMCASTPKTS */ -+ [24] = RTNL_LINK_IP6_OUTMCASTPKTS, /* IPSTATS_MIB_OUTMCASTPKTS */ -+ [25] = RTNL_LINK_IP6_INBCASTPKTS, /* IPSTATS_MIB_INBCASTPKTS */ -+ [26] = RTNL_LINK_IP6_OUTBCASTPKTS, /* IPSTATS_MIB_OUTBCASTPKTS */ -+ [27] = RTNL_LINK_IP6_INMCASTOCTETS, /* IPSTATS_MIB_INMCASTOCTETS */ -+ [28] = RTNL_LINK_IP6_OUTMCASTOCTETS, /* IPSTATS_MIB_OUTMCASTOCTETS */ -+ [29] = RTNL_LINK_IP6_INBCASTOCTETS, /* IPSTATS_MIB_INBCASTOCTETS */ -+ [30] = RTNL_LINK_IP6_OUTBCASTOCTETS, /* IPSTATS_MIB_OUTBCASTOCTETS */ -+ [31] = RTNL_LINK_IP6_CSUMERRORS, /* IPSTATS_MIB_CSUMERRORS */ -+ [32] = RTNL_LINK_IP6_NOECTPKTS, /* IPSTATS_MIB_NOECTPKTS */ -+ [33] = RTNL_LINK_IP6_ECT1PKTS, /* IPSTATS_MIB_ECT1PKTS */ -+ [34] = RTNL_LINK_IP6_ECT0PKTS, /* IPSTATS_MIB_ECT0PKTS */ -+ [35] = RTNL_LINK_IP6_CEPKTS, /* IPSTATS_MIB_CEPKTS */ -+}; -+ - static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, - void *data) - { -@@ -86,12 +164,23 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, - unsigned char *cnt = nla_data(tb[IFLA_INET6_STATS]); - uint64_t stat; - int i; -- int len = min_t(int, __IPSTATS_MIB_MAX, nla_len(tb[IFLA_INET6_STATS]) / 8); -+ int len = nla_len(tb[IFLA_INET6_STATS]) / 8; -+ const uint8_t *map_stat_id = map_stat_id_from_IPSTATS_MIB_v2; -+ -+ if (len < 32 || -+ (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) < 6)) { -+ /* kernel commit 14a196807482e6fc74f15fc03176d5c08880588f reordered the values. -+ * The later commit 6a5dc9e598fe90160fee7de098fa319665f5253e added values -+ * IPSTATS_MIB_CSUMERRORS/ICMP6_MIB_CSUMERRORS. If the netlink is shorter -+ * then this, assume that the kernel uses the previous meaning of the -+ * enumeration. */ -+ map_stat_id = map_stat_id_from_IPSTATS_MIB_v1; -+ } - -+ len = min_t(int, __IPSTATS_MIB_MAX, len); - for (i = 1; i < len; i++) { - memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat)); -- rtnl_link_set_stat(link, RTNL_LINK_IP6_INPKTS + i - 1, -- stat); -+ rtnl_link_set_stat(link, map_stat_id[i], stat); - } - } - -@@ -343,19 +432,29 @@ static void inet6_dump_stats(struct rtnl_link *link, - link->l_stats[RTNL_LINK_IP6_INADDRERRORS]); - - nl_dump(p, " InUnknownProtos InTruncatedPkts " -- " OutNoRoutes\n"); -- nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", -+ " OutNoRoutes InCsumErrors\n"); -+ nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", - link->l_stats[RTNL_LINK_IP6_INUNKNOWNPROTOS], - link->l_stats[RTNL_LINK_IP6_INTRUNCATEDPKTS], -- link->l_stats[RTNL_LINK_IP6_OUTNOROUTES]); -+ link->l_stats[RTNL_LINK_IP6_OUTNOROUTES], -+ link->l_stats[RTNL_LINK_IP6_CSUMERRORS]); - -- nl_dump(p, " ICMPv6: InMsgs InErrors " -- " OutMsgs OutErrors\n"); -+ nl_dump(p, " InNoECTPkts InECT1Pkts " -+ " InECT0Pkts InCEPkts\n"); - nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", -+ link->l_stats[RTNL_LINK_IP6_NOECTPKTS], -+ link->l_stats[RTNL_LINK_IP6_ECT1PKTS], -+ link->l_stats[RTNL_LINK_IP6_ECT0PKTS], -+ link->l_stats[RTNL_LINK_IP6_CEPKTS]); -+ -+ nl_dump(p, " ICMPv6: InMsgs InErrors " -+ " OutMsgs OutErrors InCsumErrors\n"); -+ nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n", - link->l_stats[RTNL_LINK_ICMP6_INMSGS], - link->l_stats[RTNL_LINK_ICMP6_INERRORS], - link->l_stats[RTNL_LINK_ICMP6_OUTMSGS], -- link->l_stats[RTNL_LINK_ICMP6_OUTERRORS]); -+ link->l_stats[RTNL_LINK_ICMP6_OUTERRORS], -+ link->l_stats[RTNL_LINK_ICMP6_CSUMERRORS]); - } - - static const struct nla_policy protinfo_policy = { --- -1.8.5.3 - diff --git a/SOURCES/0008-rh1127718-inet6_addr_gen.patch b/SOURCES/0008-rh1127718-inet6_addr_gen.patch deleted file mode 100644 index 346047d..0000000 --- a/SOURCES/0008-rh1127718-inet6_addr_gen.patch +++ /dev/null @@ -1,552 +0,0 @@ -From 99dde0b03a7380e29544aceac6e32432632a54dc Mon Sep 17 00:00:00 2001 -From: Dan Williams -Date: Fri, 25 Jul 2014 14:33:38 -0500 -Subject: [PATCH 1/2] link: update copy of kernel header - include/linux/if_link.h - -The next patch will use some of these defines, so update. - -Taken from upstream kernel commit bc91b0f07ada5535427373a4e2050877bcc12218, -file 'include/uapi/linux/if_link.h'. - -Signed-off-by: Dan Williams -Signed-off-by: Thomas Haller -(cherry picked from commit b51815a9dbd8e45fd2558bbe337fb360ca2fd861) - -Conflicts: - include/linux/if_link.h ---- - include/linux/if_link.h | 194 ++++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 181 insertions(+), 13 deletions(-) - -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index a753d11..ff95760 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -1,5 +1,5 @@ --#ifndef _LINUX_IF_LINK_H --#define _LINUX_IF_LINK_H -+#ifndef _UAPI_LINUX_IF_LINK_H -+#define _UAPI_LINUX_IF_LINK_H - - #include - #include -@@ -143,12 +143,20 @@ enum { - IFLA_NUM_TX_QUEUES, - IFLA_NUM_RX_QUEUES, - IFLA_CARRIER, -+ IFLA_PHYS_PORT_ID, -+ IFLA_CARRIER_CHANGES, - __IFLA_MAX - }; - - - #define IFLA_MAX (__IFLA_MAX - 1) - -+/* backwards compatibility for userspace */ -+#ifndef __KERNEL__ -+#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) -+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) -+#endif -+ - enum { - IFLA_INET_UNSPEC, - IFLA_INET_CONF, -@@ -195,11 +203,38 @@ enum { - IFLA_INET6_MCAST, /* MC things. What of them? */ - IFLA_INET6_CACHEINFO, /* time values and max reasm size */ - IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */ -+ IFLA_INET6_TOKEN, /* device token */ -+ IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */ - __IFLA_INET6_MAX - }; - - #define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) - -+enum in6_addr_gen_mode { -+ IN6_ADDR_GEN_MODE_EUI64, -+ IN6_ADDR_GEN_MODE_NONE, -+}; -+ -+enum { -+ BRIDGE_MODE_UNSPEC, -+ BRIDGE_MODE_HAIRPIN, -+}; -+ -+enum { -+ IFLA_BRPORT_UNSPEC, -+ IFLA_BRPORT_STATE, /* Spanning tree state */ -+ IFLA_BRPORT_PRIORITY, /* " priority */ -+ IFLA_BRPORT_COST, /* " cost */ -+ IFLA_BRPORT_MODE, /* mode (hairpin) */ -+ IFLA_BRPORT_GUARD, /* bpdu guard */ -+ IFLA_BRPORT_PROTECT, /* root port protection */ -+ IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ -+ IFLA_BRPORT_LEARNING, /* mac learning */ -+ IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ -+ __IFLA_BRPORT_MAX -+}; -+#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -+ - struct ifla_cacheinfo { - __u32 max_reasm_len; - __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ -@@ -212,6 +247,8 @@ enum { - IFLA_INFO_KIND, - IFLA_INFO_DATA, - IFLA_INFO_XSTATS, -+ IFLA_INFO_SLAVE_KIND, -+ IFLA_INFO_SLAVE_DATA, - __IFLA_INFO_MAX, - }; - -@@ -225,6 +262,7 @@ enum { - IFLA_VLAN_FLAGS, - IFLA_VLAN_EGRESS_QOS, - IFLA_VLAN_INGRESS_QOS, -+ IFLA_VLAN_PROTOCOL, - __IFLA_VLAN_MAX, - }; - -@@ -267,6 +305,95 @@ enum macvlan_mode { - - #define MACVLAN_FLAG_NOPROMISC 1 - -+/* VXLAN section */ -+enum { -+ IFLA_VXLAN_UNSPEC, -+ IFLA_VXLAN_ID, -+ IFLA_VXLAN_GROUP, /* group or remote address */ -+ IFLA_VXLAN_LINK, -+ IFLA_VXLAN_LOCAL, -+ IFLA_VXLAN_TTL, -+ IFLA_VXLAN_TOS, -+ IFLA_VXLAN_LEARNING, -+ IFLA_VXLAN_AGEING, -+ IFLA_VXLAN_LIMIT, -+ IFLA_VXLAN_PORT_RANGE, /* source port */ -+ IFLA_VXLAN_PROXY, -+ IFLA_VXLAN_RSC, -+ IFLA_VXLAN_L2MISS, -+ IFLA_VXLAN_L3MISS, -+ IFLA_VXLAN_PORT, /* destination port */ -+ IFLA_VXLAN_GROUP6, -+ IFLA_VXLAN_LOCAL6, -+ IFLA_VXLAN_UDP_CSUM, -+ IFLA_VXLAN_UDP_ZERO_CSUM6_TX, -+ IFLA_VXLAN_UDP_ZERO_CSUM6_RX, -+ __IFLA_VXLAN_MAX -+}; -+#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) -+ -+struct ifla_vxlan_port_range { -+ __be16 low; -+ __be16 high; -+}; -+ -+/* Bonding section */ -+ -+enum { -+ IFLA_BOND_UNSPEC, -+ IFLA_BOND_MODE, -+ IFLA_BOND_ACTIVE_SLAVE, -+ IFLA_BOND_MIIMON, -+ IFLA_BOND_UPDELAY, -+ IFLA_BOND_DOWNDELAY, -+ IFLA_BOND_USE_CARRIER, -+ IFLA_BOND_ARP_INTERVAL, -+ IFLA_BOND_ARP_IP_TARGET, -+ IFLA_BOND_ARP_VALIDATE, -+ IFLA_BOND_ARP_ALL_TARGETS, -+ IFLA_BOND_PRIMARY, -+ IFLA_BOND_PRIMARY_RESELECT, -+ IFLA_BOND_FAIL_OVER_MAC, -+ IFLA_BOND_XMIT_HASH_POLICY, -+ IFLA_BOND_RESEND_IGMP, -+ IFLA_BOND_NUM_PEER_NOTIF, -+ IFLA_BOND_ALL_SLAVES_ACTIVE, -+ IFLA_BOND_MIN_LINKS, -+ IFLA_BOND_LP_INTERVAL, -+ IFLA_BOND_PACKETS_PER_SLAVE, -+ IFLA_BOND_AD_LACP_RATE, -+ IFLA_BOND_AD_SELECT, -+ IFLA_BOND_AD_INFO, -+ __IFLA_BOND_MAX, -+}; -+ -+#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1) -+ -+enum { -+ IFLA_BOND_AD_INFO_UNSPEC, -+ IFLA_BOND_AD_INFO_AGGREGATOR, -+ IFLA_BOND_AD_INFO_NUM_PORTS, -+ IFLA_BOND_AD_INFO_ACTOR_KEY, -+ IFLA_BOND_AD_INFO_PARTNER_KEY, -+ IFLA_BOND_AD_INFO_PARTNER_MAC, -+ __IFLA_BOND_AD_INFO_MAX, -+}; -+ -+#define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1) -+ -+enum { -+ IFLA_BOND_SLAVE_UNSPEC, -+ IFLA_BOND_SLAVE_STATE, -+ IFLA_BOND_SLAVE_MII_STATUS, -+ IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, -+ IFLA_BOND_SLAVE_PERM_HWADDR, -+ IFLA_BOND_SLAVE_QUEUE_ID, -+ IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, -+ __IFLA_BOND_SLAVE_MAX, -+}; -+ -+#define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_MAX - 1) -+ - /* SR-IOV virtual function management section */ - - enum { -@@ -281,8 +408,10 @@ enum { - IFLA_VF_UNSPEC, - IFLA_VF_MAC, /* Hardware queue specific attributes */ - IFLA_VF_VLAN, -- IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */ -+ IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */ - IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ -+ IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ -+ IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */ - __IFLA_VF_MAX, - }; - -@@ -304,22 +433,28 @@ struct ifla_vf_tx_rate { - __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ - }; - -+struct ifla_vf_rate { -+ __u32 vf; -+ __u32 min_tx_rate; /* Min Bandwidth in Mbps */ -+ __u32 max_tx_rate; /* Max Bandwidth in Mbps */ -+}; -+ - struct ifla_vf_spoofchk { - __u32 vf; - __u32 setting; - }; --#ifdef __KERNEL__ - --/* We don't want this structure exposed to user space */ --struct ifla_vf_info { -+enum { -+ IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */ -+ IFLA_VF_LINK_STATE_ENABLE, /* link always up */ -+ IFLA_VF_LINK_STATE_DISABLE, /* link always down */ -+ __IFLA_VF_LINK_STATE_MAX, -+}; -+ -+struct ifla_vf_link_state { - __u32 vf; -- __u8 mac[32]; -- __u32 vlan; -- __u32 qos; -- __u32 tx_rate; -- __u32 spoofchk; -+ __u32 link_state; - }; --#endif - - /* VF ports management section - * -@@ -393,4 +528,37 @@ struct ifla_port_vsi { - __u8 pad[3]; - }; - --#endif /* _LINUX_IF_LINK_H */ -+ -+/* IPoIB section */ -+ -+enum { -+ IFLA_IPOIB_UNSPEC, -+ IFLA_IPOIB_PKEY, -+ IFLA_IPOIB_MODE, -+ IFLA_IPOIB_UMCAST, -+ __IFLA_IPOIB_MAX -+}; -+ -+enum { -+ IPOIB_MODE_DATAGRAM = 0, /* using unreliable datagram QPs */ -+ IPOIB_MODE_CONNECTED = 1, /* using connected QPs */ -+}; -+ -+#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1) -+ -+ -+/* HSR section */ -+ -+enum { -+ IFLA_HSR_UNSPEC, -+ IFLA_HSR_SLAVE1, -+ IFLA_HSR_SLAVE2, -+ IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */ -+ IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */ -+ IFLA_HSR_SEQ_NR, -+ __IFLA_HSR_MAX, -+}; -+ -+#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1) -+ -+#endif /* _UAPI_LINUX_IF_LINK_H */ --- -1.9.3 - - -From 36365bdd3df389d8f720782708a4735ccb36128c Mon Sep 17 00:00:00 2001 -From: Dan Williams -Date: Fri, 25 Jul 2014 14:36:29 -0500 -Subject: [PATCH 2/2] link/inet6: add link IPv6 address generation mode support - -Signed-off-by: Dan Williams -Signed-off-by: Thomas Haller -(cherry picked from commit 558f966782539f6d975da705fd73cea561c9dc83) - -Conflicts: - include/Makefile.am - lib/route/link/inet6.c ---- - include/Makefile.am | 1 + - include/netlink/route/link/inet6.h | 37 +++++++++++++ - lib/route/link/inet6.c | 109 ++++++++++++++++++++++++++++++++++--- - 3 files changed, 140 insertions(+), 7 deletions(-) - create mode 100644 include/netlink/route/link/inet6.h - -diff --git a/include/Makefile.am b/include/Makefile.am -index 1e07fdb..b9487e0 100644 ---- a/include/Makefile.am -+++ b/include/Makefile.am -@@ -44,6 +44,7 @@ nobase_libnlinclude_HEADERS = \ - netlink/route/link/bonding.h \ - netlink/route/link/can.h \ - netlink/route/link/inet.h \ -+ netlink/route/link/inet6.h \ - netlink/route/link/vlan.h \ - netlink/route/qdisc/cbq.h \ - netlink/route/qdisc/dsmark.h \ -diff --git a/include/netlink/route/link/inet6.h b/include/netlink/route/link/inet6.h -new file mode 100644 -index 0000000..8ffeab2 ---- /dev/null -+++ b/include/netlink/route/link/inet6.h -@@ -0,0 +1,37 @@ -+/* -+ * netlink/route/link/inet6.h INET6 Link Module -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation version 2.1 -+ * of the License. -+ * -+ * Copyright (c) 2014 Dan Williams -+ */ -+ -+#ifndef NETLINK_LINK_INET6_H_ -+#define NETLINK_LINK_INET6_H_ -+ -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+const char * rtnl_link_inet6_addrgenmode2str (uint8_t mode, -+ char *buf, -+ size_t len); -+ -+uint8_t rtnl_link_inet6_str2addrgenmode (const char *mode); -+ -+extern int rtnl_link_inet6_get_addr_gen_mode(struct rtnl_link *, -+ uint8_t *); -+ -+extern int rtnl_link_inet6_set_addr_gen_mode(struct rtnl_link *, -+ uint8_t); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c -index 6fa2741..e94bf0c 100644 ---- a/lib/route/link/inet6.c -+++ b/lib/route/link/inet6.c -@@ -15,16 +15,25 @@ - #include - #include - -+#define I6_ADDR_GEN_MODE_UNKNOWN UINT8_MAX -+ - struct inet6_data - { - uint32_t i6_flags; - struct ifla_cacheinfo i6_cacheinfo; - uint32_t i6_conf[DEVCONF_MAX]; -+ uint8_t i6_addr_gen_mode; - }; - - static void *inet6_alloc(struct rtnl_link *link) - { -- return calloc(1, sizeof(struct inet6_data)); -+ struct inet6_data *i6; -+ -+ i6 = calloc(1, sizeof(struct inet6_data)); -+ if (i6) -+ i6->i6_addr_gen_mode = I6_ADDR_GEN_MODE_UNKNOWN; -+ -+ return i6; - } - - static void *inet6_clone(struct rtnl_link *link, void *data) -@@ -43,11 +52,12 @@ static void inet6_free(struct rtnl_link *link, void *data) - } - - static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = { -- [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, -- [IFLA_INET6_CACHEINFO] = { .minlen = sizeof(struct ifla_cacheinfo) }, -- [IFLA_INET6_CONF] = { .minlen = 4 }, -- [IFLA_INET6_STATS] = { .minlen = 8 }, -- [IFLA_INET6_ICMP6STATS] = { .minlen = 8 }, -+ [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, -+ [IFLA_INET6_CACHEINFO] = { .minlen = sizeof(struct ifla_cacheinfo) }, -+ [IFLA_INET6_CONF] = { .minlen = 4 }, -+ [IFLA_INET6_STATS] = { .minlen = 8 }, -+ [IFLA_INET6_ICMP6STATS] = { .minlen = 8 }, -+ [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 }, - }; - - static const uint8_t map_stat_id_from_IPSTATS_MIB_v1[__IPSTATS_MIB_MAX] = { -@@ -155,7 +165,10 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, - if (tb[IFLA_INET6_CONF]) - nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF], - sizeof(i6->i6_conf)); -- -+ -+ if (tb[IFLA_INET6_ADDR_GEN_MODE]) -+ i6->i6_addr_gen_mode = nla_get_u8 (tb[IFLA_INET6_ADDR_GEN_MODE]); -+ - /* - * Due to 32bit data alignment, these addresses must be copied to an - * aligned location prior to access. -@@ -200,6 +213,19 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, - return 0; - } - -+static int inet6_fill_af(struct rtnl_link *link, struct nl_msg *msg, void *data) -+{ -+ struct inet6_data *id = data; -+ -+ if (id->i6_addr_gen_mode != I6_ADDR_GEN_MODE_UNKNOWN) -+ NLA_PUT_U8(msg, IFLA_INET6_ADDR_GEN_MODE, id->i6_addr_gen_mode); -+ -+ return 0; -+ -+nla_put_failure: -+ return -NLE_MSGSIZE; -+} -+ - /* These live in include/net/if_inet6.h and should be moved to include/linux */ - #define IF_RA_OTHERCONF 0x80 - #define IF_RA_MANAGED 0x40 -@@ -259,6 +285,22 @@ static char *inet6_devconf2str(int type, char *buf, size_t len) - ARRAY_SIZE(inet6_devconf)); - } - -+static const struct trans_tbl inet6_addr_gen_mode[] = { -+ __ADD(IN6_ADDR_GEN_MODE_EUI64, eui64) -+ __ADD(IN6_ADDR_GEN_MODE_NONE, none) -+}; -+ -+const char *rtnl_link_inet6_addrgenmode2str(uint8_t mode, char *buf, size_t len) -+{ -+ return __type2str(mode, buf, len, inet6_addr_gen_mode, -+ ARRAY_SIZE(inet6_addr_gen_mode)); -+} -+ -+uint8_t rtnl_link_inet6_str2addrgenmode(const char *mode) -+{ -+ return (uint8_t) __str2type(mode, inet6_addr_gen_mode, -+ ARRAY_SIZE(inet6_addr_gen_mode)); -+} - - static void inet6_dump_details(struct rtnl_link *link, - struct nl_dump_params *p, void *data) -@@ -281,6 +323,10 @@ static void inet6_dump_details(struct rtnl_link *link, - nl_dump(p, " retrans-time %s\n", - nl_msec2str(i6->i6_cacheinfo.retrans_time, buf, sizeof(buf))); - -+ nl_dump(p, " link-local address mode %s\n", -+ rtnl_link_inet6_addrgenmode2str(i6->i6_addr_gen_mode, -+ buf, sizeof(buf))); -+ - nl_dump_line(p, " devconf:\n"); - nl_dump_line(p, " "); - -@@ -468,11 +514,60 @@ static struct rtnl_link_af_ops inet6_ops = { - .ao_free = &inet6_free, - .ao_parse_protinfo = &inet6_parse_protinfo, - .ao_parse_af = &inet6_parse_protinfo, -+ .ao_fill_af = &inet6_fill_af, - .ao_dump[NL_DUMP_DETAILS] = &inet6_dump_details, - .ao_dump[NL_DUMP_STATS] = &inet6_dump_stats, - .ao_protinfo_policy = &protinfo_policy, - }; - -+/** -+ * Get IPv6 link-local address generation mode -+ * @arg link Link object -+ * @arg mode Generation mode on success -+ * -+ * Returns the link's IPv6 link-local address generation mode. -+ * -+ * @return 0 on success -+ * @return -NLE_NOATTR configuration setting not available -+ * @return -NLE_INVAL generation mode unknown. If the link was received via -+ * netlink, it means that address generation mode is not -+ * supported by the kernel. -+ */ -+int rtnl_link_inet6_get_addr_gen_mode(struct rtnl_link *link, uint8_t *mode) -+{ -+ struct inet6_data *id; -+ -+ if (!(id = rtnl_link_af_data(link, &inet6_ops))) -+ return -NLE_NOATTR; -+ -+ if (id->i6_addr_gen_mode == I6_ADDR_GEN_MODE_UNKNOWN) -+ return -NLE_INVAL; -+ -+ *mode = id->i6_addr_gen_mode; -+ return 0; -+} -+ -+/** -+ * Set IPv6 link-local address generation mode -+ * @arg link Link object -+ * @arg mode Generation mode -+ * -+ * Sets the link's IPv6 link-local address generation mode. -+ * -+ * @return 0 on success -+ * @return -NLE_NOMEM could not allocate inet6 data -+ */ -+int rtnl_link_inet6_set_addr_gen_mode(struct rtnl_link *link, uint8_t mode) -+{ -+ struct inet6_data *id; -+ -+ if (!(id = rtnl_link_af_alloc(link, &inet6_ops))) -+ return -NLE_NOMEM; -+ -+ id->i6_addr_gen_mode = mode; -+ return 0; -+} -+ - static void __init inet6_init(void) - { - rtnl_link_af_register(&inet6_ops); --- -1.9.3 - diff --git a/SOURCES/0009-rh1181255-EAGAIN.patch b/SOURCES/0009-rh1181255-EAGAIN.patch deleted file mode 100644 index ddb186e..0000000 --- a/SOURCES/0009-rh1181255-EAGAIN.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 375a6294a41e003f873821a01d947f0ecfaf76d4 Mon Sep 17 00:00:00 2001 -From: Thomas Graf -Date: Tue, 2 Apr 2013 11:58:18 +0200 -Subject: [PATCH] nl: Return -NLE_AGAIN if non-blocking socket would block - -Previously 0 was returned which gave the caller no chance of detecting -when a non-blocking socket would block. If a caller intends to never -see an error message it should utilize poll()/select() to only read -when the socket has pending data or information. - -Reported-by: Holger Eitzenberger -Signed-off-by: Thomas Graf ---- - lib/nl.c | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/lib/nl.c b/lib/nl.c -index fa43c56..0445e35 100644 ---- a/lib/nl.c -+++ b/lib/nl.c -@@ -627,11 +627,6 @@ retry: - NL_DBG(3, "recvmsg() returned EINTR, retrying\n"); - goto retry; - } -- if (errno == EAGAIN || errno == EWOULDBLOCK) { -- NL_DBG(3, "recvmsg() returned EAGAIN||EWOULDBLOCK, aborting\n"); -- retval = 0; -- goto abort; -- } - retval = -nl_syserr2nlerr(errno); - goto abort; - } --- -2.1.0 - diff --git a/SOURCES/0010-rh1249158-local-port-EADDRINUSE.patch b/SOURCES/0010-rh1249158-local-port-EADDRINUSE.patch deleted file mode 100644 index 6330f40..0000000 --- a/SOURCES/0010-rh1249158-local-port-EADDRINUSE.patch +++ /dev/null @@ -1,1176 +0,0 @@ -From 2b7b4ae45f5171231b562ba51be256d1e2c40401 Mon Sep 17 00:00:00 2001 -From: Thomas Graf -Date: Mon, 31 Mar 2014 13:21:06 +0200 -Subject: [PATCH 01/11] link: Catch missing io_free() implementations - -Signed-off-by: Thomas Graf -Signed-off-by: Thomas Haller -(cherry picked from commit 34bfce62150d07cf9894f2d9cbd0c989a203ea52) ---- - include/netlink-private/netlink.h | 7 +++++++ - lib/route/link.c | 4 ++++ - 2 files changed, 11 insertions(+) - -diff --git a/include/netlink-private/netlink.h b/include/netlink-private/netlink.h -index 6ae6d17..83eefad 100644 ---- a/include/netlink-private/netlink.h -+++ b/include/netlink-private/netlink.h -@@ -95,6 +95,13 @@ struct trans_list { - assert(0); \ - } while (0) - -+#define BUG_ON(condition) \ -+ do { \ -+ if (condition) \ -+ BUG(); \ -+ } while (0) -+ -+ - #define APPBUG(msg) \ - do { \ - NL_DBG(1, "APPLICATION BUG: %s:%d:%s: %s\n", \ -diff --git a/lib/route/link.c b/lib/route/link.c -index 8fe3376..1f27247 100644 ---- a/lib/route/link.c -+++ b/lib/route/link.c -@@ -184,6 +184,10 @@ static void release_link_info(struct rtnl_link *link) - if (io != NULL) { - if (io->io_free) - io->io_free(link); -+ else { -+ /* Catch missing io_free() implementations */ -+ BUG_ON(link->l_info); -+ } - rtnl_link_info_ops_put(io); - link->l_info_ops = NULL; - } --- -2.4.3 - - -From 369857fcf8d6c2783be8c1d225ad192363245098 Mon Sep 17 00:00:00 2001 -From: Thomas Graf -Date: Fri, 28 Jun 2013 18:53:16 +0200 -Subject: [PATCH 02/11] socket: Warn via debug message if local port namespace - is exhausted - -Signed-off-by: Thomas Graf -(cherry picked from commit 2d0810eb93704defb2375d9861892d6041da4623) ---- - lib/socket.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/lib/socket.c b/lib/socket.c -index d3e636e..f3171f5 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -89,6 +89,7 @@ static uint32_t generate_local_port(void) - nl_write_unlock(&port_map_lock); - - /* Out of sockets in our own PID namespace, what to do? FIXME */ -+ NL_DBG(1, "Warning: Ran out of unique local port namespace\n"); - return UINT_MAX; - } - --- -2.4.3 - - -From bba9ce1426728f00eccc5aa97d6d6c954d383481 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 9 Apr 2014 12:08:50 +0200 -Subject: [PATCH 03/11] lib/socket: use proper typed constant UINT32_MAX for - uint32_t typed port - -This was a bug on architectures with native int type less then 32 bit. - -Acked-by: Thomas Graf -Signed-off-by: Thomas Haller -(cherry picked from commit 0fd510b3673f479637a6376db3d66dcb9f8911d0) ---- - lib/socket.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/lib/socket.c b/lib/socket.c -index f3171f5..fa12e25 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -82,7 +82,7 @@ static uint32_t generate_local_port(void) - - nl_write_unlock(&port_map_lock); - -- return pid + (n << 22); -+ return pid + (((uint32_t)n) << 22); - } - } - -@@ -90,14 +90,14 @@ static uint32_t generate_local_port(void) - - /* Out of sockets in our own PID namespace, what to do? FIXME */ - NL_DBG(1, "Warning: Ran out of unique local port namespace\n"); -- return UINT_MAX; -+ return UINT32_MAX; - } - - static void release_local_port(uint32_t port) - { - int nr; - -- if (port == UINT_MAX) -+ if (port == UINT32_MAX) - return; - - nr = port >> 22; -@@ -126,7 +126,7 @@ static struct nl_sock *__alloc_socket(struct nl_cb *cb) - sk->s_peer.nl_family = AF_NETLINK; - sk->s_seq_expect = sk->s_seq_next = time(0); - sk->s_local.nl_pid = generate_local_port(); -- if (sk->s_local.nl_pid == UINT_MAX) { -+ if (sk->s_local.nl_pid == UINT32_MAX) { - nl_socket_free(sk); - return NULL; - } --- -2.4.3 - - -From b4c09ead0b289a74d86dd47fbf1081daafcd4826 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 9 Apr 2014 12:08:51 +0200 -Subject: [PATCH 04/11] lib/socket: don't fail if no more local ports can be - assigned in nl_socket_alloc - -By failing inside of nl_socket_alloc(), the user can not even work around -when running out of local ports. This patch changes that if there are no more -local ports, we set the port to UINT32_MAX. This is a consistent behavior -to calling nl_socket_set_local_port(sk, 0). - -In general, since nl_socket_set_local_port() does not restict the generated -ports in any way we cannot assume to have a valid port. So the check in -the constructor was harmful and users who ever encountered it (because they -created 1024 libnl3 sockets) could not even work around it. - -Acked-by: Thomas Graf -Signed-off-by: Thomas Haller -(cherry picked from commit 0271578987088210d7d2d68addbd5e8fe27d4383) ---- - lib/socket.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/lib/socket.c b/lib/socket.c -index fa12e25..f9e68ff 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -126,10 +126,6 @@ static struct nl_sock *__alloc_socket(struct nl_cb *cb) - sk->s_peer.nl_family = AF_NETLINK; - sk->s_seq_expect = sk->s_seq_next = time(0); - sk->s_local.nl_pid = generate_local_port(); -- if (sk->s_local.nl_pid == UINT32_MAX) { -- nl_socket_free(sk); -- return NULL; -- } - - return sk; - } --- -2.4.3 - - -From 5de5c84c094fd178216accd2c29f32bfe5f7f67b Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 9 Apr 2014 12:08:52 +0200 -Subject: [PATCH 05/11] lib/socket: retry generate local port in nl_connect on - ADDRINUSE - -It can easily happen that the generated local netlink port is alrady in -use. In that case bind will fail with ADDRINUSE. - -Users of libnl3 could workaround this, by managing the local ports -themselves, but sometimes these users are libraries too and they also -don't know which ports might be used by other components. - -This patch changes that nl_socket_alloc() no longer initilizes the local -port id immediately. Instead it will be initialized when the user calls -nl_socket_get_local_port() the first time and thereby shows interest in -the value. - -If bind() fails with ADDRINUSE, check if the user ever cared about the -local port, i.e. whether the local port is still unset. If it is still -unset, assume that libnl should choose a suitable port and retry until -an unused port can be found. - -Signed-off-by: Thomas Haller - -[thaller@redhat.com: modify original patch to use explicit gcc attribute -to hide private symbols instead of "libnl.sym"] - -(cherry picked from commit 4dd5fdd0af2c0b7ffe1dbc49313f263dbb2e906f) ---- - include/Makefile.am | 1 + - include/netlink-private/socket.h | 31 +++++++++++ - include/netlink/utils.h | 9 +++ - lib/nl.c | 62 ++++++++++++++++++--- - lib/socket.c | 116 ++++++++++++++++++++++++++++++++------- - lib/utils.c | 2 +- - 6 files changed, 192 insertions(+), 29 deletions(-) - create mode 100644 include/netlink-private/socket.h - -diff --git a/include/Makefile.am b/include/Makefile.am -index b9487e0..d0ed008 100644 ---- a/include/Makefile.am -+++ b/include/Makefile.am -@@ -125,6 +125,7 @@ noinst_HEADERS = \ - linux/tc_ematch/tc_em_meta.h \ - netlink-private/genl.h \ - netlink-private/netlink.h \ -+ netlink-private/socket.h \ - netlink-private/tc.h \ - netlink-private/types.h \ - netlink-private/cache-api.h \ -diff --git a/include/netlink-private/socket.h b/include/netlink-private/socket.h -new file mode 100644 -index 0000000..86a440c ---- /dev/null -+++ b/include/netlink-private/socket.h -@@ -0,0 +1,31 @@ -+/* -+ * netlink-private/socket.h Private declarations for socket -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation version 2.1 -+ * of the License. -+ * -+ * Copyright (c) 2014 Thomas Graf -+ */ -+ -+#ifndef NETLINK_SOCKET_PRIV_H_ -+#define NETLINK_SOCKET_PRIV_H_ -+ -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+int _nl_socket_is_local_port_unspecified (struct nl_sock *sk); -+uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk); -+ -+void _nl_socket_used_ports_release_all(const uint32_t *used_ports); -+void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/include/netlink/utils.h b/include/netlink/utils.h -index 2094bb4..5b0d275 100644 ---- a/include/netlink/utils.h -+++ b/include/netlink/utils.h -@@ -90,6 +90,15 @@ enum { - NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE = 1, - #define NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE - -+ /** -+ * Indicate that the local port is unspecified until the user accesses -+ * it (via nl_socket_get_local_port()) or until nl_connect(). More importantly, -+ * if the port is left unspecified, nl_connect() will retry generating another -+ * port when bind() fails with ADDRINUSE. -+ */ -+ NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE = 4, -+#define NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE -+ - __NL_CAPABILITY_MAX - #define NL_CAPABILITY_MAX (__NL_CAPABILITY_MAX - 1) - }; -diff --git a/lib/nl.c b/lib/nl.c -index 565747a..37065d4 100644 ---- a/lib/nl.c -+++ b/lib/nl.c -@@ -26,6 +26,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -75,6 +76,16 @@ - * be closed automatically if any of the `exec` family functions succeed. - * This is essential for multi threaded programs. - * -+ * @note The local port (`nl_socket_get_local_port()`) is unspecified after -+ * creating a new socket. It only gets determined when accessing the -+ * port the first time or during `nl_connect()`. When nl_connect() -+ * fails during `bind()` due to `ADDRINUSE`, it will retry with -+ * different ports if the port is unspecified. Unless you want to enforce -+ * the use of a specific local port, don't access the local port (or -+ * reset it to `unspecified` by calling `nl_socket_set_local_port(sk, 0)`). -+ * This capability is indicated by -+ * `%NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE`. -+ * - * @see nl_socket_alloc() - * @see nl_close() - * -@@ -85,6 +96,7 @@ - int nl_connect(struct nl_sock *sk, int protocol) - { - int err, flags = 0; -+ int errsv; - socklen_t addrlen; - - #ifdef SOCK_CLOEXEC -@@ -96,7 +108,9 @@ int nl_connect(struct nl_sock *sk, int protocol) - - sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol); - if (sk->s_fd < 0) { -- err = -nl_syserr2nlerr(errno); -+ errsv = errno; -+ NL_DBG(4, "nl_connect(%p): socket() failed with %d\n", sk, errsv); -+ err = -nl_syserr2nlerr(errsv); - goto errout; - } - -@@ -106,11 +120,45 @@ int nl_connect(struct nl_sock *sk, int protocol) - goto errout; - } - -- err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local, -- sizeof(sk->s_local)); -- if (err < 0) { -- err = -nl_syserr2nlerr(errno); -- goto errout; -+ if (_nl_socket_is_local_port_unspecified (sk)) { -+ uint32_t port; -+ uint32_t used_ports[32] = { 0 }; -+ -+ while (1) { -+ port = _nl_socket_generate_local_port_no_release(sk); -+ -+ if (port == UINT32_MAX) { -+ NL_DBG(4, "nl_connect(%p): no more unused local ports.\n", sk); -+ _nl_socket_used_ports_release_all(used_ports); -+ err = -NLE_EXIST; -+ goto errout; -+ } -+ err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local, -+ sizeof(sk->s_local)); -+ if (err == 0) -+ break; -+ -+ errsv = errno; -+ if (errsv == EADDRINUSE) { -+ NL_DBG(4, "nl_connect(%p): local port %u already in use. Retry.\n", sk, (unsigned) port); -+ _nl_socket_used_ports_set(used_ports, port); -+ } else { -+ NL_DBG(4, "nl_connect(%p): bind() for port %u failed with %d\n", sk, (unsigned) port, errsv); -+ _nl_socket_used_ports_release_all(used_ports); -+ err = -nl_syserr2nlerr(errsv); -+ goto errout; -+ } -+ } -+ _nl_socket_used_ports_release_all(used_ports); -+ } else { -+ err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local, -+ sizeof(sk->s_local)); -+ if (err != 0) { -+ errsv = errno; -+ NL_DBG(4, "nl_connect(%p): bind() failed with %d\n", sk, errsv); -+ err = -nl_syserr2nlerr(errsv); -+ goto errout; -+ } - } - - addrlen = sizeof(sk->s_local); -@@ -405,7 +453,7 @@ void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg) - - nlh = nlmsg_hdr(msg); - if (nlh->nlmsg_pid == NL_AUTO_PORT) -- nlh->nlmsg_pid = sk->s_local.nl_pid; -+ nlh->nlmsg_pid = nl_socket_get_local_port(sk); - - if (nlh->nlmsg_seq == NL_AUTO_SEQ) - nlh->nlmsg_seq = sk->s_seq_next++; -diff --git a/lib/socket.c b/lib/socket.c -index f9e68ff..2d6a2d3 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -30,12 +30,15 @@ - #include "defs.h" - - #include -+#include - #include - #include - #include - #include - #include - -+#define NOEXPORT __attribute__ ((visibility ("hidden"))) -+ - static int default_cb = NL_CB_DEFAULT; - - static void __init init_default_cb(void) -@@ -96,17 +99,61 @@ static uint32_t generate_local_port(void) - static void release_local_port(uint32_t port) - { - int nr; -+ uint32_t mask; - - if (port == UINT32_MAX) - return; -- -+ -+ BUG_ON(port == 0); -+ - nr = port >> 22; -+ mask = 1UL << (nr % 32); -+ nr /= 32; - - nl_write_lock(&port_map_lock); -- used_ports_map[nr / 32] &= ~(1 << (nr % 32)); -+ BUG_ON((used_ports_map[nr] & mask) != mask); -+ used_ports_map[nr] &= ~mask; - nl_write_unlock(&port_map_lock); - } - -+/** \cond skip */ -+NOEXPORT -+void _nl_socket_used_ports_release_all(const uint32_t *used_ports) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ if (used_ports[i] != 0) { -+ nl_write_lock(&port_map_lock); -+ for (; i < 32; i++) { -+ BUG_ON((used_ports_map[i] & used_ports[i]) != used_ports[i]); -+ used_ports_map[i] &= ~(used_ports[i]); -+ } -+ nl_write_unlock(&port_map_lock); -+ return; -+ } -+ } -+} -+ -+NOEXPORT -+void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port) -+{ -+ int nr; -+ int32_t mask; -+ -+ nr = port >> 22; -+ mask = 1UL << (nr % 32); -+ nr /= 32; -+ -+ /* -+ BUG_ON(port == UINT32_MAX || port == 0 || (getpid() & 0x3FFFFF) != (port & 0x3FFFFF)); -+ BUG_ON(used_ports[nr] & mask); -+ */ -+ -+ used_ports[nr] |= mask; -+} -+/** \endcond */ -+ - /** - * @name Allocation - * @{ -@@ -125,7 +172,9 @@ static struct nl_sock *__alloc_socket(struct nl_cb *cb) - sk->s_local.nl_family = AF_NETLINK; - sk->s_peer.nl_family = AF_NETLINK; - sk->s_seq_expect = sk->s_seq_next = time(0); -- sk->s_local.nl_pid = generate_local_port(); -+ -+ /* the port is 0 (unspecified), meaning NL_OWN_PORT */ -+ sk->s_flags = NL_OWN_PORT; - - return sk; - } -@@ -255,6 +304,28 @@ void nl_socket_enable_auto_ack(struct nl_sock *sk) - - /** @} */ - -+/** \cond skip */ -+NOEXPORT -+int _nl_socket_is_local_port_unspecified(struct nl_sock *sk) -+{ -+ return (sk->s_local.nl_pid == 0); -+} -+ -+NOEXPORT -+uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk) -+{ -+ uint32_t port; -+ -+ /* reset the port to generate_local_port(), but do not release -+ * the previously generated port. */ -+ -+ port = generate_local_port(); -+ sk->s_flags &= ~NL_OWN_PORT; -+ sk->s_local.nl_pid = port; -+ return port; -+} -+/** \endcond */ -+ - /** - * @name Source Idenficiation - * @{ -@@ -262,6 +333,18 @@ void nl_socket_enable_auto_ack(struct nl_sock *sk) - - uint32_t nl_socket_get_local_port(const struct nl_sock *sk) - { -+ if (sk->s_local.nl_pid == 0) { -+ /* modify the const argument sk. This is justified, because -+ * nobody ever saw the local_port from externally. So, we -+ * initilize it on first use. -+ * -+ * Note that this also means that you cannot call this function -+ * from multiple threads without synchronization. But nl_sock -+ * is not automatically threadsafe anyway, so the user is not -+ * allowed to do that. -+ */ -+ return _nl_socket_generate_local_port_no_release((struct nl_sock *) sk); -+ } - return sk->s_local.nl_pid; - } - -@@ -270,27 +353,18 @@ uint32_t nl_socket_get_local_port(const struct nl_sock *sk) - * @arg sk Netlink socket. - * @arg port Local port identifier - * -- * Assigns a local port identifier to the socket. If port is 0 -- * a unique port identifier will be generated automatically. -+ * Assigns a local port identifier to the socket. -+ * -+ * If port is 0, the port is reset to 'unspecified' as it is after newly -+ * calling nl_socket_alloc(). -+ * Unspecified means, that the port will be generated automatically later -+ * on first use (either on nl_socket_get_local_port() or nl_connect()). - */ - void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port) - { -- if (port == 0) { -- port = generate_local_port(); -- /* -- * Release local port after generation of a new one to be -- * able to change local port using nl_socket_set_local_port(, 0) -- */ -- if (!(sk->s_flags & NL_OWN_PORT)) -- release_local_port(sk->s_local.nl_pid); -- else -- sk->s_flags &= ~NL_OWN_PORT; -- } else { -- if (!(sk->s_flags & NL_OWN_PORT)) -- release_local_port(sk->s_local.nl_pid); -- sk->s_flags |= NL_OWN_PORT; -- } -- -+ if (!(sk->s_flags & NL_OWN_PORT)) -+ release_local_port(sk->s_local.nl_pid); -+ sk->s_flags |= NL_OWN_PORT; - sk->s_local.nl_pid = port; - } - -diff --git a/lib/utils.c b/lib/utils.c -index 44350c3..5149e07 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -1138,7 +1138,7 @@ int nl_has_capability (int capability) - NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE, - 0, - 0, -- 0, -+ NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE, - 0, - 0, - 0, --- -2.4.3 - - -From 4177e716532b3263abb90c5a2afa6c60f37937e3 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 9 Apr 2014 12:08:53 +0200 -Subject: [PATCH 06/11] lib/socket: randomize the generated local port - -Instead of always trying the same order of ports when -looking for an unused port, randomize the order (naively). - -As libnl-1 uses the same function, it is likely that two applications -that are using both libraries generate the same ports. By chosing a -different order how to select the local port, the chances are smaller -for this to happen (however, it cannot avoid it entirely. The user -and/or libnl3 still has to cope with the situation, that somebody -else might already use the port). - -Signed-off-by: Thomas Haller -(cherry picked from commit 1f734a8f892abcd3f81637df4a089155aca1b66a) ---- - lib/socket.c | 29 ++++++++++++++++++++++++++--- - 1 file changed, 26 insertions(+), 3 deletions(-) - -diff --git a/lib/socket.c b/lib/socket.c -index 2d6a2d3..01cf2a2 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -64,16 +64,39 @@ static NL_RW_LOCK(port_map_lock); - - static uint32_t generate_local_port(void) - { -- int i, n; -+ int i, j, n, m; -+ static uint16_t idx_state = 0; - uint32_t pid = getpid() & 0x3FFFFF; - - nl_write_lock(&port_map_lock); - -- for (i = 0; i < 32; i++) { -+ if (idx_state == 0) { -+ uint32_t t = time(NULL); -+ -+ /* from time to time (on average each 2^15 calls), the idx_state will -+ * be zero again. No problem, just "seed" anew with time(). */ -+ idx_state = t ^ (t >> 16) ^ 0x3047; -+ } else -+ idx_state = idx_state + 20011; /* add prime number */ -+ -+ i = idx_state >> 5; -+ n = idx_state; -+ for (j = 0; j < 32; j++) { -+ /* walk the index somewhat randomized, with always leaving the block -+ * #0 as last. The reason is that libnl-1 will start at block #0, -+ * so just leave the first 32 ports preferably for libnl-1 owned sockets -+ * (this is relevant only if the applications ends up using both versions -+ * of the library and doesn't hurt otherwise). */ -+ if (j == 31) -+ i = 0; -+ else -+ i = (((i-1) + 7) % 31) + 1; -+ - if (used_ports_map[i] == 0xFFFFFFFF) - continue; - -- for (n = 0; n < 32; n++) { -+ for (m = 0; m < 32; m++) { -+ n = (n + 13) % 32; - if (1UL & (used_ports_map[i] >> n)) - continue; - --- -2.4.3 - - -From 1e7b7e5472fd3ee2ba69d2029bac02e4cf4148a1 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 5 Mar 2015 08:46:31 +0100 -Subject: [PATCH 07/11] lib/socket: remove NL_SOCK_BUFSIZE_SET socket flag - -The flag was not actually used. - -NL_SOCK_BUFSIZE_SET was only set by nl_socket_set_buffer_size(). -Note that you can only call nl_socket_set_buffer_size() on a socket that -is already connected via nl_connect(). - -On first call, nl_connect() would always see NL_SOCK_BUFSIZE_SET unset, and -call nl_socket_set_buffer_size(). - -Since the flag was never unset, when trying to connect a socket a second -time, we would not set the buffer size again. Which was a bug. - -Signed-off-by: Thomas Haller -(cherry picked from commit 15824e42730980132a9e52d0c9d6929808e5ae78) ---- - include/netlink-private/types.h | 1 - - lib/nl.c | 8 +++----- - lib/socket.c | 2 -- - 3 files changed, 3 insertions(+), 8 deletions(-) - -diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h -index 72570c4..70b95c1 100644 ---- a/include/netlink-private/types.h -+++ b/include/netlink-private/types.h -@@ -19,7 +19,6 @@ - #include - #include - --#define NL_SOCK_BUFSIZE_SET (1<<0) - #define NL_SOCK_PASSCRED (1<<1) - #define NL_OWN_PORT (1<<2) - #define NL_MSG_PEEK (1<<3) -diff --git a/lib/nl.c b/lib/nl.c -index 37065d4..69d5f8f 100644 ---- a/lib/nl.c -+++ b/lib/nl.c -@@ -114,11 +114,9 @@ int nl_connect(struct nl_sock *sk, int protocol) - goto errout; - } - -- if (!(sk->s_flags & NL_SOCK_BUFSIZE_SET)) { -- err = nl_socket_set_buffer_size(sk, 0, 0); -- if (err < 0) -- goto errout; -- } -+ err = nl_socket_set_buffer_size(sk, 0, 0); -+ if (err < 0) -+ goto errout; - - if (_nl_socket_is_local_port_unspecified (sk)) { - uint32_t port; -diff --git a/lib/socket.c b/lib/socket.c -index 01cf2a2..4741719 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -692,8 +692,6 @@ int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf) - if (err < 0) - return -nl_syserr2nlerr(errno); - -- sk->s_flags |= NL_SOCK_BUFSIZE_SET; -- - return 0; - } - --- -2.4.3 - - -From 38a6d5589e7d0cfe44331687ad76271f35ab7e12 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 5 Mar 2015 10:50:04 +0100 -Subject: [PATCH 08/11] lib/nl: preserve s_local if nl_connect() fails - -s_local.nl_pid is used to track the generated port unless NL_OWN_PORT is set. -Ensure that getsockname() doesn't overwrite the value and possibly reset -the local port manually to release the generated port. - -Signed-off-by: Thomas Haller -(cherry picked from commit 9614acf4c4354892b5b734cace4778acfc019999) ---- - lib/nl.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/lib/nl.c b/lib/nl.c -index 69d5f8f..b7a9ab4 100644 ---- a/lib/nl.c -+++ b/lib/nl.c -@@ -98,6 +98,7 @@ int nl_connect(struct nl_sock *sk, int protocol) - int err, flags = 0; - int errsv; - socklen_t addrlen; -+ struct sockaddr_nl local = { 0 }; - - #ifdef SOCK_CLOEXEC - flags |= SOCK_CLOEXEC; -@@ -159,32 +160,39 @@ int nl_connect(struct nl_sock *sk, int protocol) - } - } - -- addrlen = sizeof(sk->s_local); -- err = getsockname(sk->s_fd, (struct sockaddr *) &sk->s_local, -+ addrlen = sizeof(local); -+ err = getsockname(sk->s_fd, (struct sockaddr *) &local, - &addrlen); - if (err < 0) { - err = -nl_syserr2nlerr(errno); - goto errout; - } - -- if (addrlen != sizeof(sk->s_local)) { -+ if (addrlen != sizeof(local)) { - err = -NLE_NOADDR; - goto errout; - } - -- if (sk->s_local.nl_family != AF_NETLINK) { -+ if (local.nl_family != AF_NETLINK) { - err = -NLE_AF_NOSUPPORT; - goto errout; - } - -+ if (sk->s_local.nl_pid != local.nl_pid) { -+ /* strange, the port id is not as expected. Set the local -+ * port id to release a possibly generated port and un-own -+ * it. */ -+ nl_socket_set_local_port (sk, local.nl_pid); -+ } -+ sk->s_local = local; - sk->s_proto = protocol; - - return 0; - errout: -- if (sk->s_fd != -1) { -- close(sk->s_fd); -- sk->s_fd = -1; -- } -+ if (sk->s_fd != -1) { -+ close(sk->s_fd); -+ sk->s_fd = -1; -+ } - - return err; - } --- -2.4.3 - - -From 3c00a3b7d518cee0ac2092487f38ff2e75b8728e Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Fri, 10 Jul 2015 14:58:50 +0200 -Subject: [PATCH 09/11] socket: clear port when unable to generate local port - -When running out of local ports, _nl_socket_generate_local_port_no_release() -would leave the socket with port UINT32_MAX. That means if nl_connect() -fails due to out-of-ports, it would leave the port id assigned to an -invalid port and the socket instance was not re-usable until the user -called nl_socket_set_local_port(). Fix that by resetting the local port -to zero. - -Thereby, also change generate_local_port() to return zero when -running out of ports. zero is a more natural value for ~no port found~. -It also matches the port that _nl_socket_generate_local_port_no_release() -uses when failing to generate a port. - -Also ensure that zero cannot be returned as valid port by generate_local_port(). -Arguably, that would only be possible if (getpid() & 0x3FFFFF) -returns zero. Just be extra cautious. - -Signed-off-by: Thomas Haller -(cherry picked from commit f78c3e82398a505ccf7e297b4021f23559ad8977) ---- - lib/nl.c | 2 +- - lib/socket.c | 30 ++++++++++++++++++++++-------- - 2 files changed, 23 insertions(+), 9 deletions(-) - -diff --git a/lib/nl.c b/lib/nl.c -index b7a9ab4..20de342 100644 ---- a/lib/nl.c -+++ b/lib/nl.c -@@ -126,7 +126,7 @@ int nl_connect(struct nl_sock *sk, int protocol) - while (1) { - port = _nl_socket_generate_local_port_no_release(sk); - -- if (port == UINT32_MAX) { -+ if (port == 0) { - NL_DBG(4, "nl_connect(%p): no more unused local ports.\n", sk); - _nl_socket_used_ports_release_all(used_ports); - err = -NLE_EXIST; -diff --git a/lib/socket.c b/lib/socket.c -index 4741719..4f05d09 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -108,7 +108,9 @@ static uint32_t generate_local_port(void) - - nl_write_unlock(&port_map_lock); - -- return pid + (((uint32_t)n) << 22); -+ /* ensure we don't return zero. */ -+ pid = pid + (((uint32_t)n) << 22); -+ return pid ? pid : 1024; - } - } - -@@ -116,7 +118,7 @@ static uint32_t generate_local_port(void) - - /* Out of sockets in our own PID namespace, what to do? FIXME */ - NL_DBG(1, "Warning: Ran out of unique local port namespace\n"); -- return UINT32_MAX; -+ return 0; - } - - static void release_local_port(uint32_t port) -@@ -124,9 +126,6 @@ static void release_local_port(uint32_t port) - int nr; - uint32_t mask; - -- if (port == UINT32_MAX) -- return; -- - BUG_ON(port == 0); - - nr = port >> 22; -@@ -169,7 +168,7 @@ void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port) - nr /= 32; - - /* -- BUG_ON(port == UINT32_MAX || port == 0 || (getpid() & 0x3FFFFF) != (port & 0x3FFFFF)); -+ BUG_ON(port == 0 || (getpid() & 0x3FFFFF) != (port & 0x3FFFFF)); - BUG_ON(used_ports[nr] & mask); - */ - -@@ -343,8 +342,13 @@ uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk) - * the previously generated port. */ - - port = generate_local_port(); -- sk->s_flags &= ~NL_OWN_PORT; - sk->s_local.nl_pid = port; -+ if (port == 0) { -+ /* failed to find an unsed port. Restore the socket to have an -+ * unspecified port. */ -+ sk->s_flags |= NL_OWN_PORT; -+ } else -+ sk->s_flags &= ~NL_OWN_PORT; - return port; - } - /** \endcond */ -@@ -357,6 +361,8 @@ uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk) - uint32_t nl_socket_get_local_port(const struct nl_sock *sk) - { - if (sk->s_local.nl_pid == 0) { -+ struct nl_sock *sk_mutable = (struct nl_sock *) sk; -+ - /* modify the const argument sk. This is justified, because - * nobody ever saw the local_port from externally. So, we - * initilize it on first use. -@@ -366,7 +372,15 @@ uint32_t nl_socket_get_local_port(const struct nl_sock *sk) - * is not automatically threadsafe anyway, so the user is not - * allowed to do that. - */ -- return _nl_socket_generate_local_port_no_release((struct nl_sock *) sk); -+ sk_mutable->s_local.nl_pid = generate_local_port(); -+ if (sk_mutable->s_local.nl_pid == 0) { -+ /* could not generate a local port. Assign UINT32_MAX to preserve -+ * backward compatibility. A user who cares can clear that anyway -+ * with nl_socket_set_local_port(). */ -+ sk_mutable->s_local.nl_pid = UINT32_MAX; -+ sk_mutable->s_flags |= NL_OWN_PORT; -+ } else -+ sk_mutable->s_flags &= ~NL_OWN_PORT; - } - return sk->s_local.nl_pid; - } --- -2.4.3 - - -From eb5e052347de18e1133d3cbf507e31d05cd5db6e Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Fri, 10 Jul 2015 14:58:51 +0200 -Subject: [PATCH 10/11] socket: add fallback for nl_connect() by trying to bind - to unspecified local port - -libnl allows the user to explicitly set the local port before connecting -the socket. A more convenient way is to leave the local port unspecified -and let libnl generate a port id. - -As it is, generate_local_port() would try at most 1024 ports, that -means if a user tries to connect more sockets, the automatism will -fail. - -Kernel also supports choosing the local port itself (via netlink_autobind()). -So, this could be fixed by always leaving the port unspecified and let -kernel decide on the port. For that we could entirely drop generate_local_port(). - -There are however problems with that: - - - it is unclear why generate_local_port() was even introduced in the - first place instead of always relying kernel. This code already - appeared in libnl-1, so maybe there was a good reason for it or - it is necessary on some kernel versions. - - - The deprecated libnl-1 library also uses a form of generate_local_port(). - Its first guess would always be getpid(), but the problem is that - it would not retry on EADDRINUSE. Currently libnl-3 generates ports in - a different sequence and will not generate a conflicting port (until it - already exhausted 1016 other ports). - Hence, currently if your application uses libnl1 and libnl3 - together, the automatism might just work without conflicts - (commit 1f734a8f892abcd3f81637df4a089155aca1b66a). - Accidently, kernel/netlink_autobind() also first tries the process - id as port. That means, if we change libnl-3 to leave the decision - to kernel, and - - the application connects sockets both via libnl-1 and libnl-3 - - and the libnl-3 socket happens to connect first - then the libnl-1 socket would fail to connect without retrying - another port. - - - Removing generate_local_port() entirely changes behavior in the - following case: - - sk = nl_socket_alloc(); - /* accessing local port before connecting the socket used to - * freeze the local port to the generated value. */ - port = nl_socket_get_local_port(sk); - nl_connect(sk, NETLINK_...); - -Maybe the issues are minor and it would simplify the code just to get -rid of the cruft. But instead fix the issue without changing behavior. -Just keep trying with generate_local_port() first, before fallback to -kernel. - -Reported-by: Julien Courtat -Signed-off-by: Thomas Haller - -http://lists.infradead.org/pipermail/libnl/2015-June/001889.html -(cherry picked from commit 96e1e5bdc2e803700055395cc3c428fa2525d1ca) ---- - lib/nl.c | 29 ++++++++++++++++++----------- - lib/socket.c | 3 --- - 2 files changed, 18 insertions(+), 14 deletions(-) - -diff --git a/lib/nl.c b/lib/nl.c -index 20de342..bbd1c14 100644 ---- a/lib/nl.c -+++ b/lib/nl.c -@@ -99,6 +99,7 @@ int nl_connect(struct nl_sock *sk, int protocol) - int errsv; - socklen_t addrlen; - struct sockaddr_nl local = { 0 }; -+ int try_bind = 1; - - #ifdef SOCK_CLOEXEC - flags |= SOCK_CLOEXEC; -@@ -122,20 +123,26 @@ int nl_connect(struct nl_sock *sk, int protocol) - if (_nl_socket_is_local_port_unspecified (sk)) { - uint32_t port; - uint32_t used_ports[32] = { 0 }; -+ int ntries = 0; - - while (1) { -+ if (ntries++ > 5) { -+ /* try only a few times. We hit this only if many ports are already in -+ * use but allocated *outside* libnl/generate_local_port(). */ -+ nl_socket_set_local_port (sk, 0); -+ break; -+ } -+ - port = _nl_socket_generate_local_port_no_release(sk); -+ if (port == 0) -+ break; - -- if (port == 0) { -- NL_DBG(4, "nl_connect(%p): no more unused local ports.\n", sk); -- _nl_socket_used_ports_release_all(used_ports); -- err = -NLE_EXIST; -- goto errout; -- } - err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local, - sizeof(sk->s_local)); -- if (err == 0) -+ if (err == 0) { -+ try_bind = 0; - break; -+ } - - errsv = errno; - if (errsv == EADDRINUSE) { -@@ -149,7 +156,8 @@ int nl_connect(struct nl_sock *sk, int protocol) - } - } - _nl_socket_used_ports_release_all(used_ports); -- } else { -+ } -+ if (try_bind) { - err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local, - sizeof(sk->s_local)); - if (err != 0) { -@@ -179,9 +187,8 @@ int nl_connect(struct nl_sock *sk, int protocol) - } - - if (sk->s_local.nl_pid != local.nl_pid) { -- /* strange, the port id is not as expected. Set the local -- * port id to release a possibly generated port and un-own -- * it. */ -+ /* The port id is different. That can happen if the port id was zero -+ * and kernel assigned a local port. */ - nl_socket_set_local_port (sk, local.nl_pid); - } - sk->s_local = local; -diff --git a/lib/socket.c b/lib/socket.c -index 4f05d09..6e2aaf5 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -115,9 +115,6 @@ static uint32_t generate_local_port(void) - } - - nl_write_unlock(&port_map_lock); -- -- /* Out of sockets in our own PID namespace, what to do? FIXME */ -- NL_DBG(1, "Warning: Ran out of unique local port namespace\n"); - return 0; - } - --- -2.4.3 - - -From 9d7d3895fe979ccffab350d2f71793982b060c8b Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Mon, 24 Aug 2015 17:57:16 +0200 -Subject: [PATCH 11/11] socket: fix assertion in nl_connect() when all ports - are already in use - -When generating a port fails a few times (because they are already in used -outside of libnl's knowledge), we would back off generating a local -port and instead let kernel decide. - -There was however a bug in nl_connect() that caused an assertion: - - BUG at file position socket.c:147:_nl_socket_used_ports_release_all - app: socket.c:147: _nl_socket_used_ports_release_all: Assertion `0' failed. - -Fixes: 96e1e5bdc2e803700055395cc3c428fa2525d1ca -(cherry picked from commit eaa75b7c7d3e6a4df1a2e7591ae295acfae3f73e) ---- - include/netlink-private/socket.h | 2 +- - lib/nl.c | 4 ++-- - lib/socket.c | 7 +++++-- - 3 files changed, 8 insertions(+), 5 deletions(-) - -diff --git a/include/netlink-private/socket.h b/include/netlink-private/socket.h -index 86a440c..9ceecfd 100644 ---- a/include/netlink-private/socket.h -+++ b/include/netlink-private/socket.h -@@ -19,7 +19,7 @@ extern "C" { - #endif - - int _nl_socket_is_local_port_unspecified (struct nl_sock *sk); --uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk); -+uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other); - - void _nl_socket_used_ports_release_all(const uint32_t *used_ports); - void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port); -diff --git a/lib/nl.c b/lib/nl.c -index bbd1c14..db000a3 100644 ---- a/lib/nl.c -+++ b/lib/nl.c -@@ -129,11 +129,11 @@ int nl_connect(struct nl_sock *sk, int protocol) - if (ntries++ > 5) { - /* try only a few times. We hit this only if many ports are already in - * use but allocated *outside* libnl/generate_local_port(). */ -- nl_socket_set_local_port (sk, 0); -+ _nl_socket_set_local_port_no_release (sk, 0); - break; - } - -- port = _nl_socket_generate_local_port_no_release(sk); -+ port = _nl_socket_set_local_port_no_release(sk, 1); - if (port == 0) - break; - -diff --git a/lib/socket.c b/lib/socket.c -index 6e2aaf5..d3eab60 100644 ---- a/lib/socket.c -+++ b/lib/socket.c -@@ -331,14 +331,17 @@ int _nl_socket_is_local_port_unspecified(struct nl_sock *sk) - } - - NOEXPORT --uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk) -+uint32_t _nl_socket_set_local_port_no_release(struct nl_sock *sk, int generate_other) - { - uint32_t port; - - /* reset the port to generate_local_port(), but do not release - * the previously generated port. */ - -- port = generate_local_port(); -+ if (generate_other) -+ port = generate_local_port(); -+ else -+ port = 0; - sk->s_local.nl_pid = port; - if (port == 0) { - /* failed to find an unsed port. Restore the socket to have an --- -2.4.3 - diff --git a/SOURCES/0011-support-IFLA_LINK_NETNSID-rh1255050.patch b/SOURCES/0011-support-IFLA_LINK_NETNSID-rh1255050.patch deleted file mode 100644 index 0ddd772..0000000 --- a/SOURCES/0011-support-IFLA_LINK_NETNSID-rh1255050.patch +++ /dev/null @@ -1,539 +0,0 @@ -From 42d8ecc85940e86213d194ae81bb74d174726084 Mon Sep 17 00:00:00 2001 -From: Thomas Graf -Date: Sat, 9 Nov 2013 10:04:35 +0100 -Subject: [PATCH 1/4] link: Fall back to global provisioned link cache if - object is not a cache resident - -... if that fails, print ifindices directly. - -Reported-by: Dan Williams -Signed-off-by: Thomas Graf -(cherry picked from commit 04040110cde4966e287e8d04a8ebea2855c89a79) ---- - lib/route/link.c | 31 +++++++++++++++++++++++-------- - 1 file changed, 23 insertions(+), 8 deletions(-) - -diff --git a/lib/route/link.c b/lib/route/link.c -index 1f27247..49a8b65 100644 ---- a/lib/route/link.c -+++ b/lib/route/link.c -@@ -599,6 +599,12 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) - char buf[128]; - struct nl_cache *cache = obj->ce_cache; - struct rtnl_link *link = (struct rtnl_link *) obj; -+ int fetched_cache = 0; -+ -+ if (!cache) { -+ cache = nl_cache_mngt_require_safe("route/link"); -+ fetched_cache = 1; -+ } - - nl_dump_line(p, "%s %s ", link->l_name, - nl_llproto2str(link->l_arptype, buf, sizeof(buf))); -@@ -607,10 +613,13 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) - nl_dump(p, "%s ", nl_addr2str(link->l_addr, buf, sizeof(buf))); - - if (link->ce_mask & LINK_ATTR_MASTER) { -- struct rtnl_link *master = rtnl_link_get(cache, link->l_master); -- nl_dump(p, "master %s ", master ? master->l_name : "inv"); -- if (master) -- rtnl_link_put(master); -+ if (cache) { -+ struct rtnl_link *master = rtnl_link_get(cache, link->l_master); -+ nl_dump(p, "master %s ", master ? master->l_name : "inv"); -+ if (master) -+ rtnl_link_put(master); -+ } else -+ nl_dump(p, "master %d ", link->l_master); - } - - rtnl_link_flags2str(link->l_flags, buf, sizeof(buf)); -@@ -618,10 +627,13 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) - nl_dump(p, "<%s> ", buf); - - if (link->ce_mask & LINK_ATTR_LINK) { -- struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); -- nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE"); -- if (ll) -- rtnl_link_put(ll); -+ if (cache) { -+ struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); -+ nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE"); -+ if (ll) -+ rtnl_link_put(ll); -+ } else -+ nl_dump(p, "slave-of %d ", link->l_link); - } - - if (link->ce_mask & LINK_ATTR_GROUP) -@@ -633,6 +645,9 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) - do_foreach_af(link, af_dump_line, p); - - nl_dump(p, "\n"); -+ -+ if (fetched_cache) -+ nl_cache_put(cache); - } - - static void link_dump_details(struct nl_object *obj, struct nl_dump_params *p) --- -2.4.3 - - -From a67cd6a68c16292f724269bc8da5f2f2501cacb7 Mon Sep 17 00:00:00 2001 -From: Cong Wang -Date: Tue, 9 Jun 2015 21:53:09 -0700 -Subject: [PATCH 2/4] include/linux: update copy of kernel header "if_link.h" - -Taken from upstream kernel commit b953c0d234bc72e8489d3bf51a276c5c4ec85345 -(v4.1), file 'include/uapi/linux/if_link.h' (after `make headers_install`). - -Signed-off-by: Thomas Haller -(cherry picked from commit f808b84a5de7c33694d362807e897d8a064b9bcd) ---- - include/linux/if_link.h | 69 +++++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 64 insertions(+), 5 deletions(-) - -diff --git a/include/linux/if_link.h b/include/linux/if_link.h -index ff95760..3d0d613 100644 ---- a/include/linux/if_link.h -+++ b/include/linux/if_link.h -@@ -1,5 +1,5 @@ --#ifndef _UAPI_LINUX_IF_LINK_H --#define _UAPI_LINUX_IF_LINK_H -+#ifndef _LINUX_IF_LINK_H -+#define _LINUX_IF_LINK_H - - #include - #include -@@ -145,6 +145,9 @@ enum { - IFLA_CARRIER, - IFLA_PHYS_PORT_ID, - IFLA_CARRIER_CHANGES, -+ IFLA_PHYS_SWITCH_ID, -+ IFLA_LINK_NETNSID, -+ IFLA_PHYS_PORT_NAME, - __IFLA_MAX - }; - -@@ -152,10 +155,8 @@ enum { - #define IFLA_MAX (__IFLA_MAX - 1) - - /* backwards compatibility for userspace */ --#ifndef __KERNEL__ - #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) - #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) --#endif - - enum { - IFLA_INET_UNSPEC, -@@ -213,8 +214,24 @@ enum { - enum in6_addr_gen_mode { - IN6_ADDR_GEN_MODE_EUI64, - IN6_ADDR_GEN_MODE_NONE, -+ IN6_ADDR_GEN_MODE_STABLE_PRIVACY, - }; - -+/* Bridge section */ -+ -+enum { -+ IFLA_BR_UNSPEC, -+ IFLA_BR_FORWARD_DELAY, -+ IFLA_BR_HELLO_TIME, -+ IFLA_BR_MAX_AGE, -+ IFLA_BR_AGEING_TIME, -+ IFLA_BR_STP_STATE, -+ IFLA_BR_PRIORITY, -+ __IFLA_BR_MAX, -+}; -+ -+#define IFLA_BR_MAX (__IFLA_BR_MAX - 1) -+ - enum { - BRIDGE_MODE_UNSPEC, - BRIDGE_MODE_HAIRPIN, -@@ -231,6 +248,9 @@ enum { - IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ - IFLA_BRPORT_LEARNING, /* mac learning */ - IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ -+ IFLA_BRPORT_PROXYARP, /* proxy ARP */ -+ IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */ -+ IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */ - __IFLA_BRPORT_MAX - }; - #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -@@ -291,6 +311,10 @@ enum { - IFLA_MACVLAN_UNSPEC, - IFLA_MACVLAN_MODE, - IFLA_MACVLAN_FLAGS, -+ IFLA_MACVLAN_MACADDR_MODE, -+ IFLA_MACVLAN_MACADDR, -+ IFLA_MACVLAN_MACADDR_DATA, -+ IFLA_MACVLAN_MACADDR_COUNT, - __IFLA_MACVLAN_MAX, - }; - -@@ -301,10 +325,33 @@ enum macvlan_mode { - MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */ - MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */ - MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */ -+ MACVLAN_MODE_SOURCE = 16,/* use source MAC address list to assign */ -+}; -+ -+enum macvlan_macaddr_mode { -+ MACVLAN_MACADDR_ADD, -+ MACVLAN_MACADDR_DEL, -+ MACVLAN_MACADDR_FLUSH, -+ MACVLAN_MACADDR_SET, - }; - - #define MACVLAN_FLAG_NOPROMISC 1 - -+/* IPVLAN section */ -+enum { -+ IFLA_IPVLAN_UNSPEC, -+ IFLA_IPVLAN_MODE, -+ __IFLA_IPVLAN_MAX -+}; -+ -+#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) -+ -+enum ipvlan_mode { -+ IPVLAN_MODE_L2 = 0, -+ IPVLAN_MODE_L3, -+ IPVLAN_MODE_MAX -+}; -+ - /* VXLAN section */ - enum { - IFLA_VXLAN_UNSPEC, -@@ -328,6 +375,10 @@ enum { - IFLA_VXLAN_UDP_CSUM, - IFLA_VXLAN_UDP_ZERO_CSUM6_TX, - IFLA_VXLAN_UDP_ZERO_CSUM6_RX, -+ IFLA_VXLAN_REMCSUM_TX, -+ IFLA_VXLAN_REMCSUM_RX, -+ IFLA_VXLAN_GBP, -+ IFLA_VXLAN_REMCSUM_NOPARTIAL, - __IFLA_VXLAN_MAX - }; - #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) -@@ -412,6 +463,9 @@ enum { - IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ - IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ - IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */ -+ IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query -+ * on/off switch -+ */ - __IFLA_VF_MAX, - }; - -@@ -456,6 +510,11 @@ struct ifla_vf_link_state { - __u32 link_state; - }; - -+struct ifla_vf_rss_query_en { -+ __u32 vf; -+ __u32 setting; -+}; -+ - /* VF ports management section - * - * Nested layout of set/get msg is: -@@ -561,4 +620,4 @@ enum { - - #define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1) - --#endif /* _UAPI_LINUX_IF_LINK_H */ -+#endif /* _LINUX_IF_LINK_H */ --- -2.4.3 - - -From f348f1be682ea7be2d6953162d618c0b8f69e2ab Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Fri, 14 Aug 2015 17:32:38 +0200 -Subject: [PATCH 3/4] route/link: add support for IFLA_LINK_NETNSID - -Signed-off-by: Thomas Haller -(cherry picked from commit 66aab65595fb20bf166936fcfa4c8568b58f7f68) ---- - include/netlink-private/types.h | 3 ++- - include/netlink/route/link.h | 14 ++++++++++++ - lib/route/link.c | 49 ++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 64 insertions(+), 2 deletions(-) - -diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h -index 70b95c1..598e79e 100644 ---- a/include/netlink-private/types.h -+++ b/include/netlink-private/types.h -@@ -157,8 +157,9 @@ struct rtnl_link - uint32_t l_index; - uint32_t l_flags; - uint32_t l_change; -- uint32_t l_mtu; -+ uint32_t l_mtu; - uint32_t l_link; -+ uint32_t l_link_netnsid; - uint32_t l_txqlen; - uint32_t l_weight; - uint32_t l_master; -diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h -index 2d061be..ca37f66 100644 ---- a/include/netlink/route/link.h -+++ b/include/netlink/route/link.h -@@ -201,6 +201,20 @@ extern uint8_t rtnl_link_get_operstate(struct rtnl_link *); - extern void rtnl_link_set_linkmode(struct rtnl_link *, uint8_t); - extern uint8_t rtnl_link_get_linkmode(struct rtnl_link *); - -+#ifdef NL_RHEL7_ENABLE_LINK_NETNSID -+/* The API for IFLA_LINK_NETNSID was backported from upstream to -+ * RHEL-7 (https://bugzilla.redhat.com/show_bug.cgi?id=1255050). -+ * Using backported API can cause problems when upgrading -+ * or downgrading the libnl package or when the user chooses to -+ * compile libnl from upstream source. -+ * -+ * Only use it if you understand the consequences and are willing -+ * to cope with them. -+ * */ -+int rtnl_link_set_link_netnsid(struct rtnl_link *link, uint32_t link_netnsid); -+int rtnl_link_get_link_netnsid(const struct rtnl_link *link, uint32_t *out_link_netnsid); -+#endif -+ - extern const char * rtnl_link_get_ifalias(struct rtnl_link *); - extern void rtnl_link_set_ifalias(struct rtnl_link *, const char *); - -diff --git a/lib/route/link.c b/lib/route/link.c -index 49a8b65..d914fd5 100644 ---- a/lib/route/link.c -+++ b/lib/route/link.c -@@ -57,6 +57,7 @@ - #define LINK_ATTR_CARRIER (1 << 25) - #define LINK_ATTR_PROTINFO (1 << 26) - #define LINK_ATTR_AF_SPEC (1 << 27) -+#define LINK_ATTR_LINK_NETNSID (1 << 31) - - static struct nl_cache_ops rtnl_link_ops; - static struct nl_object_ops link_obj_ops; -@@ -443,6 +444,11 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, - link->ce_mask |= LINK_ATTR_LINK; - } - -+ if (tb[IFLA_LINK_NETNSID]) { -+ link->l_link_netnsid = nla_get_u32(tb[IFLA_LINK_NETNSID]); -+ link->ce_mask |= LINK_ATTR_LINK_NETNSID; -+ } -+ - if (tb[IFLA_WEIGHT]) { - link->l_weight = nla_get_u32(tb[IFLA_WEIGHT]); - link->ce_mask |= LINK_ATTR_WEIGHT; -@@ -627,7 +633,8 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) - nl_dump(p, "<%s> ", buf); - - if (link->ce_mask & LINK_ATTR_LINK) { -- if (cache) { -+ if ( cache -+ && !(link->ce_mask & LINK_ATTR_LINK_NETNSID)) { - struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); - nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE"); - if (ll) -@@ -635,6 +642,8 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) - } else - nl_dump(p, "slave-of %d ", link->l_link); - } -+ if (link->ce_mask & LINK_ATTR_LINK_NETNSID) -+ nl_dump(p, "link-netnsid %u ", link->l_link_netnsid); - - if (link->ce_mask & LINK_ATTR_GROUP) - nl_dump(p, "group %u ", link->l_group); -@@ -858,6 +867,7 @@ static int link_compare(struct nl_object *_a, struct nl_object *_b, - diff |= LINK_DIFF(IFINDEX, a->l_index != b->l_index); - diff |= LINK_DIFF(MTU, a->l_mtu != b->l_mtu); - diff |= LINK_DIFF(LINK, a->l_link != b->l_link); -+ diff |= LINK_DIFF(LINK_NETNSID, a->l_link_netnsid != b->l_link_netnsid); - diff |= LINK_DIFF(TXQLEN, a->l_txqlen != b->l_txqlen); - diff |= LINK_DIFF(WEIGHT, a->l_weight != b->l_weight); - diff |= LINK_DIFF(MASTER, a->l_master != b->l_master); -@@ -1238,6 +1248,9 @@ static int build_link_msg(int cmd, struct ifinfomsg *hdr, - if (link->ce_mask & LINK_ATTR_LINK) - NLA_PUT_U32(msg, IFLA_LINK, link->l_link); - -+ if (link->ce_mask & LINK_ATTR_LINK_NETNSID) -+ NLA_PUT_U32(msg, IFLA_LINK_NETNSID, link->l_link_netnsid); -+ - if (link->ce_mask & LINK_ATTR_MASTER) - NLA_PUT_U32(msg, IFLA_MASTER, link->l_master); - -@@ -1894,6 +1907,40 @@ int rtnl_link_get_link(struct rtnl_link *link) - } - - /** -+ * Set the netnsid of the link -+ * @arg link Link object -+ * @link_netnsid the netnsid to set -+ * -+ * Sets the IFLA_LINK_NETNSID attribute of the link -+ * @returns 0 on success -+ */ -+int rtnl_link_set_link_netnsid(struct rtnl_link *link, uint32_t link_netnsid) -+{ -+ link->l_link_netnsid = link_netnsid; -+ link->ce_mask |= LINK_ATTR_LINK_NETNSID; -+ return 0; -+} -+ -+/** -+ * Get the netnsid of the link -+ * @arg link Link object -+ * @out_link_netnsid the netnsid -+ * -+ * Gets the IFLA_LINK_NETNSID attribute of the link -+ * or returns an error if the value is unset. -+ * -+ * @returns 0 on success -+ */ -+int rtnl_link_get_link_netnsid(const struct rtnl_link *link, uint32_t *out_link_netnsid) -+{ -+ if (!(link->ce_mask & LINK_ATTR_LINK_NETNSID)) -+ return -NLE_INVAL; -+ -+ *out_link_netnsid = link->l_link_netnsid; -+ return 0; -+} -+ -+/** - * Set master link of link object - * @arg link Link object - * @arg ifindex Interface index of master link --- -2.4.3 - - -From 7b4336d26a83d5de10bbaf67804400995848a51c Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Fri, 14 Aug 2015 17:32:36 +0200 -Subject: [PATCH 4/4] route/link: make link_netnsid argument (signed) int32_t - -Fixes: 66aab65595fb20bf166936fcfa4c8568b58f7f68 - -Signed-off-by: Thomas Haller -(cherry picked from commit 2fc97e66e7f509e89f36aa601939c314bdfe6c08) - -[thaller@redhat.com: while backporting, the patch was modified and -partially merged with commit 7bb956501ccd58ed3bbffc59de996f056e178683. -Instead of backporting new API for s32 attributes, it was defined locally] ---- - include/netlink-private/types.h | 2 +- - include/netlink/route/link.h | 4 ++-- - lib/route/link.c | 32 +++++++++++++++++++++++++++----- - 3 files changed, 30 insertions(+), 8 deletions(-) - -diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h -index 598e79e..0550e8a 100644 ---- a/include/netlink-private/types.h -+++ b/include/netlink-private/types.h -@@ -159,7 +159,7 @@ struct rtnl_link - uint32_t l_change; - uint32_t l_mtu; - uint32_t l_link; -- uint32_t l_link_netnsid; -+ int32_t l_link_netnsid; - uint32_t l_txqlen; - uint32_t l_weight; - uint32_t l_master; -diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h -index ca37f66..e1e6e20 100644 ---- a/include/netlink/route/link.h -+++ b/include/netlink/route/link.h -@@ -211,8 +211,8 @@ extern uint8_t rtnl_link_get_linkmode(struct rtnl_link *); - * Only use it if you understand the consequences and are willing - * to cope with them. - * */ --int rtnl_link_set_link_netnsid(struct rtnl_link *link, uint32_t link_netnsid); --int rtnl_link_get_link_netnsid(const struct rtnl_link *link, uint32_t *out_link_netnsid); -+int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid); -+int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid); - #endif - - extern const char * rtnl_link_get_ifalias(struct rtnl_link *); -diff --git a/lib/route/link.c b/lib/route/link.c -index d914fd5..fc88959 100644 ---- a/lib/route/link.c -+++ b/lib/route/link.c -@@ -59,6 +59,28 @@ - #define LINK_ATTR_AF_SPEC (1 << 27) - #define LINK_ATTR_LINK_NETNSID (1 << 31) - -+/***********************************************************************/ -+ -+/* upstream added new utility function. While backporting, -+ * they were needed, but we don't want to intoduce new -+ * API. Instead, define them locall.y */ -+ -+#define NLA_PUT_S32(msg, attrtype, value) \ -+ NLA_PUT_TYPE(msg, int32_t, attrtype, value) -+ -+/** -+ * Return payload of 32 bit integer attribute. -+ * @arg nla 32 bit integer attribute. -+ * -+ * @return Payload as 32 bit integer. -+ */ -+static int32_t nla_get_s32(const struct nlattr *nla) -+{ -+ return *(const int32_t *) nla_data(nla); -+} -+ -+/***********************************************************************/ -+ - static struct nl_cache_ops rtnl_link_ops; - static struct nl_object_ops link_obj_ops; - /** @endcond */ -@@ -445,7 +467,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, - } - - if (tb[IFLA_LINK_NETNSID]) { -- link->l_link_netnsid = nla_get_u32(tb[IFLA_LINK_NETNSID]); -+ link->l_link_netnsid = nla_get_s32(tb[IFLA_LINK_NETNSID]); - link->ce_mask |= LINK_ATTR_LINK_NETNSID; - } - -@@ -643,7 +665,7 @@ static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) - nl_dump(p, "slave-of %d ", link->l_link); - } - if (link->ce_mask & LINK_ATTR_LINK_NETNSID) -- nl_dump(p, "link-netnsid %u ", link->l_link_netnsid); -+ nl_dump(p, "link-netnsid %d ", link->l_link_netnsid); - - if (link->ce_mask & LINK_ATTR_GROUP) - nl_dump(p, "group %u ", link->l_group); -@@ -1249,7 +1271,7 @@ static int build_link_msg(int cmd, struct ifinfomsg *hdr, - NLA_PUT_U32(msg, IFLA_LINK, link->l_link); - - if (link->ce_mask & LINK_ATTR_LINK_NETNSID) -- NLA_PUT_U32(msg, IFLA_LINK_NETNSID, link->l_link_netnsid); -+ NLA_PUT_S32(msg, IFLA_LINK_NETNSID, link->l_link_netnsid); - - if (link->ce_mask & LINK_ATTR_MASTER) - NLA_PUT_U32(msg, IFLA_MASTER, link->l_master); -@@ -1914,7 +1936,7 @@ int rtnl_link_get_link(struct rtnl_link *link) - * Sets the IFLA_LINK_NETNSID attribute of the link - * @returns 0 on success - */ --int rtnl_link_set_link_netnsid(struct rtnl_link *link, uint32_t link_netnsid) -+int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid) - { - link->l_link_netnsid = link_netnsid; - link->ce_mask |= LINK_ATTR_LINK_NETNSID; -@@ -1931,7 +1953,7 @@ int rtnl_link_set_link_netnsid(struct rtnl_link *link, uint32_t link_netnsid) - * - * @returns 0 on success - */ --int rtnl_link_get_link_netnsid(const struct rtnl_link *link, uint32_t *out_link_netnsid) -+int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid) - { - if (!(link->ce_mask & LINK_ATTR_LINK_NETNSID)) - return -NLE_INVAL; --- -2.4.3 - diff --git a/SOURCES/0012-rh1261028-rtnl-neigh-get.patch b/SOURCES/0012-rh1261028-rtnl-neigh-get.patch deleted file mode 100644 index 7aa32b1..0000000 --- a/SOURCES/0012-rh1261028-rtnl-neigh-get.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 53d819c68d21accc815b59d887075b6e47e4c07f Mon Sep 17 00:00:00 2001 -From: Thomas Graf -Date: Fri, 1 Feb 2013 10:41:45 +0100 -Subject: [PATCH 1/2] neigh: Remove check for AF_UNSPEC in rtnl_neigh_get() - -This check was introduces to not accidently return AF_BRIDGE objects -to unaware API users as they do differ in structure. However, such -objects are only available if explicitely requests using the -NL_CACHE_AF_ITER flag or by using arg1 == AF_BRIDGE for the cache. - -Therefore remove this check and allow rtnl_neigh_get() to be used to -fetch any neighbor object of a cache. - -Reported-by: Maxime Bizon -Signed-off-by: Thomas Graf -(cherry picked from commit 8571f58f23763d8db7365d02c9b27832ad3d7005) ---- - lib/route/neigh.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/lib/route/neigh.c b/lib/route/neigh.c -index c0f80a2..288bb85 100644 ---- a/lib/route/neigh.c -+++ b/lib/route/neigh.c -@@ -532,6 +532,7 @@ int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result) - * @arg cache neighbour cache - * @arg ifindex interface index the neighbour is on - * @arg dst destination address of the neighbour -+ * - * @return neighbour handle or NULL if no match was found. - */ - struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex, -@@ -540,8 +541,7 @@ struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex, - struct rtnl_neigh *neigh; - - nl_list_for_each_entry(neigh, &cache->c_items, ce_list) { -- if (neigh->n_family == AF_UNSPEC && -- neigh->n_ifindex == ifindex && -+ if (neigh->n_ifindex == ifindex && - !nl_addr_cmp(neigh->n_dst, dst)) { - nl_object_get((struct nl_object *) neigh); - return neigh; --- -2.4.3 - - -From 6212b5522f5b40110729cd3fe4ac9c3dcaa2eb88 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Tue, 29 Sep 2015 18:32:23 +0200 -Subject: [PATCH 2/2] route: add capability indicating the behavior of - rtnl_neigh_get() - -A wrong behavior for rtnl_neigh_get() was introduced between 3.2.14 and 3.2.15 -(commit 64fcb47a36ec12d7e7f00605f6a8952ce985dd08). - -It was later fixed between 3.2.21 and 3.2.22 -(commit 8571f58f23763d8db7365d02c9b27832ad3d7005). - -Add a capability NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX -to indicate that this buggy behavior was fixed. - -https://bugzilla.redhat.com/show_bug.cgi?id=1261028 -http://lists.infradead.org/pipermail/libnl/2015-August/001951.html -Signed-off-by: Thomas Haller -(cherry picked from commit 2a8a7c31e6accf1a22caebace8da4c03028d5500) ---- - include/netlink/utils.h | 8 ++++++++ - lib/utils.c | 9 +++++++++ - 2 files changed, 17 insertions(+) - -diff --git a/include/netlink/utils.h b/include/netlink/utils.h -index 5b0d275..4b15372 100644 ---- a/include/netlink/utils.h -+++ b/include/netlink/utils.h -@@ -99,6 +99,14 @@ enum { - NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE = 4, - #define NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE - -+ /** -+ * Between 3.2.14 (64fcb47a36ec12d7e7f00605f6a8952ce985dd08) and 3.2.22 (8571f58f23763d8db7365d02c9b27832ad3d7005), -+ * rtnl_neigh_get() behaved differently and only returned objects with family AF_UNSPEC. -+ * This capability indicates, that the function was fixed. The absense of the capability, -+ * doesn't indicate however which behavior the function will have. So beware. */ -+ NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX = 10, -+#define NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX -+ - __NL_CAPABILITY_MAX - #define NL_CAPABILITY_MAX (__NL_CAPABILITY_MAX - 1) - }; -diff --git a/lib/utils.c b/lib/utils.c -index 5149e07..6b6a87c 100644 ---- a/lib/utils.c -+++ b/lib/utils.c -@@ -1143,6 +1143,15 @@ int nl_has_capability (int capability) - 0, - 0, - 0), -+ _NL_SET(1, -+ 0, -+ NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX, -+ 0, -+ 0, -+ 0, -+ 0, -+ 0, -+ 0), - #undef _NL_SET - #undef _NL_SETV - #undef _NL_ASSERT --- -2.4.3 - diff --git a/SOURCES/rh1040626-nl-Increase-receive-buffer-size-to-4-pages.patch b/SOURCES/rh1040626-nl-Increase-receive-buffer-size-to-4-pages.patch deleted file mode 100644 index c2d0e5a..0000000 --- a/SOURCES/rh1040626-nl-Increase-receive-buffer-size-to-4-pages.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nru libnl-3.2.21.orig/lib/nl.c libnl-3.2.21/lib/nl.c ---- libnl-3.2.21.orig/lib/nl.c 2014-01-21 17:14:46.017836475 +0100 -+++ libnl-3.2.21/lib/nl.c 2014-01-21 17:15:48.315460504 +0100 -@@ -597,7 +597,7 @@ - flags |= MSG_PEEK | MSG_TRUNC; - - if (page_size == 0) -- page_size = getpagesize(); -+ page_size = getpagesize() * 4; - - iov.iov_len = sk->s_bufsize ? : page_size; - iov.iov_base = malloc(iov.iov_len); diff --git a/SOURCES/rh1057024_ifa_flags_1.patch b/SOURCES/rh1057024_ifa_flags_1.patch deleted file mode 100644 index 9ae7739..0000000 --- a/SOURCES/rh1057024_ifa_flags_1.patch +++ /dev/null @@ -1,77 +0,0 @@ -From b31f8203d943346f60a92bace16098debe53205b Mon Sep 17 00:00:00 2001 -From: Jiri Pirko -Date: Sun, 8 Dec 2013 12:26:24 +0100 -Subject: [PATCH 1/3] add support for IFA_FLAGS nl attribute - -(cherry picked from commit 42c41336000e1ff781a91c6ec397fd787aae3124) - -Signed-off-by: Jiri Pirko -Signed-off-by: Thomas Haller ---- - include/linux/if_addr.h | 4 ++++ - include/netlink-private/types.h | 2 +- - lib/route/addr.c | 4 +++- - 3 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h -index c355522..63da1cd 100644 ---- a/include/linux/if_addr.h -+++ b/include/linux/if_addr.h -@@ -18,6 +18,9 @@ struct ifaddrmsg { - * It makes no difference for normally configured broadcast interfaces, - * but for point-to-point IFA_ADDRESS is DESTINATION address, - * local address is supplied in IFA_LOCAL attribute. -+ * -+ * IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags. -+ * If present, the value from struct ifaddrmsg will be ignored. - */ - enum { - IFA_UNSPEC, -@@ -28,6 +31,7 @@ enum { - IFA_ANYCAST, - IFA_CACHEINFO, - IFA_MULTICAST, -+ IFA_FLAGS, - __IFA_MAX, - }; - -diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h -index 60a3bce..72570c4 100644 ---- a/include/netlink-private/types.h -+++ b/include/netlink-private/types.h -@@ -233,8 +233,8 @@ struct rtnl_addr - - uint8_t a_family; - uint8_t a_prefixlen; -- uint8_t a_flags; - uint8_t a_scope; -+ uint32_t a_flags; - uint32_t a_ifindex; - - struct nl_addr *a_peer; -diff --git a/lib/route/addr.c b/lib/route/addr.c -index 95a9447..bcdc319 100644 ---- a/lib/route/addr.c -+++ b/lib/route/addr.c -@@ -215,8 +215,9 @@ static int addr_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, - ifa = nlmsg_data(nlh); - addr->a_family = family = ifa->ifa_family; - addr->a_prefixlen = ifa->ifa_prefixlen; -- addr->a_flags = ifa->ifa_flags; - addr->a_scope = ifa->ifa_scope; -+ addr->a_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : -+ ifa->ifa_flags; - addr->a_ifindex = ifa->ifa_index; - - addr->ce_mask = (ADDR_ATTR_FAMILY | ADDR_ATTR_PREFIXLEN | -@@ -593,6 +594,7 @@ static int build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags, - NLA_PUT(msg, IFA_CACHEINFO, sizeof(ca), &ca); - } - -+ NLA_PUT_U32(msg, IFA_FLAGS, tmpl->a_flags); - - *result = msg; - return 0; --- -1.8.3.1 - diff --git a/SOURCES/rh1057024_ifa_flags_2.patch b/SOURCES/rh1057024_ifa_flags_2.patch deleted file mode 100644 index 0a1b720..0000000 --- a/SOURCES/rh1057024_ifa_flags_2.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 6ad0773a41a713421caf3d88078aad634bc915e0 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 2 Jan 2014 10:51:38 +0100 -Subject: [PATCH 2/3] addr: add address flag IFA_F_MANAGETEMPADDR - -(cherry picked from commit dcc0baac020e033c4325e4d89c92aaab03f01b01) - -Signed-off-by: Thomas Haller ---- - include/linux/if_addr.h | 1 + - lib/route/addr.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h -index 63da1cd..94b32b4 100644 ---- a/include/linux/if_addr.h -+++ b/include/linux/if_addr.h -@@ -48,6 +48,7 @@ enum { - #define IFA_F_DEPRECATED 0x20 - #define IFA_F_TENTATIVE 0x40 - #define IFA_F_PERMANENT 0x80 -+#define IFA_F_MANAGETEMPADDR 0x100 - - struct ifa_cacheinfo { - __u32 ifa_prefered; -diff --git a/lib/route/addr.c b/lib/route/addr.c -index bcdc319..c3c59ce 100644 ---- a/lib/route/addr.c -+++ b/lib/route/addr.c -@@ -1023,6 +1023,7 @@ static const struct trans_tbl addr_flags[] = { - __ADD(IFA_F_DEPRECATED, deprecated) - __ADD(IFA_F_TENTATIVE, tentative) - __ADD(IFA_F_PERMANENT, permanent) -+ __ADD(IFA_F_MANAGETEMPADDR, mngtmpaddr) - }; - - char *rtnl_addr_flags2str(int flags, char *buf, size_t size) --- -1.8.3.1 - diff --git a/SOURCES/rh1057024_ifa_flags_3.patch b/SOURCES/rh1057024_ifa_flags_3.patch deleted file mode 100644 index 4151c07..0000000 --- a/SOURCES/rh1057024_ifa_flags_3.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 899914790776c71e0436fe39db1f5e28e6709a98 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 8 Jan 2014 01:44:58 +0100 -Subject: [PATCH 3/3] addr: add address flag IFA_F_NOPREFIXROUTE - -(cherry picked from commit b203c89d862a6ae3e82122fe1b6882b427d53551) - -Signed-off-by: Thomas Haller ---- - include/linux/if_addr.h | 1 + - lib/route/addr.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h -index 94b32b4..7d4de85 100644 ---- a/include/linux/if_addr.h -+++ b/include/linux/if_addr.h -@@ -49,6 +49,7 @@ enum { - #define IFA_F_TENTATIVE 0x40 - #define IFA_F_PERMANENT 0x80 - #define IFA_F_MANAGETEMPADDR 0x100 -+#define IFA_F_NOPREFIXROUTE 0x200 - - struct ifa_cacheinfo { - __u32 ifa_prefered; -diff --git a/lib/route/addr.c b/lib/route/addr.c -index c3c59ce..e98d73a 100644 ---- a/lib/route/addr.c -+++ b/lib/route/addr.c -@@ -1024,6 +1024,7 @@ static const struct trans_tbl addr_flags[] = { - __ADD(IFA_F_TENTATIVE, tentative) - __ADD(IFA_F_PERMANENT, permanent) - __ADD(IFA_F_MANAGETEMPADDR, mngtmpaddr) -+ __ADD(IFA_F_NOPREFIXROUTE, noprefixroute) - }; - - char *rtnl_addr_flags2str(int flags, char *buf, size_t size) --- -1.8.3.1 - diff --git a/SPECS/libnl3.spec b/SPECS/libnl3.spec index a0a5b27..ac4fd49 100644 --- a/SPECS/libnl3.spec +++ b/SPECS/libnl3.spec @@ -1,31 +1,21 @@ +Name: libnl3 +Version: 3.2.28 +Release: 2%{?dist} Summary: Convenience library for kernel netlink sockets Group: Development/Libraries License: LGPLv2 -Name: libnl3 -Version: 3.2.21 -Release: 10%{?dist} URL: http://www.infradead.org/~tgr/libnl/ -Source: http://www.infradead.org/~tgr/libnl/files/libnl-%{version}.tar.gz -Source1: http://www.infradead.org/~tgr/libnl/files/libnl-doc-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +%define fullversion %{version} + +Source: http://www.infradead.org/~tgr/libnl/files/libnl-%{fullversion}.tar.gz +Source1: http://www.infradead.org/~tgr/libnl/files/libnl-doc-%{fullversion}.tar.gz + +Patch1: 0001-compare-v4-addr-rh1370503.patch + BuildRequires: flex bison BuildRequires: python -BuildRequires: autoconf -BuildRequires: automake -BuildRequires: libtool -Patch0: rh1057024_ifa_flags_1.patch -Patch1: rh1057024_ifa_flags_2.patch -Patch2: rh1057024_ifa_flags_3.patch -Patch3: rh1040626-nl-Increase-receive-buffer-size-to-4-pages.patch -Patch4: 0004-add-nl_has_capability.patch -Patch5: 0005-rtnl_route_build_msg-set-scope.patch -Patch6: 0006-nl_msec2str-fix.patch -Patch7: 0007-relax-parsing-protinfo.patch -Patch8: 0008-rh1127718-inet6_addr_gen.patch -Patch9: 0009-rh1181255-EAGAIN.patch -Patch10: 0010-rh1249158-local-port-EADDRINUSE.patch -Patch11: 0011-support-IFLA_LINK_NETNSID-rh1255050.patch -Patch12: 0012-rh1261028-rtnl-neigh-get.patch +BuildRequires: libtool autoconf automake %description This package contains a convenience library to simplify @@ -60,25 +50,13 @@ Requires: %{name} = %{version}-%{release} This package contains libnl3 API documentation %prep -%setup -q -n libnl-%{version} -%patch0 -p1 -b .0000-rh1057024_ifa_flags_1.orig -%patch1 -p1 -b .0001-rh1057024_ifa_flags_2.orig -%patch2 -p1 -b .0002-rh1057024_ifa_flags_3.orig -%patch3 -p1 -b .0003-rh1040626.orig -%patch4 -p1 -b .0004-add-nl_has_capability.orig -%patch5 -p1 -b .0005-rtnl_route_build_msg-set-scope.orig -%patch6 -p1 -b .0006-nl_msec2str-fix.orig -%patch7 -p1 -b .0007-relax-parsing-protinfo.orig -%patch8 -p1 -b .0008-rh1127718-inet6_addr_gen.orig -%patch9 -p1 -b .0009-rh1181255-EAGAIN.orig -%patch10 -p1 -b .0010-rh1249158-local-port-EADDRINUSE.orig -%patch11 -p1 -%patch12 -p1 +%setup -q -n libnl-%{fullversion} +%patch1 -p1 tar -xzf %SOURCE1 %build -autoreconf -i --force +autoreconf -vif %configure --disable-static make %{?_smp_mflags} @@ -87,20 +65,39 @@ make install DESTDIR=$RPM_BUILD_ROOT find $RPM_BUILD_ROOT -name \*.la -delete +# rhel-7.2 installed some cli tools to /usr/sbin. Recent libnl3 releases prefer to +# install *all* cli tools bo /usr/bin. Also do that for rhel-7.3 but hardlink the +# previous locations in /usr/sbin. +mkdir -p "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/genl-ctrl-list" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-class-add" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-class-delete" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-classid-lookup" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-class-list" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-cls-add" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-cls-delete" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-cls-list" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-link-list" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-pktloc-lookup" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-qdisc-add" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-qdisc-delete" "%{buildroot}%{_sbindir}/" +ln "%{buildroot}%{_bindir}/nl-qdisc-list" "%{buildroot}%{_sbindir}/" + +%check +make check + %post -p /sbin/ldconfig %post cli -p /sbin/ldconfig %postun -p /sbin/ldconfig %postun cli -p /sbin/ldconfig %files -%defattr(-,root,root,-) %doc COPYING %exclude %{_libdir}/libnl-cli*.so.* %{_libdir}/libnl-*.so.* %config(noreplace) %{_sysconfdir}/* %files devel -%defattr(-,root,root,-) %doc COPYING %{_includedir}/libnl3/netlink/ %dir %{_includedir}/libnl3/ @@ -108,25 +105,36 @@ find $RPM_BUILD_ROOT -name \*.la -delete %{_libdir}/pkgconfig/*.pc %files cli -%defattr(-,root,root,-) %doc COPYING %{_libdir}/libnl-cli*.so.* %{_libdir}/libnl/ %{_sbindir}/* -%{_mandir}/man8/* +%{_bindir}/* +%{_mandir}/man8/* %files doc -%defattr(-,root,root,-) %doc COPYING -%doc libnl-doc-%{version}/*.html -%doc libnl-doc-%{version}/*.css -%doc libnl-doc-%{version}/stylesheets/* -%doc libnl-doc-%{version}/images/* -%doc libnl-doc-%{version}/images/icons/* -%doc libnl-doc-%{version}/images/icons/callouts/* -%doc libnl-doc-%{version}/api/* +%doc libnl-doc-%{fullversion}/*.html +%doc libnl-doc-%{fullversion}/*.css +%doc libnl-doc-%{fullversion}/stylesheets/* +%doc libnl-doc-%{fullversion}/images/* +%doc libnl-doc-%{fullversion}/images/icons/* +%doc libnl-doc-%{fullversion}/images/icons/callouts/* +%doc libnl-doc-%{fullversion}/api/* %changelog +* Fri Aug 26 2016 Thomas Haller - 3.2.28-2 +- route: fix nl_object_identical() comparing AF_INET addresses (rh #1370503) + +* Sat Jul 9 2016 Thomas Haller - 3.2.28-1 +- update to latest upstream release 3.2.28 (rh #1296058) + +* Thu Jun 30 2016 Thomas Haller - 3.2.28-0.1 +- update to latest upstream release 3.2.28-rc1 (rh #1296058) + +* Fri Jan 8 2016 Thomas Haller - 3.2.27-1 +- rebase package to upstream version 3.2.27 (rh #1296058) + * Wed Sep 30 2015 Thomas Haller - 3.2.21-10 - rtnl: fix lookup in rtnl_neigh_get() to ignore address family (rh #1261028)