diff options
author | 2015-05-15 12:00:57 +0000 | |
---|---|---|
committer | 2015-05-15 12:00:57 +0000 | |
commit | cfc71c8b10d8f3bcfadb0824a6cfcb656be46181 (patch) | |
tree | cae3b612d6b6f8201c4df49e2da0716d978f8f36 /sys/netinet6 | |
parent | Give carp(4) interfaces their own low priority. The change should not (diff) | |
download | wireguard-openbsd-cfc71c8b10d8f3bcfadb0824a6cfcb656be46181.tar.xz wireguard-openbsd-cfc71c8b10d8f3bcfadb0824a6cfcb656be46181.zip |
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/netinet6')
-rw-r--r-- | sys/netinet6/in6.c | 11 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 27 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 10 |
3 files changed, 23 insertions, 25 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 479220748c8..951476450be 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.156 2015/04/20 09:07:42 mpi Exp $ */ +/* $OpenBSD: in6.c,v 1.157 2015/05/15 12:00:57 claudio Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -78,6 +78,7 @@ #include <sys/syslog.h> #include <net/if.h> +#include <net/if_dl.h> #include <net/if_types.h> #include <net/route.h> @@ -827,6 +828,10 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, /* join solicited multicast addr for new host id */ struct sockaddr_in6 llsol; + struct sockaddr_dl sa_dl = { sizeof(sa_dl), AF_LINK }; + + sa_dl.sdl_type = ifp->if_type; + sa_dl.sdl_index = ifp->if_index; bzero(&llsol, sizeof(llsol)); llsol.sin6_family = AF_INET6; @@ -887,7 +892,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, bzero(&info, sizeof(info)); info.rti_info[RTAX_DST] = sin6tosa(&mltaddr); - info.rti_info[RTAX_GATEWAY] = sin6tosa(&ia6->ia_addr); + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl; info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask); info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr); /* XXX: we need RTF_CLONING to fake nd6_rtrequest */ @@ -956,7 +961,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, bzero(&info, sizeof(info)); info.rti_info[RTAX_DST] = sin6tosa(&mltaddr); - info.rti_info[RTAX_GATEWAY] = sin6tosa(&ia6->ia_addr); + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl; info.rti_info[RTAX_NETMASK] = sin6tosa(&mltmask); info.rti_info[RTAX_IFA] = sin6tosa(&ia6->ia_addr); info.rti_flags = RTF_UP | RTF_CLONING; diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 971a8948a1a..cea57b8c5de 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6.c,v 1.135 2015/04/27 14:51:44 mpi Exp $ */ +/* $OpenBSD: nd6.c,v 1.136 2015/05/15 12:00:57 claudio Exp $ */ /* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */ /* @@ -651,6 +651,7 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp, } if (!rt) { if (create && ifp) { + struct sockaddr_dl sa_dl = { sizeof(sa_dl), AF_LINK }; struct rt_addrinfo info; int e; @@ -666,6 +667,9 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp, if (ifa == NULL) return (NULL); + sa_dl.sdl_type = ifp->if_type; + sa_dl.sdl_index = ifp->if_index; + /* * Create a new route. RTF_LLINFO is necessary * to create a Neighbor Cache entry for the @@ -675,7 +679,7 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp, bzero(&info, sizeof(info)); info.rti_flags = RTF_UP | RTF_HOST | RTF_LLINFO; info.rti_info[RTAX_DST] = sin6tosa(&sin6); - info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl; if ((e = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &rt, rtableid)) != 0) { #if 0 @@ -940,7 +944,6 @@ nd6_rtrequest(int req, struct rtentry *rt) { struct sockaddr *gate = rt->rt_gateway; struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo; - static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; struct ifnet *ifp = rt->rt_ifp; struct ifaddr *ifa; struct nd_defrouter *dr; @@ -999,17 +1002,6 @@ nd6_rtrequest(int req, struct rtentry *rt) */ if ((rt->rt_flags & RTF_CLONING) || ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && !ln)) { - /* - * Case 1: This route should come from a route to - * interface (RTF_CLONING case) or the route should be - * treated as on-link but is currently not - * (RTF_LLINFO && !ln case). - */ - 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; if (ln) nd6_llinfo_settimer(ln, 0); if ((rt->rt_flags & RTF_CLONING) != 0) @@ -1045,7 +1037,7 @@ nd6_rtrequest(int req, struct rtentry *rt) /* FALLTHROUGH */ case RTM_RESOLVE: if (gate->sa_family != AF_LINK || - gate->sa_len < sizeof(null_sdl)) { + gate->sa_len < sizeof(struct sockaddr_dl)) { log(LOG_DEBUG, "%s: bad gateway value: %s\n", __func__, ifp->if_xname); break; @@ -1127,14 +1119,9 @@ nd6_rtrequest(int req, struct rtentry *rt) ifa = &in6ifa_ifpwithaddr(ifp, &satosin6(rt_key(rt))->sin6_addr)->ia_ifa; if (ifa) { - caddr_t macp = nd6_ifptomac(ifp); nd6_llinfo_settimer(ln, -1); ln->ln_state = ND6_LLINFO_REACHABLE; ln->ln_byhint = 0; - if (macp) { - memcpy(LLADDR(SDL(gate)), macp, ifp->if_addrlen); - SDL(gate)->sdl_alen = ifp->if_addrlen; - } /* * XXX Since lo0 is in the default rdomain we diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 8d6637fbb8e..50797c5004a 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_rtr.c,v 1.102 2015/04/27 14:51:44 mpi Exp $ */ +/* $OpenBSD: nd6_rtr.c,v 1.103 2015/05/15 12:00:57 claudio Exp $ */ /* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */ /* @@ -45,6 +45,7 @@ #include <sys/queue.h> #include <net/if.h> +#include <net/if_dl.h> #include <net/if_var.h> #include <net/if_types.h> #include <net/route.h> @@ -1651,6 +1652,7 @@ nd6_prefix_onlink(struct nd_prefix *pr) struct ifaddr *ifa; struct ifnet *ifp = pr->ndpr_ifp; struct sockaddr_in6 mask6; + struct sockaddr_dl sa_dl = { sizeof(sa_dl), AF_LINK }; struct nd_prefix *opr; u_long rtflags; int error = 0; @@ -1723,6 +1725,10 @@ nd6_prefix_onlink(struct nd_prefix *pr) bzero(&mask6, sizeof(mask6)); mask6.sin6_len = sizeof(mask6); mask6.sin6_addr = pr->ndpr_mask; + + sa_dl.sdl_type = ifp->if_type; + sa_dl.sdl_index = ifp->if_index; + /* rtrequest1() will probably set RTF_UP, but we're not sure. */ rtflags = RTF_UP; if (nd6_need_cache(ifp)) @@ -1733,7 +1739,7 @@ nd6_prefix_onlink(struct nd_prefix *pr) bzero(&info, sizeof(info)); info.rti_flags = rtflags; info.rti_info[RTAX_DST] = sin6tosa(&pr->ndpr_prefix); - info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&sa_dl; info.rti_info[RTAX_NETMASK] = sin6tosa(&mask6); error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &rt, ifp->if_rdomain); |