Skip to content

Commit

Permalink
IPv6: Don't set IN6_IFF_TENTATIVE when the address exists
Browse files Browse the repository at this point in the history
We can only work it out when we know the address, not beforehand.
  • Loading branch information
rsmarples committed Oct 9, 2024
1 parent fdeb8c7 commit 58230c2
Showing 1 changed file with 40 additions and 51 deletions.
91 changes: 40 additions & 51 deletions src/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@

#ifdef IPV6_POLLADDRFLAG
# warning kernel does not report IPv6 address flag changes
# warning polling tentative address flags periodically
#endif

/* Hackery at it's finest. */
Expand Down Expand Up @@ -661,8 +660,7 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
struct interface *ifp;
uint32_t pltime, vltime;
int loglevel;
struct ipv6_state *state;
struct ipv6_addr *ia2;
struct ipv6_addr *iaf;

#ifdef __sun
/* If we re-add then address on Solaris then the prefix
Expand All @@ -678,8 +676,9 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
/* Remember the interface of the address. */
ifp = ia->iface;

if (!(ia->flags & IPV6_AF_DADCOMPLETED) &&
ipv6_iffindaddr(ifp, &ia->addr, IN6_IFF_NOTUSEABLE))
/* Find any existing address. */
iaf = ipv6_iffindaddr(ifp, &ia->addr, 0);
if (iaf != NULL && !(iaf->addr_flags & IN6_IFF_NOTUSEABLE))
ia->flags |= IPV6_AF_DADCOMPLETED;

/* Adjust plftime and vltime based on acquired time */
Expand Down Expand Up @@ -785,18 +784,15 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
/* Take a copy of the address and add it to our state if
* it does not exist.
* This is important if route overflow loses the message. */
state = IPV6_STATE(ifp);
TAILQ_FOREACH(ia2, &state->addrs, next) {
if (IN6_ARE_ADDR_EQUAL(&ia2->addr, &ia->addr))
break;
}
if (ia2 == NULL) {
if ((ia2 = malloc(sizeof(*ia2))) == NULL) {
if (iaf == NULL) {
struct ipv6_state *state = IPV6_STATE(ifp);

if ((iaf = malloc(sizeof(*iaf))) == NULL) {
logerr(__func__);
return 0; /* Well, we did add the address */
}
memcpy(ia2, ia, sizeof(*ia2));
TAILQ_INSERT_TAIL(&state->addrs, ia2, next);
memcpy(iaf, ia, sizeof(*iaf));
TAILQ_INSERT_TAIL(&state->addrs, iaf, next);
}

return 0;
Expand Down Expand Up @@ -1330,17 +1326,19 @@ ipv6_iffindaddr(struct interface *ifp, const struct in6_addr *addr,
struct ipv6_addr *ap;

state = IPV6_STATE(ifp);
if (state) {
TAILQ_FOREACH(ap, &state->addrs, next) {
if (addr == NULL) {
if (IN6_IS_ADDR_LINKLOCAL(&ap->addr) &&
(!revflags || !(ap->addr_flags & revflags)))
return ap;
} else {
if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr) &&
(!revflags || !(ap->addr_flags & revflags)))
return ap;
}
if (state == NULL)
return NULL;

TAILQ_FOREACH(ap, &state->addrs, next) {
if (addr == NULL) {
if (IN6_IS_ADDR_LINKLOCAL(&ap->addr) &&
(!revflags || !(ap->addr_flags & revflags)))
return ap;
} else if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr)) {
/* This is our address so we will return now */
if (!revflags || !(ap->addr_flags & revflags))
return ap;
return NULL;
}
}
return NULL;
Expand Down Expand Up @@ -1606,38 +1604,13 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
struct ipv6_addr *ia, *iaf;
char buf[INET6_ADDRSTRLEN];
const char *cbp;
bool tempaddr;
int addr_flags;

#ifdef IPV6_AF_TEMPORARY
tempaddr = flags & IPV6_AF_TEMPORARY;
#else
tempaddr = false;
#endif

/* If adding a new DHCP / RA derived address, check current flags
* from an existing address. */
if (tempaddr)
iaf = NULL;
else if (flags & IPV6_AF_AUTOCONF)
iaf = ipv6nd_iffindprefix(ifp, addr, prefix_len);
else
iaf = ipv6_iffindaddr(ifp, addr, 0);
if (iaf != NULL) {
addr_flags = iaf->addr_flags;
flags |= IPV6_AF_ADDED;
} else
addr_flags = IN6_IFF_TENTATIVE;

ia = calloc(1, sizeof(*ia));
if (ia == NULL)
goto err;

ia->iface = ifp;
ia->addr_flags = addr_flags;
ia->flags = IPV6_AF_NEW | flags;
if (!(ia->addr_flags & IN6_IFF_NOTUSEABLE))
ia->flags |= IPV6_AF_DADCOMPLETED;
ia->prefix_len = prefix_len;
ia->dhcp6_fd = -1;

Expand All @@ -1649,6 +1622,7 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
goto makepfx;
else if (ia->flags & IPV6_AF_AUTOCONF) {
ia->prefix = *addr;
iaf = ipv6nd_iffindprefix(ifp, addr, prefix_len);
if (iaf != NULL)
memcpy(&ia->addr, &iaf->addr, sizeof(ia->addr));
else {
Expand All @@ -1666,7 +1640,7 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
cbp = inet_ntop(AF_INET6, &ia->addr, buf, sizeof(buf));
goto paddr;
#else
return ia;
goto flags;
#endif
} else if (ia->flags & (IPV6_AF_REQUEST | IPV6_AF_PFXDELEGATION)) {
ia->prefix = *addr;
Expand All @@ -1686,6 +1660,21 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
goto err;
snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d", cbp, ia->prefix_len);

#ifndef __sun
flags:
#endif
/* If adding a new DHCP / RA derived address, check current flags
* from an existing address. */
iaf = ipv6_iffindaddr(ifp, &ia->addr, 0);
if (iaf != NULL) {
ia->addr_flags = iaf->addr_flags;
ia->flags |= IPV6_AF_ADDED;
} else
ia->addr_flags |= IN6_IFF_TENTATIVE;

if (!(ia->addr_flags & IN6_IFF_NOTUSEABLE))
ia->flags |= IPV6_AF_DADCOMPLETED;

return ia;

err:
Expand Down

0 comments on commit 58230c2

Please sign in to comment.