aboutsummaryrefslogtreecommitdiffstats
path: root/proto/radv
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2017-12-07 13:06:01 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2017-12-07 13:06:01 +0100
commit153f02da3bce1f3f1a99295648679c71327e8319 (patch)
treeb7b7acf8026ba182f3a81f2d6da975b0b1524972 /proto/radv
parent4ae3ee1200b386219673c2168eae996c6207b077 (diff)
downloadbird-153f02da3bce1f3f1a99295648679c71327e8319.tar.gz
Nest: Maintain separate IPv4, IPv6 and LLv6 preferred addresses
Also redesign preferred address selection and update protocols to use appropriate preferred address. Based on a previous work by Jan Maria Matejka.
Diffstat (limited to 'proto/radv')
-rw-r--r--proto/radv/packets.c2
-rw-r--r--proto/radv/radv.c41
2 files changed, 22 insertions, 21 deletions
diff --git a/proto/radv/packets.c b/proto/radv/packets.c
index 15ca5738..9ea8feee 100644
--- a/proto/radv/packets.c
+++ b/proto/radv/packets.c
@@ -358,7 +358,7 @@ radv_rx_hook(sock *sk, uint size)
if (sk->lifindex != sk->iface->index)
return 1;
- if (ipa_equal(sk->faddr, ifa->addr->ip))
+ if (ipa_equal(sk->faddr, sk->saddr))
return 1;
if (size < 8)
diff --git a/proto/radv/radv.c b/proto/radv/radv.c
index b4b1bc58..2c0a23ad 100644
--- a/proto/radv/radv.c
+++ b/proto/radv/radv.c
@@ -138,17 +138,6 @@ radv_iface_add(struct object_lock *lock)
radv_iface_notify(ifa, RA_EV_INIT);
}
-static inline struct ifa *
-find_lladdr(struct iface *iface)
-{
- struct ifa *a;
- WALK_LIST(a, iface->addrs)
- if ((a->prefix.type == NET_IP6) && (a->scope == SCOPE_LINK))
- return a;
-
- return NULL;
-}
-
static void
radv_iface_new(struct radv_proto *p, struct iface *iface, struct radv_iface_config *cf)
{
@@ -161,16 +150,10 @@ radv_iface_new(struct radv_proto *p, struct iface *iface, struct radv_iface_conf
ifa->ra = p;
ifa->cf = cf;
ifa->iface = iface;
+ ifa->addr = iface->llv6;
add_tail(&p->iface_list, NODE ifa);
- ifa->addr = find_lladdr(iface);
- if (!ifa->addr)
- {
- log(L_ERR "%s: Missing link-local address on interface %s", p->p.name, iface->name);
- return;
- }
-
timer *tm = tm_new(pool);
tm->hook = radv_timer;
tm->data = ifa;
@@ -216,8 +199,15 @@ radv_if_notify(struct proto *P, unsigned flags, struct iface *iface)
if (flags & IF_CHANGE_UP)
{
- struct radv_iface_config *ic = (struct radv_iface_config *)
- iface_patt_find(&cf->patt_list, iface, NULL);
+ struct radv_iface_config *ic = (void *) iface_patt_find(&cf->patt_list, iface, NULL);
+
+ /* Ignore non-multicast ifaces */
+ if (!(iface->flags & IF_MULTICAST))
+ return;
+
+ /* Ignore ifaces without link-local address */
+ if (!iface->llv6)
+ return;
if (ic)
radv_iface_new(p, iface, ic);
@@ -395,6 +385,17 @@ radv_reconfigure(struct proto *P, struct proto_config *CF)
struct iface *iface;
WALK_LIST(iface, iface_list)
{
+ if (!(iface->flags & IF_UP))
+ continue;
+
+ /* Ignore non-multicast ifaces */
+ if (!(iface->flags & IF_MULTICAST))
+ continue;
+
+ /* Ignore ifaces without link-local address */
+ if (!iface->llv6)
+ continue;
+
struct radv_iface *ifa = radv_iface_find(p, iface);
struct radv_iface_config *ic = (struct radv_iface_config *)
iface_patt_find(&new->patt_list, iface, NULL);