summaryrefslogtreecommitdiff
path: root/proto/radv/packets.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/radv/packets.c')
-rw-r--r--proto/radv/packets.c97
1 files changed, 37 insertions, 60 deletions
diff --git a/proto/radv/packets.c b/proto/radv/packets.c
index 1c9837a4..19d71f97 100644
--- a/proto/radv/packets.c
+++ b/proto/radv/packets.c
@@ -70,36 +70,6 @@ struct radv_opt_dnssl
char domain[];
};
-
-static struct radv_prefix_config default_prefix = {
- .onlink = 1,
- .autonomous = 1,
- .valid_lifetime = DEFAULT_VALID_LIFETIME,
- .preferred_lifetime = DEFAULT_PREFERRED_LIFETIME
-};
-
-
-static struct radv_prefix_config *
-radv_prefix_match(struct radv_iface *ifa, struct ifa *a)
-{
- struct radv_proto *p = ifa->ra;
- struct radv_config *cf = (struct radv_config *) (p->p.cf);
- struct radv_prefix_config *pc;
-
- if (a->scope <= SCOPE_LINK)
- return NULL;
-
- WALK_LIST(pc, ifa->cf->pref_list)
- if ((a->pxlen >= pc->pxlen) && ipa_in_net(a->prefix, pc->prefix, pc->pxlen))
- return pc;
-
- WALK_LIST(pc, cf->pref_list)
- if ((a->pxlen >= pc->pxlen) && ipa_in_net(a->prefix, pc->prefix, pc->pxlen))
- return pc;
-
- return &default_prefix;
-}
-
static int
radv_prepare_rdnss(struct radv_iface *ifa, list *rdnss_list, char **buf, char *bufend)
{
@@ -123,7 +93,7 @@ radv_prepare_rdnss(struct radv_iface *ifa, list *rdnss_list, char **buf, char *b
else
op->lifetime = htonl(rcf->lifetime);
- while(NODE_VALID(rcf) &&
+ while(NODE_VALID(rcf) &&
(rcf->lifetime == rcf_base->lifetime) &&
(rcf->lifetime_mult == rcf_base->lifetime_mult))
{
@@ -136,7 +106,7 @@ radv_prepare_rdnss(struct radv_iface *ifa, list *rdnss_list, char **buf, char *b
rcf = NODE_NEXT(rcf);
}
-
+
op->length = 1+2*i;
*buf += 8 * op->length;
}
@@ -235,6 +205,37 @@ radv_prepare_dnssl(struct radv_iface *ifa, list *dnssl_list, char **buf, char *b
return -1;
}
+static int
+radv_prepare_prefix(struct radv_iface *ifa, struct radv_prefix *prefix,
+ char **buf, char *bufend)
+{
+ struct radv_prefix_config *pc = prefix->cf;
+
+ if (*buf + sizeof(struct radv_opt_prefix) > bufend)
+ {
+ log(L_WARN "%s: Too many prefixes on interface %s",
+ ifa->ra->p.name, ifa->iface->name);
+ return -1;
+ }
+
+ struct radv_opt_prefix *op = (void *) *buf;
+ op->type = OPT_PREFIX;
+ op->length = 4;
+ op->pxlen = prefix->len;
+ op->flags = (pc->onlink ? OPT_PX_ONLINK : 0) |
+ (pc->autonomous ? OPT_PX_AUTONOMOUS : 0);
+ op->valid_lifetime = (ifa->ra->active || !pc->valid_lifetime_sensitive) ?
+ htonl(pc->valid_lifetime) : 0;
+ op->preferred_lifetime = (ifa->ra->active || !pc->preferred_lifetime_sensitive) ?
+ htonl(pc->preferred_lifetime) : 0;
+ op->reserved = 0;
+ op->prefix = prefix->prefix;
+ ipa_hton(op->prefix);
+ *buf += sizeof(*op);
+
+ return 0;
+}
+
static void
radv_prepare_ra(struct radv_iface *ifa)
{
@@ -270,35 +271,11 @@ radv_prepare_ra(struct radv_iface *ifa)
buf += sizeof (*om);
}
- struct ifa *addr;
- WALK_LIST(addr, ifa->iface->addrs)
+ struct radv_prefix *prefix;
+ WALK_LIST(prefix, ifa->prefixes)
{
- struct radv_prefix_config *pc;
- pc = radv_prefix_match(ifa, addr);
-
- if (!pc || pc->skip)
- continue;
-
- if (buf + sizeof(struct radv_opt_prefix) > bufend)
- {
- log(L_WARN "%s: Too many prefixes on interface %s", p->p.name, ifa->iface->name);
+ if (radv_prepare_prefix(ifa, prefix, &buf, bufend) < 0)
goto done;
- }
-
- struct radv_opt_prefix *op = (void *) buf;
- op->type = OPT_PREFIX;
- op->length = 4;
- op->pxlen = addr->pxlen;
- op->flags = (pc->onlink ? OPT_PX_ONLINK : 0) |
- (pc->autonomous ? OPT_PX_AUTONOMOUS : 0);
- op->valid_lifetime = (p->active || !pc->valid_lifetime_sensitive) ?
- htonl(pc->valid_lifetime) : 0;
- op->preferred_lifetime = (p->active || !pc->preferred_lifetime_sensitive) ?
- htonl(pc->preferred_lifetime) : 0;
- op->reserved = 0;
- op->prefix = addr->prefix;
- ipa_hton(op->prefix);
- buf += sizeof(*op);
}
if (! ic->rdnss_local)
@@ -407,7 +384,7 @@ radv_err_hook(sock *sk, int err)
int
radv_sk_open(struct radv_iface *ifa)
{
- sock *sk = sk_new(ifa->ra->p.pool);
+ sock *sk = sk_new(ifa->pool);
sk->type = SK_IP;
sk->dport = ICMPV6_PROTO;
sk->saddr = ifa->addr->ip;