summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorsperreault <sperreault@cvs.openbsd.org>2011-11-24 17:39:56 +0000
committersperreault <sperreault@cvs.openbsd.org>2011-11-24 17:39:56 +0000
commitd67c8bea4b36b638bcf0cd636e0c6156e7426a00 (patch)
treec8dd340a09fc02bbe2662fc4377f61b38b9f64b7 /sys/netinet6
parent23c8c1b7348659e6da6ee988df1422e263d59262 (diff)
rdomain support for IPv6
ok mikeb
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/icmp6.c20
-rw-r--r--sys/netinet6/in6.c22
-rw-r--r--sys/netinet6/in6.h4
-rw-r--r--sys/netinet6/in6_ifattach.c13
-rw-r--r--sys/netinet6/in6_pcb.c6
-rw-r--r--sys/netinet6/in6_src.c39
-rw-r--r--sys/netinet6/ip6_output.c4
-rw-r--r--sys/netinet6/ip6_var.h6
-rw-r--r--sys/netinet6/mld6.c3
-rw-r--r--sys/netinet6/nd6.c13
-rw-r--r--sys/netinet6/nd6_nbr.c12
-rw-r--r--sys/netinet6/nd6_rtr.c13
-rw-r--r--sys/netinet6/raw_ip6.c12
-rw-r--r--sys/netinet6/udp6_output.c9
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;