diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/iface.c | 20 | ||||
-rw-r--r-- | nest/iface.h | 13 |
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 */ |