summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2010-07-09 16:58:07 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2010-07-09 16:58:07 +0000
commit9b4939a135e7439d02025abc3fae443f6b34a436 (patch)
tree4d6d474863598a533548ed438df229f82ffd9a59 /sys
parent74c8e65b12d50b84bca2cad414861a6a3de2ec89 (diff)
Add support for using IPsec in multiple rdomains.
This allows to run isakmpd/iked/ipsecctl in multiple rdomains independently (with "route exec"); the kernel will pickup the rdomain from the process context of the pfkey socket and load the flows and SAs into the matching rdomain encap routing table. The network stack also needs to pass the rdomain to the ipsec stack to lookup the correct rdomain that belongs to an interface/mbuf/... You can now run individual IPsec configs per rdomain or create IPsec VPNs between multiple rdomains on the same machine ;). Note that a primary enc(4) in addition to enc0 interface is required per rdomain, eg. enc1 rdomain 1. Test by some people, mostly on existing "rdomain 0" setups. Was in snaps for some days and people didn't complain. ok claudio@ naddy@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_bridge.c8
-rw-r--r--sys/net/if_pfsync.c5
-rw-r--r--sys/net/if_pfsync.h4
-rw-r--r--sys/net/pfkeyv2.c100
-rw-r--r--sys/net/pfkeyv2.h7
-rw-r--r--sys/net/route.c10
-rw-r--r--sys/netinet/ip_ah.c11
-rw-r--r--sys/netinet/ip_esp.c13
-rw-r--r--sys/netinet/ip_input.c8
-rw-r--r--sys/netinet/ip_ipcomp.c8
-rw-r--r--sys/netinet/ip_ipsp.c90
-rw-r--r--sys/netinet/ip_ipsp.h23
-rw-r--r--sys/netinet/ip_output.c12
-rw-r--r--sys/netinet/ip_spd.c26
-rw-r--r--sys/netinet/ipsec_input.c25
-rw-r--r--sys/netinet/ipsec_output.c6
-rw-r--r--sys/netinet/tcp_input.c20
-rw-r--r--sys/netinet/tcp_output.c5
-rw-r--r--sys/netinet/tcp_var.h4
-rw-r--r--sys/netinet/udp_usrreq.c5
-rw-r--r--sys/netinet6/ip6_forward.c12
-rw-r--r--sys/netinet6/ip6_output.c17
22 files changed, 267 insertions, 152 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 5dd8b2e9217..4fbe0470dbe 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.181 2010/07/02 02:40:16 blambert Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.182 2010/07/09 16:58:06 reyk Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -2402,7 +2402,7 @@ bridge_ipsec(struct bridge_softc *sc, struct ifnet *ifp,
s = spltdb();
- tdb = gettdb(spi, &dst, proto);
+ tdb = gettdb(ifp->if_rdomain, spi, &dst, proto);
if (tdb != NULL && (tdb->tdb_flags & TDBF_INVALID) == 0 &&
tdb->tdb_xform != NULL) {
if (tdb->tdb_first_use == 0) {
@@ -2457,7 +2457,7 @@ bridge_ipsec(struct bridge_softc *sc, struct ifnet *ifp,
switch (af) {
#ifdef INET
case AF_INET:
- if ((encif = enc_getif(0,
+ if ((encif = enc_getif(tdb->tdb_rdomain,
tdb->tdb_tap)) == NULL ||
pf_test(dir, encif,
&m, NULL) != PF_PASS) {
@@ -2468,7 +2468,7 @@ bridge_ipsec(struct bridge_softc *sc, struct ifnet *ifp,
#endif /* INET */
#ifdef INET6
case AF_INET6:
- if ((encif = enc_getif(0,
+ if ((encif = enc_getif(tdb->tdb_rdomain,
tdb->tdb_tap)) == NULL ||
pf_test6(dir, encif,
&m, NULL) != PF_PASS) {
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
index 95894c3cb0c..535205daaf9 100644
--- a/sys/net/if_pfsync.c
+++ b/sys/net/if_pfsync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.151 2010/07/09 13:09:34 dlg Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.152 2010/07/09 16:58:06 reyk Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -1239,7 +1239,7 @@ pfsync_update_net_tdb(struct pfsync_tdb *pt)
goto bad;
s = spltdb();
- tdb = gettdb(pt->spi, &pt->dst, pt->sproto);
+ tdb = gettdb(ntohs(pt->rdomain), pt->spi, &pt->dst, pt->sproto);
if (tdb) {
pt->rpl = ntohl(pt->rpl);
pt->cur_bytes = betoh64(pt->cur_bytes);
@@ -2162,6 +2162,7 @@ pfsync_out_tdb(struct tdb *t, void *buf)
RPL_INCR : 0));
ut->cur_bytes = htobe64(t->tdb_cur_bytes);
ut->sproto = t->tdb_sproto;
+ ut->rdomain = htons(t->tdb_rdomain);
}
void
diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h
index dafe6d4e43f..ba83a6607ff 100644
--- a/sys/net/if_pfsync.h
+++ b/sys/net/if_pfsync.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.h,v 1.42 2010/01/12 23:38:02 dlg Exp $ */
+/* $OpenBSD: if_pfsync.h,v 1.43 2010/07/09 16:58:06 reyk Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -216,7 +216,7 @@ struct pfsync_tdb {
u_int64_t cur_bytes;
u_int8_t sproto;
u_int8_t updates;
- u_int8_t _pad[2];
+ u_int16_t rdomain;
} __packed;
/*
diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c
index b5c0178406f..19568d3be13 100644
--- a/sys/net/pfkeyv2.c
+++ b/sys/net/pfkeyv2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.c,v 1.120 2010/07/01 02:09:45 reyk Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.121 2010/07/09 16:58:06 reyk Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
@@ -159,6 +159,12 @@ pfkeyv2_create(struct socket *socket)
pfkeyv2_socket->socket = socket;
pfkeyv2_socket->pid = curproc->p_pid;
+ /*
+ * XXX we should get this from the socket instead but
+ * XXX rawcb doesn't store the rdomain like inpcb does.
+ */
+ pfkeyv2_socket->rdomain = rtable_l2(curproc->p_p->ps_rtableid);
+
pfkeyv2_sockets = pfkeyv2_socket;
return (0);
@@ -201,7 +207,7 @@ pfkeyv2_release(struct socket *socket)
*/
int
pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
- u_int8_t satype, int count)
+ u_int8_t satype, int count, u_int rdomain)
{
int i, j, rval;
void *p, *buffer = NULL;
@@ -272,7 +278,8 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
*/
for (s = pfkeyv2_sockets; s; s = s->next)
if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
- (s->socket != socket))
+ (s->socket != socket) &&
+ (s->rdomain == rdomain))
pfkey_sendup(s->socket, packet, 1);
/* Done, let's be a bit paranoid */
@@ -286,7 +293,8 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
* the specified satype (e.g., all IPSEC-ESP negotiators)
*/
for (s = pfkeyv2_sockets; s; s = s->next)
- if (s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) {
+ if ((s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) &&
+ (s->rdomain == rdomain)) {
if (!satype) /* Just send to everyone registered */
pfkey_sendup(s->socket, packet, 1);
else {
@@ -316,7 +324,8 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
/* Send to all registered promiscuous listeners */
for (s = pfkeyv2_sockets; s; s = s->next)
if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
- !(s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED))
+ !(s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) &&
+ (s->rdomain == rdomain))
pfkey_sendup(s->socket, packet, 1);
m_freem(packet);
@@ -324,9 +333,10 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
case PFKEYV2_SENDMESSAGE_BROADCAST:
/* Send message to all sockets */
- for (s = pfkeyv2_sockets; s; s = s->next)
- pfkey_sendup(s->socket, packet, 1);
-
+ for (s = pfkeyv2_sockets; s; s = s->next) {
+ if (s->rdomain == rdomain)
+ pfkey_sendup(s->socket, packet, 1);
+ }
m_freem(packet);
break;
}
@@ -742,7 +752,8 @@ pfkeyv2_dump_walker(struct tdb *sa, void *state, int last)
/* Send the message to the specified socket */
rval = pfkeyv2_sendmessage(headers,
- PFKEYV2_SENDMESSAGE_UNICAST, dump_state->socket, 0, 0);
+ PFKEYV2_SENDMESSAGE_UNICAST, dump_state->socket, 0, 0,
+ sa->tdb_rdomain);
free(buffer, M_PFKEY);
if (rval)
@@ -859,6 +870,8 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
struct sadb_supported *ssup;
struct sadb_ident *sid;
+ u_int rdomain;
+
/* Verify that we received this over a legitimate pfkeyv2 socket */
bzero(headers, sizeof(headers));
@@ -872,6 +885,8 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
goto ret;
}
+ rdomain = pfkeyv2_socket->rdomain;
+
/* If we have any promiscuous listeners, send them a copy of the message */
if (npromisc) {
struct mbuf *packet;
@@ -899,9 +914,11 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
goto ret;
/* Send to all promiscuous listeners */
- for (so = pfkeyv2_sockets; so; so = so->next)
- if (so->flags & PFKEYV2_SOCKETFLAGS_PROMISC)
+ for (so = pfkeyv2_sockets; so; so = so->next) {
+ if ((so->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
+ (so->rdomain == rdomain))
pfkey_sendup(so->socket, packet, 1);
+ }
/* Paranoid */
m_zero(packet);
@@ -934,9 +951,9 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
/* Find an unused SA identifier */
sprng = (struct sadb_spirange *) headers[SADB_EXT_SPIRANGE];
- sa.tdb_spi = reserve_spi(sprng->sadb_spirange_min,
- sprng->sadb_spirange_max, &sa.tdb_src, &sa.tdb_dst,
- sa.tdb_sproto, &rval);
+ sa.tdb_spi = reserve_spi(rdomain,
+ sprng->sadb_spirange_min, sprng->sadb_spirange_max,
+ &sa.tdb_src, &sa.tdb_dst, sa.tdb_sproto, &rval);
if (sa.tdb_spi == 0)
goto ret;
@@ -989,7 +1006,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
s = spltdb();
/* Find TDB */
- sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
+ sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
/* If there's no such SA, we're done */
@@ -1005,7 +1022,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
int alg;
/* Create new TDB */
- freeme = tdb_alloc();
+ freeme = tdb_alloc(rdomain);
bzero(&ii, sizeof(struct ipsecinit));
newsa = (struct tdb *) freeme;
@@ -1150,7 +1167,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
s = spltdb();
- sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
+ sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
/* We can't add an existing SA! */
@@ -1166,7 +1183,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
}
/* Allocate and initialize new TDB */
- freeme = tdb_alloc();
+ freeme = tdb_alloc(rdomain);
{
struct tdb *newsa = (struct tdb *) freeme;
@@ -1262,7 +1279,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
sizeof(struct sadb_address));
s = spltdb();
- sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
+ sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
if (sa2 == NULL) {
rval = ESRCH;
@@ -1298,7 +1315,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
s = spltdb();
- sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
+ sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
if (sa2 == NULL) {
rval = ESRCH;
@@ -1398,7 +1415,8 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
for (ipo = TAILQ_FIRST(&ipsec_policy_head);
ipo != NULL; ipo = tmpipo) {
tmpipo = TAILQ_NEXT(ipo, ipo_list);
- if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
+ if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET) &&
+ ipo->ipo_rdomain == rdomain)
ipsec_delete_policy(ipo);
}
splx(s);
@@ -1412,7 +1430,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
#endif /* TCP_SIGNATURE */
s = spltdb();
- tdb_walk(pfkeyv2_flush_walker,
+ tdb_walk(rdomain, pfkeyv2_flush_walker,
(u_int8_t *) &(smsg->sadb_msg_satype));
splx(s);
@@ -1431,7 +1449,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
dump_state.socket = socket;
s = spltdb();
- rval = tdb_walk(pfkeyv2_dump_walker, &dump_state);
+ rval = tdb_walk(rdomain, pfkeyv2_dump_walker, &dump_state);
splx(s);
if (!rval)
@@ -1453,7 +1471,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
s = spltdb();
- tdb1 = gettdb(ssa->sadb_sa_spi, sunionp,
+ tdb1 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(smsg->sadb_msg_satype));
if (tdb1 == NULL) {
rval = ESRCH;
@@ -1465,7 +1483,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
sizeof(struct sadb_address));
sa_proto = ((struct sadb_protocol *) headers[SADB_X_EXT_PROTOCOL]);
- tdb2 = gettdb(ssa->sadb_sa_spi, sunionp,
+ tdb2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
SADB_X_GETSPROTO(sa_proto->sadb_protocol_proto));
if (tdb2 == NULL) {
rval = ESRCH;
@@ -1544,6 +1562,9 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
s = spltdb();
+ /* Set the rdomain that was obtained from the socket */
+ re.re_tableid = rdomain;
+
rtalloc((struct route *) &re);
if (re.re_rt != NULL) {
ipo = ((struct sockaddr_encap *) re.re_rt->rt_gateway)->sen_ipsp;
@@ -1617,6 +1638,8 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
sizeof(struct sockaddr_encap));
bcopy(&encapnetmask, &ipo->ipo_mask,
sizeof(struct sockaddr_encap));
+
+ ipo->ipo_rdomain = rdomain;
}
switch (((struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE])->sadb_protocol_proto) {
@@ -1744,7 +1767,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
(struct sockaddr *)&encapnetmask;
info.rti_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
if ((rval = rtrequest1(RTM_ADD, &info, RTP_DEFAULT,
- NULL, 0)) != 0) {
+ NULL, rdomain)) != 0) {
/* Remove from linked list of policies on TDB */
if (ipo->ipo_tdb)
TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
@@ -1779,6 +1802,7 @@ pfkeyv2_send(struct socket *socket, void *message, int len)
for (so = pfkeyv2_sockets; so; so = so->next)
if ((so != pfkeyv2_socket) &&
+ (so->rdomain == rdomain) &&
(!smsg->sadb_msg_seq ||
(smsg->sadb_msg_seq == pfkeyv2_socket->pid)))
pfkey_sendup(so->socket, packet, 1);
@@ -1840,7 +1864,7 @@ ret:
goto realret;
}
- rval = pfkeyv2_sendmessage(headers, mode, socket, 0, 0);
+ rval = pfkeyv2_sendmessage(headers, mode, socket, 0, 0, rdomain);
realret:
if (freeme)
@@ -2121,8 +2145,8 @@ pfkeyv2_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw,
/* Send the ACQUIRE message to all compliant registered listeners. */
if ((rval = pfkeyv2_sendmessage(headers,
- PFKEYV2_SENDMESSAGE_REGISTERED, NULL, smsg->sadb_msg_satype, 0))
- != 0)
+ PFKEYV2_SENDMESSAGE_REGISTERED, NULL, smsg->sadb_msg_satype, 0,
+ ipo->ipo_rdomain)) != 0)
goto ret;
rval = 0;
@@ -2203,7 +2227,7 @@ pfkeyv2_expire(struct tdb *sa, u_int16_t type)
export_address(&p, (struct sockaddr *) &sa->tdb_dst);
if ((rval = pfkeyv2_sendmessage(headers, PFKEYV2_SENDMESSAGE_BROADCAST,
- NULL, 0, 0)) != 0)
+ NULL, 0, 0, sa->tdb_rdomain)) != 0)
goto ret;
rval = 0;
@@ -2415,13 +2439,17 @@ ret:
* Caller is responsible for setting at least spltdb().
*/
int
-pfkeyv2_ipo_walk(int (*walker)(struct ipsec_policy *, void *), void *arg)
+pfkeyv2_ipo_walk(u_int rdomain, int (*walker)(struct ipsec_policy *, void *),
+ void *arg)
{
int rval = 0;
struct ipsec_policy *ipo;
- TAILQ_FOREACH(ipo, &ipsec_policy_head, ipo_list)
+ TAILQ_FOREACH(ipo, &ipsec_policy_head, ipo_list) {
+ if (ipo->ipo_rdomain != rdomain)
+ continue;
rval = walker(ipo, (void *)arg);
+ }
return (rval);
}
@@ -2494,6 +2522,7 @@ pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
{
struct pfkeyv2_sysctl_walk w;
int s, error = EINVAL;
+ u_int rdomain;
if (new)
return (EPERM);
@@ -2504,12 +2533,14 @@ pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
w.w_where = oldp;
w.w_len = oldp ? *oldlenp : 0;
+ rdomain = rtable_l2(curproc->p_p->ps_rtableid);
+
switch(w.w_op) {
case NET_KEY_SADB_DUMP:
if ((error = suser(curproc, 0)) != 0)
return (error);
s = spltdb();
- error = tdb_walk(pfkeyv2_sysctl_walker, &w);
+ error = tdb_walk(rdomain, pfkeyv2_sysctl_walker, &w);
splx(s);
if (oldp)
*oldlenp = w.w_where - oldp;
@@ -2519,7 +2550,8 @@ pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
case NET_KEY_SPD_DUMP:
s = spltdb();
- error = pfkeyv2_ipo_walk(pfkeyv2_sysctl_policydumper, &w);
+ error = pfkeyv2_ipo_walk(rdomain,
+ pfkeyv2_sysctl_policydumper, &w);
splx(s);
if (oldp)
*oldlenp = w.w_where - oldp;
diff --git a/sys/net/pfkeyv2.h b/sys/net/pfkeyv2.h
index 6e4d146b374..efe79a1ab1a 100644
--- a/sys/net/pfkeyv2.h
+++ b/sys/net/pfkeyv2.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.h,v 1.57 2010/07/01 02:09:45 reyk Exp $ */
+/* $OpenBSD: pfkeyv2.h,v 1.58 2010/07/09 16:58:06 reyk Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) January 1998
*
@@ -412,6 +412,7 @@ struct pfkeyv2_socket
int flags;
uint32_t pid;
uint32_t registration; /* Increase size if SATYPE_MAX > 31 */
+ uint rdomain;
};
struct dump_state
@@ -436,14 +437,14 @@ int pfkeyv2_get(struct tdb *, void **, void **, int *);
int pfkeyv2_policy(struct ipsec_acquire *, void **, void **);
int pfkeyv2_release(struct socket *);
int pfkeyv2_send(struct socket *, void *, int);
-int pfkeyv2_sendmessage(void **, int, struct socket *, u_int8_t, int);
+int pfkeyv2_sendmessage(void **, int, struct socket *, u_int8_t, int, u_int);
int pfkeyv2_dump_policy(struct ipsec_policy *, void **, void **, int *);
int pfkeyv2_dump_walker(struct tdb *, void *, int);
int pfkeyv2_flush_walker(struct tdb *, void *, int);
int pfkeyv2_get_proto_alg(u_int8_t, u_int8_t *, int *);
int pfkeyv2_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int pfkeyv2_sysctl_walker(struct tdb *, void *, int);
-int pfkeyv2_ipo_walk(int (*)(struct ipsec_policy *, void *), void *);
+int pfkeyv2_ipo_walk(u_int, int (*)(struct ipsec_policy *, void *), void *);
int pfkeyv2_sysctl_dump(void *);
int pfkeyv2_sysctl_policydumper(struct ipsec_policy *, void *);
diff --git a/sys/net/route.c b/sys/net/route.c
index 07ae9d72d30..6f5541bcd55 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.124 2010/07/09 15:44:20 claudio Exp $ */
+/* $OpenBSD: route.c,v 1.125 2010/07/09 16:58:06 reyk Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -129,7 +129,7 @@
#include <netinet/ip_ipsp.h>
#include <net/if_enc.h>
-struct ifaddr *encap_findgwifa(struct sockaddr *);
+struct ifaddr *encap_findgwifa(struct sockaddr *, u_int);
#endif
#define SA(p) ((struct sockaddr *)(p))
@@ -165,11 +165,11 @@ TAILQ_HEAD(rt_labels, rt_label) rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);
#ifdef IPSEC
struct ifaddr *
-encap_findgwifa(struct sockaddr *gw)
+encap_findgwifa(struct sockaddr *gw, u_int rdomain)
{
struct ifnet *encif;
- if ((encif = enc_getif(0, 0)) == NULL)
+ if ((encif = enc_getif(rdomain, 0)) == NULL)
return (NULL);
return (TAILQ_FIRST(&encif->if_addrlist));
@@ -624,7 +624,7 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
* enc0.
*/
if (dst && (dst->sa_family == PF_KEY))
- return (encap_findgwifa(gateway));
+ return (encap_findgwifa(gateway, rtableid));
#endif
if ((flags & RTF_GATEWAY) == 0) {
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c
index 1a9bf0cbd95..eae796f36af 100644
--- a/sys/netinet/ip_ah.c
+++ b/sys/netinet/ip_ah.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ah.c,v 1.96 2010/07/02 02:40:16 blambert Exp $ */
+/* $OpenBSD: ip_ah.c,v 1.97 2010/07/09 16:58:06 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -662,6 +662,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
tdbi = (struct tdb_ident *) (mtag + 1);
if (tdbi->proto == tdb->tdb_sproto &&
tdbi->spi == tdb->tdb_spi &&
+ tdbi->rdomain == tdb->tdb_rdomain &&
!bcmp(&tdbi->dst, &tdb->tdb_dst,
sizeof(union sockaddr_union)))
break;
@@ -721,6 +722,7 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
tc->tc_spi = tdb->tdb_spi;
tc->tc_proto = tdb->tdb_sproto;
tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified. */
+ tc->tc_rdomain = tdb->tdb_rdomain;
bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
if (mtag == NULL)
@@ -767,7 +769,7 @@ ah_input_cb(void *op)
s = spltdb();
- tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto);
if (tdb == NULL) {
free(tc, M_XDATA);
ahstat.ahs_notdb++;
@@ -988,7 +990,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
#if NBPFILTER > 0
struct ifnet *encif;
- if ((encif = enc_getif(0, tdb->tdb_tap)) != NULL) {
+ if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) != NULL) {
encif->if_opackets++;
encif->if_obytes += m->m_pkthdr.len;
@@ -1249,6 +1251,7 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
tc->tc_protoff = protoff;
tc->tc_spi = tdb->tdb_spi;
tc->tc_proto = tdb->tdb_sproto;
+ tc->tc_rdomain = tdb->tdb_rdomain;
bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
@@ -1289,7 +1292,7 @@ ah_output_cb(void *op)
s = spltdb();
- tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto);
if (tdb == NULL) {
free(tc, M_XDATA);
ahstat.ahs_notdb++;
diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c
index 1ca5f791e7e..66f50499e50 100644
--- a/sys/netinet/ip_esp.c
+++ b/sys/netinet/ip_esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_esp.c,v 1.109 2010/07/02 02:40:16 blambert Exp $ */
+/* $OpenBSD: ip_esp.c,v 1.110 2010/07/09 16:58:06 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -386,7 +386,8 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
tdbi = (struct tdb_ident *) (mtag + 1);
if (tdbi->proto == tdb->tdb_sproto && tdbi->spi == tdb->tdb_spi &&
- !bcmp(&tdbi->dst, &tdb->tdb_dst, sizeof(union sockaddr_union)))
+ tdbi->rdomain == tdb->tdb_rdomain && !bcmp(&tdbi->dst,
+ &tdb->tdb_dst, sizeof(union sockaddr_union)))
break;
}
#else
@@ -449,6 +450,7 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
tc->tc_protoff = protoff;
tc->tc_spi = tdb->tdb_spi;
tc->tc_proto = tdb->tdb_sproto;
+ tc->tc_rdomain = tdb->tdb_rdomain;
bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
/* Decryption descriptor */
@@ -516,7 +518,7 @@ esp_input_cb(void *op)
s = spltdb();
- tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto);
if (tdb == NULL) {
free(tc, M_XDATA);
espstat.esps_notdb++;
@@ -733,7 +735,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
#if NBPFILTER > 0
struct ifnet *encif;
- if ((encif = enc_getif(0, tdb->tdb_tap)) != NULL) {
+ if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) != NULL) {
encif->if_opackets++;
encif->if_obytes += m->m_pkthdr.len;
@@ -963,6 +965,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
tc->tc_spi = tdb->tdb_spi;
tc->tc_proto = tdb->tdb_sproto;
+ tc->tc_rdomain = tdb->tdb_rdomain;
bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
/* Crypto operation descriptor. */
@@ -1019,7 +1022,7 @@ esp_output_cb(void *op)
s = spltdb();
- tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto);
if (tdb == NULL) {
free(tc, M_XDATA);
espstat.esps_notdb++;
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index e8177a35e42..c2d4d2400e5 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.181 2010/06/07 13:26:35 henning Exp $ */
+/* $OpenBSD: ip_input.c,v 1.182 2010/07/09 16:58:06 reyk Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -490,7 +490,8 @@ ipv4_input(m)
s = splnet();
if (mtag != NULL) {
tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi,
+ &tdbi->dst, tdbi->proto);
} else
tdb = NULL;
ipsp_spd_lookup(m, AF_INET, hlen, &error,
@@ -649,7 +650,8 @@ found:
s = splnet();
if (mtag) {
tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst,
+ tdbi->proto);
} else
tdb = NULL;
ipsp_spd_lookup(m, AF_INET, hlen, &error, IPSP_DIRECTION_IN,
diff --git a/sys/netinet/ip_ipcomp.c b/sys/netinet/ip_ipcomp.c
index af855f0d7cb..fff0dbfe999 100644
--- a/sys/netinet/ip_ipcomp.c
+++ b/sys/netinet/ip_ipcomp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipcomp.c,v 1.26 2010/07/02 02:40:16 blambert Exp $ */
+/* $OpenBSD: ip_ipcomp.c,v 1.27 2010/07/09 16:58:06 reyk Exp $ */
/*
* Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org)
@@ -195,6 +195,7 @@ ipcomp_input(m, tdb, skip, protoff)
tc->tc_protoff = protoff;
tc->tc_spi = tdb->tdb_spi;
tc->tc_proto = IPPROTO_IPCOMP;
+ tc->tc_rdomain = tdb->tdb_rdomain;
bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
return crypto_dispatch(crp);
@@ -234,7 +235,7 @@ ipcomp_input_cb(op)
s = spltdb();
- tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto);
if (tdb == NULL) {
free(tc, M_XDATA);
ipcompstat.ipcomps_notdb++;
@@ -526,6 +527,7 @@ ipcomp_output(m, tdb, mp, skip, protoff)
tc->tc_spi = tdb->tdb_spi;
tc->tc_proto = tdb->tdb_sproto;
tc->tc_skip = skip;
+ tc->tc_rdomain = tdb->tdb_rdomain;
bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
/* Crypto operation descriptor */
@@ -577,7 +579,7 @@ ipcomp_output_cb(cp)
s = spltdb();
- tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
+ tdb = gettdb(tc->tc_rdomain, tc->tc_spi, &tc->tc_dst, tc->tc_proto);
if (tdb == NULL) {
free(tc, M_XDATA);
ipcompstat.ipcomps_notdb++;
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index 40df7b69f7b..93c18ee3a5d 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.180 2010/04/20 22:05:43 tedu Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.181 2010/07/09 16:58:06 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -94,7 +94,7 @@ void tdb_timeout(void *v);
void tdb_firstuse(void *v);
void tdb_soft_timeout(void *v);
void tdb_soft_firstuse(void *v);
-int tdb_hash(u_int32_t, union sockaddr_union *, u_int8_t);
+int tdb_hash(u_int, u_int32_t, union sockaddr_union *, u_int8_t);
extern int ipsec_auth_default_level;
extern int ipsec_esp_trans_default_level;
@@ -155,7 +155,8 @@ static int tdb_count;
* so we cannot be DoS-attacked via choosing of the data to hash.
*/
int
-tdb_hash(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
+tdb_hash(u_int rdomain, u_int32_t spi, union sockaddr_union *dst,
+ u_int8_t proto)
{
static u_int32_t mult1 = 0, mult2 = 0;
u_int8_t *ptr = (u_int8_t *) dst;
@@ -168,7 +169,7 @@ tdb_hash(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
while (mult2 == 0)
mult2 = arc4random();
- hash = (spi ^ proto) * mult1;
+ hash = (spi ^ proto ^ rdomain) * mult1;
for (i = 0; i < SA_LEN(&dst->sa); i++) {
val32 = (val32 << 8) | ptr[i];
if (i % 4 == 3) {
@@ -192,8 +193,9 @@ tdb_hash(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
* an error return value.
*/
u_int32_t
-reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
- union sockaddr_union *dst, u_int8_t sproto, int *errval)
+reserve_spi(u_int rdomain, u_int32_t sspi, u_int32_t tspi,
+ union sockaddr_union *src, union sockaddr_union *dst,
+ u_int8_t sproto, int *errval)
{
struct tdb *tdbp;
u_int32_t spi;
@@ -248,13 +250,13 @@ reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
/* Check whether we're using this SPI already. */
s = spltdb();
- tdbp = gettdb(spi, dst, sproto);
+ tdbp = gettdb(rdomain, spi, dst, sproto);
splx(s);
if (tdbp != (struct tdb *) NULL)
continue;
- tdbp = tdb_alloc();
+ tdbp = tdb_alloc(rdomain);
tdbp->tdb_spi = spi;
bcopy(&dst->sa, &tdbp->tdb_dst.sa, SA_LEN(&dst->sa));
@@ -289,7 +291,7 @@ reserve_spi(u_int32_t sspi, u_int32_t tspi, union sockaddr_union *src,
* Caller is responsible for setting at least spltdb().
*/
struct tdb *
-gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
+gettdb(u_int rdomain, u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
{
u_int32_t hashval;
struct tdb *tdbp;
@@ -297,10 +299,11 @@ gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
if (tdbh == NULL)
return (struct tdb *) NULL;
- hashval = tdb_hash(spi, dst, proto);
+ hashval = tdb_hash(rdomain, spi, dst, proto);
for (tdbp = tdbh[hashval]; tdbp != NULL; tdbp = tdbp->tdb_hnext)
if ((tdbp->tdb_spi == spi) && (tdbp->tdb_sproto == proto) &&
+ (tdbp->tdb_rdomain == rdomain) &&
!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)))
break;
@@ -313,7 +316,7 @@ gettdb(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto)
* matches all SPIs.
*/
struct tdb *
-gettdbbysrcdst(u_int32_t spi, union sockaddr_union *src,
+gettdbbysrcdst(u_int rdomain, u_int32_t spi, union sockaddr_union *src,
union sockaddr_union *dst, u_int8_t proto)
{
u_int32_t hashval;
@@ -323,11 +326,12 @@ gettdbbysrcdst(u_int32_t spi, union sockaddr_union *src,
if (tdbsrc == NULL)
return (struct tdb *) NULL;
- hashval = tdb_hash(0, src, proto);
+ hashval = tdb_hash(rdomain, 0, src, proto);
for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
if (tdbp->tdb_sproto == proto &&
(spi == 0 || tdbp->tdb_spi == spi) &&
+ (tdbp->tdb_rdomain == rdomain) &&
((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
(tdbp->tdb_dst.sa.sa_family == AF_UNSPEC ||
!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa))) &&
@@ -339,11 +343,12 @@ gettdbbysrcdst(u_int32_t spi, union sockaddr_union *src,
bzero(&su_null, sizeof(su_null));
su_null.sa.sa_len = sizeof(struct sockaddr);
- hashval = tdb_hash(0, &su_null, proto);
+ hashval = tdb_hash(rdomain, 0, &su_null, proto);
for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
if (tdbp->tdb_sproto == proto &&
(spi == 0 || tdbp->tdb_spi == spi) &&
+ (tdbp->tdb_rdomain == rdomain) &&
((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
(tdbp->tdb_dst.sa.sa_family == AF_UNSPEC ||
!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa))) &&
@@ -412,7 +417,7 @@ ipsp_aux_match(struct tdb *tdb,
* the desired IDs.
*/
struct tdb *
-gettdbbyaddr(union sockaddr_union *dst, u_int8_t sproto,
+gettdbbyaddr(u_int rdomain, union sockaddr_union *dst, u_int8_t sproto,
struct ipsec_ref *srcid, struct ipsec_ref *dstid,
struct ipsec_ref *local_cred, struct mbuf *m, int af,
struct sockaddr_encap *filter, struct sockaddr_encap *filtermask)
@@ -423,10 +428,11 @@ gettdbbyaddr(union sockaddr_union *dst, u_int8_t sproto,
if (tdbaddr == NULL)
return (struct tdb *) NULL;
- hashval = tdb_hash(0, dst, sproto);
+ hashval = tdb_hash(rdomain, 0, dst, sproto);
for (tdbp = tdbaddr[hashval]; tdbp != NULL; tdbp = tdbp->tdb_anext)
if ((tdbp->tdb_sproto == sproto) &&
+ (tdbp->tdb_rdomain == rdomain) &&
((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
(!bcmp(&tdbp->tdb_dst, dst, SA_LEN(&dst->sa)))) {
/* Do IDs and local credentials match ? */
@@ -444,7 +450,7 @@ gettdbbyaddr(union sockaddr_union *dst, u_int8_t sproto,
* the desired IDs.
*/
struct tdb *
-gettdbbysrc(union sockaddr_union *src, u_int8_t sproto,
+gettdbbysrc(u_int rdomain, union sockaddr_union *src, u_int8_t sproto,
struct ipsec_ref *srcid, struct ipsec_ref *dstid,
struct mbuf *m, int af, struct sockaddr_encap *filter,
struct sockaddr_encap *filtermask)
@@ -455,10 +461,11 @@ gettdbbysrc(union sockaddr_union *src, u_int8_t sproto,
if (tdbsrc == NULL)
return (struct tdb *) NULL;
- hashval = tdb_hash(0, src, sproto);
+ hashval = tdb_hash(rdomain, 0, src, sproto);
for (tdbp = tdbsrc[hashval]; tdbp != NULL; tdbp = tdbp->tdb_snext)
if ((tdbp->tdb_sproto == sproto) &&
+ (tdbp->tdb_rdomain == rdomain) &&
((tdbp->tdb_flags & TDBF_INVALID) == 0) &&
(!bcmp(&tdbp->tdb_src, src, SA_LEN(&src->sa)))) {
/* Check whether IDs match */
@@ -506,7 +513,7 @@ tdb_hashstats(void)
* Caller is responsible for setting at least spltdb().
*/
int
-tdb_walk(int (*walker)(struct tdb *, void *, int), void *arg)
+tdb_walk(u_int rdomain, int (*walker)(struct tdb *, void *, int), void *arg)
{
int i, rval = 0;
struct tdb *tdbp, *next;
@@ -517,6 +524,10 @@ tdb_walk(int (*walker)(struct tdb *, void *, int), void *arg)
for (i = 0; i <= tdb_hashmask; i++)
for (tdbp = tdbh[i]; rval == 0 && tdbp != NULL; tdbp = next) {
next = tdbp->tdb_hnext;
+
+ if (rdomain != tdbp->tdb_rdomain)
+ continue;
+
if (i == tdb_hashmask && next == NULL)
rval = walker(tdbp, (void *)arg, 1);
else
@@ -606,7 +617,8 @@ tdb_rehash(void)
for (i = 0; i <= old_hashmask; i++) {
for (tdbp = tdbh[i]; tdbp != NULL; tdbp = tdbnp) {
tdbnp = tdbp->tdb_hnext;
- hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
+ hashval = tdb_hash(tdbp->tdb_rdomain,
+ tdbp->tdb_spi, &tdbp->tdb_dst,
tdbp->tdb_sproto);
tdbp->tdb_hnext = new_tdbh[hashval];
new_tdbh[hashval] = tdbp;
@@ -614,7 +626,8 @@ tdb_rehash(void)
for (tdbp = tdbaddr[i]; tdbp != NULL; tdbp = tdbnp) {
tdbnp = tdbp->tdb_anext;
- hashval = tdb_hash(0, &tdbp->tdb_dst,
+ hashval = tdb_hash(tdbp->tdb_rdomain,
+ 0, &tdbp->tdb_dst,
tdbp->tdb_sproto);
tdbp->tdb_anext = new_tdbaddr[hashval];
new_tdbaddr[hashval] = tdbp;
@@ -622,7 +635,8 @@ tdb_rehash(void)
for (tdbp = tdbsrc[i]; tdbp != NULL; tdbp = tdbnp) {
tdbnp = tdbp->tdb_snext;
- hashval = tdb_hash(0, &tdbp->tdb_src,
+ hashval = tdb_hash(tdbp->tdb_rdomain,
+ 0, &tdbp->tdb_src,
tdbp->tdb_sproto);
tdbp->tdb_snext = new_srcaddr[hashval];
new_srcaddr[hashval] = tdbp;
@@ -657,7 +671,8 @@ puttdb(struct tdb *tdbp)
M_TDB, M_WAITOK | M_ZERO);
}
- hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
+ hashval = tdb_hash(tdbp->tdb_rdomain, tdbp->tdb_spi,
+ &tdbp->tdb_dst, tdbp->tdb_sproto);
/*
* Rehash if this tdb would cause a bucket to have more than
@@ -670,18 +685,20 @@ puttdb(struct tdb *tdbp)
if (tdbh[hashval] != NULL && tdbh[hashval]->tdb_hnext != NULL &&
tdb_count * 10 > tdb_hashmask + 1) {
tdb_rehash();
- hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst,
- tdbp->tdb_sproto);
+ hashval = tdb_hash(tdbp->tdb_rdomain, tdbp->tdb_spi,
+ &tdbp->tdb_dst, tdbp->tdb_sproto);
}
tdbp->tdb_hnext = tdbh[hashval];
tdbh[hashval] = tdbp;
- hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
+ hashval = tdb_hash(tdbp->tdb_rdomain, 0, &tdbp->tdb_dst,
+ tdbp->tdb_sproto);
tdbp->tdb_anext = tdbaddr[hashval];
tdbaddr[hashval] = tdbp;
- hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
+ hashval = tdb_hash(tdbp->tdb_rdomain, 0, &tdbp->tdb_src,
+ tdbp->tdb_sproto);
tdbp->tdb_snext = tdbsrc[hashval];
tdbsrc[hashval] = tdbp;
@@ -705,7 +722,8 @@ tdb_delete(struct tdb *tdbp)
if (tdbh == NULL)
return;
- hashval = tdb_hash(tdbp->tdb_spi, &tdbp->tdb_dst, tdbp->tdb_sproto);
+ hashval = tdb_hash(tdbp->tdb_rdomain, tdbp->tdb_spi,
+ &tdbp->tdb_dst, tdbp->tdb_sproto);
s = spltdb();
if (tdbh[hashval] == tdbp) {
@@ -722,7 +740,8 @@ tdb_delete(struct tdb *tdbp)
tdbp->tdb_hnext = NULL;
- hashval = tdb_hash(0, &tdbp->tdb_dst, tdbp->tdb_sproto);
+ hashval = tdb_hash(tdbp->tdb_rdomain, 0, &tdbp->tdb_dst,
+ tdbp->tdb_sproto);
if (tdbaddr[hashval] == tdbp) {
tdbaddr[hashval] = tdbp->tdb_anext;
@@ -736,7 +755,8 @@ tdb_delete(struct tdb *tdbp)
}
}
- hashval = tdb_hash(0, &tdbp->tdb_src, tdbp->tdb_sproto);
+ hashval = tdb_hash(tdbp->tdb_rdomain, 0, &tdbp->tdb_src,
+ tdbp->tdb_sproto);
if (tdbsrc[hashval] == tdbp) {
tdbsrc[hashval] = tdbp->tdb_snext;
@@ -762,7 +782,7 @@ tdb_delete(struct tdb *tdbp)
* Allocate a TDB and initialize a few basic fields.
*/
struct tdb *
-tdb_alloc(void)
+tdb_alloc(u_int rdomain)
{
struct tdb *tdbp;
@@ -777,6 +797,9 @@ tdb_alloc(void)
/* Record establishment time. */
tdbp->tdb_established = time_second;
+ /* Save routing domain */
+ tdbp->tdb_rdomain = rdomain;
+
/* Initialize timeouts. */
timeout_set(&tdbp->tdb_timer_tmo, tdb_timeout, tdbp);
timeout_set(&tdbp->tdb_first_tmo, tdb_firstuse, tdbp);
@@ -1041,7 +1064,7 @@ ipsp_skipcrypto_mark(struct tdb_ident *tdbi)
struct tdb *tdb;
int s = spltdb();
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst, tdbi->proto);
if (tdb != NULL) {
tdb->tdb_flags |= TDBF_SKIPCRYPTO;
tdb->tdb_last_marked = time_second;
@@ -1056,7 +1079,7 @@ ipsp_skipcrypto_unmark(struct tdb_ident *tdbi)
struct tdb *tdb;
int s = spltdb();
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst, tdbi->proto);
if (tdb != NULL) {
tdb->tdb_flags &= ~TDBF_SKIPCRYPTO;
tdb->tdb_last_marked = time_second;
@@ -1163,6 +1186,8 @@ ipsp_parse_headers(struct mbuf *m, int off, u_int8_t proto)
tdbi->dst.sin6.sin6_len =
sizeof(struct sockaddr_in6);
tdbi->dst.sin6.sin6_addr = ip6_dst;
+ tdbi->rdomain =
+ rtable_l2(m->m_pkthdr.rdomain);
SLIST_INSERT_HEAD(&tags,
mtag, m_tag_link);
}
@@ -1270,6 +1295,7 @@ ipsp_parse_headers(struct mbuf *m, int off, u_int8_t proto)
(caddr_t) &tdbi->spi);
tdbi->proto = proto; /* AH or ESP */
+ tdbi->rdomain = rtable_l2(m->m_pkthdr.rdomain);
#ifdef INET
/* Last network header was IPv4. */
diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h
index 3bfad3ee55c..d0cbe90d1ee 100644
--- a/sys/netinet/ip_ipsp.h
+++ b/sys/netinet/ip_ipsp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.h,v 1.143 2010/07/01 02:09:45 reyk Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.144 2010/07/09 16:58:06 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -201,6 +201,7 @@ struct ipsec_policy {
u_int8_t ipo_flags; /* See IPSP_POLICY_* definitions */
u_int8_t ipo_type; /* USE/ACQUIRE/... */
u_int8_t ipo_sproto; /* ESP/AH; if zero, use system dflts */
+ u_int ipo_rdomain;
int ipo_ref_count;
@@ -374,6 +375,8 @@ struct tdb { /* tunnel descriptor block */
u_int16_t tdb_tag; /* Packet filter tag */
u_int32_t tdb_tap; /* Alternate enc(4) interface */
+ u_int tdb_rdomain; /* Routing domain */
+
struct sockaddr_encap tdb_filter; /* What traffic is acceptable */
struct sockaddr_encap tdb_filtermask; /* And the mask */
@@ -387,6 +390,7 @@ struct tdb_ident {
u_int32_t spi;
union sockaddr_union dst;
u_int8_t proto;
+ u_int rdomain;
};
struct tdb_crypto {
@@ -396,6 +400,7 @@ struct tdb_crypto {
int tc_protoff;
int tc_skip;
caddr_t tc_ptr;
+ u_int tc_rdomain;
};
struct ipsecinit {
@@ -511,23 +516,23 @@ extern char *ipsp_address(union sockaddr_union);
/* TDB management routines */
extern void tdb_add_inp(struct tdb *, struct inpcb *, int);
-extern u_int32_t reserve_spi(u_int32_t, u_int32_t, union sockaddr_union *,
- union sockaddr_union *, u_int8_t, int *);
-extern struct tdb *gettdb(u_int32_t, union sockaddr_union *, u_int8_t);
-extern struct tdb *gettdbbyaddr(union sockaddr_union *, u_int8_t,
+extern u_int32_t reserve_spi(u_int, u_int32_t, u_int32_t,
+ union sockaddr_union *, union sockaddr_union *, u_int8_t, int *);
+extern struct tdb *gettdb(u_int, u_int32_t, union sockaddr_union *, u_int8_t);
+extern struct tdb *gettdbbyaddr(u_int, union sockaddr_union *, u_int8_t,
struct ipsec_ref *, struct ipsec_ref *, struct ipsec_ref *,
struct mbuf *, int, struct sockaddr_encap *, struct sockaddr_encap *);
-extern struct tdb *gettdbbysrc(union sockaddr_union *, u_int8_t,
+extern struct tdb *gettdbbysrc(u_int, union sockaddr_union *, u_int8_t,
struct ipsec_ref *, struct ipsec_ref *, struct mbuf *, int,
struct sockaddr_encap *, struct sockaddr_encap *);
-extern struct tdb *gettdbbysrcdst(u_int32_t, union sockaddr_union *,
+extern struct tdb *gettdbbysrcdst(u_int, u_int32_t, union sockaddr_union *,
union sockaddr_union *, u_int8_t);
extern void puttdb(struct tdb *);
extern void tdb_delete(struct tdb *);
-extern struct tdb *tdb_alloc(void);
+extern struct tdb *tdb_alloc(u_int);
extern void tdb_free(struct tdb *);
extern int tdb_init(struct tdb *, u_int16_t, struct ipsecinit *);
-extern int tdb_walk(int (*)(struct tdb *, void *, int), void *);
+extern int tdb_walk(u_int, int (*)(struct tdb *, void *, int), void *);
/* XF_IP4 */
extern int ipe4_attach(void);
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 8dca59f9b4d..63a1cb2a020 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.209 2010/07/03 04:44:51 guenther Exp $ */
+/* $OpenBSD: ip_output.c,v 1.210 2010/07/09 16:58:06 reyk Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -272,7 +272,8 @@ reroute:
mtag->m_tag_len, sizeof (struct tdb_ident));
#endif
tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain,
+ tdbi->spi, &tdbi->dst, tdbi->proto);
if (tdb == NULL)
error = -EINVAL;
m_tag_delete(m, mtag);
@@ -315,6 +316,7 @@ reroute:
tdbi = (struct tdb_ident *)(mtag + 1);
if (tdbi->spi == tdb->tdb_spi &&
tdbi->proto == tdb->tdb_sproto &&
+ tdbi->rdomain == tdb->tdb_rdomain &&
!bcmp(&tdbi->dst, &tdb->tdb_dst,
sizeof(union sockaddr_union))) {
splx(s);
@@ -586,7 +588,8 @@ sendit:
if (sproto != 0) {
s = splnet();
- tdb = gettdb(sspi, &sdst, sproto);
+ tdb = gettdb(rtable_l2(m->m_pkthdr.rdomain),
+ sspi, &sdst, sproto);
if (tdb == NULL) {
DPRINTF(("ip_output: unknown TDB"));
error = EHOSTUNREACH;
@@ -599,7 +602,8 @@ sendit:
* Packet filter
*/
#if NPF > 0
- if ((encif = enc_getif(0, tdb->tdb_tap)) == NULL ||
+ if ((encif = enc_getif(tdb->tdb_rdomain,
+ tdb->tdb_tap)) == NULL ||
pf_test(PF_OUT, encif, &m, NULL) != PF_PASS) {
error = EHOSTUNREACH;
splx(s);
diff --git a/sys/netinet/ip_spd.c b/sys/netinet/ip_spd.c
index e3fd6117317..6d4a8572454 100644
--- a/sys/netinet/ip_spd.c
+++ b/sys/netinet/ip_spd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_spd.c,v 1.61 2010/07/02 03:58:48 david Exp $ */
+/* $OpenBSD: ip_spd.c,v 1.62 2010/07/09 16:58:06 reyk Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
@@ -86,6 +86,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
struct sockaddr_encap *ddst;
struct ipsec_policy *ipo;
int signore = 0, dignore = 0;
+ u_int rdomain = rtable_l2(m->m_pkthdr.rdomain);
/*
* If there are no flows in place, there's no point
@@ -231,6 +232,9 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
return NULL;
}
+ /* Set the rdomain that was obtained from the mbuf */
+ re->re_tableid = rdomain;
+
/* Actual SPD lookup. */
rtalloc((struct route *) re);
if (re->re_rt == NULL) {
@@ -391,7 +395,8 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
/* Find an appropriate SA from the existing ones. */
ipo->ipo_tdb =
- gettdbbyaddr(dignore ? &sdst : &ipo->ipo_dst,
+ gettdbbyaddr(rdomain,
+ dignore ? &sdst : &ipo->ipo_dst,
ipo->ipo_sproto, ipo->ipo_srcid,
ipo->ipo_dstid, ipo->ipo_local_cred, m, af,
&ipo->ipo_addr, &ipo->ipo_mask);
@@ -504,7 +509,8 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
ipo->ipo_last_searched = time_second;
ipo->ipo_tdb =
- gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst,
+ gettdbbysrc(rdomain,
+ dignore ? &ssrc : &ipo->ipo_dst,
ipo->ipo_sproto, ipo->ipo_srcid,
ipo->ipo_dstid, m, af, &ipo->ipo_addr,
&ipo->ipo_mask);
@@ -579,7 +585,8 @@ ipsec_delete_policy(struct ipsec_policy *ipo)
info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&ipo->ipo_mask;
/* XXX other tables? */
- err = rtrequest1(RTM_DELETE, &info, RTP_DEFAULT, NULL, 0);
+ err = rtrequest1(RTM_DELETE, &info, RTP_DEFAULT, NULL,
+ ipo->ipo_rdomain);
}
if (ipo->ipo_tdb != NULL)
TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
@@ -635,6 +642,7 @@ ipsec_add_policy(struct inpcb *inp, int af, int direction)
* policies (for tunnel/transport and ESP/AH), as needed.
*/
ipon->ipo_sproto = IPPROTO_ESP;
+ ipon->ipo_rdomain = rtable_l2(inp->inp_rtableid);
TAILQ_INIT(&ipon->ipo_acquires);
TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list);
@@ -1001,7 +1009,8 @@ ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
inp->inp_ipo->ipo_last_searched = time_second;
/* Do we have an SA already established ? */
- if (gettdbbysrc(&inp->inp_ipo->ipo_dst,
+ if (gettdbbysrc(rtable_l2(inp->inp_rtableid),
+ &inp->inp_ipo->ipo_dst,
inp->inp_ipo->ipo_sproto,
inp->inp_ipo->ipo_srcid,
inp->inp_ipo->ipo_dstid, m, af,
@@ -1057,7 +1066,8 @@ ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
ipsec_update_policy(inp, inp->inp_ipo, af,
IPSP_DIRECTION_OUT);
- tdb = gettdbbyaddr(&inp->inp_ipo->ipo_dst,
+ tdb = gettdbbyaddr(rtable_l2(inp->inp_rtableid),
+ &inp->inp_ipo->ipo_dst,
inp->inp_ipo->ipo_sproto,
inp->inp_ipo->ipo_srcid,
inp->inp_ipo->ipo_dstid,
@@ -1073,7 +1083,8 @@ ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
ipsec_update_policy(inp, &sipon, af,
IPSP_DIRECTION_OUT);
- tdb = gettdbbyaddr(&sipon.ipo_dst, IPPROTO_ESP, NULL,
+ tdb = gettdbbyaddr(rtable_l2(inp->inp_rtableid),
+ &sipon.ipo_dst, IPPROTO_ESP, NULL,
NULL, NULL, m, af, &sipon.ipo_addr,
&sipon.ipo_mask);
}
@@ -1143,6 +1154,7 @@ ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
tdbi = (struct tdb_ident *)(mtag + 1);
tdbi->spi = ipo->ipo_tdb->tdb_spi;
tdbi->proto = ipo->ipo_tdb->tdb_sproto;
+ tdbi->rdomain = rtable_l2(inp->inp_rtableid);
bcopy(&ipo->ipo_tdb->tdb_dst, &tdbi->dst,
ipo->ipo_tdb->tdb_dst.sa.sa_len);
m_tag_prepend(m, mtag);
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c
index f646902ad05..f9e1b1ee14d 100644
--- a/sys/netinet/ipsec_input.c
+++ b/sys/netinet/ipsec_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_input.c,v 1.97 2010/07/01 02:09:45 reyk Exp $ */
+/* $OpenBSD: ipsec_input.c,v 1.98 2010/07/09 16:58:06 reyk Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -81,7 +81,7 @@
#include "bpfilter.h"
-void *ipsec_common_ctlinput(int, struct sockaddr *, void *, int);
+void *ipsec_common_ctlinput(u_int, int, struct sockaddr *, void *, int);
#ifdef ENCDEBUG
#define DPRINTF(x) if (encdebug) printf x
@@ -201,7 +201,8 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto,
}
s = spltdb();
- tdbp = gettdb(spi, &dst_address, sproto);
+ tdbp = gettdb(rtable_l2(m->m_pkthdr.rdomain),
+ spi, &dst_address, sproto);
if (tdbp == NULL) {
splx(s);
DPRINTF(("ipsec_common_input(): could not find SA for "
@@ -240,7 +241,8 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto,
}
if (sproto != IPPROTO_IPCOMP) {
- if ((encif = enc_getif(0, tdbp->tdb_tap)) == NULL) {
+ if ((encif = enc_getif(tdbp->tdb_rdomain,
+ tdbp->tdb_tap)) == NULL) {
splx(s);
DPRINTF(("ipsec_common_input(): "
"no enc%u interface for SA %s/%08x/%u\n",
@@ -554,6 +556,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
sizeof(union sockaddr_union));
tdbi->proto = tdbp->tdb_sproto;
tdbi->spi = tdbp->tdb_spi;
+ tdbi->rdomain = tdbp->tdb_rdomain;
m_tag_prepend(m, mtag);
}
@@ -580,7 +583,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff,
m->m_flags |= M_TUNNEL;
#if NBPFILTER > 0
- if ((encif = enc_getif(0, tdbp->tdb_tap)) != NULL) {
+ if ((encif = enc_getif(tdbp->tdb_rdomain, tdbp->tdb_tap)) != NULL) {
encif->if_ipackets++;
encif->if_ibytes += m->m_pkthdr.len;
@@ -772,7 +775,7 @@ ah4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
sa->sa_len != sizeof(struct sockaddr_in))
return (NULL);
- return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_AH));
+ return (ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_AH));
}
/* IPv4 ESP wrapper. */
@@ -861,7 +864,8 @@ ipcomp4_input_cb(struct mbuf *m, ...)
}
void *
-ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
+ipsec_common_ctlinput(u_int rdomain, int cmd, struct sockaddr *sa,
+ void *v, int proto)
{
extern u_int ip_mtudisc_timeout;
struct ip *ip = v;
@@ -895,7 +899,8 @@ ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
bcopy((caddr_t)ip + hlen, &spi, sizeof(u_int32_t));
s = spltdb();
- tdbp = gettdb(spi, (union sockaddr_union *)&dst, proto);
+ tdbp = gettdb(rdomain, spi, (union sockaddr_union *)&dst,
+ proto);
if (tdbp == NULL || tdbp->tdb_flags & TDBF_INVALID) {
splx(s);
return (NULL);
@@ -961,7 +966,7 @@ udpencap_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
su_src = (union sockaddr_union *)&src;
s = spltdb();
- tdbp = gettdbbysrcdst(0, su_src, su_dst, IPPROTO_ESP);
+ tdbp = gettdbbysrcdst(rdomain, 0, su_src, su_dst, IPPROTO_ESP);
for (; tdbp != NULL; tdbp = tdbp->tdb_snext) {
if (tdbp->tdb_sproto == IPPROTO_ESP &&
@@ -993,7 +998,7 @@ esp4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
sa->sa_len != sizeof(struct sockaddr_in))
return (NULL);
- return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_ESP));
+ return (ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_ESP));
}
#endif /* INET */
diff --git a/sys/netinet/ipsec_output.c b/sys/netinet/ipsec_output.c
index 232f3e4d438..13601532e09 100644
--- a/sys/netinet/ipsec_output.c
+++ b/sys/netinet/ipsec_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_output.c,v 1.42 2010/01/10 12:43:07 markus Exp $ */
+/* $OpenBSD: ipsec_output.c,v 1.43 2010/07/09 16:58:06 reyk Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
@@ -490,6 +490,7 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb)
bcopy(&tdb->tdb_dst, &tdbi->dst, sizeof(union sockaddr_union));
tdbi->proto = tdb->tdb_sproto;
tdbi->spi = tdb->tdb_spi;
+ tdbi->rdomain = tdb->tdb_rdomain;
m_tag_prepend(m, mtag);
@@ -605,7 +606,8 @@ ipsec_adjust_mtu(struct mbuf *m, u_int32_t mtu)
for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL); mtag;
mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, mtag)) {
tdbi = (struct tdb_ident *)(mtag + 1);
- tdbp = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdbp = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst,
+ tdbi->proto);
if (tdbp == NULL)
break;
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index a9716a68433..3516af7deb8 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.233 2010/07/03 04:44:51 guenther Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.234 2010/07/09 16:58:06 reyk Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -893,7 +893,8 @@ after_listen:
s = splnet();
if (mtag != NULL) {
tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi,
+ &tdbi->dst, tdbi->proto);
} else
tdb = NULL;
ipsp_spd_lookup(m, af, iphlen, &error, IPSP_DIRECTION_IN,
@@ -962,7 +963,8 @@ after_listen:
#else
if (optp)
#endif
- if (tcp_dooptions(tp, optp, optlen, th, m, iphlen, &opti))
+ if (tcp_dooptions(tp, optp, optlen, th, m, iphlen, &opti,
+ m->m_pkthdr.rdomain))
goto drop;
if (opti.ts_present && opti.ts_ecr) {
@@ -2256,7 +2258,8 @@ drop:
int
tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcphdr *th,
- struct mbuf *m, int iphlen, struct tcp_opt_info *oi)
+ struct mbuf *m, int iphlen, struct tcp_opt_info *oi,
+ u_int rtableid)
{
u_int16_t mss = 0;
int opt, optlen;
@@ -2388,7 +2391,8 @@ tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt, struct tcphdr *th,
#endif /* INET6 */
}
- tdb = gettdbbysrcdst(0, &src, &dst, IPPROTO_TCP);
+ tdb = gettdbbysrcdst(rtable_l2(rtableid),
+ 0, &src, &dst, IPPROTO_TCP);
/*
* We don't have an SA for this peer, so we turn off
@@ -3982,7 +3986,8 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
tb.t_flags |= TF_SIGNATURE;
#endif
tb.t_state = TCPS_LISTEN;
- if (tcp_dooptions(&tb, optp, optlen, th, m, iphlen, oi))
+ if (tcp_dooptions(&tb, optp, optlen, th, m, iphlen, oi,
+ sotoinpcb(so)->inp_rtableid))
return (0);
} else
tb.t_flags = 0;
@@ -4267,7 +4272,8 @@ syn_cache_respond(struct syn_cache *sc, struct mbuf *m)
#endif /* INET6 */
}
- tdb = gettdbbysrcdst(0, &src, &dst, IPPROTO_TCP);
+ tdb = gettdbbysrcdst(rtable_l2(sc->sc_rtableid),
+ 0, &src, &dst, IPPROTO_TCP);
if (tdb == NULL) {
if (m)
m_freem(m);
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index cb9964e9e32..58de7ef9557 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_output.c,v 1.89 2010/07/03 04:44:51 guenther Exp $ */
+/* $OpenBSD: tcp_output.c,v 1.90 2010/07/09 16:58:06 reyk Exp $ */
/* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */
/*
@@ -924,7 +924,8 @@ send:
/* XXX gettdbbysrcdst() should really be called at spltdb(). */
/* XXX this is splsoftnet(), currently they are the same. */
- tdb = gettdbbysrcdst(0, &src, &dst, IPPROTO_TCP);
+ tdb = gettdbbysrcdst(rtable_l2(tp->t_inpcb->inp_rtableid),
+ 0, &src, &dst, IPPROTO_TCP);
if (tdb == NULL)
return (EPERM);
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 57cd44fd8ef..1558747c0fd 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.94 2010/07/03 04:44:51 guenther Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.95 2010/07/09 16:58:06 reyk Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -565,7 +565,7 @@ struct tcpcb *
struct tcpcb *
tcp_drop(struct tcpcb *, int);
int tcp_dooptions(struct tcpcb *, u_char *, int, struct tcphdr *,
- struct mbuf *, int, struct tcp_opt_info *);
+ struct mbuf *, int, struct tcp_opt_info *, u_int);
void tcp_init(void);
#if defined(INET6) && !defined(TCP6)
int tcp6_input(struct mbuf **, int *, int);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 55bfe45b7ab..707ec2d32b0 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.135 2010/07/03 04:44:51 guenther Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.136 2010/07/09 16:58:06 reyk Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -616,7 +616,8 @@ udp_input(struct mbuf *m, ...)
s = splnet();
if (mtag != NULL) {
tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi,
+ &tdbi->dst, tdbi->proto);
} else
tdb = NULL;
ipsp_spd_lookup(m, srcsa.sa.sa_family, iphlen, &error,
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index d08183d9e08..7904a23581c 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_forward.c,v 1.48 2010/07/01 02:09:45 reyk Exp $ */
+/* $OpenBSD: ip6_forward.c,v 1.49 2010/07/09 16:58:06 reyk Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/*
@@ -164,7 +164,8 @@ reroute:
mtag->m_tag_len, sizeof (struct tdb_ident));
#endif
tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst,
+ tdbi->proto);
if (tdb == NULL)
error = -EINVAL;
m_tag_delete(m, mtag);
@@ -205,6 +206,7 @@ reroute:
tdbi = (struct tdb_ident *)(mtag + 1);
if (tdbi->spi == tdb->tdb_spi &&
tdbi->proto == tdb->tdb_sproto &&
+ tdbi->rdomain == tdb->tdb_rdomain &&
!bcmp(&tdbi->dst, &tdb->tdb_dst,
sizeof(union sockaddr_union))) {
splx(s);
@@ -337,7 +339,8 @@ reroute:
if (sproto != 0) {
s = splnet();
- tdb = gettdb(sspi, &sdst, sproto);
+ tdb = gettdb(rtable_l2(m->m_pkthdr.rdomain),
+ sspi, &sdst, sproto);
if (tdb == NULL) {
splx(s);
error = EHOSTUNREACH;
@@ -346,7 +349,8 @@ reroute:
}
#if NPF > 0
- if ((encif = enc_getif(0, tdb->tdb_tap)) == NULL ||
+ if ((encif = enc_getif(tdb->tdb_rdomain,
+ tdb->tdb_tap)) == NULL ||
pf_test6(PF_OUT, encif, &m, NULL) != PF_PASS) {
splx(s);
error = EHOSTUNREACH;
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 4e993ffc8d0..216bc10ec4c 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_output.c,v 1.115 2010/07/08 19:42:46 jsg Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.116 2010/07/09 16:58:06 reyk Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -242,7 +242,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, struct route_in6 *ro,
mtag->m_tag_len, sizeof (struct tdb_ident));
#endif
tdbi = (struct tdb_ident *)(mtag + 1);
- tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
+ tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst, tdbi->proto);
if (tdb == NULL)
error = -EINVAL;
m_tag_delete(m, mtag);
@@ -283,6 +283,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, struct route_in6 *ro,
tdbi = (struct tdb_ident *)(mtag + 1);
if (tdbi->spi == tdb->tdb_spi &&
tdbi->proto == tdb->tdb_sproto &&
+ tdbi->rdomain == tdb->tdb_rdomain &&
!bcmp(&tdbi->dst, &tdb->tdb_dst,
sizeof(union sockaddr_union))) {
splx(s);
@@ -509,7 +510,8 @@ reroute:
* packet gets tunneled?
*/
- tdb = gettdb(sspi, &sdst, sproto);
+ tdb = gettdb(rtable_l2(m->m_pkthdr.rdomain),
+ sspi, &sdst, sproto);
if (tdb == NULL) {
splx(s);
error = EHOSTUNREACH;
@@ -518,7 +520,8 @@ reroute:
}
#if NPF > 0
- if ((encif = enc_getif(0, tdb->tdb_tap)) == NULL ||
+ if ((encif = enc_getif(tdb->tdb_rdomain,
+ tdb->tdb_tap)) == NULL ||
pf_test6(PF_OUT, encif, &m, NULL) != PF_PASS) {
splx(s);
error = EHOSTUNREACH;
@@ -1636,8 +1639,8 @@ do { \
}
tdbip = mtod(m, struct tdb_ident *);
s = spltdb();
- tdb = gettdb(tdbip->spi, &tdbip->dst,
- tdbip->proto);
+ tdb = gettdb(tdbip->rdomain, tdbip->spi,
+ &tdbip->dst, tdbip->proto);
if (tdb == NULL)
error = ESRCH;
else
@@ -1908,6 +1911,8 @@ do { \
tdbi.spi = inp->inp_tdb_out->tdb_spi;
tdbi.dst = inp->inp_tdb_out->tdb_dst;
tdbi.proto = inp->inp_tdb_out->tdb_sproto;
+ tdbi.rdomain =
+ inp->inp_tdb_out->tdb_rdomain;
*mp = m = m_get(M_WAIT, MT_SOOPTS);
m->m_len = sizeof(tdbi);
bcopy((caddr_t)&tdbi, mtod(m, caddr_t),