summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_mbuf.c3
-rw-r--r--sys/kern/uipc_socket.c4
-rw-r--r--sys/net/if.c89
-rw-r--r--sys/net/if.h14
-rw-r--r--sys/net/if_ethersubr.c23
-rw-r--r--sys/net/if_fddisubr.c4
-rw-r--r--sys/net/pf.c46
-rw-r--r--sys/net/route.c71
-rw-r--r--sys/net/route.h8
-rw-r--r--sys/net/rtsock.c17
-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
-rw-r--r--sys/netinet6/icmp6.c6
-rw-r--r--sys/netinet6/in6_pcb.c14
-rw-r--r--sys/netinet6/raw_ip6.c5
-rw-r--r--sys/sys/mbuf.h5
-rw-r--r--sys/sys/socket.h6
-rw-r--r--sys/sys/sockio.h5
38 files changed, 501 insertions, 287 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index acd7a7f4330..cd45d0d0491 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf.c,v 1.120 2009/06/02 00:05:13 blambert Exp $ */
+/* $OpenBSD: uipc_mbuf.c,v 1.121 2009/06/05 00:05:21 claudio Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */
/*
@@ -224,6 +224,7 @@ m_gethdr(int nowait, int type)
m->m_data = m->m_pktdat;
m->m_flags = M_PKTHDR;
m->m_pkthdr.rcvif = NULL;
+ m->m_pkthdr.rdomain = 0;
SLIST_INIT(&m->m_pkthdr.tags);
m->m_pkthdr.csum_flags = 0;
m->m_pkthdr.ether_vtag = 0;
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 9841a6396e0..3c56aee1b3e 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket.c,v 1.76 2009/03/15 19:40:41 miod Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.77 2009/06/05 00:05:21 claudio Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@@ -46,6 +46,7 @@
#include <sys/socketvar.h>
#include <sys/signalvar.h>
#include <sys/resourcevar.h>
+#include <net/route.h>
#include <sys/pool.h>
void filt_sordetach(struct knote *kn);
@@ -986,6 +987,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
} else {
switch (optname) {
case SO_BINDANY:
+ case SO_RDOMAIN:
if ((error = suser(curproc, 0)) != 0) /* XXX */
goto bad;
break;
diff --git a/sys/net/if.c b/sys/net/if.c
index 061b8772190..8dd2fd9582b 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.193 2009/06/04 19:07:21 henning Exp $ */
+/* $OpenBSD: if.c,v 1.194 2009/06/05 00:05:21 claudio Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -878,7 +878,7 @@ if_congestion_clear(void *arg)
*/
/*ARGSUSED*/
struct ifaddr *
-ifa_ifwithaddr(struct sockaddr *addr)
+ifa_ifwithaddr(struct sockaddr *addr, u_int rdomain)
{
struct ifnet *ifp;
struct ifaddr *ifa;
@@ -887,6 +887,8 @@ ifa_ifwithaddr(struct sockaddr *addr)
(bcmp((caddr_t)(a1), (caddr_t)(a2), \
((struct sockaddr *)(a1))->sa_len) == 0)
TAILQ_FOREACH(ifp, &ifnet, if_list) {
+ if (ifp->if_rdomain != rdomain)
+ continue;
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
if (ifa->ifa_addr->sa_family != addr->sa_family)
continue;
@@ -906,20 +908,22 @@ ifa_ifwithaddr(struct sockaddr *addr)
*/
/*ARGSUSED*/
struct ifaddr *
-ifa_ifwithdstaddr(struct sockaddr *addr)
+ifa_ifwithdstaddr(struct sockaddr *addr, u_int rdomain)
{
struct ifnet *ifp;
struct ifaddr *ifa;
TAILQ_FOREACH(ifp, &ifnet, if_list) {
- if (ifp->if_flags & IFF_POINTOPOINT)
- TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
- if (ifa->ifa_addr->sa_family != addr->sa_family ||
- ifa->ifa_dstaddr == NULL)
- continue;
- if (equal(addr, ifa->ifa_dstaddr))
- return (ifa);
- }
+ if (ifp->if_rdomain != rdomain)
+ continue;
+ if (ifp->if_flags & IFF_POINTOPOINT)
+ TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+ if (ifa->ifa_addr->sa_family !=
+ addr->sa_family || ifa->ifa_dstaddr == NULL)
+ continue;
+ if (equal(addr, ifa->ifa_dstaddr))
+ return (ifa);
+ }
}
return (NULL);
}
@@ -929,7 +933,7 @@ ifa_ifwithdstaddr(struct sockaddr *addr)
* is most specific found.
*/
struct ifaddr *
-ifa_ifwithnet(struct sockaddr *addr)
+ifa_ifwithnet(struct sockaddr *addr, u_int rdomain)
{
struct ifnet *ifp;
struct ifaddr *ifa;
@@ -944,6 +948,8 @@ ifa_ifwithnet(struct sockaddr *addr)
return (ifnet_addrs[sdl->sdl_index]);
}
TAILQ_FOREACH(ifp, &ifnet, if_list) {
+ if (ifp->if_rdomain != rdomain)
+ continue;
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
char *cp, *cp2, *cp3;
@@ -972,12 +978,14 @@ ifa_ifwithnet(struct sockaddr *addr)
* Find an interface using a specific address family
*/
struct ifaddr *
-ifa_ifwithaf(int af)
+ifa_ifwithaf(int af, u_int rdomain)
{
struct ifnet *ifp;
struct ifaddr *ifa;
TAILQ_FOREACH(ifp, &ifnet, if_list) {
+ if (ifp->if_rdomain != rdomain)
+ continue;
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
if (ifa->ifa_addr->sa_family == af)
return (ifa);
@@ -1202,7 +1210,7 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
{
struct ifnet *ifp;
struct ifreq *ifr;
- struct ifaddr *ifa;
+ struct ifaddr *ifa, *nifa;
struct sockaddr_dl *sdl;
struct ifgroupreq *ifgr;
char ifdescrbuf[IFDESCRSIZE];
@@ -1403,6 +1411,59 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
ifp->if_priority = ifr->ifr_metric;
break;
+ case SIOCGIFRTABLEID:
+ ifr->ifr_rdomainid = ifp->if_rdomain;
+ break;
+
+ case SIOCSIFRTABLEID:
+ if ((error = suser(p, 0)) != 0)
+ return (error);
+ if (ifr->ifr_rdomainid < 0 ||
+ ifr->ifr_rdomainid > RT_TABLEID_MAX)
+ return (EINVAL);
+ /* remove all routing entries when switching domains */
+ /* XXX hell this is ugly */
+ if (ifr->ifr_rdomainid != ifp->if_rdomain) {
+ rt_if_remove(ifp);
+#ifdef INET
+ rti_delete(ifp);
+#if NETHER > 0
+ myip_ifp = NULL;
+#endif
+#ifdef MROUTING
+ vif_delete(ifp);
+#endif
+#endif
+#ifdef INET6
+ in6_ifdetach(ifp);
+#endif
+#ifdef INET
+ for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
+ ifa = nifa) {
+ nifa = TAILQ_NEXT(ifa, ifa_list);
+
+ /* only remove AF_INET */
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ TAILQ_REMOVE(&in_ifaddr,
+ (struct in_ifaddr *)ifa, ia_list);
+ TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
+ ifa->ifa_ifp = NULL;
+ IFAFREE(ifa);
+ }
+#endif
+ }
+
+ /* make sure that the routing table exists */
+ if (!rtable_exists(ifr->ifr_rdomainid)) {
+ if (rtable_add(ifr->ifr_rdomainid) == -1)
+ panic("rtinit: rtable_add");
+ }
+
+ ifp->if_rdomain = ifr->ifr_rdomainid;
+ break;
+
case SIOCAIFGROUP:
if ((error = suser(p, 0)))
return (error);
diff --git a/sys/net/if.h b/sys/net/if.h
index 94885445c40..65e40ef621f 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.h,v 1.105 2009/06/04 19:07:21 henning Exp $ */
+/* $OpenBSD: if.h,v 1.106 2009/06/05 00:05:21 claudio Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
@@ -215,6 +215,7 @@ struct ifnet { /* and the entries */
struct if_data if_data; /* stats and other data about if */
u_int32_t if_hardmtu; /* maximum MTU device supports */
int if_capabilities; /* interface capabilities */
+ u_int if_rdomain; /* routing instance */
char if_description[IFDESCRSIZE]; /* interface description */
u_short if_rtlabelid; /* next route label */
u_int8_t if_priority;
@@ -588,6 +589,7 @@ struct ifreq {
#define ifr_metric ifr_ifru.ifru_metric /* metric */
#define ifr_mtu ifr_ifru.ifru_metric /* mtu (overload) */
#define ifr_media ifr_ifru.ifru_metric /* media options (overload) */
+#define ifr_rdomainid ifr_ifru.ifru_metric /* VRF instance (overload) */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
};
@@ -804,12 +806,12 @@ void if_group_routechange(struct sockaddr *, struct sockaddr *);
struct ifnet *ifunit(const char *);
void if_start(struct ifnet *);
-struct ifaddr *ifa_ifwithaddr(struct sockaddr *);
-struct ifaddr *ifa_ifwithaf(int);
-struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
-struct ifaddr *ifa_ifwithnet(struct sockaddr *);
+struct ifaddr *ifa_ifwithaddr(struct sockaddr *, u_int);
+struct ifaddr *ifa_ifwithaf(int, u_int);
+struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *, u_int);
+struct ifaddr *ifa_ifwithnet(struct sockaddr *, u_int);
struct ifaddr *ifa_ifwithroute(int, struct sockaddr *,
- struct sockaddr *);
+ struct sockaddr *, u_int);
struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
void ifafree(struct ifaddr *);
void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 5a6ce60cc0d..d0166e2e84a 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.132 2009/03/05 19:47:05 michele Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.133 2009/06/05 00:05:21 claudio Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -230,6 +230,15 @@ ether_output(ifp0, m0, dst, rt0)
short mflags;
struct ifnet *ifp = ifp0;
+#ifdef DIAGNOSTIC
+ if (ifp->if_rdomain != m->m_pkthdr.rdomain) {
+ printf("%s: trying to send packet on wrong domain. "
+ "%d vs. %d, AF %d\n", ifp->if_xname, ifp->if_rdomain,
+ m->m_pkthdr.rdomain, dst->sa_family);
+ senderr(ENETDOWN);
+ }
+#endif
+
#if NTRUNK > 0
if (ifp->if_type == IFT_IEEE8023ADLAG)
senderr(EBUSY);
@@ -241,7 +250,8 @@ ether_output(ifp0, m0, dst, rt0)
/* loop back if this is going to the carp interface */
if (dst != NULL && LINK_STATE_IS_UP(ifp0->if_link_state) &&
- (ifa = ifa_ifwithaddr(dst)) != NULL &&
+ /* XXX why ifa_ifwithaddr() and not ifaof_ifpforaddr() */
+ (ifa = ifa_ifwithaddr(dst, ifp->if_rdomain)) != NULL &&
ifa->ifa_ifp == ifp0)
return (looutput(ifp0, m, dst, rt0));
@@ -258,7 +268,8 @@ ether_output(ifp0, m0, dst, rt0)
senderr(ENETDOWN);
if ((rt = rt0) != NULL) {
if ((rt->rt_flags & RTF_UP) == 0) {
- if ((rt0 = rt = rtalloc1(dst, 1, 0)) != NULL)
+ if ((rt0 = rt = rtalloc1(dst, 1,
+ m->m_pkthdr.pf.rtableid)) != NULL)
rt->rt_refcnt--;
else
senderr(EHOSTUNREACH);
@@ -274,7 +285,8 @@ ether_output(ifp0, m0, dst, rt0)
goto lookup;
if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
rtfree(rt); rt = rt0;
- lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 0);
+ lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
+ ifp->if_rdomain);
if ((rt = rt->rt_gwroute) == 0)
senderr(EHOSTUNREACH);
}
@@ -532,6 +544,9 @@ ether_input(ifp0, eh, m)
m_cluncount(m, 1);
+ /* mark incomming routing domain */
+ m->m_pkthdr.rdomain = ifp->if_rdomain;
+
if (eh == NULL) {
eh = mtod(m, struct ether_header *);
m_adj(m, ETHER_HDR_LEN);
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index e33adfb9a0a..a43177f5089 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_fddisubr.c,v 1.54 2008/05/07 13:45:35 dlg Exp $ */
+/* $OpenBSD: if_fddisubr.c,v 1.55 2009/06/05 00:05:21 claudio Exp $ */
/* $NetBSD: if_fddisubr.c,v 1.5 1996/05/07 23:20:21 christos Exp $ */
/*
@@ -154,7 +154,7 @@ fddi_output(ifp0, m0, dst, rt0)
/* loop back if this is going to the carp interface */
if (dst != NULL && LINK_STATE_IS_UP(ifp0->if_link_state) &&
- (ifa = ifa_ifwithaddr(dst)) != NULL &&
+ (ifa = ifa_ifwithaddr(dst, ifp->if_rdomain)) != NULL &&
ifa->ifa_ifp == ifp0)
return (looutput(ifp0, m, dst, rt0));
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 2c68a807512..b3da5a1ca67 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.648 2009/05/18 20:37:13 bluhm Exp $ */
+/* $OpenBSD: pf.c,v 1.649 2009/06/05 00:05:21 claudio Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -153,8 +153,8 @@ void pf_send_tcp(const struct pf_rule *, sa_family_t,
const struct pf_addr *, const struct pf_addr *,
u_int16_t, u_int16_t, u_int32_t, u_int32_t,
u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
- u_int16_t, struct ether_header *, struct ifnet *,
- int);
+ u_int16_t, u_short, struct ether_header *,
+ struct ifnet *, int);
void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
sa_family_t, struct pf_rule *, int);
void pf_detach_state(struct pf_state *);
@@ -1093,6 +1093,10 @@ pf_src_tree_remove_state(struct pf_state *s)
void
pf_unlink_state(struct pf_state *cur)
{
+ /*
+ * XXX XXX XXX state needs to know routing domain so that states
+ * XXX XXX XXX can not float between domain. May simplify other code.
+ */
splsoftassert(IPL_SOFTNET);
if (cur->src.state == PF_TCPS_PROXY_DST) {
@@ -1103,7 +1107,7 @@ pf_unlink_state(struct pf_state *cur)
cur->key[PF_SK_WIRE]->port[1],
cur->key[PF_SK_WIRE]->port[0],
cur->src.seqhi, cur->src.seqlo + 1,
- TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL,
+ TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, 0, NULL, NULL,
cur->rtableid);
}
RB_REMOVE(pf_state_tree_id, &tree_id, cur);
@@ -1878,7 +1882,8 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af,
const struct pf_addr *saddr, const struct pf_addr *daddr,
u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
- u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp, int rtableid)
+ u_int16_t rtag, u_short rdom, struct ether_header *eh, struct ifnet *ifp,
+ int rtableid)
{
struct mbuf *m;
int len, tlen;
@@ -1916,6 +1921,7 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af,
if (tag)
m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
m->m_pkthdr.pf.tag = rtag;
+ m->m_pkthdr.rdomain = rdom;
if (rtableid >= 0)
m->m_pkthdr.pf.rtableid = rtableid;
@@ -2040,6 +2046,7 @@ pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
return;
m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
+ m0->m_pkthdr.rdomain = m->m_pkthdr.rdomain;
if (rtableid >= 0)
m0->m_pkthdr.pf.rtableid = rtableid;
@@ -2402,10 +2409,11 @@ pf_socket_lookup(int direction, struct pf_pdesc *pd)
switch (pd->af) {
#ifdef INET
case AF_INET:
- inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
+ inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport,
+ /* XXX */ 0);
if (inp == NULL) {
inp = in_pcblookup_listen(tb, daddr->v4, dport, 0,
- NULL);
+ NULL, 0);
if (inp == NULL)
return (-1);
}
@@ -2526,6 +2534,7 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer)
int hlen;
u_int16_t mss = tcp_mssdflt;
+ /* XXX needs to know about routing domain or actually rtableid */
switch (af) {
#ifdef INET
case AF_INET:
@@ -3018,8 +3027,8 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
pf_send_tcp(r, af, pd->dst,
pd->src, th->th_dport, th->th_sport,
ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
- r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp,
- act.rtableid);
+ r->return_ttl, 1, 0, m->m_pkthdr.rdomain,
+ pd->eh, kif->pfik_ifp, act.rtableid);
}
} else if (pd->proto != IPPROTO_ICMP && af == AF_INET &&
r->return_icmp)
@@ -3280,8 +3289,7 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
s->src.mss = mss;
pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport,
th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
- TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL,
- act->rtableid);
+ TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, /* XXX */ 0, NULL, NULL, act->rtableid);
REASON_SET(&reason, PFRES_SYNPROXY);
return (PF_SYNPROXY_DROP);
}
@@ -3694,7 +3702,8 @@ pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst,
th->th_sport, ntohl(th->th_ack), 0,
TH_RST, 0, 0,
(*state)->rule.ptr->return_ttl, 1, 0,
- pd->eh, kif->pfik_ifp, (*state)->rtableid);
+ m->m_pkthdr.rdomain, pd->eh,
+ kif->pfik_ifp, (*state)->rtableid);
src->seqlo = 0;
src->seqhi = 1;
src->max_win = 1;
@@ -3846,7 +3855,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
pd->src, th->th_dport, th->th_sport,
(*state)->src.seqhi, ntohl(th->th_seq) + 1,
TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
- 0, NULL, NULL, (*state)->rtableid);
+ 0, /* XXX */ 0, NULL, NULL, (*state)->rtableid);
REASON_SET(reason, PFRES_SYNPROXY);
return (PF_SYNPROXY_DROP);
} else if (!(th->th_flags & TH_ACK) ||
@@ -3876,8 +3885,8 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
&sk->addr[pd->sidx], &sk->addr[pd->didx],
sk->port[pd->sidx], sk->port[pd->didx],
(*state)->dst.seqhi, 0, TH_SYN, 0,
- (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL,
- (*state)->rtableid);
+ (*state)->src.mss, 0, 0, (*state)->tag, /* XXX */ 0,
+ NULL, NULL, (*state)->rtableid);
REASON_SET(reason, PFRES_SYNPROXY);
return (PF_SYNPROXY_DROP);
} else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
@@ -3892,13 +3901,14 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
pd->src, th->th_dport, th->th_sport,
ntohl(th->th_ack), ntohl(th->th_seq) + 1,
TH_ACK, (*state)->src.max_win, 0, 0, 0,
- (*state)->tag, NULL, NULL, (*state)->rtableid);
+ (*state)->tag, /* XXX */ 0, NULL, NULL,
+ (*state)->rtableid);
pf_send_tcp((*state)->rule.ptr, pd->af,
&sk->addr[pd->sidx], &sk->addr[pd->didx],
sk->port[pd->sidx], sk->port[pd->didx],
(*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
TH_ACK, (*state)->dst.max_win, 0, 0, 1,
- 0, NULL, NULL, (*state)->rtableid);
+ 0, /* XXX */ 0, NULL, NULL, (*state)->rtableid);
(*state)->src.seqdiff = (*state)->dst.seqhi -
(*state)->src.seqlo;
(*state)->dst.seqdiff = (*state)->src.seqhi -
@@ -4827,6 +4837,7 @@ pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif)
struct rtentry *rt;
struct ifnet *ifp;
+ /* XXX needs to know about routing domain or actually rtableid */
check_mpath = 0;
bzero(&ro, sizeof(ro));
switch (af) {
@@ -4908,6 +4919,7 @@ pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw)
#endif
int ret = 0;
+ /* XXX needs to know about routing domain or actually rtableid */
bzero(&ro, sizeof(ro));
switch (af) {
case AF_INET:
diff --git a/sys/net/route.c b/sys/net/route.c
index c09effaf253..d2acd43bd47 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.108 2009/05/31 04:07:03 claudio Exp $ */
+/* $OpenBSD: route.c,v 1.109 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -251,7 +251,7 @@ rtable_exists(u_int id) /* verify table with that ID exists */
if (id > rtbl_id_max)
return (0);
- if (rt_tables[id] == NULL) /* should not happen */
+ if (rt_tables[id] == NULL)
return (0);
return (1);
@@ -450,7 +450,7 @@ ifafree(struct ifaddr *ifa)
void
rtredirect(struct sockaddr *dst, struct sockaddr *gateway,
struct sockaddr *netmask, int flags, struct sockaddr *src,
- struct rtentry **rtp)
+ struct rtentry **rtp, u_int rdomain)
{
struct rtentry *rt;
int error = 0;
@@ -462,12 +462,12 @@ rtredirect(struct sockaddr *dst, struct sockaddr *gateway,
splsoftassert(IPL_SOFTNET);
/* verify the gateway is directly reachable */
- if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
+ if ((ifa = ifa_ifwithnet(gateway, rdomain)) == NULL) {
error = ENETUNREACH;
goto out;
}
ifp = ifa->ifa_ifp;
- rt = rtalloc1(dst, 0, 0);
+ rt = rtalloc1(dst, 0, rdomain);
/*
* If the redirect isn't from our current router for this dst,
* it's either old or wrong. If it redirects us to ourselves,
@@ -480,7 +480,7 @@ rtredirect(struct sockaddr *dst, struct sockaddr *gateway,
if (!(flags & RTF_DONE) && rt &&
(!equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
error = EINVAL;
- else if (ifa_ifwithaddr(gateway) != NULL)
+ else if (ifa_ifwithaddr(gateway, rdomain) != NULL)
error = EHOSTUNREACH;
if (error)
goto done;
@@ -513,7 +513,8 @@ create:
info.rti_ifa = ifa;
info.rti_flags = flags;
rt = NULL;
- error = rtrequest1(RTM_ADD, &info, RTP_DEFAULT, &rt, 0);
+ error = rtrequest1(RTM_ADD, &info, RTP_DEFAULT, &rt,
+ rdomain);
if (rt != NULL)
flags = rt->rt_flags;
stat = &rtstat.rts_dynamic;
@@ -525,7 +526,7 @@ create:
rt->rt_flags |= RTF_MODIFIED;
flags |= RTF_MODIFIED;
stat = &rtstat.rts_newgateway;
- rt_setgate(rt, rt_key(rt), gateway, 0);
+ rt_setgate(rt, rt_key(rt), gateway, rdomain);
}
} else
error = EHOSTUNREACH;
@@ -546,7 +547,7 @@ out:
info.rti_info[RTAX_GATEWAY] = gateway;
info.rti_info[RTAX_NETMASK] = netmask;
info.rti_info[RTAX_AUTHOR] = src;
- rt_missmsg(RTM_REDIRECT, &info, flags, ifp, error, 0);
+ rt_missmsg(RTM_REDIRECT, &info, flags, ifp, error, rdomain);
}
/*
@@ -614,7 +615,8 @@ rtioctl(u_long req, caddr_t data, struct proc *p)
}
struct ifaddr *
-ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway)
+ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
+ u_int rdomain)
{
struct ifaddr *ifa;
@@ -639,21 +641,21 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway)
*/
ifa = NULL;
if (flags & RTF_HOST)
- ifa = ifa_ifwithdstaddr(dst);
+ ifa = ifa_ifwithdstaddr(dst, rdomain);
if (ifa == NULL)
- ifa = ifa_ifwithaddr(gateway);
+ ifa = ifa_ifwithaddr(gateway, rdomain);
} else {
/*
* If we are adding a route to a remote net
* or host, the gateway may still be on the
* other end of a pt to pt link.
*/
- ifa = ifa_ifwithdstaddr(gateway);
+ ifa = ifa_ifwithdstaddr(gateway, rdomain);
}
if (ifa == NULL)
- ifa = ifa_ifwithnet(gateway);
+ ifa = ifa_ifwithnet(gateway, rdomain);
if (ifa == NULL) {
- struct rtentry *rt = rtalloc1(gateway, 0, 0);
+ struct rtentry *rt = rtalloc1(gateway, 0, rdomain);
if (rt == NULL)
return (NULL);
rt->rt_refcnt--;
@@ -676,7 +678,7 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway)
#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
int
-rt_getifa(struct rt_addrinfo *info)
+rt_getifa(struct rt_addrinfo *info, u_int rdom)
{
struct ifaddr *ifa;
int error = 0;
@@ -687,12 +689,12 @@ rt_getifa(struct rt_addrinfo *info)
*/
if (info->rti_ifp == NULL && info->rti_info[RTAX_IFP] != NULL
&& info->rti_info[RTAX_IFP]->sa_family == AF_LINK &&
- (ifa = ifa_ifwithnet((struct sockaddr *)info->rti_info[RTAX_IFP]))
- != NULL)
+ (ifa = ifa_ifwithnet((struct sockaddr *)info->rti_info[RTAX_IFP],
+ rdom)) != NULL)
info->rti_ifp = ifa->ifa_ifp;
if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL)
- info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA]);
+ info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rdom);
if (info->rti_ifa == NULL) {
struct sockaddr *sa;
@@ -707,10 +709,11 @@ rt_getifa(struct rt_addrinfo *info)
info->rti_info[RTAX_GATEWAY] != NULL)
info->rti_ifa = ifa_ifwithroute(info->rti_flags,
info->rti_info[RTAX_DST],
- info->rti_info[RTAX_GATEWAY]);
+ info->rti_info[RTAX_GATEWAY],
+ rdom);
else if (sa != NULL)
info->rti_ifa = ifa_ifwithroute(info->rti_flags,
- sa, sa);
+ sa, sa, rdom);
}
if ((ifa = info->rti_ifa) != NULL) {
if (info->rti_ifp == NULL)
@@ -820,7 +823,8 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
goto makeroute;
case RTM_ADD:
- if (info->rti_ifa == 0 && (error = rt_getifa(info)))
+ if (info->rti_ifa == 0 && (error = rt_getifa(info,
+ /* XXX wrong because only rdomains allowed */ tableid)))
senderr(error);
ifa = info->rti_ifa;
makeroute:
@@ -1057,6 +1061,7 @@ rtinit(struct ifaddr *ifa, int cmd, int flags)
int error;
struct rt_addrinfo info;
struct sockaddr_rtlabel sa_rl;
+ u_short rtableid = ifa->ifa_ifp->if_rdomain;
dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
if (cmd == RTM_DELETE) {
@@ -1068,7 +1073,7 @@ rtinit(struct ifaddr *ifa, int cmd, int flags)
rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
dst = deldst;
}
- if ((rt = rtalloc1(dst, 0, 0)) != NULL) {
+ if ((rt = rtalloc1(dst, 0, rtableid)) != NULL) {
rt->rt_refcnt--;
if (rt->rt_ifa != ifa) {
if (m != NULL)
@@ -1094,7 +1099,7 @@ rtinit(struct ifaddr *ifa, int cmd, int flags)
* change it to meet bsdi4 behavior.
*/
info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
- error = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, 0);
+ error = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, rtableid);
if (cmd == RTM_DELETE && error == 0 && (rt = nrt) != NULL) {
rt_newaddrmsg(cmd, ifa, error, nrt);
if (rt->rt_refcnt <= 0) {
@@ -1289,6 +1294,8 @@ rt_timer_add(struct rtentry *rt, void (*func)(struct rtentry *,
struct radix_node_head *
rt_gettable(sa_family_t af, u_int id)
{
+ if (id > rtbl_id_max)
+ return (NULL);
return (rt_tables[id] ? rt_tables[id][af2rtafidx[af]] : NULL);
}
@@ -1431,13 +1438,17 @@ void
rt_if_remove(struct ifnet *ifp)
{
int i;
+ u_int tid;
struct radix_node_head *rnh;
- for (i = 1; i <= AF_MAX; i++)
- if ((rnh = rt_gettable(i, 0)) != NULL)
- while ((*rnh->rnh_walktree)(rnh,
- rt_if_remove_rtdelete, ifp) == EAGAIN)
- ; /* nothing */
+ for (tid = 0; tid <= rtbl_id_max; tid++) {
+ for (i = 1; i <= AF_MAX; i++) {
+ if ((rnh = rt_gettable(i, tid)) != NULL)
+ while ((*rnh->rnh_walktree)(rnh,
+ rt_if_remove_rtdelete, ifp) == EAGAIN)
+ ; /* nothing */
+ }
+ }
}
/*
@@ -1455,7 +1466,7 @@ rt_if_remove_rtdelete(struct radix_node *rn, void *vifp)
if (rt->rt_ifp == ifp) {
int cloning = (rt->rt_flags & RTF_CLONING);
- if (rtdeletemsg(rt, 0) == 0 && cloning)
+ if (rtdeletemsg(rt, ifp->if_rdomain /* XXX wrong */) == 0 && cloning)
return (EAGAIN);
}
diff --git a/sys/net/route.h b/sys/net/route.h
index 728ce54a6d6..d79c3d93883 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.62 2009/05/26 08:29:44 reyk Exp $ */
+/* $OpenBSD: route.h,v 1.63 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -351,8 +351,6 @@ struct sockaddr_rtlabel {
char sr_label[RTLABEL_LEN];
};
-#define RT_TABLEID_MAX 255
-
#ifdef _KERNEL
const char *rtlabel_id2name(u_int16_t);
u_int16_t rtlabel_name2id(char *);
@@ -416,12 +414,12 @@ void rtalloc_noclone(struct route *, int);
struct rtentry *
rtalloc2(struct sockaddr *, int, int);
void rtfree(struct rtentry *);
-int rt_getifa(struct rt_addrinfo *);
+int rt_getifa(struct rt_addrinfo *, u_int);
int rtinit(struct ifaddr *, int, int);
int rtioctl(u_long, caddr_t, struct proc *);
void rtredirect(struct sockaddr *, struct sockaddr *,
struct sockaddr *, int, struct sockaddr *,
- struct rtentry **);
+ struct rtentry **, u_int);
int rtrequest1(int, struct rt_addrinfo *, u_int8_t, struct rtentry **,
u_int);
void rt_if_remove(struct ifnet *);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 536debd3bb4..f1615869a99 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.87 2009/05/31 18:00:54 claudio Exp $ */
+/* $OpenBSD: rtsock.c,v 1.88 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -620,19 +620,22 @@ report:
* flags may also be different; ifp may be specified
* by ll sockaddr when protocol address is ambiguous
*/
- if ((error = rt_getifa(&info)) != 0)
+ if ((error = rt_getifa(&info,
+ /* XXX wrong, only rdomain */ tableid)) != 0)
goto flush;
if (gate && rt_setgate(rt, rt_key(rt), gate, tableid)) {
error = EDQUOT;
goto flush;
}
- if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr)) &&
+ if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr,
+ /* XXX again rtable vs. rdomain */ tableid)) &&
(ifp = ifa->ifa_ifp) && (ifaaddr || gate))
ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate,
- ifp);
- else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr))) ||
+ ifp);
+ else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr,
+ /* XXX one more time */ tableid))) ||
(gate && (ifa = ifa_ifwithroute(rt->rt_flags,
- rt_key(rt), gate))))
+ rt_key(rt), gate, /* XXX again */ tableid))))
ifp = ifa->ifa_ifp;
if (ifa) {
struct ifaddr *oifa = rt->rt_ifa;
@@ -1062,6 +1065,7 @@ rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
ifam->ifam_metric = ifa->ifa_metric;
ifam->ifam_flags = ifa->ifa_flags;
ifam->ifam_addrs = info.rti_addrs;
+ ifam->ifam_tableid = ifp->if_rdomain;
}
if ((cmd == RTM_ADD && pass == 2) ||
(cmd == RTM_DELETE && pass == 1)) {
@@ -1079,6 +1083,7 @@ rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
rtm->rtm_flags |= rt->rt_flags;
rtm->rtm_errno = error;
rtm->rtm_addrs = info.rti_addrs;
+ rtm->rtm_tableid = ifp->if_rdomain;
}
if (sa == NULL)
route_proto.sp_protocol = 0;
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),
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 67e3904a4f7..7453fe1e7b0 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: icmp6.c,v 1.104 2009/02/22 17:43:20 claudio Exp $ */
+/* $OpenBSD: icmp6.c,v 1.105 2009/06/05 00:05:22 claudio Exp $ */
/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
/*
@@ -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))
+ if (ifa_ifwithaddr((struct sockaddr *)&sin6, /* XXX */ 0))
; /* unicast/anycast, fine */
else if (IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr))
; /* link-local multicast, fine */
@@ -2336,7 +2336,7 @@ icmp6_redirect_input(struct mbuf *m, int off)
rtredirect((struct sockaddr *)&sdst, (struct sockaddr *)&sgw,
(struct sockaddr *)NULL, RTF_GATEWAY | RTF_HOST,
(struct sockaddr *)&ssrc,
- &newrt);
+ &newrt, /* XXX */ 0);
if (newrt) {
(void)rt_timer_add(newrt, icmp6_redirect_timeout,
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index a008f565912..a5f4f9502f7 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_pcb.c,v 1.48 2008/11/23 13:30:59 claudio Exp $ */
+/* $OpenBSD: in6_pcb.c,v 1.49 2009/06/05 00:05:22 claudio Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -235,8 +235,8 @@ 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))
- == NULL))
+ (ia = ifa_ifwithaddr((struct sockaddr *)sin6,
+ /* XXX */ 0)) == NULL)
return EADDRNOTAVAIL;
/*
@@ -276,7 +276,7 @@ in6_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p)
t = in_pcblookup(head,
(struct in_addr *)&zeroin6_addr, 0,
(struct in_addr *)&sin6->sin6_addr, lport,
- wild);
+ wild, /* XXX */ 0);
if (t && (reuseport & t->inp_socket->so_options) == 0)
return EADDRINUSE;
@@ -353,7 +353,7 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p)
lport = htons(*lastport);
} while (in_baddynamic(*lastport, so->so_proto->pr_protocol) ||
in_pcblookup(table, &zeroin6_addr, 0,
- &inp->inp_laddr6, lport, wild));
+ &inp->inp_laddr6, lport, wild, /* XXX */ 0));
} else {
/*
* counting up
@@ -371,7 +371,7 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p)
lport = htons(*lastport);
} while (in_baddynamic(*lastport, so->so_proto->pr_protocol) ||
in_pcblookup(table, &zeroin6_addr, 0,
- &inp->inp_laddr6, lport, wild));
+ &inp->inp_laddr6, lport, wild, /* XXX */ 0));
}
inp->inp_lport = lport;
@@ -452,7 +452,7 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam)
if (in_pcblookup(inp->inp_table, &sin6->sin6_addr, sin6->sin6_port,
IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) ? in6a : &inp->inp_laddr6,
- inp->inp_lport, INPLOOKUP_IPV6)) {
+ inp->inp_lport, INPLOOKUP_IPV6, /* XXX */ 0)) {
return (EADDRINUSE);
}
if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) {
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 94ebaee050e..ec91971dd13 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip6.c,v 1.38 2008/11/23 13:30:59 claudio Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.39 2009/06/05 00:05:22 claudio Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
@@ -673,7 +673,8 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
* this in a more natural way.
*/
if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) &&
- (ia = ifa_ifwithaddr((struct sockaddr *)addr)) == 0) {
+ (ia = ifa_ifwithaddr((struct sockaddr *)addr,
+ /* XXX */ 0)) == 0) {
error = EADDRNOTAVAIL;
break;
}
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 75d73b52c1f..68871411ce6 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbuf.h,v 1.122 2009/06/02 00:05:13 blambert Exp $ */
+/* $OpenBSD: mbuf.h,v 1.123 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */
/*
@@ -78,8 +78,8 @@ struct m_hdr {
struct pkthdr_pf {
void *hdr; /* saved hdr pos in mbuf, for ECN */
void *statekey; /* pf stackside statekey */
- u_int rtableid; /* alternate routing table id */
u_int32_t qid; /* queue id */
+ u_int rtableid; /* alternate routing table id */
u_int16_t tag; /* tag id */
u_int8_t flags;
u_int8_t routed;
@@ -98,6 +98,7 @@ struct pkthdr {
int len; /* total packet length */
u_int16_t csum_flags; /* checksum flags */
u_int16_t ether_vtag; /* Ethernet 802.1p+Q vlan tag */
+ u_int rdomain; /* routing domain id */
struct pkthdr_pf pf;
};
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index 76788cf0629..771bc58ec37 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: socket.h,v 1.59 2008/09/16 15:48:12 gollo Exp $ */
+/* $OpenBSD: socket.h,v 1.60 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: socket.h,v 1.14 1996/02/09 18:25:36 christos Exp $ */
/*
@@ -44,6 +44,9 @@
* Definitions related to sockets: types, address families, options.
*/
+/* Maximum number of alternate routing tables */
+#define RT_TABLEID_MAX 255
+
/*
* Types
*/
@@ -82,6 +85,7 @@
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
#define SO_NETPROC 0x1020 /* multiplex; network processing */
+#define SO_RDOMAIN 0x1021 /* routing domain socket belongs to */
/*
* Structure used for manipulating linger option.
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index b1480572a3a..4e2c89e190d 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sockio.h,v 1.44 2009/06/04 19:07:21 henning Exp $ */
+/* $OpenBSD: sockio.h,v 1.45 2009/06/05 00:05:22 claudio Exp $ */
/* $NetBSD: sockio.h,v 1.5 1995/08/23 00:40:47 thorpej Exp $ */
/*-
@@ -173,6 +173,9 @@
#define SIOCSIFXFLAGS _IOW('i', 157, struct ifreq) /* set ifnet xflags */
#define SIOCGIFXFLAGS _IOWR('i', 158, struct ifreq) /* get ifnet xflags */
+#define SIOCSIFRTABLEID _IOW('i', 159, struct ifreq) /* set ifnet VRF id */
+#define SIOCGIFRTABLEID _IOWR('i', 160, struct ifreq) /* get ifnet VRF id */
+
#define SIOCSVH _IOWR('i', 245, struct ifreq) /* set carp param */
#define SIOCGVH _IOWR('i', 246, struct ifreq) /* get carp param */