From f4def34acbc9ce1fdf048c8a8a8058ca475e5587 Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 12 Jan 2015 13:51:45 +0000 Subject: [PATCH] Kill the global list of IPv4 addresses. ok claudio@, mikeb@, bluhm@ --- sys/netinet/in.c | 119 ++++++++++++++++++++++------------------- sys/netinet/in_var.h | 5 +- sys/netinet/ip_input.c | 4 +- 3 files changed, 67 insertions(+), 61 deletions(-) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index c46d62668f4..974c61a0971 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in.c,v 1.114 2015/01/05 10:21:58 mpi Exp $ */ +/* $OpenBSD: in.c,v 1.115 2015/01/12 13:51:45 mpi Exp $ */ /* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */ /* @@ -607,9 +607,6 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, splsoftassert(IPL_SOFTNET); - if (newaddr) - TAILQ_INSERT_TAIL(&in_ifaddr, ia, ia_list); - /* * Always remove the address from the tree to make sure its * position gets updated in case the key changes. @@ -629,9 +626,18 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) { ia->ia_addr = oldaddr; - goto out; } + /* + * Add the address to the local list and the global tree. If an + * error occured, put back the original address. + */ + ifa_add(ifp, &ia->ia_ifa); + rt_ifa_addlocal(&ia->ia_ifa); + + if (error) + goto out; + if (ia->ia_netmask == 0) { if (IN_CLASSA(i)) ia->ia_netmask = IN_CLASSA_NET; @@ -678,18 +684,6 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, } out: - /* - * Add the address to the local list and the global tree - * even if an error occured to make sure the various - * global structures are consistent. - * - * XXX This is necessary because we added the address - * to the global list in the first place because of - * carp(4). - */ - ifa_add(ifp, &ia->ia_ifa); - rt_ifa_addlocal(&ia->ia_ifa); - if (error && newaddr) in_purgeaddr(&ia->ia_ifa); @@ -709,7 +703,6 @@ in_purgeaddr(struct ifaddr *ifa) rt_ifa_dellocal(&ia->ia_ifa); ifa_del(ifp, &ia->ia_ifa); - TAILQ_REMOVE(&in_ifaddr, ia, ia_list); if (ia->ia_allhosts != NULL) { in_delmulti(ia->ia_allhosts); ia->ia_allhosts = NULL; @@ -775,6 +768,8 @@ in_remove_prefix(struct in_ifaddr *ia) int in_addprefix(struct in_ifaddr *ia0) { + struct ifnet *ifp; + struct ifaddr *ifa; struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; @@ -782,36 +777,44 @@ in_addprefix(struct in_ifaddr *ia0) mask = ia0->ia_sockmask.sin_addr; prefix.s_addr &= mask.s_addr; - TAILQ_FOREACH(ia, &in_ifaddr, ia_list) { - if (ia->ia_ifp->if_rdomain != ia0->ia_ifp->if_rdomain) + TAILQ_FOREACH(ifp, &ifnet, if_list) { + if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) continue; - if ((ia->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) + if (ifp->if_rdomain != ia0->ia_ifp->if_rdomain) continue; - if ((ia->ia_flags & IFA_ROUTE) == 0) - continue; + TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { + if (ifa->ifa_addr->sa_family != AF_INET) + continue; - p = ia->ia_addr.sin_addr; - m = ia->ia_sockmask.sin_addr; - p.s_addr &= m.s_addr; + ia = ifatoia(ifa); - if (prefix.s_addr != p.s_addr || mask.s_addr != m.s_addr) - continue; + if ((ia->ia_flags & IFA_ROUTE) == 0) + continue; + + p = ia->ia_addr.sin_addr; + m = ia->ia_sockmask.sin_addr; + p.s_addr &= m.s_addr; + + if (prefix.s_addr != p.s_addr || + mask.s_addr != m.s_addr) + continue; #if NCARP > 0 - /* move to a real interface instead of carp interface */ - if (ia->ia_ifp->if_type == IFT_CARP && - ia0->ia_ifp->if_type != IFT_CARP) { - in_remove_prefix(ia); - break; - } + /* move to a real interface instead of carp interface */ + if (ia->ia_ifp->if_type == IFT_CARP && + ia0->ia_ifp->if_type != IFT_CARP) { + in_remove_prefix(ia); + break; + } #endif - /* - * if we got a matching prefix route inserted by other - * interface address, we don't need to bother - */ - return 0; + /* + * If we got a matching prefix route inserted by other + * interface address, we don't need to bother + */ + return (0); + } } /* @@ -828,6 +831,8 @@ in_addprefix(struct in_ifaddr *ia0) int in_scrubprefix(struct in_ifaddr *ia0) { + struct ifnet *ifp; + struct ifaddr *ifa; struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; @@ -838,28 +843,34 @@ in_scrubprefix(struct in_ifaddr *ia0) mask = ia0->ia_sockmask.sin_addr; prefix.s_addr &= mask.s_addr; - TAILQ_FOREACH(ia, &in_ifaddr, ia_list) { - if (ia->ia_ifp->if_rdomain != ia0->ia_ifp->if_rdomain) + TAILQ_FOREACH(ifp, &ifnet, if_list) { + if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) continue; - if ((ia->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) + if (ifp->if_rdomain != ia0->ia_ifp->if_rdomain) continue; - if ((ia->ia_flags & IFA_ROUTE) != 0) - continue; + TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { + if (ifa->ifa_addr->sa_family != AF_INET) + continue; - p = ia->ia_addr.sin_addr; - m = ia->ia_sockmask.sin_addr; - p.s_addr &= m.s_addr; + ia = ifatoia(ifa); - if (prefix.s_addr != p.s_addr || mask.s_addr != m.s_addr) - continue; + if ((ia->ia_flags & IFA_ROUTE) != 0) + continue; - /* - * if we got a matching prefix route, move IFA_ROUTE to him - */ - in_remove_prefix(ia0); - return in_insert_prefix(ia); + p = ia->ia_addr.sin_addr; + m = ia->ia_sockmask.sin_addr; + p.s_addr &= m.s_addr; + + if (prefix.s_addr != p.s_addr || + mask.s_addr != m.s_addr) + continue; + + /* Move IFA_ROUTE to the matching prefix route. */ + in_remove_prefix(ia0); + return (in_insert_prefix(ia)); + } } /* diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index c8d7caed508..29ff5071e07 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_var.h,v 1.34 2014/03/27 10:39:23 mpi Exp $ */ +/* $OpenBSD: in_var.h,v 1.35 2015/01/12 13:51:45 mpi Exp $ */ /* $NetBSD: in_var.h,v 1.16 1996/02/13 23:42:15 christos Exp $ */ /* @@ -77,9 +77,6 @@ struct in_aliasreq { #ifdef _KERNEL -TAILQ_HEAD(in_ifaddrhead, in_ifaddr); -extern struct in_ifaddrhead in_ifaddr; - /* * Macro for finding the internet address structure (in_ifaddr) corresponding * to a given interface (ifnet structure). diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 43f169c63e4..e155210cdbc 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.243 2014/12/05 15:50:04 mpi Exp $ */ +/* $OpenBSD: ip_input.c,v 1.244 2015/01/12 13:51:45 mpi Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -114,7 +114,6 @@ int ip_frags = 0; int *ipctl_vars[IPCTL_MAXID] = IPCTL_VARS; -struct in_ifaddrhead in_ifaddr; struct ifqueue ipintrq; struct pool ipqent_pool; @@ -172,7 +171,6 @@ ip_init(void) ip_protox[pr->pr_protocol] = pr - inetsw; LIST_INIT(&ipq); IFQ_SET_MAXLEN(&ipintrq, IFQ_MAXLEN); - TAILQ_INIT(&in_ifaddr); if (ip_mtudisc != 0) ip_mtudisc_timeout_q = rt_timer_queue_create(ip_mtudisc_timeout); -- 2.20.1