On 12/21/15 11:36, Martin Pieuchot wrote:
> Currently if you try to configure the same IPv6 address twice via the
> SIOCAIFADDR_IN6 ioctl(2) the kernel will return EEXIST and the address
> will be unset: 
> 
> # ifconfig vether0 inet6 2001::1
> # ifconfig vether0 inet6 2001::1 
> ifconfig: SIOCAIFADDR: File exists
> 
> Diff below fixes that by not inserting the local route if we're "just"
> updating an existing address.  sebastia@ confirmed it fixes his use
> case, so I'm looking for oks.
> 
> Index: netinet6/in6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/in6.c,v
> retrieving revision 1.181
> diff -u -p -r1.181 in6.c
> --- netinet6/in6.c    3 Dec 2015 13:13:42 -0000       1.181
> +++ netinet6/in6.c    18 Dec 2015 09:27:18 -0000
[...]
> @@ -454,12 +454,15 @@ in6_control(struct socket *so, u_long cm
>                       return (EINVAL);
>               }
>  
> +             if (ia6 == NULL)
> +                     newifaddr = 1;
> +
>               /*
>                * Make the address tentative before joining multicast
>                * addresses, so that corresponding MLD responses would
>                * not have a tentative source address.
>                */
> -             if ((ia6 == NULL) && in6if_do_dad(ifp))
> +             if (newifaddr && in6if_do_dad(ifp))
>                       ifra->ifra_flags |= IN6_IFF_TENTATIVE;
>  
>               /*
[...]
> @@ -489,6 +493,9 @@ in6_control(struct socket *so, u_long cm
>               /* Perform DAD, if needed. */
>               if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
>                       nd6_dad_start(&ia6->ia_ifa);
> +
> +             if (!newifaddr)
> +                     break;
>  
>               plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL);
>               if ((ifp->if_flags & IFF_LOOPBACK) || plen == 128) {
> 


The "if (!newaddr)" should be moved above the "if (IN6_IFF_TENTATIVE)" ;
this way the skipping of DAD when !newaddr is more explicit.

Reply via email to