]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Netlink: Ignore tentative addresses
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 20 Jul 2016 13:06:57 +0000 (15:06 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 20 Jul 2016 13:06:57 +0000 (15:06 +0200)
Ignore tentative IPv6 addresses and wait until finish of Duplicate
Address Detection (We got notification when an address is no longer
tentative) to avoid problems when protocols try to use interfaces
with tentative link-local addresses.

Based on patch from Jan Moskyto Matejka

sysdep/linux/netlink.c

index b42e7b6f1b301bc2f376077b67c6bfc5f0cd2a96..f6cedbd837c9f3628b35bc2ea6c33a2186c73143 100644 (file)
@@ -247,18 +247,20 @@ static struct nl_want_attrs ifla_attr_want[BIRD_IFLA_MAX] = {
 };
 
 
-#define BIRD_IFA_MAX  (IFA_ANYCAST+1)
+#define BIRD_IFA_MAX  (IFA_FLAGS+1)
 
 #ifndef IPV6
 static struct nl_want_attrs ifa_attr_want4[BIRD_IFA_MAX] = {
   [IFA_ADDRESS]          = { 1, 1, sizeof(ip4_addr) },
   [IFA_LOCAL]    = { 1, 1, sizeof(ip4_addr) },
   [IFA_BROADCAST] = { 1, 1, sizeof(ip4_addr) },
+  [IFA_FLAGS]    = { 1, 1, sizeof(u32) },
 };
 #else
 static struct nl_want_attrs ifa_attr_want6[BIRD_IFA_MAX] = {
   [IFA_ADDRESS]          = { 1, 1, sizeof(ip6_addr) },
   [IFA_LOCAL]    = { 1, 1, sizeof(ip6_addr) },
+  [IFA_FLAGS]    = { 1, 1, sizeof(u32) },
 };
 #endif
 
@@ -611,6 +613,7 @@ nl_parse_addr(struct nlmsghdr *h, int scan)
   struct ifa ifa;
   struct iface *ifi;
   int scope;
+  u32 ifa_flags;
 
   if (!(i = nl_checkin(h, sizeof(*i))))
     return;
@@ -643,6 +646,11 @@ nl_parse_addr(struct nlmsghdr *h, int scan)
       return;
     }
 
+  if (a[IFA_FLAGS])
+    ifa_flags = rta_get_u32(a[IFA_FLAGS]);
+  else
+    ifa_flags = i->ifa_flags;
+
   ifi = if_find_by_index(i->ifa_index);
   if (!ifi)
     {
@@ -652,9 +660,15 @@ nl_parse_addr(struct nlmsghdr *h, int scan)
 
   bzero(&ifa, sizeof(ifa));
   ifa.iface = ifi;
-  if (i->ifa_flags & IFA_F_SECONDARY)
+  if (ifa_flags & IFA_F_SECONDARY)
     ifa.flags |= IA_SECONDARY;
 
+#ifdef IPV6
+  /* Ignore tentative addresses silently */
+  if (ifa_flags & IFA_F_TENTATIVE)
+    return;
+#endif
+
   /* IFA_LOCAL can be unset for IPv6 interfaces */
   memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL] ? : a[IFA_ADDRESS]), sizeof(ifa.ip));
   ipa_ntoh(ifa.ip);