diff options
author | sperreault <sperreault@cvs.openbsd.org> | 2011-11-24 17:39:56 +0000 |
---|---|---|
committer | sperreault <sperreault@cvs.openbsd.org> | 2011-11-24 17:39:56 +0000 |
commit | d67c8bea4b36b638bcf0cd636e0c6156e7426a00 (patch) | |
tree | c8dd340a09fc02bbe2662fc4377f61b38b9f64b7 /sys/netinet6 | |
parent | 23c8c1b7348659e6da6ee988df1422e263d59262 (diff) |
rdomain support for IPv6
ok mikeb
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/icmp6.c | 20 | ||||
-rw-r--r-- | sys/netinet6/in6.c | 22 | ||||
-rw-r--r-- | sys/netinet6/in6.h | 4 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 13 | ||||
-rw-r--r-- | sys/netinet6/in6_pcb.c | 6 | ||||
-rw-r--r-- | sys/netinet6/in6_src.c | 39 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 6 | ||||
-rw-r--r-- | sys/netinet6/mld6.c | 3 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 13 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 12 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 13 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 12 | ||||
-rw-r--r-- | sys/netinet6/udp6_output.c | 9 |
14 files changed, 104 insertions, 72 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 722fa369919..1501766bfac 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.116 2011/04/06 19:23:15 sthen Exp $ */ +/* $OpenBSD: icmp6.c,v 1.117 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -181,7 +181,7 @@ int ni6_addrs(struct icmp6_nodeinfo *, struct mbuf *, struct ifnet **, int ni6_store_addrs(struct icmp6_nodeinfo *, struct icmp6_nodeinfo *, struct ifnet *, int); int icmp6_notify_error(struct mbuf *, int, int, int); -struct rtentry *icmp6_mtudisc_clone(struct sockaddr *); +struct rtentry *icmp6_mtudisc_clone(struct sockaddr *, u_int); void icmp6_mtudisc_timeout(struct rtentry *, struct rttimer *); void icmp6_redirect_timeout(struct rtentry *, struct rttimer *); @@ -1147,7 +1147,7 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated) htons(m->m_pkthdr.rcvif->if_index); } /* sin6.sin6_scope_id = XXX: should be set if DST is a scoped addr */ - rt = icmp6_mtudisc_clone((struct sockaddr *)&sin6); + rt = icmp6_mtudisc_clone((struct sockaddr *)&sin6, m->m_pkthdr.rdomain); if (rt && (rt->rt_flags & RTF_HOST) && !(rt->rt_rmx.rmx_locks & RTV_MTU) && @@ -1217,7 +1217,7 @@ ni6_input(struct mbuf *m, int off) sin6.sin6_len = sizeof(struct sockaddr_in6); bcopy(&ip6->ip6_dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr)); /* XXX scopeid */ - if (ifa_ifwithaddr((struct sockaddr *)&sin6, /* XXX */ 0)) + if (ifa_ifwithaddr((struct sockaddr *)&sin6, m->m_pkthdr.rdomain)) ; /* unicast/anycast, fine */ else if (IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) ; /* link-local multicast, fine */ @@ -2083,7 +2083,8 @@ icmp6_reflect(struct mbuf *m, size_t off) * source address of the erroneous packet. */ bzero(&ro, sizeof(ro)); - src = in6_selectsrc(&sa6_src, NULL, NULL, &ro, NULL, &e); + src = in6_selectsrc(&sa6_src, NULL, NULL, &ro, NULL, &e, + m->m_pkthdr.rdomain); if (ro.ro_rt) { /* XXX: see comments in icmp6_mtudisc_update */ RTFREE(ro.ro_rt); /* XXX: we could use this */ } @@ -2220,7 +2221,7 @@ icmp6_redirect_input(struct mbuf *m, int off) sin6.sin6_family = AF_INET6; sin6.sin6_len = sizeof(struct sockaddr_in6); bcopy(&reddst6, &sin6.sin6_addr, sizeof(reddst6)); - rt = rtalloc1((struct sockaddr *)&sin6, 0, 0); + rt = rtalloc1((struct sockaddr *)&sin6, 0, m->m_pkthdr.rdomain); if (rt) { if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) { @@ -2747,12 +2748,12 @@ icmp6_ratelimit(const struct in6_addr *dst, const int type, const int code) } struct rtentry * -icmp6_mtudisc_clone(struct sockaddr *dst) +icmp6_mtudisc_clone(struct sockaddr *dst, u_int rdomain) { struct rtentry *rt; int error; - rt = rtalloc1(dst, RT_REPORT, 0); + rt = rtalloc1(dst, RT_REPORT, rdomain); if (rt == 0) return NULL; @@ -2765,7 +2766,8 @@ icmp6_mtudisc_clone(struct sockaddr *dst) info.rti_flags = RTF_GATEWAY | RTF_HOST | RTF_DYNAMIC; info.rti_info[RTAX_DST] = dst; info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; - error = rtrequest1(RTM_ADD, &info, rt->rt_priority, &nrt, 0); + error = rtrequest1(RTM_ADD, &info, rt->rt_priority, &nrt, + rdomain); if (error) { rtfree(rt); return NULL; diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 52fd97568f7..99535f54698 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.93 2011/08/08 13:04:35 bluhm Exp $ */ +/* $OpenBSD: in6.c,v 1.94 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -171,7 +171,8 @@ in6_ifloop_request(int cmd, struct ifaddr *ifa) if (cmd != RTM_DELETE) info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&all1_sa; - e = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, 0); + e = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, + ifa->ifa_ifp->if_rdomain); if (e != 0) { log(LOG_ERR, "in6_ifloop_request: " "%s operation failed for %s (errno=%d)\n", @@ -227,7 +228,7 @@ in6_ifaddloop(struct ifaddr *ifa) struct rtentry *rt; /* If there is no loopback entry, allocate one. */ - rt = rtalloc1(ifa->ifa_addr, 0, 0); + rt = rtalloc1(ifa->ifa_addr, 0, ifa->ifa_ifp->if_rdomain); if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 || (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) in6_ifloop_request(RTM_ADD, ifa); @@ -1084,7 +1085,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, * actually do not need the routes, since they usually specify * the outgoing interface. */ - rt = rtalloc1((struct sockaddr *)&mltaddr, 0, 0); + rt = rtalloc1((struct sockaddr *)&mltaddr, 0, ifp->if_rdomain); if (rt) { /* * 32bit came from "mltmask" @@ -1110,7 +1111,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, /* XXX: we need RTF_CLONING to fake nd6_rtrequest */ info.rti_flags = RTF_UP | RTF_CLONING; error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, NULL, - 0); + ifp->if_rdomain); if (error) goto cleanup; } else { @@ -1156,7 +1157,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, mltaddr.sin6_scope_id = 0; /* XXX: again, do we really need the route? */ - rt = rtalloc1((struct sockaddr *)&mltaddr, 0, 0); + rt = rtalloc1((struct sockaddr *)&mltaddr, 0, ifp->if_rdomain); if (rt) { /* 32bit came from "mltmask" */ if (memcmp(&mltaddr.sin6_addr, @@ -1179,7 +1180,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, (struct sockaddr *)&ia->ia_addr; info.rti_flags = RTF_UP | RTF_CLONING; error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, - NULL, 0); + NULL, ifp->if_rdomain); if (error) goto cleanup; } else { @@ -1937,7 +1938,7 @@ in6_ifpprefix(const struct ifnet *ifp, const struct in6_addr *addr) { struct sockaddr_in6 dst; struct rtentry *rt; - u_int tableid = 0; /* XXX */ + u_int tableid = ifp->if_rdomain; bzero(&dst, sizeof(dst)); dst.sin6_len = sizeof(struct sockaddr_in6); @@ -2179,7 +2180,7 @@ in6_prefixlen2mask(struct in6_addr *maskp, int len) * return the best address out of the same scope */ struct in6_ifaddr * -in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst) +in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst, u_int rdomain) { int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0; int blen = -1; @@ -2199,6 +2200,9 @@ in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst) */ for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { + if (ifp->if_rdomain != rdomain) + continue; + /* * We can never take an address that breaks the scope zone * of the destination. diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 4b55f0e1f03..80cca1a9232 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.h,v 1.54 2011/10/13 18:23:40 claudio Exp $ */ +/* $OpenBSD: in6.h,v 1.55 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ /* @@ -784,7 +784,7 @@ struct cmsghdr; int in6_cksum(struct mbuf *, u_int8_t, u_int32_t, u_int32_t); int in6_localaddr(struct in6_addr *); int in6_addrscope(struct in6_addr *); -struct in6_ifaddr *in6_ifawithscope(struct ifnet *, struct in6_addr *); +struct in6_ifaddr *in6_ifawithscope(struct ifnet *, struct in6_addr *, u_int); extern void in6_if_up(struct ifnet *); void in6_get_rand_ifid(struct ifnet *, struct in6_addr *); int in6_mask2len(struct in6_addr *, u_char *); diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index be61bddc831..1a7d1b4c28e 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_ifattach.c,v 1.51 2010/04/06 14:12:10 stsp Exp $ */ +/* $OpenBSD: in6_ifattach.c,v 1.52 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $ */ /* @@ -699,7 +699,8 @@ in6_ifdetach(struct ifnet *ifp) /* remove from the routing table */ if ((ia->ia_flags & IFA_ROUTE) && - (rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0, 0))) { + (rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0, + ifp->if_rdomain))) { struct rt_addrinfo info; u_int8_t prio; @@ -713,7 +714,8 @@ in6_ifdetach(struct ifnet *ifp) info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&ia->ia_prefixmask; rtfree(rt); - rtrequest1(RTM_DELETE, &info, prio, NULL, 0); + rtrequest1(RTM_DELETE, &info, prio, NULL, + ifp->if_rdomain); } /* remove from the linked list */ @@ -758,7 +760,7 @@ in6_ifdetach(struct ifnet *ifp) sin6.sin6_family = AF_INET6; sin6.sin6_addr = in6addr_linklocal_allnodes; sin6.sin6_addr.s6_addr16[1] = htons(ifp->if_index); - rt = rtalloc1((struct sockaddr *)&sin6, 0, 0); + rt = rtalloc1((struct sockaddr *)&sin6, 0, ifp->if_rdomain); if (rt && rt->rt_ifp == ifp) { struct rt_addrinfo info; @@ -767,7 +769,8 @@ in6_ifdetach(struct ifnet *ifp) info.rti_info[RTAX_DST] = rt_key(rt); info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; info.rti_info[RTAX_NETMASK] = rt_mask(rt); - rtrequest1(RTM_DELETE, &info, rt->rt_priority, NULL, 0); + rtrequest1(RTM_DELETE, &info, rt->rt_priority, NULL, + ifp->if_rdomain); rtfree(rt); } } diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index a5f4f9502f7..c0fb81ec6f5 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.49 2009/06/05 00:05:22 claudio Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.50 2011/11/24 17:39:55 sperreault Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -236,7 +236,7 @@ in6_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) sin6->sin6_flowinfo = 0; if (!(so->so_options & SO_BINDANY) && (ia = ifa_ifwithaddr((struct sockaddr *)sin6, - /* XXX */ 0)) == NULL) + inp->inp_rtableid)) == NULL) return EADDRNOTAVAIL; /* @@ -438,7 +438,7 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam) */ in6a = in6_selectsrc(sin6, inp->inp_outputopts6, inp->inp_moptions6, &inp->inp_route6, &inp->inp_laddr6, - &error); + &error, inp->inp_rtableid); if (in6a == 0) { if (error == 0) error = EADDRNOTAVAIL; diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index d4ba5a85272..4182737d9ab 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_src.c,v 1.26 2011/08/07 18:49:50 mikeb Exp $ */ +/* $OpenBSD: in6_src.c,v 1.27 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */ /* @@ -87,10 +87,10 @@ #include <netinet6/nd6.h> int in6_selectif(struct sockaddr_in6 *, struct ip6_pktopts *, - struct ip6_moptions *, struct route_in6 *, struct ifnet **); + struct ip6_moptions *, struct route_in6 *, struct ifnet **, u_int); int selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, struct ip6_moptions *, struct route_in6 *, struct ifnet **, - struct rtentry **, int); + struct rtentry **, int, u_int); /* * Return an IPv6 address, which is the most appropriate for a given @@ -101,7 +101,7 @@ int selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, struct in6_addr * in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, struct ip6_moptions *mopts, struct route_in6 *ro, struct in6_addr *laddr, - int *errorp) + int *errorp, u_int rtableid) { struct in6_addr *dst; struct in6_ifaddr *ia6 = 0; @@ -123,7 +123,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, /* get the outgoing interface */ if ((*errorp = in6_selectif(dstsock, opts, mopts, ro, - &ifp)) != 0) + &ifp, rtableid)) != 0) return (NULL); bzero(&sa6, sizeof(sa6)); @@ -135,7 +135,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, sa6.sin6_addr.s6_addr16[1] = htons(ifp->if_index); ia6 = (struct in6_ifaddr *) - ifa_ifwithaddr((struct sockaddr *)&sa6, 0); + ifa_ifwithaddr((struct sockaddr *)&sa6, rtableid); if (ia6 == NULL || (ia6->ia6_flags & (IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) { *errorp = EADDRNOTAVAIL; @@ -162,7 +162,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, if (pi && pi->ipi6_ifindex) { /* XXX boundary check is assumed to be already done. */ ia6 = in6_ifawithscope(ifindex2ifnet[pi->ipi6_ifindex], - dst); + dst, rtableid); if (ia6 == 0) { *errorp = EADDRNOTAVAIL; return (0); @@ -192,7 +192,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, return (0); } ia6 = in6_ifawithscope(ifindex2ifnet[dstsock->sin6_scope_id], - dst); + dst, rtableid); if (ia6 == 0) { *errorp = EADDRNOTAVAIL; return (0); @@ -214,7 +214,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, ifp = ifindex2ifnet[htons(dstsock->sin6_scope_id)]; if (ifp) { - ia6 = in6_ifawithscope(ifp, dst); + ia6 = in6_ifawithscope(ifp, dst, rtableid); if (ia6 == 0) { *errorp = EADDRNOTAVAIL; return (0); @@ -236,7 +236,8 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, sin6_next = satosin6(opts->ip6po_nexthop); rt = nd6_lookup(&sin6_next->sin6_addr, 1, NULL); if (rt) { - ia6 = in6_ifawithscope(rt->rt_ifp, dst); + ia6 = in6_ifawithscope(rt->rt_ifp, dst, + rtableid); if (ia6 == 0) ia6 = ifatoia6(rt->rt_ifa); } @@ -284,7 +285,8 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, */ if (ro->ro_rt) { - ia6 = in6_ifawithscope(ro->ro_rt->rt_ifa->ifa_ifp, dst); + ia6 = in6_ifawithscope(ro->ro_rt->rt_ifa->ifa_ifp, dst, + rtableid); if (ia6 == 0) /* xxx scope error ?*/ ia6 = ifatoia6(ro->ro_rt->rt_ifa); } @@ -321,7 +323,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, int selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp, - struct rtentry **retrt, int norouteok) + struct rtentry **retrt, int norouteok, u_int rtableid) { int error = 0; struct ifnet *ifp = NULL; @@ -401,7 +403,7 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, ron->ro_rt = NULL; } *satosin6(&ron->ro_dst) = *sin6_next; - ron->ro_tableid = 0; /* XXX rtableid */ + ron->ro_tableid = rtableid; } if (ron->ro_rt == NULL) { rtalloc((struct route *)ron); /* multi path case? */ @@ -454,6 +456,7 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, sa6 = (struct sockaddr_in6 *)&ro->ro_dst; *sa6 = *dstsock; sa6->sin6_scope_id = 0; + ro->ro_tableid = rtableid; rtalloc_mpath((struct route *)ro, NULL); } @@ -515,13 +518,14 @@ selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, int in6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, - struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp) + struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp, + u_int rtableid) { struct rtentry *rt = NULL; int error; if ((error = selectroute(dstsock, opts, mopts, ro, retifp, - &rt, 1)) != 0) + &rt, 1, rtableid)) != 0) return (error); /* @@ -560,10 +564,11 @@ in6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, int in6_selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp, - struct rtentry **retrt) + struct rtentry **retrt, u_int rtableid) { - return (selectroute(dstsock, opts, mopts, ro, retifp, retrt, 0)); + return (selectroute(dstsock, opts, mopts, ro, retifp, retrt, 0, + rtableid)); } /* diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index b4f7ff7a35f..148a51b0660 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.122 2011/07/04 06:54:49 claudio Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.123 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -563,7 +563,7 @@ reroute: dstsock.sin6_addr = ip6->ip6_dst; dstsock.sin6_len = sizeof(dstsock); if ((error = in6_selectroute(&dstsock, opt, im6o, ro, &ifp, - &rt)) != 0) { + &rt, m->m_pkthdr.rdomain)) != 0) { switch (error) { case EHOSTUNREACH: ip6stat.ip6s_noroute++; diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 7bfba24207f..61e30f08b4c 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.40 2011/03/22 23:13:01 bluhm Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.41 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -322,10 +322,10 @@ int none_input(struct mbuf **, int *, int); struct in6_addr *in6_selectsrc(struct sockaddr_in6 *, struct ip6_pktopts *, struct ip6_moptions *, struct route_in6 *, struct in6_addr *, - int *); + int *, u_int); int in6_selectroute(struct sockaddr_in6 *, struct ip6_pktopts *, struct ip6_moptions *, struct route_in6 *, struct ifnet **, - struct rtentry **); + struct rtentry **, u_int rtableid); u_int32_t ip6_randomflowlabel(void); #endif /* _KERNEL */ diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index 768d6cecf8d..41850220854 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mld6.c,v 1.27 2011/04/15 15:14:44 chl Exp $ */ +/* $OpenBSD: mld6.c,v 1.28 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: mld6.c,v 1.26 2001/02/16 14:50:35 itojun Exp $ */ /* @@ -386,6 +386,7 @@ mld6_sendpkt(struct in6_multi *in6m, int type, const struct in6_addr *dst) mh->m_next = md; mh->m_pkthdr.rcvif = NULL; + mh->m_pkthdr.rdomain = ifp->if_rdomain; mh->m_pkthdr.len = sizeof(struct ip6_hdr) + sizeof(struct mld_hdr); mh->m_len = sizeof(struct ip6_hdr); MH_ALIGN(mh, sizeof(struct ip6_hdr)); diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 0207bfbf964..95a94b124cf 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6.c,v 1.87 2011/06/17 07:06:47 mk Exp $ */ +/* $OpenBSD: nd6.c,v 1.88 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */ /* @@ -676,7 +676,7 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp) sin6.sin6_family = AF_INET6; sin6.sin6_addr = *addr6; - rt = rtalloc1((struct sockaddr *)&sin6, create, 0); + rt = rtalloc1((struct sockaddr *)&sin6, create, ifp->if_rdomain); if (rt && (rt->rt_flags & RTF_LLINFO) == 0) { /* * This is the case for the default route. @@ -720,7 +720,7 @@ nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp) info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&all1_sa; if ((e = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, - &rt, 0)) != 0) { + &rt, ifp->if_rdomain)) != 0) { #if 0 log(LOG_ERR, "nd6_lookup: failed to add route for a " @@ -928,7 +928,8 @@ nd6_free(struct rtentry *rt, int gc) bzero(&info, sizeof(info)); info.rti_info[RTAX_DST] = rt_key(rt); info.rti_info[RTAX_NETMASK] = rt_mask(rt); - rtrequest1(RTM_DELETE, &info, rt->rt_priority, NULL, 0); + rtrequest1(RTM_DELETE, &info, rt->rt_priority, NULL, + rt->rt_ifp->if_rdomain); return (next); } @@ -1774,7 +1775,7 @@ nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, if (rt) { if ((rt->rt_flags & RTF_UP) == 0) { if ((rt0 = rt = rtalloc1((struct sockaddr *)dst, - RT_REPORT, 0)) != NULL) + RT_REPORT, m->m_pkthdr.rdomain)) != NULL) { rt->rt_refcnt--; if (rt->rt_ifp != ifp) @@ -1813,7 +1814,7 @@ nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, rtfree(rt); rt = rt0; lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, - RT_REPORT, 0); + RT_REPORT, m->m_pkthdr.rdomain); if ((rt = rt->rt_gwroute) == 0) senderr(EHOSTUNREACH); } diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 4a6d8aeb6b7..e1a497c4c5a 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_nbr.c,v 1.59 2011/10/15 10:29:06 nigel Exp $ */ +/* $OpenBSD: nd6_nbr.c,v 1.60 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -222,7 +222,8 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) tsin6.sin6_family = AF_INET6; tsin6.sin6_addr = taddr6; - rt = rtalloc1((struct sockaddr *)&tsin6, 0, 0); + rt = rtalloc1((struct sockaddr *)&tsin6, 0, + m->m_pkthdr.rdomain); if (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 && rt->rt_gateway->sa_family == AF_LINK) { /* @@ -382,6 +383,7 @@ nd6_ns_output(struct ifnet *ifp, struct in6_addr *daddr6, if (m == NULL) return; m->m_pkthdr.rcvif = NULL; + m->m_pkthdr.rdomain = ifp->if_rdomain; if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) { m->m_flags |= M_MCAST; @@ -454,7 +456,7 @@ nd6_ns_output(struct ifnet *ifp, struct in6_addr *daddr6, bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa)); src0 = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, - &error); + &error, m->m_pkthdr.rdomain); if (src0 == NULL) { nd6log((LOG_DEBUG, "nd6_ns_output: source can't be " @@ -899,6 +901,7 @@ nd6_na_output(struct ifnet *ifp, struct in6_addr *daddr6, if (m == NULL) return; m->m_pkthdr.rcvif = NULL; + m->m_pkthdr.rdomain = ifp->if_rdomain; if (IN6_IS_ADDR_MULTICAST(daddr6)) { m->m_flags |= M_MCAST; @@ -939,7 +942,8 @@ nd6_na_output(struct ifnet *ifp, struct in6_addr *daddr6, * Select a source whose scope is the same as that of the dest. */ bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa)); - src0 = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, &error); + src0 = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, &error, + m->m_pkthdr.rdomain); if (src0 == NULL) { nd6log((LOG_DEBUG, "nd6_na_output: source can't be " "determined: dst=%s, error=%d\n", diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index f783f0c4489..3c890e30ead 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_rtr.c,v 1.55 2011/02/24 01:25:17 stsp Exp $ */ +/* $OpenBSD: nd6_rtr.c,v 1.56 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */ /* @@ -459,7 +459,8 @@ defrouter_addreq(struct nd_defrouter *new) info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask; s = splsoftnet(); - error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &newrt, 0); + error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &newrt, + new->ifp->if_rdomain); if (newrt) { nd6_rtmsg(RTM_ADD, newrt); /* tell user process */ newrt->rt_refcnt--; @@ -565,7 +566,8 @@ defrouter_delreq(struct nd_defrouter *dr) info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw; info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask; - rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &oldrt, 0); + rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &oldrt, + dr->ifp->if_rdomain); if (oldrt) { nd6_rtmsg(RTM_DELETE, oldrt); if (oldrt->rt_refcnt <= 0) { @@ -1623,7 +1625,7 @@ nd6_prefix_onlink(struct nd_prefix *pr) info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask6; - error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &rt, 0); + error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &rt, ifp->if_rdomain); if (error == 0) { if (rt != NULL) /* this should be non NULL, though */ nd6_rtmsg(RTM_ADD, rt); @@ -1674,7 +1676,8 @@ nd6_prefix_offlink(struct nd_prefix *pr) bzero(&info, sizeof(info)); info.rti_info[RTAX_DST] = (struct sockaddr *)&sa6; info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask6; - error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &rt, 0); + error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &rt, + ifp->if_rdomain); if (error == 0) { pr->ndpr_stateflags &= ~NDPRF_ONLINK; diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 65c1884d1c0..99de480d0f7 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.43 2011/05/13 14:31:17 oga Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.44 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -434,7 +434,8 @@ rip6_output(struct mbuf *m, ...) struct in6_addr *in6a; if ((in6a = in6_selectsrc(dstsock, optp, in6p->in6p_moptions, - &in6p->in6p_route, &in6p->in6p_laddr, &error)) == 0) { + &in6p->in6p_route, &in6p->in6p_laddr, &error, + in6p->inp_rtableid)) == 0) { if (error == 0) error = EADDRNOTAVAIL; goto bad; @@ -487,6 +488,9 @@ rip6_output(struct mbuf *m, ...) if (in6p->in6p_flags & IN6P_MINMTU) flags |= IPV6_MINMTU; + /* force routing domain */ + m->m_pkthdr.rdomain = in6p->inp_rtableid; + error = ip6_output(m, optp, &in6p->in6p_route, flags, in6p->in6p_moptions, &oifp, in6p); if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { @@ -677,7 +681,7 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, */ if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && (ia = ifa_ifwithaddr((struct sockaddr *)addr, - /* XXX */ 0)) == 0) { + in6p->inp_rtableid)) == 0) { error = EADDRNOTAVAIL; break; } @@ -725,7 +729,7 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, /* Source address selection. XXX: need pcblookup? */ in6a = in6_selectsrc(addr, in6p->in6p_outputopts, in6p->in6p_moptions, &in6p->in6p_route, - &in6p->in6p_laddr, &error); + &in6p->in6p_laddr, &error, in6p->inp_rtableid); if (in6a == NULL) { if (error == 0) error = EADDRNOTAVAIL; diff --git a/sys/netinet6/udp6_output.c b/sys/netinet6/udp6_output.c index 358814c97e3..a69966a2744 100644 --- a/sys/netinet6/udp6_output.c +++ b/sys/netinet6/udp6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp6_output.c,v 1.16 2008/11/23 13:30:59 claudio Exp $ */ +/* $OpenBSD: udp6_output.c,v 1.17 2011/11/24 17:39:55 sperreault Exp $ */ /* $KAME: udp6_output.c,v 1.21 2001/02/07 11:51:54 itojun Exp $ */ /* @@ -188,7 +188,8 @@ udp6_output(struct in6pcb *in6p, struct mbuf *m, struct mbuf *addr6, laddr = in6_selectsrc(sin6, optp, in6p->in6p_moptions, &in6p->in6p_route, - &in6p->in6p_laddr, &error); + &in6p->in6p_laddr, &error, + in6p->inp_rtableid); } else laddr = &in6p->in6p_laddr; /*XXX*/ if (laddr == NULL) { @@ -268,6 +269,10 @@ udp6_output(struct in6pcb *in6p, struct mbuf *m, struct mbuf *addr6, flags |= IPV6_MINMTU; udp6stat.udp6s_opackets++; + + /* force routing domain */ + m->m_pkthdr.rdomain = in6p->inp_rtableid; + error = ip6_output(m, optp, &in6p->in6p_route, flags, in6p->in6p_moptions, NULL, in6p); break; |