diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2015-05-15 12:00:58 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2015-05-15 12:00:58 +0000 |
commit | 126dddc1d3268bd2e77ddccee20727012cda36ad (patch) | |
tree | 5d1fd6b9bf9ab027388fa104373b32bd6b3a32f3 /sys/netinet | |
parent | 4b5a1269369e0f7a0ec798bcb1a3c62c23b98fc1 (diff) |
Allow multiple connected/interface routes to exist at the same time.
Use the existing multipath code. Switch away from using the ifa address
when making the cloning route and instead put a dummy sockaddr_dl route
in. With this it is possible to use the same network on multiple interfaces
at the same time. So if wireless and ethernet share the same network
the system will use the wired connection as long as there is link.
Still missing is builtin proxy-arp for the other interface IPs to allow
hitless failover.
OK mpi@
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/if_ether.c | 16 | ||||
-rw-r--r-- | sys/netinet/in.c | 128 |
2 files changed, 5 insertions, 139 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index b7e582e009a..be83797b409 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.c,v 1.151 2015/04/22 04:12:22 jsg Exp $ */ +/* $OpenBSD: if_ether.c,v 1.152 2015/05/15 12:00:57 claudio Exp $ */ /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */ /* @@ -121,8 +121,6 @@ void db_print_llinfo(caddr_t); int db_show_radix_node(struct radix_node *, void *, u_int); #endif -static const struct sockaddr_dl null_sdl = { sizeof(null_sdl), AF_LINK }; - /* * Timeout routine. Age arp_tab entries periodically. */ @@ -190,14 +188,6 @@ arp_rtrequest(int req, struct rtentry *rt) if (rt->rt_flags & RTF_CLONING || ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && !la)) { /* - * Case 1: This route should come from a route to iface. - */ - rt_setgate(rt, (struct sockaddr *)&null_sdl, - ifp->if_rdomain); - gate = rt->rt_gateway; - SDL(gate)->sdl_type = ifp->if_type; - SDL(gate)->sdl_index = ifp->if_index; - /* * Give this route an expiration time, even though * it's a "permanent" route, so that routes cloned * from it do not need their expiration time set. @@ -261,10 +251,6 @@ arp_rtrequest(int req, struct rtentry *rt) } if (ifa) { rt->rt_expire = 0; - SDL(gate)->sdl_alen = ETHER_ADDR_LEN; - memcpy(LLADDR(SDL(gate)), - ((struct arpcom *)ifp)->ac_enaddr, ETHER_ADDR_LEN); - /* * XXX Since lo0 is in the default rdomain we * should not (ab)use it for any route related diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 974c61a0971..91636b9390b 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in.c,v 1.115 2015/01/12 13:51:45 mpi Exp $ */ +/* $OpenBSD: in.c,v 1.116 2015/05/15 12:00:57 claudio Exp $ */ /* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */ /* @@ -93,8 +93,6 @@ int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, struct ifnet *); void in_purgeaddr(struct ifaddr *); -int in_addprefix(struct in_ifaddr *); -int in_scrubprefix(struct in_ifaddr *); int in_addhost(struct in_ifaddr *, struct sockaddr_in *); int in_scrubhost(struct in_ifaddr *, struct sockaddr_in *); int in_insert_prefix(struct in_ifaddr *); @@ -590,7 +588,8 @@ in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia) if (ISSET(ifp->if_flags, IFF_POINTOPOINT)) in_scrubhost(ia, &ia->ia_dstaddr); else if (!ISSET(ifp->if_flags, IFF_LOOPBACK)) - in_scrubprefix(ia); + if (ia->ia_flags & IFA_ROUTE) + in_remove_prefix(ia); } /* @@ -669,7 +668,7 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, goto out; error = in_addhost(ia, &ia->ia_dstaddr); } else if (!ISSET(ifp->if_flags, IFF_LOOPBACK)) { - error = in_addprefix(ia); + error = in_insert_prefix(ia); } /* @@ -762,125 +761,6 @@ in_remove_prefix(struct in_ifaddr *ia) } /* - * add a route to prefix ("connected route" in cisco terminology). - * does nothing if there's some interface address with the same prefix already. - */ -int -in_addprefix(struct in_ifaddr *ia0) -{ - struct ifnet *ifp; - struct ifaddr *ifa; - struct in_ifaddr *ia; - struct in_addr prefix, mask, p, m; - - prefix = ia0->ia_addr.sin_addr; - mask = ia0->ia_sockmask.sin_addr; - prefix.s_addr &= mask.s_addr; - - TAILQ_FOREACH(ifp, &ifnet, if_list) { - if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) - continue; - - if (ifp->if_rdomain != ia0->ia_ifp->if_rdomain) - continue; - - TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { - if (ifa->ifa_addr->sa_family != AF_INET) - continue; - - ia = ifatoia(ifa); - - 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; - } -#endif - /* - * If we got a matching prefix route inserted by other - * interface address, we don't need to bother - */ - return (0); - } - } - - /* - * noone seem to have prefix route. insert it. - */ - return in_insert_prefix(ia0); -} - -/* - * remove a route to prefix ("connected route" in cisco terminology). - * re-installs the route by using another interface address, if there's one - * with the same prefix (otherwise we lose the route mistakenly). - */ -int -in_scrubprefix(struct in_ifaddr *ia0) -{ - struct ifnet *ifp; - struct ifaddr *ifa; - struct in_ifaddr *ia; - struct in_addr prefix, mask, p, m; - - if ((ia0->ia_flags & IFA_ROUTE) == 0) - return 0; - - prefix = ia0->ia_addr.sin_addr; - mask = ia0->ia_sockmask.sin_addr; - prefix.s_addr &= mask.s_addr; - - TAILQ_FOREACH(ifp, &ifnet, if_list) { - if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) - continue; - - if (ifp->if_rdomain != ia0->ia_ifp->if_rdomain) - continue; - - TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { - if (ifa->ifa_addr->sa_family != AF_INET) - continue; - - ia = ifatoia(ifa); - - 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; - - /* Move IFA_ROUTE to the matching prefix route. */ - in_remove_prefix(ia0); - return (in_insert_prefix(ia)); - } - } - - /* - * noone seem to have prefix route. remove it. - */ - in_remove_prefix(ia0); - return 0; -} - -/* * Return 1 if the address is a local broadcast address. */ int |