diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-03-12 06:46:32 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-03-12 06:46:32 +0000 |
commit | 5e514fa422eb8e48f5ebae22bcd0257995eb28f2 (patch) | |
tree | 7a42b95eb3a700b736d05571baca4b92391c92c0 /sys | |
parent | 4b7499ad205b2daa71bf039fe717220a19d317a1 (diff) |
undo interface address addition, if in_ifinit fails.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/in.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 7d3e5b73f88..0f02f4c916a 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in.c,v 1.15 2000/01/04 21:38:56 fgsch Exp $ */ +/* $OpenBSD: in.c,v 1.16 2000/03/12 06:46:31 itojun Exp $ */ /* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */ /* @@ -195,6 +195,7 @@ in_control(so, cmd, data, ifp) struct in_aliasreq *ifra = (struct in_aliasreq *)data; struct sockaddr_in oldaddr; int error, hostIsNew, maskIsNew; + int newifaddr; #if NGIF > 0 if (ifp && ifp->if_type == IFT_GIF) { @@ -272,7 +273,10 @@ in_control(so, cmd, data, ifp) LIST_INIT(&ia->ia_multiaddrs); if ((ifp->if_flags & IFF_LOOPBACK) == 0) in_interfaces++; - } + + newifaddr = 1; + } else + newifaddr = 0; break; case SIOCSIFBRDADDR: @@ -347,7 +351,16 @@ in_control(so, cmd, data, ifp) break; case SIOCSIFADDR: - return (in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1)); + error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1); + undo: + if (error && newifaddr){ + TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list); + TAILQ_REMOVE(&in_ifaddr, ia, ia_list); + FREE(ia, M_IFADDR); + if ((ifp->if_flags & IFF_LOOPBACK) == 0) + in_interfaces--; + } + return error; case SIOCSIFNETMASK: ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr = @@ -379,8 +392,11 @@ in_control(so, cmd, data, ifp) maskIsNew = 1; /* We lie; but the effect's the same */ } if (ifra->ifra_addr.sin_family == AF_INET && - (hostIsNew || maskIsNew)) + (hostIsNew || maskIsNew)) { error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); + if (error) + goto undo; + } if ((ifp->if_flags & IFF_BROADCAST) && (ifra->ifra_broadaddr.sin_family == AF_INET)) ia->ia_broadaddr = ifra->ifra_broadaddr; |