summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2018-05-07 21:20:26 +0100
committerRoy Marples <roy@marples.name>2018-05-07 21:20:26 +0100
commit766ce48c95982388ad9c23bde67678dde26354f1 (patch)
tree49860fc3018bf33fbfce93fabb4afcf159aef640
parent9fc2b57c27b551a58ef69b615f69e570a21de103 (diff)
downloaddhcpcd-766ce48c95982388ad9c23bde67678dde26354f1.tar.xz
dhcp6: IAID is now unique for IA type
RFC3315 is a bit ambigious about this. At the start it says that IAID is supposed to be unique across the client, but futher down it starts to mention that the IAID number space is unqiuie to the IA type. RFC3315bis clarifies it's unique for the client and IA type, so you can now have ia_na 1 and ia_pd 1.
-rw-r--r--src/dhcp6.c13
-rw-r--r--src/dhcpcd.c28
-rw-r--r--src/if-options.c5
3 files changed, 21 insertions, 25 deletions
diff --git a/src/dhcp6.c b/src/dhcp6.c
index 37be2078..18fb6079 100644
--- a/src/dhcp6.c
+++ b/src/dhcp6.c
@@ -2195,6 +2195,7 @@ dhcp6_findia(struct interface *ifp, struct dhcp6_message *m, size_t l,
uint8_t iaid[4];
char buf[sizeof(iaid) * 3];
struct ipv6_addr *ap;
+ struct if_ia *ifia;
if (l < sizeof(*m)) {
/* Should be impossible with guards at packet in
@@ -2248,8 +2249,9 @@ dhcp6_findia(struct interface *ifp, struct dhcp6_message *m, size_t l,
o.len = (uint16_t)(o.len - nl);
for (j = 0; j < ifo->ia_len; j++) {
- if (memcmp(&ifo->ia[j].iaid, ia.iaid,
- sizeof(ia.iaid)) == 0)
+ ifia = &ifo->ia[j];
+ if (ifia->ia_type == o.code &&
+ memcmp(ifia->iaid, ia.iaid, sizeof(ia.iaid)) == 0)
break;
}
if (j == ifo->ia_len &&
@@ -2261,13 +2263,6 @@ dhcp6_findia(struct interface *ifp, struct dhcp6_message *m, size_t l,
buf, sizeof(buf)));
continue;
}
- if ( j < ifo->ia_len && ifo->ia[j].ia_type != o.code) {
- logerrx("%s: IAID %s: option type mismatch",
- ifp->name,
- hwaddr_ntoa(ia.iaid, sizeof(ia.iaid),
- buf, sizeof(buf)));
- continue;
- }
if (o.code != D6_OPTION_IA_TA) {
ia.t1 = ntohl(ia.t1);
diff --git a/src/dhcpcd.c b/src/dhcpcd.c
index 4944c00f..2483e38c 100644
--- a/src/dhcpcd.c
+++ b/src/dhcpcd.c
@@ -770,20 +770,23 @@ dhcpcd_handlecarrier(struct dhcpcd_ctx *ctx, int carrier, unsigned int flags,
}
static void
-warn_iaid_conflict(struct interface *ifp, uint8_t *iaid)
+warn_iaid_conflict(struct interface *ifp, uint16_t ia_type, uint8_t *iaid)
{
struct interface *ifn;
size_t i;
+ struct if_ia *ia;
TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
if (ifn == ifp || !ifn->active)
continue;
- if (memcmp(ifn->options->iaid, iaid,
+ if (ia_type == 0 &&
+ memcmp(ifn->options->iaid, iaid,
sizeof(ifn->options->iaid)) == 0)
break;
for (i = 0; i < ifn->options->ia_len; i++) {
- if (memcmp(&ifn->options->ia[i].iaid, iaid,
- sizeof(ifn->options->ia[i].iaid)) == 0)
+ ia = &ifn->options->ia[i];
+ if (ia->ia_type == ia_type &&
+ memcmp(ia->iaid, iaid, sizeof(ia->iaid)) == 0)
break;
}
}
@@ -839,20 +842,21 @@ dhcpcd_startinterface(void *arg)
}
if (ifo->options & (DHCPCD_DUID | DHCPCD_IPV6)) {
+ struct if_ia *ia;
+
/* Report IAIDs */
loginfox("%s: IAID %s", ifp->name,
hwaddr_ntoa(ifo->iaid, sizeof(ifo->iaid),
buf, sizeof(buf)));
- warn_iaid_conflict(ifp, ifo->iaid);
+ warn_iaid_conflict(ifp, 0, ifo->iaid);
for (i = 0; i < ifo->ia_len; i++) {
- if (memcmp(ifo->iaid, ifo->ia[i].iaid,
- sizeof(ifo->iaid)))
- {
- loginfox("%s: IAID %s",
- ifp->name, hwaddr_ntoa(ifo->ia[i].iaid,
- sizeof(ifo->ia[i].iaid),
+ ia = &ifo->ia[i];
+ if (memcmp(ifo->iaid, ia->iaid, sizeof(ifo->iaid))) {
+ loginfox("%s: IA type %u IAID %s",
+ ifp->name, ia->ia_type,
+ hwaddr_ntoa(ia->iaid, sizeof(ia->iaid),
buf, sizeof(buf)));
- warn_iaid_conflict(ifp, ifo->ia[i].iaid);
+ warn_iaid_conflict(ifp, ia->ia_type, ia->iaid);
}
}
}
diff --git a/src/if-options.c b/src/if-options.c
index 5943e700..b017bad5 100644
--- a/src/if-options.c
+++ b/src/if-options.c
@@ -1360,6 +1360,7 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
for (sl = 0; sl < ifo->ia_len; sl++) {
if ((arg == NULL && !ifo->ia[sl].iaid_set) ||
(arg != NULL && ifo->ia[sl].iaid_set &&
+ ifo->ia[sl].ia_type == (uint16_t)i &&
ifo->ia[sl].iaid[0] == iaid[0] &&
ifo->ia[sl].iaid[1] == iaid[1] &&
ifo->ia[sl].iaid[2] == iaid[2] &&
@@ -1369,10 +1370,6 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
break;
}
}
- if (ia && ia->ia_type != (uint16_t)i) {
- logerrx("Cannot mix IA for the same IAID");
- break;
- }
if (ia == NULL) {
ia = reallocarray(ifo->ia,
ifo->ia_len + 1, sizeof(*ifo->ia));