summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/iface.c20
-rw-r--r--nest/iface.h13
2 files changed, 30 insertions, 3 deletions
diff --git a/nest/iface.c b/nest/iface.c
index 56de1f5c..7acadc7d 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -470,10 +470,24 @@ struct ifa *kif_choose_primary(struct iface *i);
static int
ifa_recalc_primary(struct iface *i)
{
- struct ifa *a = kif_choose_primary(i);
+ struct ifa *a;
+ int c = 0;
+
+#ifdef IPV6
+ struct ifa *ll = NULL;
+
+ WALK_LIST(a, i->addrs)
+ if (ipa_is_link_local(a->ip) && (!ll || (a == i->llv6)))
+ ll = a;
+
+ c = (ll != i->llv6);
+ i->llv6 = ll;
+#endif
+
+ a = kif_choose_primary(i);
if (a == i->addr)
- return 0;
+ return c;
if (i->addr)
i->addr->flags &= ~IA_PRIMARY;
@@ -577,7 +591,7 @@ ifa_delete(struct ifa *a)
b->flags &= ~IF_UP;
ifa_notify_change(IF_CHANGE_DOWN, b);
}
- if (b->flags & IA_PRIMARY)
+ if ((b->flags & IA_PRIMARY) || (b == ifa_llv6(i)))
{
if_change_flags(i, i->flags | IF_TMP_DOWN);
ifa_recalc_primary(i);
diff --git a/nest/iface.h b/nest/iface.h
index b8e69838..cf81660b 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -37,6 +37,9 @@ struct iface {
unsigned master_index; /* Interface index of master iface */
list addrs; /* Addresses assigned to this interface */
struct ifa *addr; /* Primary address */
+#ifdef IPV6
+ struct ifa *llv6; /* Selected IPv6 link-local address */
+#endif
struct iface *master; /* Master iface (e.g. for VRF) */
list neighbors; /* All neighbors on this interface */
};
@@ -103,6 +106,16 @@ struct iface *if_find_by_name(char *);
struct iface *if_get_by_name(char *);
void ifa_recalc_all_primary_addresses(void);
+static inline struct ifa *
+ifa_llv6(struct iface *i UNUSED4)
+{
+#ifdef IPV6
+ return i->llv6;
+#else
+ return NULL;
+#endif
+}
+
/* The Neighbor Cache */