summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-04-04 16:14:46 +0200
committerThomas Haller <thaller@redhat.com>2014-04-04 19:48:44 +0200
commitdac51747ab5853b00557d7d97d4b2eae05968c03 (patch)
tree0056147d04cabcc10c32c03766f5e467f8c943bf
parentf73e3669b3bb9b3547173896dcea8e2eb17d30ec (diff)
downloadNetworkManager-dac51747ab5853b00557d7d97d4b2eae05968c03.tar.gz
platform: workaround older kernels that don't accept extended address flags via netlink
Extended address flags are represented by the additional netlink attribute IFA_FLAGS. Older kernels don't know this flag and refuse the messages RTM_NEWADDR and RTMDEL_ADDR when it contains unknown attributes. See net/core/rtnetlink.c, rtnetlink_rcv_msg(). This was fixed by kernel commit 661d2967b3f1b34eeaa7e212e7b9bbe8ee072b59. libnl was fixed in commit 5206c050504f8676a24854519b9c351470fb7cc6 only to send the additional netlink attribute, when there are actually flags that make this necessary. This commit changes nm-platform to strip the flags to &= 0xFF, if we detect that the kernel does not understand extended address flags. https://bugzilla.redhat.com/show_bug.cgi?id=1063885 Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--src/platform/nm-linux-platform.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index d52ebfaf3a..57977f1cad 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -2828,8 +2828,19 @@ build_rtnl_addr (int family,
rtnl_addr_set_valid_lifetime (rtnladdr, lifetime);
rtnl_addr_set_preferred_lifetime (rtnladdr, preferred);
}
- if (flags)
+ if (flags) {
+ if ((flags & ~0xFF) && !check_support_kernel_extended_ifa_flags (nm_platform_get ())) {
+ /* Older kernels don't accept unknown netlink attributes.
+ *
+ * With commit libnl commit 5206c050504f8676a24854519b9c351470fb7cc6, libnl will only set
+ * the extended address flags attribute IFA_FLAGS when necessary (> 8 bit). But it's up to
+ * us not to shove those extended flags on to older kernels.
+ *
+ * Just silently clear them. The kernel should ignore those unknown flags anyway. */
+ flags &= 0xFF;
+ }
rtnl_addr_set_flags (rtnladdr, flags);
+ }
if (label && *label)
rtnl_addr_set_label (rtnladdr, label);