summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2020-10-30 18:25:55 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2020-10-30 18:25:55 +0000
commit0721d1b83cafeec82a806822940c34f017127786 (patch)
tree6cb3dfa75e485624ea2d4169ce971a5d78065087 /sbin
parent1d9c0024fab327a7e4a6f48da9f6709173253cdd (diff)
update_iface_ra does too much, move prefix handling into function.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/slaacd/engine.c246
1 files changed, 115 insertions, 131 deletions
diff --git a/sbin/slaacd/engine.c b/sbin/slaacd/engine.c
index 4ca07ab60ae..ec39d01f8c8 100644
--- a/sbin/slaacd/engine.c
+++ b/sbin/slaacd/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.51 2020/10/30 18:25:29 florian Exp $ */
+/* $OpenBSD: engine.c,v 1.52 2020/10/30 18:25:54 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -296,6 +296,8 @@ char *parse_dnssl(char *, int);
void update_iface_ra(struct slaacd_iface *, struct radv *);
void update_iface_ra_dfr(struct slaacd_iface *,
struct radv *);
+void update_iface_ra_prefix(struct slaacd_iface *,
+ struct radv *, struct radv_prefix *prefix);
void start_probe(struct slaacd_iface *);
void address_proposal_timeout(int, short, void *);
void dfr_proposal_timeout(int, short, void *);
@@ -1739,153 +1741,26 @@ void update_iface_ra(struct slaacd_iface *iface, struct radv *ra)
{
struct radv *old_ra;
struct radv_prefix *prefix;
- struct address_proposal *addr_proposal;
- uint32_t remaining_lifetime;
- int found, found_privacy, duplicate_found;
- const char *hbuf;
if ((old_ra = find_ra(iface, &ra->from)) == NULL)
LIST_INSERT_HEAD(&iface->radvs, ra, entries);
else {
LIST_REPLACE(old_ra, ra, entries);
-
merge_dad_couters(old_ra, ra);
-
free_ra(old_ra);
}
update_iface_ra_dfr(iface, ra);
- if (ra->router_lifetime != 0) {
+ if (ra->router_lifetime != 0)
LIST_FOREACH(prefix, &ra->prefixes, entries) {
if (!prefix->autonomous || prefix->vltime == 0 ||
prefix->pltime > prefix->vltime ||
IN6_IS_ADDR_LINKLOCAL(&prefix->prefix))
continue;
- found = 0;
- found_privacy = 0;
- duplicate_found = 0;
-
- LIST_FOREACH(addr_proposal, &iface->addr_proposals,
- entries) {
- if (prefix->prefix_len ==
- addr_proposal-> prefix_len &&
- memcmp(&prefix->prefix,
- &addr_proposal->prefix,
- sizeof(struct in6_addr)) != 0)
- continue;
-
- if (memcmp(&addr_proposal->hw_address,
- &iface->hw_address,
- sizeof(addr_proposal->hw_address)) != 0)
- continue;
-
- if (memcmp(&addr_proposal->soiikey,
- &iface->soiikey,
- sizeof(addr_proposal->soiikey)) != 0)
- continue;
-
- if (addr_proposal->privacy) {
- /*
- * create new privacy address if old
- * expires
- */
- if (addr_proposal->state !=
- PROPOSAL_NEARLY_EXPIRED &&
- addr_proposal->state !=
- PROPOSAL_DUPLICATED)
- found_privacy = 1;
-
- if (!iface->autoconfprivacy)
- log_debug("%s XXX need to "
- "remove privacy address",
- __func__);
-
- log_debug("%s, privacy addr state: %s",
- __func__, proposal_state_name[
- addr_proposal->state]);
-
- /* privacy addresses just expire */
- continue;
- }
-
- if (addr_proposal->state ==
- PROPOSAL_DUPLICATED) {
- duplicate_found = 1;
- continue;
- }
-
- found = 1;
-
- remaining_lifetime =
- real_lifetime(&addr_proposal->uptime,
- addr_proposal->vltime);
-
- addr_proposal->when = ra->when;
- addr_proposal->uptime = ra->uptime;
-
-/* RFC 4862 5.5.3 two hours rule */
-#define TWO_HOURS 2 * 3600
- if (prefix->vltime > TWO_HOURS ||
- prefix->vltime > remaining_lifetime)
- addr_proposal->vltime = prefix->vltime;
- else
- addr_proposal->vltime = TWO_HOURS;
- addr_proposal->pltime = prefix->pltime;
-
- if (ra->mtu == iface->cur_mtu)
- addr_proposal->mtu = 0;
- else {
- addr_proposal->mtu = ra->mtu;
- iface->cur_mtu = ra->mtu;
- }
-
- log_debug("%s, addr state: %s", __func__,
- proposal_state_name[addr_proposal->state]);
-
- switch (addr_proposal->state) {
- case PROPOSAL_CONFIGURED:
- case PROPOSAL_NEARLY_EXPIRED:
- log_debug("updating address");
- configure_address(addr_proposal);
- break;
- default:
- hbuf = sin6_to_str(&addr_proposal->
- addr);
- log_debug("%s: iface %d: %s", __func__,
- iface->if_index, hbuf);
- break;
- }
- }
-
- if (!found && duplicate_found && iface->soii) {
- prefix->dad_counter++;
- log_debug("%s dad_counter: %d",
- __func__, prefix->dad_counter);
- }
-
- if (!found &&
- (iface->soii || prefix->prefix_len <= 64))
- /* new proposal */
- gen_address_proposal(iface, ra, prefix, 0);
-
- /* privacy addresses do not depend on eui64 */
- if (!found_privacy && iface->autoconfprivacy) {
- if (prefix->pltime <
- ND6_PRIV_MAX_DESYNC_FACTOR) {
- hbuf = sin6_to_str(&ra->from);
- log_warnx("%s: pltime from %s is too "
- "small: %d < %d; not generating "
- "privacy address", __func__, hbuf,
- prefix->pltime,
- ND6_PRIV_MAX_DESYNC_FACTOR);
- } else
- /* new privacy proposal */
- gen_address_proposal(iface, ra, prefix,
- 1);
- }
+ update_iface_ra_prefix(iface, ra, prefix);
}
- }
+
#ifndef SMALL
update_iface_ra_rdns(iface, ra);
#endif /* SMALL */
@@ -1938,6 +1813,115 @@ update_iface_ra_dfr(struct slaacd_iface *iface, struct radv *ra)
}
}
+void
+update_iface_ra_prefix(struct slaacd_iface *iface, struct radv *ra,
+ struct radv_prefix *prefix)
+{
+ struct address_proposal *addr_proposal;
+ uint32_t remaining_lifetime;
+ int found, found_privacy, duplicate_found;
+
+ found = found_privacy = duplicate_found = 0;
+
+ LIST_FOREACH(addr_proposal, &iface->addr_proposals, entries) {
+ if (prefix->prefix_len == addr_proposal-> prefix_len &&
+ memcmp(&prefix->prefix, &addr_proposal->prefix,
+ sizeof(struct in6_addr)) != 0)
+ continue;
+
+ if (memcmp(&addr_proposal->hw_address,
+ &iface->hw_address,
+ sizeof(addr_proposal->hw_address)) != 0)
+ continue;
+
+ if (memcmp(&addr_proposal->soiikey, &iface->soiikey,
+ sizeof(addr_proposal->soiikey)) != 0)
+ continue;
+
+ if (addr_proposal->privacy) {
+ /* create new privacy address if old expires */
+ if (addr_proposal->state != PROPOSAL_NEARLY_EXPIRED &&
+ addr_proposal->state != PROPOSAL_DUPLICATED)
+ found_privacy = 1;
+
+ if (!iface->autoconfprivacy)
+ log_debug("%s XXX remove privacy address",
+ __func__);
+
+ log_debug("%s, privacy addr state: %s", __func__,
+ proposal_state_name[addr_proposal->state]);
+
+ /* privacy addresses just expire */
+ continue;
+ }
+
+ if (addr_proposal->state == PROPOSAL_DUPLICATED) {
+ duplicate_found = 1;
+ continue;
+ }
+
+ found = 1;
+
+ remaining_lifetime = real_lifetime(&addr_proposal->uptime,
+ addr_proposal->vltime);
+
+ addr_proposal->when = ra->when;
+ addr_proposal->uptime = ra->uptime;
+
+ /* RFC 4862 5.5.3 two hours rule */
+#define TWO_HOURS 2 * 3600
+ if (prefix->vltime > TWO_HOURS ||
+ prefix->vltime > remaining_lifetime)
+ addr_proposal->vltime = prefix->vltime;
+ else
+ addr_proposal->vltime = TWO_HOURS;
+ addr_proposal->pltime = prefix->pltime;
+
+ if (ra->mtu == iface->cur_mtu)
+ addr_proposal->mtu = 0;
+ else {
+ addr_proposal->mtu = ra->mtu;
+ iface->cur_mtu = ra->mtu;
+ }
+
+ log_debug("%s, addr state: %s", __func__,
+ proposal_state_name[addr_proposal->state]);
+
+ switch (addr_proposal->state) {
+ case PROPOSAL_CONFIGURED:
+ case PROPOSAL_NEARLY_EXPIRED:
+ log_debug("updating address");
+ configure_address(addr_proposal);
+ break;
+ default:
+ log_debug("%s: iface %d: %s", __func__, iface->if_index,
+ sin6_to_str(&addr_proposal->addr));
+ break;
+ }
+ }
+
+ if (!found && duplicate_found && iface->soii) {
+ prefix->dad_counter++;
+ log_debug("%s dad_counter: %d", __func__, prefix->dad_counter);
+ }
+
+ if (!found && (iface->soii || prefix->prefix_len <= 64))
+ /* new proposal */
+ gen_address_proposal(iface, ra, prefix, 0);
+
+ /* privacy addresses do not depend on eui64 */
+ if (!found_privacy && iface->autoconfprivacy) {
+ if (prefix->pltime < ND6_PRIV_MAX_DESYNC_FACTOR) {
+ log_warnx("%s: pltime from %s is too small: %d < %d; "
+ "not generating privacy address", __func__,
+ sin6_to_str(&ra->from), prefix->pltime,
+ ND6_PRIV_MAX_DESYNC_FACTOR);
+ } else
+ /* new privacy proposal */
+ gen_address_proposal(iface, ra, prefix, 1);
+ }
+}
+
#ifndef SMALL
void
update_iface_ra_rdns(struct slaacd_iface *iface, struct radv *ra)