summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2009-06-05 00:05:21 +0000
committerclaudio <claudio@openbsd.org>2009-06-05 00:05:21 +0000
commit22760f565a521eee1242a6b1041c186acc77d298 (patch)
treecf09757382c6a5172e7749b5e2348595c70d6bc3 /sys/netinet
parentMake imsg completely async model agnostic by not requiring an (diff)
downloadwireguard-openbsd-22760f565a521eee1242a6b1041c186acc77d298.tar.xz
wireguard-openbsd-22760f565a521eee1242a6b1041c186acc77d298.zip
Initial support for routing domains. This allows to bind interfaces to
alternate routing table and separate them from other interfaces in distinct routing tables. The same network can now be used in any doamin at the same time without causing conflicts. This diff is mostly mechanical and adds the necessary rdomain checks accross net and netinet. L2 and IPv4 are mostly covered still missing pf and IPv6. input and tested by jsg@, phessler@ and reyk@. "put it in" deraadt@
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/if_ether.c30
-rw-r--r--sys/netinet/in.c19
-rw-r--r--sys/netinet/in.h4
-rw-r--r--sys/netinet/in_pcb.c103
-rw-r--r--sys/netinet/in_pcb.h11
-rw-r--r--sys/netinet/in_var.h7
-rw-r--r--sys/netinet/ip_carp.c29
-rw-r--r--sys/netinet/ip_icmp.c25
-rw-r--r--sys/netinet/ip_icmp.h6
-rw-r--r--sys/netinet/ip_input.c64
-rw-r--r--sys/netinet/ip_ipip.c4
-rw-r--r--sys/netinet/ip_mroute.c4
-rw-r--r--sys/netinet/ip_output.c77
-rw-r--r--sys/netinet/ip_var.h8
-rw-r--r--sys/netinet/raw_ip.c12
-rw-r--r--sys/netinet/tcp_input.c10
-rw-r--r--sys/netinet/tcp_output.c5
-rw-r--r--sys/netinet/tcp_subr.c11
-rw-r--r--sys/netinet/tcp_timer.c7
-rw-r--r--sys/netinet/tcp_usrreq.c13
-rw-r--r--sys/netinet/tcp_var.h3
-rw-r--r--sys/netinet/udp_usrreq.c16
22 files changed, 283 insertions, 185 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 695ecbbea4b..cd814028cee 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ether.c,v 1.79 2008/12/24 08:26:27 claudio Exp $ */
+/* $OpenBSD: if_ether.c,v 1.80 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */
/*
@@ -82,7 +82,7 @@ int arpt_down = 20; /* once declared down, don't send for 20 secs */
void arptfree(struct llinfo_arp *);
void arptimer(void *);
-struct llinfo_arp *arplookup(u_int32_t, int, int);
+struct llinfo_arp *arplookup(u_int32_t, int, int, u_int);
void in_arpinput(struct mbuf *);
LIST_HEAD(, llinfo_arp) llinfo_arp;
@@ -200,7 +200,8 @@ arp_rtrequest(req, rt, info)
* Case 1: This route should come from a route to iface.
*/
rt_setgate(rt, rt_key(rt),
- (struct sockaddr *)&null_sdl, 0);
+ (struct sockaddr *)&null_sdl,
+ rt->rt_ifp->if_rdomain);
gate = rt->rt_gateway;
SDL(gate)->sdl_type = rt->rt_ifp->if_type;
SDL(gate)->sdl_index = rt->rt_ifp->if_index;
@@ -338,6 +339,7 @@ arprequest(ifp, sip, tip, enaddr)
return;
m->m_len = sizeof(*ea);
m->m_pkthdr.len = sizeof(*ea);
+ m->m_pkthdr.rdomain = ifp->if_rdomain;
MH_ALIGN(m, sizeof(*ea));
ea = mtod(m, struct ether_arp *);
eh = (struct ether_header *)sa.sa_data;
@@ -397,7 +399,8 @@ arpresolve(ac, rt, m, dst, desten)
log(LOG_DEBUG, "arpresolve: %s: route without link "
"local address\n", inet_ntoa(SIN(dst)->sin_addr));
} else {
- if ((la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0)) != NULL)
+ if ((la = arplookup(SIN(dst)->sin_addr.s_addr, 1, 0,
+ ac->ac_if.if_rdomain)) != NULL)
rt = la->la_rt;
else
log(LOG_DEBUG,
@@ -689,7 +692,8 @@ in_arpinput(m)
itaddr = myaddr;
goto reply;
}
- la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0);
+ la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0,
+ m->m_pkthdr.rdomain);
if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) {
if (sdl->sdl_alen) {
if (bcmp(ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) {
@@ -771,7 +775,8 @@ reply:
bcopy(ea->arp_sha, ea->arp_tha, sizeof(ea->arp_sha));
bcopy(enaddr, ea->arp_sha, sizeof(ea->arp_sha));
} else {
- la = arplookup(itaddr.s_addr, 0, SIN_PROXY);
+ la = arplookup(itaddr.s_addr, 0, SIN_PROXY,
+ m->m_pkthdr.rdomain);
if (la == 0)
goto out;
rt = la->la_rt;
@@ -812,6 +817,7 @@ arptfree(la)
struct rtentry *rt = la->la_rt;
struct sockaddr_dl *sdl;
struct rt_addrinfo info;
+ u_int tid = 0;
if (rt == 0)
panic("arptfree");
@@ -826,16 +832,20 @@ arptfree(la)
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);
+ if (rt->rt_ifp)
+ tid = rt->rt_ifp->if_rdomain;
+
+ rtrequest1(RTM_DELETE, &info, rt->rt_priority, NULL, tid);
}
/*
* Lookup or enter a new address in arptab.
*/
struct llinfo_arp *
-arplookup(addr, create, proxy)
+arplookup(addr, create, proxy, tableid)
u_int32_t addr;
int create, proxy;
+ u_int tableid;
{
struct rtentry *rt;
static struct sockaddr_inarp sin;
@@ -844,7 +854,7 @@ arplookup(addr, create, proxy)
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = addr;
sin.sin_other = proxy ? SIN_PROXY : 0;
- rt = rtalloc1(sintosa(&sin), create, 0);
+ rt = rtalloc1(sintosa(&sin), create, tableid);
if (rt == 0)
return (0);
rt->rt_refcnt--;
@@ -861,7 +871,7 @@ arplookup(addr, create, proxy)
info.rti_info[RTAX_NETMASK] = rt_mask(rt);
rtrequest1(RTM_DELETE, &info, rt->rt_priority,
- NULL, 0);
+ NULL, tableid);
}
}
return (0);
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 887b3fda6b0..13e22342aed 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in.c,v 1.53 2009/03/15 19:40:41 miod Exp $ */
+/* $OpenBSD: in.c,v 1.54 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */
/*
@@ -113,19 +113,24 @@ int hostzeroisbroadcast = HOSTZEROBROADCAST;
* Otherwise, it includes only the directly-connected (sub)nets.
*/
int
-in_localaddr(in)
- struct in_addr in;
+in_localaddr(struct in_addr in, u_int rdomain)
{
struct in_ifaddr *ia;
if (subnetsarelocal) {
- TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
+ TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
+ if (ia->ia_ifp->if_rdomain != rdomain)
+ continue;
if ((in.s_addr & ia->ia_netmask) == ia->ia_net)
return (1);
+ }
} else {
- TAILQ_FOREACH(ia, &in_ifaddr, ia_list)
+ TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
+ if (ia->ia_ifp->if_rdomain != rdomain)
+ continue;
if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet)
return (1);
+ }
}
return (0);
}
@@ -786,6 +791,8 @@ in_addprefix(target, flags)
}
TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
+ if (ia->ia_ifp->if_rdomain != target->ia_ifp->if_rdomain)
+ continue;
if (rtinitflags(ia)) {
p = ia->ia_dstaddr.sin_addr;
if (prefix.s_addr != p.s_addr)
@@ -857,6 +864,8 @@ in_scrubprefix(target)
p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
}
+ if (ia->ia_ifp->if_rdomain != target->ia_ifp->if_rdomain)
+ continue;
if (prefix.s_addr != p.s_addr)
continue;
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 18835e77c81..3e9256327ba 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in.h,v 1.78 2008/12/24 07:41:59 dlg Exp $ */
+/* $OpenBSD: in.h,v 1.79 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */
/*
@@ -766,7 +766,7 @@ int in_canforward(struct in_addr);
int in_cksum(struct mbuf *, int);
int in4_cksum(struct mbuf *, u_int8_t, int, int);
void in_delayed_cksum(struct mbuf *);
-int in_localaddr(struct in_addr);
+int in_localaddr(struct in_addr, u_int);
void in_socktrim(struct sockaddr_in *);
char *inet_ntoa(struct in_addr);
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 0077d250628..2a0cf48040f 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.104 2009/03/15 19:40:41 miod Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.105 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -121,17 +121,17 @@ int ipport_hilastauto = IPPORT_HILASTAUTO;
struct pool inpcb_pool;
int inpcb_pool_initialized = 0;
-#define INPCBHASH(table, faddr, fport, laddr, lport) \
+#define INPCBHASH(table, faddr, fport, laddr, lport, rdom) \
&(table)->inpt_hashtbl[(ntohl((faddr)->s_addr) + \
- ntohs((fport)) + ntohs((lport))) & (table->inpt_hash)]
+ ntohs((fport)) + ntohs((lport)) + (rdom)) & (table->inpt_hash)]
#define IN6PCBHASH(table, faddr, fport, laddr, lport) \
&(table)->inpt_hashtbl[(ntohl((faddr)->s6_addr32[0] ^ \
(faddr)->s6_addr32[3]) + ntohs((fport)) + ntohs((lport))) & \
(table->inpt_hash)]
-#define INPCBLHASH(table, lport) \
- &(table)->inpt_lhashtbl[lport & table->inpt_lhash]
+#define INPCBLHASH(table, lport, rdom) \
+ &(table)->inpt_lhashtbl[(ntohs((lport)) + (rdom)) & table->inpt_lhash]
void
in_pcbinit(table, hashsize)
@@ -200,9 +200,10 @@ in_pcballoc(so, v)
inp->inp_seclevel[SL_IPCOMP] = ipsec_ipcomp_default_level;
s = splnet();
CIRCLEQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue);
- LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport), inp, inp_lhash);
+ LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport, inp->inp_rdomain),
+ inp, inp_lhash);
LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr, inp->inp_fport,
- &inp->inp_laddr, inp->inp_lport), inp, inp_hash);
+ &inp->inp_laddr, inp->inp_lport, inp->inp_rdomain), inp, inp_hash);
splx(s);
so->so_pcb = inp;
inp->inp_hops = -1;
@@ -274,7 +275,8 @@ in_pcbbind(v, nam, p)
} else if (sin->sin_addr.s_addr != INADDR_ANY) {
sin->sin_port = 0; /* yech... */
if (!(so->so_options & SO_BINDANY) &&
- in_iawithaddr(sin->sin_addr, NULL) == 0)
+ in_iawithaddr(sin->sin_addr, NULL,
+ inp->inp_rdomain) == 0)
return (EADDRNOTAVAIL);
}
if (lport) {
@@ -286,12 +288,13 @@ in_pcbbind(v, nam, p)
return (EACCES);
if (so->so_euid) {
t = in_pcblookup(table, &zeroin_addr, 0,
- &sin->sin_addr, lport, INPLOOKUP_WILDCARD);
+ &sin->sin_addr, lport, INPLOOKUP_WILDCARD,
+ inp->inp_rdomain);
if (t && (so->so_euid != t->inp_socket->so_euid))
return (EADDRINUSE);
}
t = in_pcblookup(table, &zeroin_addr, 0,
- &sin->sin_addr, lport, wild);
+ &sin->sin_addr, lport, wild, inp->inp_rdomain);
if (t && (reuseport & t->inp_socket->so_options) == 0)
return (EADDRINUSE);
}
@@ -339,7 +342,7 @@ in_pcbbind(v, nam, p)
lport = htons(*lastport);
} while (in_baddynamic(*lastport, so->so_proto->pr_protocol) ||
in_pcblookup(table, &zeroin_addr, 0,
- &inp->inp_laddr, lport, wild));
+ &inp->inp_laddr, lport, wild, inp->inp_rdomain));
} else {
/*
* counting up
@@ -357,7 +360,7 @@ in_pcbbind(v, nam, p)
lport = htons(*lastport);
} while (in_baddynamic(*lastport, so->so_proto->pr_protocol) ||
in_pcblookup(table, &zeroin_addr, 0,
- &inp->inp_laddr, lport, wild));
+ &inp->inp_laddr, lport, wild, inp->inp_rdomain));
}
}
inp->inp_lport = lport;
@@ -410,7 +413,8 @@ in_pcbconnect(v, nam)
if (inp->inp_laddr.s_addr == INADDR_ANY) {
int error;
ifaddr = in_selectsrc(sin, &inp->inp_route,
- inp->inp_socket->so_options, inp->inp_moptions, &error);
+ inp->inp_socket->so_options, inp->inp_moptions, &error,
+ inp->inp_rdomain);
if (ifaddr == NULL) {
if (error == 0)
error = EADDRNOTAVAIL;
@@ -419,7 +423,7 @@ in_pcbconnect(v, nam)
}
if (in_pcbhashlookup(inp->inp_table, sin->sin_addr, sin->sin_port,
inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr,
- inp->inp_lport) != 0)
+ inp->inp_lport, inp->inp_rdomain) != 0)
return (EADDRINUSE);
if (inp->inp_laddr.s_addr == INADDR_ANY) {
if (inp->inp_lport == 0 &&
@@ -630,10 +634,11 @@ in_losing(inp)
info.rti_info[RTAX_DST] = &inp->inp_route.ro_dst;
info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
info.rti_info[RTAX_NETMASK] = rt_mask(rt);
- rt_missmsg(RTM_LOSING, &info, rt->rt_flags, rt->rt_ifp, 0, 0);
+ rt_missmsg(RTM_LOSING, &info, rt->rt_flags, rt->rt_ifp, 0,
+ inp->inp_rdomain);
if (rt->rt_flags & RTF_DYNAMIC)
(void)rtrequest1(RTM_DELETE, &info, rt->rt_priority,
- (struct rtentry **)0, 0);
+ (struct rtentry **)0, inp->inp_rdomain);
/*
* A new route can be allocated
* the next time output is attempted.
@@ -664,11 +669,7 @@ in_rtchange(inp, errno)
}
struct inpcb *
-in_pcblookup(table, faddrp, fport_arg, laddrp, lport_arg, flags)
- struct inpcbtable *table;
- void *faddrp, *laddrp;
- u_int fport_arg, lport_arg;
- int flags;
+in_pcblookup(struct inpcbtable *table, void *faddrp, u_int fport_arg, void *laddrp, u_int lport_arg, int flags, u_int rdomain)
{
struct inpcb *inp, *match = 0;
int matchwild = 3, wildcard;
@@ -676,8 +677,10 @@ in_pcblookup(table, faddrp, fport_arg, laddrp, lport_arg, flags)
struct in_addr faddr = *(struct in_addr *)faddrp;
struct in_addr laddr = *(struct in_addr *)laddrp;
- for (inp = LIST_FIRST(INPCBLHASH(table, lport)); inp;
+ for (inp = LIST_FIRST(INPCBLHASH(table, lport, rdomain)); inp;
inp = LIST_NEXT(inp, inp_lhash)) {
+ if (inp->inp_rdomain != rdomain)
+ continue;
if (inp->inp_lport != lport)
continue;
wildcard = 0;
@@ -791,12 +794,8 @@ in_pcbrtentry(inp)
}
struct sockaddr_in *
-in_selectsrc(sin, ro, soopts, mopts, errorp)
- struct sockaddr_in *sin;
- struct route *ro;
- int soopts;
- struct ip_moptions *mopts;
- int *errorp;
+in_selectsrc(struct sockaddr_in *sin, struct route *ro, int soopts,
+ struct ip_moptions *mopts, int *errorp, u_int rdomain)
{
struct sockaddr_in *sin2;
struct in_ifaddr *ia;
@@ -820,7 +819,7 @@ in_selectsrc(sin, ro, soopts, mopts, errorp)
ro->ro_dst.sa_family = AF_INET;
ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
satosin(&ro->ro_dst)->sin_addr = sin->sin_addr;
- rtalloc_mpath(ro, NULL, 0);
+ rtalloc_mpath(ro, NULL, rdomain);
/*
* It is important to bzero out the rest of the
@@ -841,9 +840,9 @@ in_selectsrc(sin, ro, soopts, mopts, errorp)
u_int16_t fport = sin->sin_port;
sin->sin_port = 0;
- ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin)));
+ ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin), rdomain));
if (ia == 0)
- ia = ifatoia(ifa_ifwithnet(sintosa(sin)));
+ ia = ifatoia(ifa_ifwithnet(sintosa(sin), rdomain));
sin->sin_port = fport;
if (ia == 0)
ia = TAILQ_FIRST(&in_ifaddr);
@@ -885,7 +884,8 @@ in_pcbrehash(inp)
s = splnet();
LIST_REMOVE(inp, inp_lhash);
- LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport), inp, inp_lhash);
+ LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport, inp->inp_rdomain),
+ inp, inp_lhash);
LIST_REMOVE(inp, inp_hash);
#ifdef INET6
if (inp->inp_flags & INP_IPV6) {
@@ -895,8 +895,8 @@ in_pcbrehash(inp)
} else {
#endif /* INET6 */
LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr,
- inp->inp_fport, &inp->inp_laddr, inp->inp_lport),
- inp, inp_hash);
+ inp->inp_fport, &inp->inp_laddr, inp->inp_lport,
+ inp->inp_rdomain), inp, inp_hash);
#ifdef INET6
}
#endif /* INET6 */
@@ -917,16 +917,14 @@ int in_pcbnotifymiss = 0;
* After those two lookups no other are necessary.
*/
struct inpcb *
-in_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg)
- struct inpcbtable *table;
- struct in_addr faddr, laddr;
- u_int fport_arg, lport_arg;
+in_pcbhashlookup(struct inpcbtable *table, struct in_addr faddr,
+ u_int fport_arg, struct in_addr laddr, u_int lport_arg, u_int rdomain)
{
struct inpcbhead *head;
struct inpcb *inp;
u_int16_t fport = fport_arg, lport = lport_arg;
- head = INPCBHASH(table, &faddr, fport, &laddr, lport);
+ head = INPCBHASH(table, &faddr, fport, &laddr, lport, rdomain);
LIST_FOREACH(inp, head, inp_hash) {
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
@@ -935,7 +933,8 @@ in_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg)
if (inp->inp_faddr.s_addr == faddr.s_addr &&
inp->inp_fport == fport &&
inp->inp_lport == lport &&
- inp->inp_laddr.s_addr == laddr.s_addr) {
+ inp->inp_laddr.s_addr == laddr.s_addr &&
+ inp->inp_rdomain == rdomain) {
/*
* Move this PCB to the head of hash chain so that
* repeated accesses are quicker. This is analogous to
@@ -950,9 +949,9 @@ in_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg)
}
#ifdef DIAGNOSTIC
if (inp == NULL && in_pcbnotifymiss) {
- printf("in_pcbhashlookup: faddr=%08x fport=%d laddr=%08x lport=%d\n",
+ printf("in_pcbhashlookup: faddr=%08x fport=%d laddr=%08x lport=%d rdom=%d\n",
ntohl(faddr.s_addr), ntohs(fport),
- ntohl(laddr.s_addr), ntohs(lport));
+ ntohl(laddr.s_addr), ntohs(lport), rdomain);
}
#endif
return (inp);
@@ -960,10 +959,8 @@ in_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg)
#ifdef INET6
struct inpcb *
-in6_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg)
- struct inpcbtable *table;
- struct in6_addr *faddr, *laddr;
- u_int fport_arg, lport_arg;
+in6_pcbhashlookup(struct inpcbtable *table, struct in6_addr *faddr,
+ u_int fport_arg, struct in6_addr *laddr, u_int lport_arg)
{
struct inpcbhead *head;
struct inpcb *inp;
@@ -1008,7 +1005,7 @@ in6_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg)
*/
struct inpcb *
in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
- u_int lport_arg, int reverse, struct mbuf *m)
+ u_int lport_arg, int reverse, struct mbuf *m, u_int rdomain)
{
struct inpcbhead *head;
struct in_addr *key1, *key2;
@@ -1018,7 +1015,7 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
#if NPF > 0
if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
struct pf_divert *divert;
-
+ /* XXX rdomain */
if ((divert = pf_find_divert(m)) == NULL)
return (NULL);
key1 = key2 = &divert->addr.ipv4;
@@ -1033,7 +1030,7 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
key2 = &zeroin_addr;
}
- head = INPCBHASH(table, &zeroin_addr, 0, key1, lport);
+ head = INPCBHASH(table, &zeroin_addr, 0, key1, lport, rdomain);
LIST_FOREACH(inp, head, inp_hash) {
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
@@ -1041,11 +1038,12 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
#endif
if (inp->inp_lport == lport && inp->inp_fport == 0 &&
inp->inp_laddr.s_addr == key1->s_addr &&
- inp->inp_faddr.s_addr == INADDR_ANY)
+ inp->inp_faddr.s_addr == INADDR_ANY &&
+ inp->inp_rdomain == rdomain)
break;
}
if (inp == NULL && key1->s_addr != key2->s_addr) {
- head = INPCBHASH(table, &zeroin_addr, 0, key2, lport);
+ head = INPCBHASH(table, &zeroin_addr, 0, key2, lport, rdomain);
LIST_FOREACH(inp, head, inp_hash) {
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
@@ -1053,7 +1051,8 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
#endif
if (inp->inp_lport == lport && inp->inp_fport == 0 &&
inp->inp_laddr.s_addr == key2->s_addr &&
- inp->inp_faddr.s_addr == INADDR_ANY)
+ inp->inp_faddr.s_addr == INADDR_ANY &&
+ inp->inp_rdomain == rdomain)
break;
}
}
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index d3188b12adc..7e75d8294c6 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.h,v 1.66 2008/07/10 02:19:28 djm Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.67 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@@ -146,6 +146,7 @@ struct inpcb {
#endif
struct icmp6_filter *inp_icmp6filt;
void *inp_pf_sk;
+ u_int inp_rdomain;
};
struct inpcbtable {
@@ -250,10 +251,10 @@ void in_pcbdetach(void *);
void in_pcbdisconnect(void *);
struct inpcb *
in_pcbhashlookup(struct inpcbtable *, struct in_addr,
- u_int, struct in_addr, u_int);
+ u_int, struct in_addr, u_int, u_int);
struct inpcb *
in_pcblookup_listen(struct inpcbtable *, struct in_addr, u_int, int,
- struct mbuf *);
+ struct mbuf *, u_int);
#ifdef INET6
struct inpcb *
in6_pcbhashlookup(struct inpcbtable *, struct in6_addr *,
@@ -269,7 +270,7 @@ int in6_setpeeraddr(struct inpcb *, struct mbuf *);
void in_pcbinit(struct inpcbtable *, int);
struct inpcb *
in_pcblookup(struct inpcbtable *, void *, u_int, void *,
- u_int, int);
+ u_int, int, u_int);
void in_pcbnotifyall(struct inpcbtable *, struct sockaddr *,
int, void (*)(struct inpcb *, int));
void in_pcbrehash(struct inpcb *);
@@ -278,7 +279,7 @@ void in_setpeeraddr(struct inpcb *, struct mbuf *);
void in_setsockaddr(struct inpcb *, struct mbuf *);
int in_baddynamic(u_int16_t, u_int16_t);
extern struct sockaddr_in *in_selectsrc(struct sockaddr_in *,
- struct route *, int, struct ip_moptions *, int *);
+ struct route *, int, struct ip_moptions *, int *, u_int);
struct rtentry *
in_pcbrtentry(struct inpcb *);
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 8ebf216cb61..ac078c83fe5 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_var.h,v 1.11 2008/11/08 12:54:58 dlg Exp $ */
+/* $OpenBSD: in_var.h,v 1.12 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: in_var.h,v 1.16 1996/02/13 23:42:15 christos Exp $ */
/*
@@ -89,14 +89,15 @@ void in_socktrim(struct sockaddr_in *);
* Macro for finding the interface (ifnet structure) corresponding to one
* of our IP addresses.
*/
-#define INADDR_TO_IFP(addr, ifp) \
+#define INADDR_TO_IFP(addr, ifp, rdomain) \
/* struct in_addr addr; */ \
/* struct ifnet *ifp; */ \
do { \
struct in_ifaddr *ia; \
\
for (ia = TAILQ_FIRST(&in_ifaddr); ia != TAILQ_END(&in_ifaddr) && \
- ia->ia_addr.sin_addr.s_addr != (addr).s_addr; \
+ (ia->ia_ifp->if_rdomain != rdomain || \
+ ia->ia_addr.sin_addr.s_addr != (addr).s_addr); \
ia = TAILQ_NEXT(ia, ia_list)) \
continue; \
(ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 228163fcf6c..87be99facf6 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.169 2008/10/28 23:07:12 mpf Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.170 2009/06/05 00:05:22 claudio Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -424,9 +424,9 @@ carp_setroute(struct carp_softc *sc, int cmd)
info.rti_info[RTAX_DST] = ifa->ifa_addr;
info.rti_flags = RTF_HOST;
error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED,
- NULL, 0);
+ NULL, sc->sc_if.if_rdomain);
rt_missmsg(RTM_DELETE, &info, info.rti_flags, NULL,
- error, 0);
+ error, sc->sc_if.if_rdomain);
/* Check for our address on another interface */
/* XXX cries for proper API */
@@ -441,7 +441,7 @@ carp_setroute(struct carp_softc *sc, int cmd)
satosin(&sa)->sin_addr.s_addr = satosin(ifa->ifa_netmask
)->sin_addr.s_addr & satosin(&sa)->sin_addr.s_addr;
rt = (struct rtentry *)rt_lookup(&sa,
- ifa->ifa_netmask, 0);
+ ifa->ifa_netmask, sc->sc_if.if_rdomain);
nr_ourif = (rt && rt->rt_ifp == &sc->sc_if);
/* Restore the route label */
@@ -465,9 +465,11 @@ carp_setroute(struct carp_softc *sc, int cmd)
info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
info.rti_flags = RTF_UP | RTF_HOST;
error = rtrequest1(RTM_ADD, &info,
- RTP_CONNECTED, NULL, 0);
- rt_missmsg(RTM_ADD, &info, info.rti_flags,
- &sc->sc_if, error, 0);
+ RTP_CONNECTED, NULL,
+ sc->sc_if.if_rdomain);
+ rt_missmsg(RTM_ADD, &info,
+ info.rti_flags, &sc->sc_if,
+ error, sc->sc_if.if_rdomain);
}
if (!hr_otherif || nr_ourif || !rt) {
if (nr_ourif && !(rt->rt_flags &
@@ -475,9 +477,11 @@ carp_setroute(struct carp_softc *sc, int cmd)
bzero(&info, sizeof(info));
info.rti_info[RTAX_DST] = &sa;
info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
- error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, NULL, 0);
+ error = rtrequest1(RTM_DELETE,
+ &info, RTP_CONNECTED, NULL,
+ sc->sc_if.if_rdomain);
rt_missmsg(RTM_DELETE, &info, info.rti_flags, NULL,
- error, 0);
+ error, sc->sc_if.if_rdomain);
}
ifa->ifa_rtrequest = arp_rtrequest;
@@ -489,11 +493,13 @@ carp_setroute(struct carp_softc *sc, int cmd)
info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
info.rti_info[RTAX_LABEL] =
(struct sockaddr *)&sa_rl;
- error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, NULL, 0);
+ error = rtrequest1(RTM_ADD, &info,
+ RTP_CONNECTED, NULL,
+ sc->sc_if.if_rdomain);
if (error == 0)
ifa->ifa_flags |= IFA_ROUTE;
rt_missmsg(RTM_ADD, &info, info.rti_flags,
- &sc->sc_if, error, 0);
+ &sc->sc_if, error, sc->sc_if.if_rdomain);
}
break;
case RTM_DELETE:
@@ -1996,6 +2002,7 @@ carp_set_addr(struct carp_softc *sc, struct sockaddr_in *sin)
if (ia->ia_ifp != &sc->sc_if &&
ia->ia_ifp->if_type != IFT_CARP &&
(ia->ia_ifp->if_flags & IFF_MULTICAST) &&
+ ia->ia_ifp->if_rdomain == sc->sc_if.if_rdomain &&
(sin->sin_addr.s_addr & ia->ia_subnetmask) ==
ia->ia_subnet) {
if (!ia_if)
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 337490e5b83..c60ad936701 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.82 2008/09/10 09:10:55 henning Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.83 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -213,6 +213,8 @@ icmp_do_error(struct mbuf *n, int type, int code, n_long dest, int destmtu)
}
if (m == NULL)
goto freeit;
+ /* keep in same domain and rtable (the latter is a bit unclear) */
+ m->m_pkthdr.rdomain = n->m_pkthdr.rdomain;
m->m_len = icmplen + ICMP_MINLEN;
if ((m->m_flags & M_EXT) == 0)
MH_ALIGN(m, m->m_len);
@@ -587,9 +589,11 @@ reflect:
goto freeit;
#endif
rt = NULL;
+ /* XXX rdomain vs. rtable */
rtredirect(sintosa(&icmpsrc), sintosa(&icmpdst),
(struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
- sintosa(&icmpgw), (struct rtentry **)&rt);
+ sintosa(&icmpgw), (struct rtentry **)&rt,
+ m->m_pkthdr.rdomain);
if (rt != NULL && icmp_redirtimeout != 0) {
(void)rt_timer_add(rt, icmp_redirect_timeout,
icmp_redirect_timeout_q);
@@ -659,6 +663,8 @@ icmp_reflect(struct mbuf *m)
* the address which corresponds to the incoming interface.
*/
TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
+ if (ia->ia_ifp->if_rdomain != m->m_pkthdr.rdomain)
+ continue;
if (t.s_addr == ia->ia_addr.sin_addr.s_addr)
break;
if ((ia->ia_ifp->if_flags & IFF_BROADCAST) &&
@@ -680,7 +686,9 @@ icmp_reflect(struct mbuf *m)
dst->sin_len = sizeof(*dst);
dst->sin_addr = ip->ip_src;
- rtalloc(&ro);
+ /* keep packet in the original VRF instance */
+ ro.ro_rt = rtalloc1(&ro.ro_dst, 1,
+ m->m_pkthdr.rdomain);
if (ro.ro_rt == 0) {
ipstat.ips_noroute++;
m_freem(m);
@@ -863,14 +871,13 @@ icmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
}
-/* XXX only handles table 0 right now */
struct rtentry *
-icmp_mtudisc_clone(struct sockaddr *dst)
+icmp_mtudisc_clone(struct sockaddr *dst, u_int rtableid)
{
struct rtentry *rt;
int error;
- rt = rtalloc1(dst, 1, 0);
+ rt = rtalloc1(dst, 1, rtableid);
if (rt == 0)
return (NULL);
@@ -885,7 +892,7 @@ icmp_mtudisc_clone(struct sockaddr *dst)
info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
info.rti_flags = RTF_GATEWAY | RTF_HOST | RTF_DYNAMIC;
- error = rtrequest1(RTM_ADD, &info, rt->rt_priority, &nrt, 0);
+ error = rtrequest1(RTM_ADD, &info, RTP_DEFAULT, &nrt, rtableid);
if (error) {
rtfree(rt);
return (NULL);
@@ -904,7 +911,7 @@ icmp_mtudisc_clone(struct sockaddr *dst)
}
void
-icmp_mtudisc(struct icmp *icp)
+icmp_mtudisc(struct icmp *icp, u_int rtableid)
{
struct rtentry *rt;
struct sockaddr *dst = sintosa(&icmpsrc);
@@ -917,7 +924,7 @@ icmp_mtudisc(struct icmp *icp)
4352, 2002, 1492, 1006, 508, 296, 68, 0
};
- rt = icmp_mtudisc_clone(dst);
+ rt = icmp_mtudisc_clone(dst, rtableid);
if (rt == 0)
return;
diff --git a/sys/netinet/ip_icmp.h b/sys/netinet/ip_icmp.h
index 1a79d3a06bd..6e89454fe33 100644
--- a/sys/netinet/ip_icmp.h
+++ b/sys/netinet/ip_icmp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.h,v 1.21 2005/07/31 03:30:55 pascoe Exp $ */
+/* $OpenBSD: ip_icmp.h,v 1.22 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: ip_icmp.h,v 1.10 1996/02/13 23:42:28 christos Exp $ */
/*
@@ -214,7 +214,7 @@ void icmp_reflect(struct mbuf *);
void icmp_send(struct mbuf *, struct mbuf *);
int icmp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
struct rtentry *
- icmp_mtudisc_clone(struct sockaddr *);
-void icmp_mtudisc(struct icmp *);
+ icmp_mtudisc_clone(struct sockaddr *, u_int);
+void icmp_mtudisc(struct icmp *, u_int);
#endif /* _KERNEL */
#endif /* _NETINET_IP_ICMP_H_ */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 1413f0244cc..d709855848e 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.163 2009/06/04 05:02:25 henning Exp $ */
+/* $OpenBSD: ip_input.c,v 1.164 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -172,7 +172,7 @@ static struct ip_srcrt {
} ip_srcrt;
void save_rte(u_char *, struct in_addr);
-int ip_weadvertise(u_int32_t);
+int ip_weadvertise(u_int32_t, u_int);
/*
* IP initialization: fill in IP protocol switch table.
@@ -401,8 +401,8 @@ ipv4_input(m)
if (!m->m_pkthdr.pf.statekey ||
!((struct pf_state_key *)m->m_pkthdr.pf.statekey)->reverse)
#endif
- if ((ia = in_iawithaddr(ip->ip_dst, m)) != NULL &&
- (ia->ia_ifp->if_flags & IFF_UP))
+ if ((ia = in_iawithaddr(ip->ip_dst, m, m->m_pkthdr.rdomain)) !=
+ NULL && (ia->ia_ifp->if_flags & IFF_UP))
goto ours;
if (IN_MULTICAST(ip->ip_dst.s_addr)) {
@@ -677,13 +677,13 @@ bad:
}
struct in_ifaddr *
-in_iawithaddr(ina, m)
- struct in_addr ina;
- struct mbuf *m;
+in_iawithaddr(struct in_addr ina, struct mbuf *m, u_int rdomain)
{
struct in_ifaddr *ia;
TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
+ if (ia->ia_ifp->if_rdomain != rdomain)
+ continue;
if ((ina.s_addr == ia->ia_addr.sin_addr.s_addr) ||
((ia->ia_ifp->if_flags & (IFF_LOOPBACK|IFF_LINK1)) ==
(IFF_LOOPBACK|IFF_LINK1) &&
@@ -1040,7 +1040,8 @@ ip_dooptions(m)
goto bad;
}
ipaddr.sin_addr = ip->ip_dst;
- ia = ifatoia(ifa_ifwithaddr(sintosa(&ipaddr)));
+ ia = ifatoia(ifa_ifwithaddr(sintosa(&ipaddr),
+ m->m_pkthdr.rdomain));
if (ia == 0) {
if (opt == IPOPT_SSRR) {
type = ICMP_UNREACH;
@@ -1070,10 +1071,15 @@ ip_dooptions(m)
if (opt == IPOPT_SSRR) {
#define INA struct in_ifaddr *
#define SA struct sockaddr *
- if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
- ia = (INA)ifa_ifwithnet((SA)&ipaddr);
+ if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr,
+ m->m_pkthdr.rdomain)) == 0)
+ ia = (INA)ifa_ifwithnet((SA)&ipaddr,
+ m->m_pkthdr.rdomain);
} else
- ia = ip_rtaddr(ipaddr.sin_addr);
+ /* keep packet in the original VRF instance */
+ /* XXX rdomain or rtableid ??? */
+ ia = ip_rtaddr(ipaddr.sin_addr,
+ m->m_pkthdr.rdomain);
if (ia == 0) {
type = ICMP_UNREACH;
code = ICMP_UNREACH_SRCFAIL;
@@ -1110,9 +1116,13 @@ ip_dooptions(m)
/*
* locate outgoing interface; if we're the destination,
* use the incoming interface (should be same).
+ * Again keep the packet inside the VRF instance.
+ * XXX rdomain vs. rtableid ???
*/
- if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
- (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
+ if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr,
+ m->m_pkthdr.rdomain)) == 0 &&
+ (ia = ip_rtaddr(ipaddr.sin_addr,
+ m->m_pkthdr.rdomain)) == 0) {
type = ICMP_UNREACH;
code = ICMP_UNREACH_HOST;
goto bad;
@@ -1160,7 +1170,8 @@ ip_dooptions(m)
goto bad;
bcopy((caddr_t)&sin, (caddr_t)&ipaddr.sin_addr,
sizeof(struct in_addr));
- if (ifa_ifwithaddr((SA)&ipaddr) == 0)
+ if (ifa_ifwithaddr((SA)&ipaddr,
+ m->m_pkthdr.rdomain) == 0)
continue;
ipt.ipt_ptr += sizeof(struct in_addr);
break;
@@ -1193,8 +1204,7 @@ bad:
* return internet address info of interface to be used to get there.
*/
struct in_ifaddr *
-ip_rtaddr(dst)
- struct in_addr dst;
+ip_rtaddr(struct in_addr dst, u_int rtableid)
{
struct sockaddr_in *sin;
@@ -1209,7 +1219,8 @@ ip_rtaddr(dst)
sin->sin_len = sizeof(*sin);
sin->sin_addr = dst;
- rtalloc(&ipforward_rt);
+ ipforward_rt.ro_rt = rtalloc1(&ipforward_rt.ro_dst, 1,
+ rtableid);
}
if (ipforward_rt.ro_rt == 0)
return ((struct in_ifaddr *)0);
@@ -1244,8 +1255,7 @@ save_rte(option, dst)
* Code shamelessly copied from arplookup().
*/
int
-ip_weadvertise(addr)
- u_int32_t addr;
+ip_weadvertise(u_int32_t addr, u_int rtableid)
{
struct rtentry *rt;
struct ifnet *ifp;
@@ -1256,7 +1266,7 @@ ip_weadvertise(addr)
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = addr;
sin.sin_other = SIN_PROXY;
- rt = rtalloc1(sintosa(&sin), 0, 0); /* XXX other tables? */
+ rt = rtalloc1(sintosa(&sin), 0, rtableid);
if (rt == 0)
return 0;
@@ -1266,7 +1276,9 @@ ip_weadvertise(addr)
return 0;
}
- TAILQ_FOREACH(ifp, &ifnet, if_list)
+ TAILQ_FOREACH(ifp, &ifnet, if_list) {
+ if (ifp->if_rdomain != rtableid)
+ continue;
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
if (ifa->ifa_addr->sa_family != rt->rt_gateway->sa_family)
continue;
@@ -1278,6 +1290,7 @@ ip_weadvertise(addr)
return 1;
}
}
+ }
RTFREE(rt);
return 0;
@@ -1431,9 +1444,9 @@ ip_forward(m, srcrt)
return;
}
-#if NPF > 0
- rtableid = m->m_pkthdr.pf.rtableid;
-#endif
+ rtableid = m->m_pkthdr.rdomain;
+ if (m->m_pkthdr.pf.rtableid)
+ rtableid = m->m_pkthdr.pf.rtableid;
sin = satosin(&ipforward_rt.ro_dst);
if ((rt = ipforward_rt.ro_rt) == 0 ||
@@ -1481,7 +1494,8 @@ ip_forward(m, srcrt)
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
ipsendredirects && !srcrt &&
- !ip_weadvertise(satosin(rt_key(rt))->sin_addr.s_addr)) {
+ !ip_weadvertise(satosin(rt_key(rt))->sin_addr.s_addr,
+ m->m_pkthdr.rdomain)) {
if (rt->rt_ifa &&
(ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_subnetmask) ==
ifatoia(rt->rt_ifa)->ia_subnet) {
diff --git a/sys/netinet/ip_ipip.c b/sys/netinet/ip_ipip.c
index 81c7d75a07b..e37cefa04aa 100644
--- a/sys/netinet/ip_ipip.c
+++ b/sys/netinet/ip_ipip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipip.c,v 1.42 2008/11/26 16:08:17 henning Exp $ */
+/* $OpenBSD: ip_ipip.c,v 1.43 2009/06/05 00:05:22 claudio Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -288,6 +288,8 @@ ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
!(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) &&
ipip_allow != 2) {
TAILQ_FOREACH(ifp, &ifnet, if_list) {
+ if (ifp->if_rdomain != m->m_pkthdr.rdomain)
+ continue;
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
#ifdef INET
if (ipo) {
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index bdd8d221f6d..38e16eac821 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_mroute.c,v 1.52 2008/09/16 21:33:37 chl Exp $ */
+/* $OpenBSD: ip_mroute.c,v 1.53 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: ip_mroute.c,v 1.85 2004/04/26 01:31:57 matt Exp $ */
/*
@@ -840,7 +840,7 @@ add_vif(struct mbuf *m)
#endif
{
sin.sin_addr = vifcp->vifc_lcl_addr;
- ifa = ifa_ifwithaddr(sintosa(&sin));
+ ifa = ifa_ifwithaddr(sintosa(&sin), /* XXX */ 0);
if (ifa == NULL)
return (EADDRNOTAVAIL);
}
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index ab65a4b0eb4..8247955acab 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.193 2009/01/30 20:46:33 claudio Exp $ */
+/* $OpenBSD: ip_output.c,v 1.194 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -201,11 +201,13 @@ ip_output(struct mbuf *m0, ...)
* If routing to interface only, short-circuit routing lookup.
*/
if (flags & IP_ROUTETOIF) {
- if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
- (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
- ipstat.ips_noroute++;
- error = ENETUNREACH;
- goto bad;
+ if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst),
+ m->m_pkthdr.rdomain))) == 0 &&
+ (ia = ifatoia(ifa_ifwithnet(sintosa(dst),
+ m->m_pkthdr.rdomain))) == 0) {
+ ipstat.ips_noroute++;
+ error = ENETUNREACH;
+ goto bad;
}
ifp = ia->ia_ifp;
@@ -219,7 +221,8 @@ ip_output(struct mbuf *m0, ...)
IFP_TO_IA(ifp, ia);
} else {
if (ro->ro_rt == 0)
- rtalloc_mpath(ro, NULL, 0);
+ rtalloc_mpath(ro, NULL,
+ m->m_pkthdr.rdomain);
if (ro->ro_rt == 0) {
ipstat.ips_noroute++;
@@ -371,11 +374,13 @@ ip_output(struct mbuf *m0, ...)
* If routing to interface only, short-circuit routing lookup.
*/
if (flags & IP_ROUTETOIF) {
- if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
- (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
- ipstat.ips_noroute++;
- error = ENETUNREACH;
- goto bad;
+ if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst),
+ m->m_pkthdr.rdomain))) == 0 &&
+ (ia = ifatoia(ifa_ifwithnet(sintosa(dst),
+ m->m_pkthdr.rdomain))) == 0) {
+ ipstat.ips_noroute++;
+ error = ENETUNREACH;
+ goto bad;
}
ifp = ia->ia_ifp;
@@ -389,7 +394,8 @@ ip_output(struct mbuf *m0, ...)
IFP_TO_IA(ifp, ia);
} else {
if (ro->ro_rt == 0)
- rtalloc_mpath(ro, &ip->ip_src.s_addr, 0);
+ rtalloc_mpath(ro, &ip->ip_src.s_addr,
+ m->m_pkthdr.rdomain);
if (ro->ro_rt == 0) {
ipstat.ips_noroute++;
@@ -623,7 +629,8 @@ sendit:
struct sockaddr_in dst = {
sizeof(struct sockaddr_in), AF_INET};
dst.sin_addr = ip->ip_dst;
- rt = icmp_mtudisc_clone((struct sockaddr *)&dst);
+ rt = icmp_mtudisc_clone((struct sockaddr *)&dst,
+ m->m_pkthdr.rdomain);
rt_mtucloned = 1;
}
DPRINTF(("ip_output: spi %08x mtu %d rt %p cloned %d\n",
@@ -632,8 +639,9 @@ sendit:
rt->rt_rmx.rmx_mtu = icmp_mtu;
if (ro && ro->ro_rt != NULL) {
RTFREE(ro->ro_rt);
- ro->ro_rt = (struct rtentry *) 0;
- rtalloc(ro);
+ ro->ro_rt = NULL;
+ rtalloc1(&ro->ro_dst, 1,
+ m->m_pkthdr.rdomain);
}
if (rt_mtucloned)
rtfree(rt);
@@ -1037,6 +1045,7 @@ ip_ctloutput(op, so, level, optname, mp)
u_int16_t opt16val;
#endif
int error = 0;
+ u_int rtid = 0;
if (level != IPPROTO_IP) {
error = EINVAL;
@@ -1121,7 +1130,8 @@ ip_ctloutput(op, so, level, optname, mp)
case IP_MULTICAST_LOOP:
case IP_ADD_MEMBERSHIP:
case IP_DROP_MEMBERSHIP:
- error = ip_setmoptions(optname, &inp->inp_moptions, m);
+ error = ip_setmoptions(optname, &inp->inp_moptions, m,
+ inp->inp_rdomain);
break;
case IP_PORTRANGE:
@@ -1385,6 +1395,18 @@ ip_ctloutput(op, so, level, optname, mp)
}
#endif
break;
+ case SO_RDOMAIN:
+ if (m == NULL || m->m_len < sizeof(u_int)) {
+ error = EINVAL;
+ break;
+ }
+ rtid = *mtod(m, u_int *);
+ if (!rtable_exists(rtid)) {
+ error = EINVAL;
+ break;
+ }
+ inp->inp_rdomain = rtid;
+ break;
default:
error = ENOPROTOOPT;
break;
@@ -1575,6 +1597,11 @@ ip_ctloutput(op, so, level, optname, mp)
}
#endif
break;
+ case SO_RDOMAIN:
+ *mp = m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(u_int);
+ *mtod(m, u_int *) = inp->inp_rdomain;
+ break;
default:
error = ENOPROTOOPT;
break;
@@ -1696,10 +1723,8 @@ bad:
* Set the IP multicast options in response to user setsockopt().
*/
int
-ip_setmoptions(optname, imop, m)
- int optname;
- struct ip_moptions **imop;
- struct mbuf *m;
+ip_setmoptions(int optname, struct ip_moptions **imop, struct mbuf *m,
+ u_int rdomain)
{
int error = 0;
u_char loop;
@@ -1756,7 +1781,7 @@ ip_setmoptions(optname, imop, m)
* IP address. Find the interface and confirm that
* it supports multicasting.
*/
- INADDR_TO_IFP(addr, ifp);
+ INADDR_TO_IFP(addr, ifp, rdomain);
if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
error = EADDRNOTAVAIL;
break;
@@ -1812,7 +1837,9 @@ ip_setmoptions(optname, imop, m)
dst->sin_len = sizeof(*dst);
dst->sin_family = AF_INET;
dst->sin_addr = mreq->imr_multiaddr;
- rtalloc(&ro);
+ if (!(ro.ro_rt && ro.ro_rt->rt_ifp &&
+ (ro.ro_rt->rt_flags & RTF_UP)))
+ ro.ro_rt = rtalloc1(&ro.ro_dst, 1, rdomain);
if (ro.ro_rt == NULL) {
error = EADDRNOTAVAIL;
break;
@@ -1820,7 +1847,7 @@ ip_setmoptions(optname, imop, m)
ifp = ro.ro_rt->rt_ifp;
rtfree(ro.ro_rt);
} else {
- INADDR_TO_IFP(mreq->imr_interface, ifp);
+ INADDR_TO_IFP(mreq->imr_interface, ifp, rdomain);
}
/*
* See if we found an interface, and confirm that it
@@ -1906,7 +1933,7 @@ ip_setmoptions(optname, imop, m)
if (mreq->imr_interface.s_addr == INADDR_ANY)
ifp = NULL;
else {
- INADDR_TO_IFP(mreq->imr_interface, ifp);
+ INADDR_TO_IFP(mreq->imr_interface, ifp, rdomain);
if (ifp == NULL) {
error = EADDRNOTAVAIL;
break;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index bc72a08ff57..853b4816e85 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_var.h,v 1.38 2008/05/23 15:51:12 thib Exp $ */
+/* $OpenBSD: ip_var.h,v 1.39 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
@@ -172,12 +172,12 @@ int ip_pcbopts(struct mbuf **, struct mbuf *);
struct mbuf *
ip_reass(struct ipqent *, struct ipq *);
struct in_ifaddr *
- in_iawithaddr(struct in_addr, struct mbuf *);
+ in_iawithaddr(struct in_addr, struct mbuf *, u_int);
struct in_ifaddr *
- ip_rtaddr(struct in_addr);
+ ip_rtaddr(struct in_addr, u_int);
u_int16_t
ip_randomid(void);
-int ip_setmoptions(int, struct ip_moptions **, struct mbuf *);
+int ip_setmoptions(int, struct ip_moptions **, struct mbuf *, u_int);
void ip_slowtimo(void);
struct mbuf *
ip_srcroute(void);
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 032b83e0a27..0cbaa96a5c2 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip.c,v 1.46 2008/10/23 22:22:44 deraadt Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.47 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@@ -132,12 +132,16 @@ rip_input(struct mbuf *m, ...)
if (inp->inp_flags & INP_IPV6)
continue;
#endif
+ if (inp->inp_rdomain != m->m_pkthdr.rdomain)
+ continue;
+
if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p)
continue;
#if NPF > 0
if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
struct pf_divert *divert;
+ /* XXX rdomain support */
if ((divert = pf_find_divert(m)) == NULL)
continue;
if (inp->inp_laddr.s_addr != divert->addr.ipv4.s_addr)
@@ -267,6 +271,9 @@ rip_output(struct mbuf *m, ...)
* ip_output should be guarded against v6/v4 problems.
*/
#endif
+ /* force routing domain */
+ m->m_pkthdr.rdomain = inp->inp_rdomain;
+
return (ip_output(m, inp->inp_options, &inp->inp_route, flags,
inp->inp_moptions, inp));
}
@@ -411,7 +418,8 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
(addr->sin_family != AF_IMPLINK)) ||
(addr->sin_addr.s_addr &&
(!(so->so_options & SO_BINDANY) &&
- in_iawithaddr(addr->sin_addr, NULL) == 0))) {
+ in_iawithaddr(addr->sin_addr, NULL, inp->inp_rdomain) ==
+ 0))) {
error = EADDRNOTAVAIL;
break;
}
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index aee2240007e..c8912fccf68 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.225 2009/06/03 18:22:44 naddy Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.226 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -605,7 +605,8 @@ findpcb:
#endif
case AF_INET:
inp = in_pcbhashlookup(&tcbtable, ip->ip_src,
- th->th_sport, ip->ip_dst, th->th_dport);
+ th->th_sport, ip->ip_dst, th->th_dport,
+ m->m_pkthdr.rdomain);
break;
}
#if NPF > 0
@@ -630,7 +631,8 @@ findpcb:
#endif /* INET6 */
case AF_INET:
inp = in_pcblookup_listen(&tcbtable,
- ip->ip_dst, th->th_dport, inpl_flags, m);
+ ip->ip_dst, th->th_dport, inpl_flags, m,
+ m->m_pkthdr.rdomain);
break;
}
/*
@@ -3033,7 +3035,7 @@ tcp_mss(struct tcpcb *tp, int offer)
else if (tp->pf == AF_INET) {
if (ip_mtudisc)
mss = ifp->if_mtu - iphlen - sizeof(struct tcphdr);
- else if (inp && in_localaddr(inp->inp_faddr))
+ else if (inp && in_localaddr(inp->inp_faddr, inp->inp_rdomain))
mss = ifp->if_mtu - iphlen - sizeof(struct tcphdr);
}
#ifdef INET6
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 8e0ca68f182..d4da8619528 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_output.c,v 1.86 2008/09/03 12:51:39 henning Exp $ */
+/* $OpenBSD: tcp_output.c,v 1.87 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
/*
@@ -1059,6 +1059,9 @@ send:
}
#endif
+ /* force routing domain */
+ m->m_pkthdr.rdomain = tp->t_inpcb->inp_rdomain;
+
switch (tp->pf) {
case 0: /*default to PF_INET*/
#ifdef INET
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 5b482b0ce9d..e6b0cf18732 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_subr.c,v 1.105 2008/06/09 07:07:17 djm Exp $ */
+/* $OpenBSD: tcp_subr.c,v 1.106 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */
/*
@@ -809,7 +809,8 @@ tcp_ctlinput(cmd, sa, v)
th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
seq = ntohl(th->th_seq);
inp = in_pcbhashlookup(&tcbtable,
- ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport);
+ ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport,
+ /* XXX */ 0);
if (inp && (tp = intotcpcb(inp)) &&
SEQ_GEQ(seq, tp->snd_una) &&
SEQ_LT(seq, tp->snd_max)) {
@@ -831,7 +832,8 @@ tcp_ctlinput(cmd, sa, v)
* route (traditional PMTUD).
*/
tp->t_flags &= ~TF_PMTUD_PEND;
- icmp_mtudisc(icp);
+ /* XXX inherit rdomain from PCB */
+ icmp_mtudisc(icp, 0);
} else {
/*
* Record the information got in the ICMP
@@ -866,7 +868,8 @@ tcp_ctlinput(cmd, sa, v)
if (ip) {
th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
inp = in_pcbhashlookup(&tcbtable,
- ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport);
+ ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport,
+ /* XXX */ 0);
if (inp) {
seq = ntohl(th->th_seq);
if (inp->inp_socket &&
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 69c70b9cc29..f939e3faa0a 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_timer.c,v 1.42 2008/02/20 11:24:03 markus Exp $ */
+/* $OpenBSD: tcp_timer.c,v 1.43 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */
/*
@@ -213,7 +213,7 @@ tcp_timer_rexmt(void *arg)
icmp.icmp_ip.ip_len = tp->t_pmtud_ip_len;
icmp.icmp_ip.ip_hl = tp->t_pmtud_ip_hl;
icmpsrc.sin_addr = tp->t_inpcb->inp_faddr;
- icmp_mtudisc(&icmp);
+ icmp_mtudisc(&icmp, tp->t_inpcb->inp_rdomain);
/*
* Notify all connections to the same peer about
@@ -285,7 +285,8 @@ tcp_timer_rexmt(void *arg)
sin.sin_family = AF_INET;
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_addr = inp->inp_faddr;
- rt = icmp_mtudisc_clone(sintosa(&sin));
+ rt = icmp_mtudisc_clone(sintosa(&sin),
+ inp->inp_rdomain);
break;
}
if (rt != NULL) {
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 00997e16a02..facb9830def 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.99 2008/05/24 19:48:32 thib Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.100 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -764,12 +764,7 @@ tcp_usrclosed(tp)
* Look up a socket for ident or tcpdrop, ...
*/
int
-tcp_ident(oldp, oldlenp, newp, newlen, dodrop)
- void *oldp;
- size_t *oldlenp;
- void *newp;
- size_t newlen;
- int dodrop;
+tcp_ident(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int dodrop)
{
int error = 0, s;
struct tcp_ident_mapping tir;
@@ -830,7 +825,7 @@ tcp_ident(oldp, oldlenp, newp, newlen, dodrop)
#endif
case AF_INET:
inp = in_pcbhashlookup(&tcbtable, fin->sin_addr,
- fin->sin_port, lin->sin_addr, lin->sin_port);
+ fin->sin_port, lin->sin_addr, lin->sin_port , tir.rdomain);
break;
}
@@ -855,7 +850,7 @@ tcp_ident(oldp, oldlenp, newp, newlen, dodrop)
#endif
case AF_INET:
inp = in_pcblookup_listen(&tcbtable,
- lin->sin_addr, lin->sin_port, 0, NULL);
+ lin->sin_addr, lin->sin_port, 0, NULL, tir.rdomain);
break;
}
}
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index dcd291b0124..4fa1bda8c61 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.90 2008/11/08 12:54:58 dlg Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.91 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -520,6 +520,7 @@ struct tcpstat {
struct tcp_ident_mapping {
struct sockaddr_storage faddr, laddr;
int euid, ruid;
+ u_int rdomain;
};
#ifdef _KERNEL
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index d93dcd1b26a..94ee74c0d7b 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.128 2009/06/03 18:22:44 naddy Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.129 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -440,6 +440,8 @@ udp_input(struct mbuf *m, ...)
if (!ip6 && (inp->inp_flags & INP_IPV6))
continue;
#endif
+ if (inp->inp_rdomain != m->m_pkthdr.rdomain)
+ continue;
if (inp->inp_lport != uh->uh_dport)
continue;
#ifdef INET6
@@ -558,7 +560,7 @@ udp_input(struct mbuf *m, ...)
else
#endif /* INET6 */
inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport,
- ip->ip_dst, uh->uh_dport);
+ ip->ip_dst, uh->uh_dport, m->m_pkthdr.rdomain);
#if NPF > 0
if (m->m_pkthdr.pf.statekey && inp) {
((struct pf_state_key *)m->m_pkthdr.pf.statekey)->inp =
@@ -579,7 +581,8 @@ udp_input(struct mbuf *m, ...)
} else
#endif /* INET6 */
inp = in_pcblookup_listen(&udbtable,
- ip->ip_dst, uh->uh_dport, inpl_reverse, m);
+ ip->ip_dst, uh->uh_dport, inpl_reverse, m,
+ m->m_pkthdr.rdomain);
if (inp == 0) {
udpstat.udps_noport++;
if (m->m_flags & (M_BCAST | M_MCAST)) {
@@ -901,7 +904,8 @@ udp_ctlinput(int cmd, struct sockaddr *sa, void *v)
}
#endif
inp = in_pcbhashlookup(&udbtable,
- ip->ip_dst, uhp->uh_dport, ip->ip_src, uhp->uh_sport);
+ ip->ip_dst, uhp->uh_dport, ip->ip_src, uhp->uh_sport,
+ /* XXX */ 0);
if (inp && inp->inp_socket != NULL)
notify(inp, errno);
} else
@@ -1001,6 +1005,10 @@ udp_output(struct mbuf *m, ...)
((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos;
udpstat.udps_opackets++;
+
+ /* force routing domain */
+ m->m_pkthdr.rdomain = inp->inp_rdomain;
+
error = ip_output(m, inp->inp_options, &inp->inp_route,
inp->inp_socket->so_options &
(SO_DONTROUTE | SO_BROADCAST | SO_JUMBO),