diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2010-11-17 19:25:50 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2010-11-17 19:25:50 +0000 |
commit | fba69b74bcc33f33bfb568967517a2990fa781bd (patch) | |
tree | 719494fb31a98a3501e19952ec4c8b1b1c19845f /sys/netinet | |
parent | fca6097ec78e2ba41a18ba185ebefad4abc48c50 (diff) |
an extra parameter for in_ifinit, indicating wether the ifaddr passed to it
is new or an already existing one. for existing ones, call ifa_del first
tested by many as part of a larger diff, ok claudio dlg krw sthen
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in.c | 17 | ||||
-rw-r--r-- | sys/netinet/in_var.h | 4 |
2 files changed, 14 insertions, 7 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index e51fbcb0afa..29bb773679c 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in.c,v 1.62 2010/11/17 19:21:28 henning Exp $ */ +/* $OpenBSD: in.c,v 1.63 2010/11/17 19:25:49 henning Exp $ */ /* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */ /* @@ -356,7 +356,8 @@ in_control(so, cmd, data, ifp) case SIOCSIFADDR: s = splsoftnet(); - error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1); + error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1, + newifaddr); if (!error) dohooks(ifp->if_addrhooks, 0); else if (newifaddr) { @@ -381,7 +382,7 @@ in_control(so, cmd, data, ifp) ifra->ifra_addr = ia->ia_addr; hostIsNew = 0; } else if (ifra->ifra_addr.sin_addr.s_addr == - ia->ia_addr.sin_addr.s_addr) + ia->ia_addr.sin_addr.s_addr && !newifaddr) hostIsNew = 0; } if (ifra->ifra_mask.sin_len) { @@ -406,7 +407,8 @@ in_control(so, cmd, data, ifp) } if (ifra->ifra_addr.sin_family == AF_INET && (hostIsNew || maskIsNew)) { - error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); + error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0, + newifaddr); } if (!error) dohooks(ifp->if_addrhooks, 0); @@ -657,18 +659,22 @@ in_ifscrub(ifp, ia) * and routing table entry. */ int -in_ifinit(ifp, ia, sin, scrub) +in_ifinit(ifp, ia, sin, scrub, newaddr) struct ifnet *ifp; struct in_ifaddr *ia; struct sockaddr_in *sin; int scrub; + int newaddr; { u_int32_t i = sin->sin_addr.s_addr; struct sockaddr_in oldaddr; int s = splnet(), flags = RTF_UP, error; + if (!newaddr) + ifa_del(ifp, (struct ifaddr *)ia); oldaddr = ia->ia_addr; ia->ia_addr = *sin; + /* * Give the interface a chance to initialize * if this is its first address, @@ -724,6 +730,7 @@ in_ifinit(ifp, ia, sin, scrub) flags |= RTF_HOST; } error = in_addprefix(ia, flags); + /* * If the interface supports multicast, join the "all hosts" * multicast group on that interface. diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index f09b9b54644..ec3530d1d6a 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_var.h,v 1.15 2010/01/13 07:05:28 henning Exp $ */ +/* $OpenBSD: in_var.h,v 1.16 2010/11/17 19:25:49 henning Exp $ */ /* $NetBSD: in_var.h,v 1.16 1996/02/13 23:42:15 christos Exp $ */ /* @@ -207,7 +207,7 @@ do { \ } while (/* CONSTCOND */ 0) int in_ifinit(struct ifnet *, - struct in_ifaddr *, struct sockaddr_in *, int); + struct in_ifaddr *, struct sockaddr_in *, int, int); struct in_multi *in_addmulti(struct in_addr *, struct ifnet *); void in_delmulti(struct in_multi *); void in_ifscrub(struct ifnet *, struct in_ifaddr *); |