summaryrefslogtreecommitdiff
path: root/sysdep/linux/netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdep/linux/netlink.c')
-rw-r--r--sysdep/linux/netlink.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index b42e7b6f..f6cedbd8 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -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);