On Fri, Jul 02, 2010 at 10:49:52PM +0200, Reyk Floeter wrote:
> I need people to test the following IPsec diff on existing setups
> running -current.  This diff will add some cool features for the next
> release but I first need regression testing with plain old setups
> (ipsec.conf with static keying or isakmpd); preferrably on IPsecs that
> are running closely to production.  This diff depends on -current and
> my latest changes on enc(4) from earlier this week.
> 

here is an updated diff that will apply to -current.

Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.181
diff -u -p -r1.181 if_bridge.c
--- net/if_bridge.c     2 Jul 2010 02:40:16 -0000       1.181
+++ net/if_bridge.c     3 Jul 2010 17:22:52 -0000
@@ -152,7 +152,8 @@ u_int8_t bridge_filterrule(struct brl_he
 struct mbuf *bridge_filter(struct bridge_softc *, int, struct ifnet *,
     struct ether_header *, struct mbuf *m);
 #endif
-int    bridge_ifenqueue(struct bridge_softc *, struct ifnet *, struct mbuf *);
+int    bridge_ifenqueue(struct bridge_softc *, struct ifnet *, struct mbuf *,
+    struct ether_header *);
 void   bridge_fragment(struct bridge_softc *, struct ifnet *,
     struct ether_header *, struct mbuf *);
 #ifdef INET
@@ -1143,7 +1144,7 @@ bridge_output(struct ifnet *ifp, struct 
                                mc = m1;
                        }
 
-                       error = bridge_ifenqueue(sc, dst_if, mc);
+                       error = bridge_ifenqueue(sc, dst_if, mc, eh);
                        if (error)
                                continue;
                }
@@ -1160,7 +1161,7 @@ sendunicast:
                splx(s);
                return (ENETDOWN);
        }
-       bridge_ifenqueue(sc, dst_if, m);
+       bridge_ifenqueue(sc, dst_if, m, eh);
        splx(s);
        return (0);
 }
@@ -1372,7 +1373,7 @@ bridgeintr_frame(struct bridge_softc *sc
                bridge_fragment(sc, dst_if, &eh, m);
        else {
                s = splnet();
-               bridge_ifenqueue(sc, dst_if, m);
+               bridge_ifenqueue(sc, dst_if, m, &eh);
                splx(s);
        }
 }
@@ -1665,7 +1666,7 @@ bridge_broadcast(struct bridge_softc *sc
                if ((len - ETHER_HDR_LEN) > dst_if->if_mtu)
                        bridge_fragment(sc, dst_if, eh, mc);
                else {
-                       bridge_ifenqueue(sc, dst_if, mc);
+                       bridge_ifenqueue(sc, dst_if, mc, eh);
                }
        }
 
@@ -1757,7 +1758,7 @@ bridge_span(struct bridge_softc *sc, str
                        continue;
                }
 
-               error = bridge_ifenqueue(sc, ifp, mc);
+               error = bridge_ifenqueue(sc, ifp, mc, eh);
                if (error)
                        continue;
        }
@@ -2402,7 +2403,7 @@ bridge_ipsec(struct bridge_softc *sc, st
 
                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 +2458,7 @@ bridge_ipsec(struct bridge_softc *sc, st
                        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 +2469,7 @@ bridge_ipsec(struct bridge_softc *sc, st
 #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) {
@@ -2720,7 +2721,7 @@ bridge_fragment(struct bridge_softc *sc,
                if ((ifp->if_capabilities & IFCAP_VLAN_MTU) &&
                    (len - sizeof(struct ether_vlan_header) <= ifp->if_mtu)) {
                        s = splnet();
-                       bridge_ifenqueue(sc, ifp, m);
+                       bridge_ifenqueue(sc, ifp, m, eh);
                        splx(s);
                        return;
                }
@@ -2790,7 +2791,7 @@ bridge_fragment(struct bridge_softc *sc,
                        }
                        bcopy(eh, mtod(m, caddr_t), sizeof(*eh));
                        s = splnet();
-                       error = bridge_ifenqueue(sc, ifp, m);
+                       error = bridge_ifenqueue(sc, ifp, m, eh);
                        if (error) {
                                splx(s);
                                continue;
@@ -2811,7 +2812,8 @@ bridge_fragment(struct bridge_softc *sc,
 }
 
 int
-bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m)
+bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m,
+    struct ether_header *eh)
 {
        int error, len;
        short mflags;
Index: net/if_pfsync.c
===================================================================
RCS file: /cvs/src/sys/net/if_pfsync.c,v
retrieving revision 1.147
diff -u -p -r1.147 if_pfsync.c
--- net/if_pfsync.c     24 May 2010 02:11:04 -0000      1.147
+++ net/if_pfsync.c     3 Jul 2010 17:22:52 -0000
@@ -1239,7 +1239,7 @@ pfsync_update_net_tdb(struct pfsync_tdb 
                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
Index: net/if_pfsync.h
===================================================================
RCS file: /cvs/src/sys/net/if_pfsync.h,v
retrieving revision 1.42
diff -u -p -r1.42 if_pfsync.h
--- net/if_pfsync.h     12 Jan 2010 23:38:02 -0000      1.42
+++ net/if_pfsync.h     3 Jul 2010 17:22:52 -0000
@@ -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;
 
 /*
Index: net/pfkeyv2.c
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2.c,v
retrieving revision 1.120
diff -u -p -r1.120 pfkeyv2.c
--- net/pfkeyv2.c       1 Jul 2010 02:09:45 -0000       1.120
+++ net/pfkeyv2.c       3 Jul 2010 17:22:52 -0000
@@ -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 
                 */
                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 
                 * 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 
                /* 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 
 
        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
 
                /* 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
        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
                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
                        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
 
                /* 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
                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
                        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
 
                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
                }
 
                /* 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
                        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
 
                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
                        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
 #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
                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
 
                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
                    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
 
                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
                            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
                            (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
 
                        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
 
        /* 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
        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,
 {
        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,
        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,
 
        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;
Index: net/pfkeyv2.h
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2.h,v
retrieving revision 1.57
diff -u -p -r1.57 pfkeyv2.h
--- net/pfkeyv2.h       1 Jul 2010 02:09:45 -0000       1.57
+++ net/pfkeyv2.h       3 Jul 2010 17:22:52 -0000
@@ -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 **, v
 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 *);
 
Index: net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.123
diff -u -p -r1.123 route.c
--- net/route.c 2 Jul 2010 00:20:49 -0000       1.123
+++ net/route.c 3 Jul 2010 17:22:52 -0000
@@ -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_label
 
 #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 sockad
         * enc0.
         */
        if (dst && (dst->sa_family == PF_KEY))
-               return (encap_findgwifa(gateway));
+               return (encap_findgwifa(gateway, rtableid));
 #endif
 
        if ((flags & RTF_GATEWAY) == 0) {
Index: netinet/ip_ah.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ah.c,v
retrieving revision 1.96
diff -u -p -r1.96 ip_ah.c
--- netinet/ip_ah.c     2 Jul 2010 02:40:16 -0000       1.96
+++ netinet/ip_ah.c     3 Jul 2010 17:22:52 -0000
@@ -662,6 +662,7 @@ ah_input(struct mbuf *m, struct tdb *tdb
                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
        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 *td
 #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 *td
        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++;
Index: netinet/ip_esp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_esp.c,v
retrieving revision 1.109
diff -u -p -r1.109 ip_esp.c
--- netinet/ip_esp.c    2 Jul 2010 02:40:16 -0000       1.109
+++ netinet/ip_esp.c    3 Jul 2010 17:22:52 -0000
@@ -386,7 +386,8 @@ esp_input(struct mbuf *m, struct tdb *td
 
                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 *td
        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 *t
 #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 *t
 
        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++;
Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.181
diff -u -p -r1.181 ip_input.c
--- netinet/ip_input.c  7 Jun 2010 13:26:35 -0000       1.181
+++ netinet/ip_input.c  3 Jul 2010 17:22:52 -0000
@@ -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,
Index: netinet/ip_ipcomp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipcomp.c,v
retrieving revision 1.26
diff -u -p -r1.26 ip_ipcomp.c
--- netinet/ip_ipcomp.c 2 Jul 2010 02:40:16 -0000       1.26
+++ netinet/ip_ipcomp.c 3 Jul 2010 17:22:52 -0000
@@ -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++;
Index: netinet/ip_ipsp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipsp.c,v
retrieving revision 1.180
diff -u -p -r1.180 ip_ipsp.c
--- netinet/ip_ipsp.c   20 Apr 2010 22:05:43 -0000      1.180
+++ netinet/ip_ipsp.c   3 Jul 2010 17:22:52 -0000
@@ -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_u
        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_u
  * 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 ts
 
                /* 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 ts
  * 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_uni
        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_uni
  * 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 sock
        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 sock
 
        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, 
        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, 
  * 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
        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 *, voi
        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 *t
        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 
        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 o
                                        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 o
                                    (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. */
Index: netinet/ip_ipsp.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipsp.h,v
retrieving revision 1.143
diff -u -p -r1.143 ip_ipsp.h
--- netinet/ip_ipsp.h   1 Jul 2010 02:09:45 -0000       1.143
+++ netinet/ip_ipsp.h   3 Jul 2010 17:22:52 -0000
@@ -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 blo
        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
 
 /* 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);
Index: netinet/ip_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.209
diff -u -p -r1.209 ip_output.c
--- netinet/ip_output.c 3 Jul 2010 04:44:51 -0000       1.209
+++ netinet/ip_output.c 3 Jul 2010 17:22:52 -0000
@@ -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);
Index: netinet/ip_spd.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_spd.c,v
retrieving revision 1.61
diff -u -p -r1.61 ip_spd.c
--- netinet/ip_spd.c    2 Jul 2010 03:58:48 -0000       1.61
+++ netinet/ip_spd.c    3 Jul 2010 17:22:52 -0000
@@ -86,6 +86,7 @@ ipsp_spd_lookup(struct mbuf *m, int af, 
        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, 
                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, 
 
                        /* 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, 
                                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 
                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 
         * 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
                                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
                                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
                        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
        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);
Index: netinet/ipsec_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ipsec_input.c,v
retrieving revision 1.97
diff -u -p -r1.97 ipsec_input.c
--- netinet/ipsec_input.c       1 Jul 2010 02:09:45 -0000       1.97
+++ netinet/ipsec_input.c       3 Jul 2010 17:22:53 -0000
@@ -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 s
        }
 
        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 s
        }
 
        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, st
                    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, st
                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 *s
            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 so
                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 sockad
        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->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 */
 
Index: netinet/ipsec_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ipsec_output.c,v
retrieving revision 1.42
diff -u -p -r1.42 ipsec_output.c
--- netinet/ipsec_output.c      10 Jan 2010 12:43:07 -0000      1.42
+++ netinet/ipsec_output.c      3 Jul 2010 17:22:53 -0000
@@ -490,6 +490,7 @@ ipsp_process_done(struct mbuf *m, struct
        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
        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;
 
Index: netinet/tcp_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.233
diff -u -p -r1.233 tcp_input.c
--- netinet/tcp_input.c 3 Jul 2010 04:44:51 -0000       1.233
+++ netinet/tcp_input.c 3 Jul 2010 17:22:53 -0000
@@ -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 *
 #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, stru
                        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, 
 #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);
Index: netinet/tcp_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.89
diff -u -p -r1.89 tcp_output.c
--- netinet/tcp_output.c        3 Jul 2010 04:44:51 -0000       1.89
+++ netinet/tcp_output.c        3 Jul 2010 17:22:53 -0000
@@ -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);
 
Index: netinet/tcp_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.94
diff -u -p -r1.94 tcp_var.h
--- netinet/tcp_var.h   3 Jul 2010 04:44:51 -0000       1.94
+++ netinet/tcp_var.h   3 Jul 2010 17:22:53 -0000
@@ -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);
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.135
diff -u -p -r1.135 udp_usrreq.c
--- netinet/udp_usrreq.c        3 Jul 2010 04:44:51 -0000       1.135
+++ netinet/udp_usrreq.c        3 Jul 2010 17:22:53 -0000
@@ -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,
Index: netinet6/ip6_forward.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_forward.c,v
retrieving revision 1.48
diff -u -p -r1.48 ip6_forward.c
--- netinet6/ip6_forward.c      1 Jul 2010 02:09:45 -0000       1.48
+++ netinet6/ip6_forward.c      3 Jul 2010 17:22:53 -0000
@@ -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;
Index: netinet6/ip6_output.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.114
diff -u -p -r1.114 ip6_output.c
--- netinet6/ip6_output.c       1 Jul 2010 02:09:45 -0000       1.114
+++ netinet6/ip6_output.c       3 Jul 2010 17:22:53 -0000
@@ -242,7 +242,7 @@ ip6_output(struct mbuf *m0, struct ip6_p
                            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_p
                        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),

Reply via email to