diff options
-rw-r--r-- | sys/net/if_bridge.c | 8 | ||||
-rw-r--r-- | sys/net/if_pfsync.c | 5 | ||||
-rw-r--r-- | sys/net/if_pfsync.h | 4 | ||||
-rw-r--r-- | sys/net/pfkeyv2.c | 100 | ||||
-rw-r--r-- | sys/net/pfkeyv2.h | 7 | ||||
-rw-r--r-- | sys/net/route.c | 10 | ||||
-rw-r--r-- | sys/netinet/ip_ah.c | 11 | ||||
-rw-r--r-- | sys/netinet/ip_esp.c | 13 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 8 | ||||
-rw-r--r-- | sys/netinet/ip_ipcomp.c | 8 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.c | 90 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 23 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 12 | ||||
-rw-r--r-- | sys/netinet/ip_spd.c | 26 | ||||
-rw-r--r-- | sys/netinet/ipsec_input.c | 25 | ||||
-rw-r--r-- | sys/netinet/ipsec_output.c | 6 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 20 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 5 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 4 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 5 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 12 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 17 |
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), |