diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-12-22 10:01:02 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-12-22 10:01:02 +0000 |
commit | a944b660296fb9ffb078e76213a00e4d833793c4 (patch) | |
tree | 6fb3a0efd01a74e1e697bbfb6327e70a76843369 /sys/netinet6/in6.c | |
parent | a18d798c10619d3bbcd6d420d8658849539f6fd1 (diff) |
Do not return EEXIST if the same address is added twice.
Reported by sebastisa@.
ok sebasitia@, stsp@, florian@, vgross@
Diffstat (limited to 'sys/netinet6/in6.c')
-rw-r--r-- | sys/netinet6/in6.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 1072a8a780d..a2c6b67b223 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.181 2015/12/03 13:13:42 tedu Exp $ */ +/* $OpenBSD: in6.c,v 1.182 2015/12/22 10:01:01 mpi Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -444,7 +444,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) case SIOCAIFADDR_IN6: { - int plen, error = 0; + int plen, error = 0, newifaddr = 0; /* reject read-only flags */ if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 || @@ -454,12 +454,15 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) 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; /* @@ -477,8 +480,9 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) splx(s); if (error != 0) return (error); - if ((ia6 = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr)) - == NULL) { + + ia6 = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr); + if (ia6 == NULL) { /* * this can happen when the user specify the 0 valid * lifetime. @@ -486,6 +490,9 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) break; } + if (!newifaddr) + break; + /* Perform DAD, if needed. */ if (ia6->ia6_flags & IN6_IFF_TENTATIVE) nd6_dad_start(&ia6->ia_ifa); |