summaryrefslogtreecommitdiffstats
path: root/nest/iface.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2009-05-29 22:49:30 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2009-05-29 22:49:30 +0200
commit874b868544c3a6ba45ace062091cc3aee007b719 (patch)
treedc9558c4e5e1537ea11469bb4be93bf941b9ee28 /nest/iface.c
parent51f4469f03759642870a45634d9b53054e3deb92 (diff)
downloadbird-874b868544c3a6ba45ace062091cc3aee007b719.tar
bird-874b868544c3a6ba45ace062091cc3aee007b719.zip
Implements primary address selection base on 'primary' option.
Diffstat (limited to 'nest/iface.c')
-rw-r--r--nest/iface.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/nest/iface.c b/nest/iface.c
index 01f2581..5e88b21 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -399,29 +399,43 @@ if_find_by_name(char *name)
return NULL;
}
+struct ifa *kif_choose_primary(struct iface *i);
+
static int
ifa_recalc_primary(struct iface *i)
{
- struct ifa *a, *b = NULL;
- int res;
+ struct ifa *a = kif_choose_primary(i);
- WALK_LIST(a, i->addrs)
+ if (a == i->addr)
+ return 0;
+
+ if (i->addr)
+ i->addr->flags &= ~IA_PRIMARY;
+
+ if (a)
{
- if (!(a->flags & IA_SECONDARY) && (!b || a->scope > b->scope))
- b = a;
- a->flags &= ~IA_PRIMARY;
+ a->flags |= IA_PRIMARY;
+ rem_node(&a->n);
+ add_head(&i->addrs, &a->n);
}
- res = (b != i->addr);
- i->addr = b;
- if (b)
+
+ i->addr = a;
+ return 1;
+}
+
+void
+ifa_recalc_all_primary_addresses(void)
+{
+ struct iface *i;
+
+ WALK_LIST(i, iface_list)
{
- b->flags |= IA_PRIMARY;
- rem_node(&b->n);
- add_head(&i->addrs, &b->n);
+ if (ifa_recalc_primary(i))
+ if_change_flags(i, i->flags | IF_TMP_DOWN);
}
- return res;
}
+
/**
* ifa_update - update interface address
* @a: new interface address
@@ -464,7 +478,7 @@ ifa_update(struct ifa *a)
memcpy(b, a, sizeof(struct ifa));
add_tail(&i->addrs, &b->n);
b->flags = (i->flags & ~IA_FLAGS) | (a->flags & IA_FLAGS);
- if ((!i->addr || i->addr->scope < b->scope) && ifa_recalc_primary(i))
+ if (ifa_recalc_primary(i))
if_change_flags(i, i->flags | IF_TMP_DOWN);
if (b->flags & IF_UP)
ifa_notify_change(IF_CHANGE_CREATE | IF_CHANGE_UP, b);