8989
9090#ifdef IPV6_POLLADDRFLAG
9191# warning kernel does not report IPv6 address flag changes
92- # warning polling tentative address flags periodically
9392#endif
9493
9594/* Hackery at it's finest. */
@@ -661,8 +660,7 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
661660 struct interface * ifp ;
662661 uint32_t pltime , vltime ;
663662 int loglevel ;
664- struct ipv6_state * state ;
665- struct ipv6_addr * ia2 ;
663+ struct ipv6_addr * iaf ;
666664
667665#ifdef __sun
668666 /* If we re-add then address on Solaris then the prefix
@@ -678,8 +676,9 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
678676 /* Remember the interface of the address. */
679677 ifp = ia -> iface ;
680678
681- if (!(ia -> flags & IPV6_AF_DADCOMPLETED ) &&
682- ipv6_iffindaddr (ifp , & ia -> addr , IN6_IFF_NOTUSEABLE ))
679+ /* Find any existing address. */
680+ iaf = ipv6_iffindaddr (ifp , & ia -> addr , 0 );
681+ if (iaf != NULL && !(iaf -> addr_flags & IN6_IFF_NOTUSEABLE ))
683682 ia -> flags |= IPV6_AF_DADCOMPLETED ;
684683
685684 /* Adjust plftime and vltime based on acquired time */
@@ -785,18 +784,15 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
785784 /* Take a copy of the address and add it to our state if
786785 * it does not exist.
787786 * This is important if route overflow loses the message. */
788- state = IPV6_STATE (ifp );
789- TAILQ_FOREACH (ia2 , & state -> addrs , next ) {
790- if (IN6_ARE_ADDR_EQUAL (& ia2 -> addr , & ia -> addr ))
791- break ;
792- }
793- if (ia2 == NULL ) {
794- if ((ia2 = malloc (sizeof (* ia2 ))) == NULL ) {
787+ if (iaf == NULL ) {
788+ struct ipv6_state * state = IPV6_STATE (ifp );
789+
790+ if ((iaf = malloc (sizeof (* iaf ))) == NULL ) {
795791 logerr (__func__ );
796792 return 0 ; /* Well, we did add the address */
797793 }
798- memcpy (ia2 , ia , sizeof (* ia2 ));
799- TAILQ_INSERT_TAIL (& state -> addrs , ia2 , next );
794+ memcpy (iaf , ia , sizeof (* iaf ));
795+ TAILQ_INSERT_TAIL (& state -> addrs , iaf , next );
800796 }
801797
802798 return 0 ;
@@ -1330,17 +1326,19 @@ ipv6_iffindaddr(struct interface *ifp, const struct in6_addr *addr,
13301326 struct ipv6_addr * ap ;
13311327
13321328 state = IPV6_STATE (ifp );
1333- if (state ) {
1334- TAILQ_FOREACH (ap , & state -> addrs , next ) {
1335- if (addr == NULL ) {
1336- if (IN6_IS_ADDR_LINKLOCAL (& ap -> addr ) &&
1337- (!revflags || !(ap -> addr_flags & revflags )))
1338- return ap ;
1339- } else {
1340- if (IN6_ARE_ADDR_EQUAL (& ap -> addr , addr ) &&
1341- (!revflags || !(ap -> addr_flags & revflags )))
1342- return ap ;
1343- }
1329+ if (state == NULL )
1330+ return NULL ;
1331+
1332+ TAILQ_FOREACH (ap , & state -> addrs , next ) {
1333+ if (addr == NULL ) {
1334+ if (IN6_IS_ADDR_LINKLOCAL (& ap -> addr ) &&
1335+ (!revflags || !(ap -> addr_flags & revflags )))
1336+ return ap ;
1337+ } else if (IN6_ARE_ADDR_EQUAL (& ap -> addr , addr )) {
1338+ /* This is our address so we will return now */
1339+ if (!revflags || !(ap -> addr_flags & revflags ))
1340+ return ap ;
1341+ return NULL ;
13441342 }
13451343 }
13461344 return NULL ;
@@ -1606,38 +1604,13 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
16061604 struct ipv6_addr * ia , * iaf ;
16071605 char buf [INET6_ADDRSTRLEN ];
16081606 const char * cbp ;
1609- bool tempaddr ;
1610- int addr_flags ;
1611-
1612- #ifdef IPV6_AF_TEMPORARY
1613- tempaddr = flags & IPV6_AF_TEMPORARY ;
1614- #else
1615- tempaddr = false;
1616- #endif
1617-
1618- /* If adding a new DHCP / RA derived address, check current flags
1619- * from an existing address. */
1620- if (tempaddr )
1621- iaf = NULL ;
1622- else if (flags & IPV6_AF_AUTOCONF )
1623- iaf = ipv6nd_iffindprefix (ifp , addr , prefix_len );
1624- else
1625- iaf = ipv6_iffindaddr (ifp , addr , 0 );
1626- if (iaf != NULL ) {
1627- addr_flags = iaf -> addr_flags ;
1628- flags |= IPV6_AF_ADDED ;
1629- } else
1630- addr_flags = IN6_IFF_TENTATIVE ;
16311607
16321608 ia = calloc (1 , sizeof (* ia ));
16331609 if (ia == NULL )
16341610 goto err ;
16351611
16361612 ia -> iface = ifp ;
1637- ia -> addr_flags = addr_flags ;
16381613 ia -> flags = IPV6_AF_NEW | flags ;
1639- if (!(ia -> addr_flags & IN6_IFF_NOTUSEABLE ))
1640- ia -> flags |= IPV6_AF_DADCOMPLETED ;
16411614 ia -> prefix_len = prefix_len ;
16421615 ia -> dhcp6_fd = -1 ;
16431616
@@ -1649,6 +1622,7 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
16491622 goto makepfx ;
16501623 else if (ia -> flags & IPV6_AF_AUTOCONF ) {
16511624 ia -> prefix = * addr ;
1625+ iaf = ipv6nd_iffindprefix (ifp , addr , prefix_len );
16521626 if (iaf != NULL )
16531627 memcpy (& ia -> addr , & iaf -> addr , sizeof (ia -> addr ));
16541628 else {
@@ -1666,7 +1640,7 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
16661640 cbp = inet_ntop (AF_INET6 , & ia -> addr , buf , sizeof (buf ));
16671641 goto paddr ;
16681642#else
1669- return ia ;
1643+ goto flags ;
16701644#endif
16711645 } else if (ia -> flags & (IPV6_AF_REQUEST | IPV6_AF_PFXDELEGATION )) {
16721646 ia -> prefix = * addr ;
@@ -1686,6 +1660,21 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
16861660 goto err ;
16871661 snprintf (ia -> saddr , sizeof (ia -> saddr ), "%s/%d" , cbp , ia -> prefix_len );
16881662
1663+ #ifndef __sun
1664+ flags :
1665+ #endif
1666+ /* If adding a new DHCP / RA derived address, check current flags
1667+ * from an existing address. */
1668+ iaf = ipv6_iffindaddr (ifp , & ia -> addr , 0 );
1669+ if (iaf != NULL ) {
1670+ ia -> addr_flags = iaf -> addr_flags ;
1671+ ia -> flags |= IPV6_AF_ADDED ;
1672+ } else
1673+ ia -> addr_flags |= IN6_IFF_TENTATIVE ;
1674+
1675+ if (!(ia -> addr_flags & IN6_IFF_NOTUSEABLE ))
1676+ ia -> flags |= IPV6_AF_DADCOMPLETED ;
1677+
16891678 return ia ;
16901679
16911680err :
0 commit comments