Skip to content

Commit 82c24ee

Browse files
committed
IPv6: Add the added address to state
We used to rely on route(4) adding it to state based on RTM_NEWADDR but the message could get lost if the socket overflows. Work around this by always adding the address to the state.
1 parent ab5ec18 commit 82c24ee

1 file changed

Lines changed: 13 additions & 19 deletions

File tree

src/ipv6.c

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -666,13 +666,13 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
666666
struct interface *ifp;
667667
uint32_t pltime, vltime;
668668
int loglevel;
669+
struct ipv6_state *state;
670+
struct ipv6_addr *ia2;
669671
#ifdef ND6_ADVERTISE
670672
bool vltime_was_zero = ia->prefix_vltime == 0;
671673
#endif
672-
#ifdef __sun
673-
struct ipv6_state *state;
674-
struct ipv6_addr *ia2;
675674

675+
#ifdef __sun
676676
/* If we re-add then address on Solaris then the prefix
677677
* route will be scrubbed and re-added. Something might
678678
* be using it, so let's avoid it. */
@@ -794,12 +794,9 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
794794
}
795795
#endif
796796

797-
#ifdef __sun
798-
/* Solaris does not announce new addresses which need DaD
799-
* so we need to take a copy and add it to our list.
800-
* Otherwise aliasing gets confused if we add another
801-
* address during DaD. */
802-
797+
/* Take a copy of the address and add it to our state if
798+
* it does not exist.
799+
* This is important if route overflow loses the message. */
803800
state = IPV6_STATE(ifp);
804801
TAILQ_FOREACH(ia2, &state->addrs, next) {
805802
if (IN6_ARE_ADDR_EQUAL(&ia2->addr, &ia->addr))
@@ -808,17 +805,14 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
808805
if (ia2 == NULL) {
809806
if ((ia2 = malloc(sizeof(*ia2))) == NULL) {
810807
logerr(__func__);
811-
return 0; /* Well, we did add the address */
808+
goto advertise; /* Well, we did add the address */
812809
}
813810
memcpy(ia2, ia, sizeof(*ia2));
814811
TAILQ_INSERT_TAIL(&state->addrs, ia2, next);
815812
}
816-
#endif
817813

818-
#ifdef ND6_ADVERTISE
819-
#ifdef __sun
820814
advertise:
821-
#endif
815+
#ifdef ND6_ADVERTISE
822816
/* Re-advertise the preferred address to be safe. */
823817
if (!vltime_was_zero)
824818
ipv6nd_advertise(ia);
@@ -1908,6 +1902,10 @@ ipv6_handleifa_addrs(int cmd,
19081902

19091903
ia->addr_flags = addr->addr_flags;
19101904

1905+
if (cmd == RTM_DELADDR && ia->flags & IPV6_AF_ADDED)
1906+
logwarnx("%s: pid %d deleted address %s",
1907+
ia->iface->name, pid, ia->saddr);
1908+
19111909
/* Check DAD.
19121910
* On Linux we can get IN6_IFF_DUPLICATED via RTM_DELADDR. */
19131911
if (((ia->addr_flags &
@@ -1924,11 +1922,7 @@ ipv6_handleifa_addrs(int cmd,
19241922
}
19251923

19261924
if (cmd == RTM_DELADDR) {
1927-
if (ia->flags & IPV6_AF_ADDED) {
1928-
logwarnx("%s: pid %d deleted address %s",
1929-
ia->iface->name, pid, ia->saddr);
1930-
ia->flags &= ~IPV6_AF_ADDED;
1931-
}
1925+
ia->flags &= ~IPV6_AF_ADDED;
19321926
ipv6_deletedaddr(ia);
19331927
if (ia->flags & IPV6_AF_DELEGATED) {
19341928
TAILQ_REMOVE(addrs, ia, next);

0 commit comments

Comments
 (0)