diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if.c | 11 | ||||
-rw-r--r-- | sys/net/if_atmsubr.c | 10 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 13 | ||||
-rw-r--r-- | sys/net/if_fddisubr.c | 10 | ||||
-rw-r--r-- | sys/net/if_pfsync.c | 89 | ||||
-rw-r--r-- | sys/net/if_pfsync.h | 34 | ||||
-rw-r--r-- | sys/net/if_ppp.c | 10 | ||||
-rw-r--r-- | sys/net/if_sl.c | 11 | ||||
-rw-r--r-- | sys/net/if_spppsubr.c | 11 | ||||
-rw-r--r-- | sys/net/pf.c | 149 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 9 | ||||
-rw-r--r-- | sys/net/pf_lb.c | 11 | ||||
-rw-r--r-- | sys/net/pfvar.h | 20 | ||||
-rw-r--r-- | sys/net/route.c | 57 | ||||
-rw-r--r-- | sys/net/route.h | 4 | ||||
-rw-r--r-- | sys/net/rtsock.c | 15 | ||||
-rw-r--r-- | sys/netinet/if_ether.c | 6 | ||||
-rw-r--r-- | sys/netinet/in.c | 3 | ||||
-rw-r--r-- | sys/netinet/in_pcb.c | 12 | ||||
-rw-r--r-- | sys/netinet/in_var.h | 4 | ||||
-rw-r--r-- | sys/netinet/ip_icmp.c | 7 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 12 | ||||
-rw-r--r-- | sys/netinet/ip_ipip.c | 6 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 5 | ||||
-rw-r--r-- | sys/netinet/raw_ip.c | 4 | ||||
-rw-r--r-- | sys/netinet/tcp_input.c | 12 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 5 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 4 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 3 |
31 files changed, 343 insertions, 212 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 5adb852e14c..5c989cc8ab0 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.199 2009/08/12 15:58:20 henning Exp $ */ +/* $OpenBSD: if.c,v 1.200 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -887,6 +887,8 @@ ifa_ifwithaddr(struct sockaddr *addr, u_int rdomain) #define equal(a1, a2) \ (bcmp((caddr_t)(a1), (caddr_t)(a2), \ ((struct sockaddr *)(a1))->sa_len) == 0) + + rdomain = rtable_l2(rdomain); TAILQ_FOREACH(ifp, &ifnet, if_list) { if (ifp->if_rdomain != rdomain) continue; @@ -914,6 +916,7 @@ ifa_ifwithdstaddr(struct sockaddr *addr, u_int rdomain) struct ifnet *ifp; struct ifaddr *ifa; + rdomain = rtable_l2(rdomain); TAILQ_FOREACH(ifp, &ifnet, if_list) { if (ifp->if_rdomain != rdomain) continue; @@ -942,6 +945,7 @@ ifa_ifwithnet(struct sockaddr *addr, u_int rdomain) u_int af = addr->sa_family; char *addr_data = addr->sa_data, *cplim; + rdomain = rtable_l2(rdomain); if (af == AF_LINK) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr; if (sdl->sdl_index && sdl->sdl_index < if_indexlim && @@ -984,6 +988,7 @@ ifa_ifwithaf(int af, u_int rdomain) struct ifnet *ifp; struct ifaddr *ifa; + rdomain = rtable_l2(rdomain); TAILQ_FOREACH(ifp, &ifnet, if_list) { if (ifp->if_rdomain != rdomain) continue; @@ -1490,6 +1495,10 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p) if (rtable_add(ifr->ifr_rdomainid) == -1) panic("rtinit: rtable_add"); } + if (ifr->ifr_rdomainid != rtable_l2(ifr->ifr_rdomainid)) { + /* XXX we should probably flush the table */ + rtable_l2set(ifr->ifr_rdomainid, ifr->ifr_rdomainid); + } ifp->if_rdomain = ifr->ifr_rdomainid; break; diff --git a/sys/net/if_atmsubr.c b/sys/net/if_atmsubr.c index 0c9b76975ea..fc73789311f 100644 --- a/sys/net/if_atmsubr.c +++ b/sys/net/if_atmsubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_atmsubr.c,v 1.28 2009/07/08 15:01:50 claudio Exp $ */ +/* $OpenBSD: if_atmsubr.c,v 1.29 2009/11/03 10:59:04 claudio Exp $ */ /* * @@ -146,11 +146,11 @@ atm_output(ifp, m0, dst, rt0) senderr(ENETDOWN); #ifdef DIAGNOSTIC - if (ifp->if_rdomain != m->m_pkthdr.rdomain) { + if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.rdomain)) { printf("%s: trying to send packet on wrong domain. " - "%d vs. %d, AF %d\n", ifp->if_xname, ifp->if_rdomain, - m->m_pkthdr.rdomain, dst->sa_family); - senderr(ENETDOWN); + "if %d vs. mbuf %d, AF %d\n", ifp->if_xname, + ifp->if_rdomain, rtable_l2(m->m_pkthdr.rdomain), + dst->sa_family); } #endif diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index a4ee764bdbe..1cdb60d0287 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.135 2009/08/12 20:02:42 dlg Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.136 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -231,11 +231,11 @@ ether_output(ifp0, m0, dst, rt0) struct ifnet *ifp = ifp0; #ifdef DIAGNOSTIC - if (ifp->if_rdomain != m->m_pkthdr.rdomain) { + if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.rdomain)) { printf("%s: trying to send packet on wrong domain. " - "%d vs. %d, AF %d\n", ifp->if_xname, ifp->if_rdomain, - m->m_pkthdr.rdomain, dst->sa_family); - senderr(ENETDOWN); + "if %d vs. mbuf %d, AF %d\n", ifp->if_xname, + ifp->if_rdomain, rtable_l2(m->m_pkthdr.rdomain), + dst->sa_family); } #endif @@ -250,7 +250,6 @@ ether_output(ifp0, m0, dst, rt0) /* loop back if this is going to the carp interface */ if (dst != NULL && LINK_STATE_IS_UP(ifp0->if_link_state) && - /* XXX why ifa_ifwithaddr() and not ifaof_ifpforaddr() */ (ifa = ifa_ifwithaddr(dst, ifp->if_rdomain)) != NULL && ifa->ifa_ifp == ifp0) return (looutput(ifp0, m, dst, rt0)); @@ -269,7 +268,7 @@ ether_output(ifp0, m0, dst, rt0) if ((rt = rt0) != NULL) { if ((rt->rt_flags & RTF_UP) == 0) { if ((rt0 = rt = rtalloc1(dst, 1, - m->m_pkthdr.pf.rtableid)) != NULL) + m->m_pkthdr.rdomain)) != NULL) rt->rt_refcnt--; else senderr(EHOSTUNREACH); diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c index f1c4d775d9f..70b29fb63a6 100644 --- a/sys/net/if_fddisubr.c +++ b/sys/net/if_fddisubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_fddisubr.c,v 1.56 2009/07/08 15:01:50 claudio Exp $ */ +/* $OpenBSD: if_fddisubr.c,v 1.57 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: if_fddisubr.c,v 1.5 1996/05/07 23:20:21 christos Exp $ */ /* @@ -149,11 +149,11 @@ fddi_output(ifp0, m0, dst, rt0) struct ifnet *ifp = ifp0; #ifdef DIAGNOSTIC - if (ifp->if_rdomain != m->m_pkthdr.rdomain) { + if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.rdomain)) { printf("%s: trying to send packet on wrong domain. " - "%d vs. %d, AF %d\n", ifp->if_xname, ifp->if_rdomain, - m->m_pkthdr.rdomain, dst->sa_family); - senderr(ENETDOWN); + "if %d vs. mbuf %d, AF %d\n", ifp->if_xname, + ifp->if_rdomain, rtable_l2(m->m_pkthdr.rdomain), + dst->sa_family); } #endif diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c index c5a212dbd31..96f46bd377f 100644 --- a/sys/net/if_pfsync.c +++ b/sys/net/if_pfsync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.c,v 1.129 2009/09/28 03:01:23 dlg Exp $ */ +/* $OpenBSD: if_pfsync.c,v 1.130 2009/11/03 10:59:04 claudio Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -101,24 +101,24 @@ int pfsync_upd_tcp(struct pf_state *, struct pfsync_state_peer *, struct pfsync_state_peer *); int pfsync_in_clr(struct pfsync_pkt *, struct mbuf *, int, int); -int pfsync_in_ins(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_iack(struct pfsync_pkt *, struct mbuf *, int, int); -int pfsync_in_upd(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_upd_c(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_ureq(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_del(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_del_c(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_bus(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_tdb(struct pfsync_pkt *, struct mbuf *, int, int); +int pfsync_in_ins(struct pfsync_pkt *, struct mbuf *, int, int); +int pfsync_in_upd(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_eof(struct pfsync_pkt *, struct mbuf *, int, int); int pfsync_in_error(struct pfsync_pkt *, struct mbuf *, int, int); int (*pfsync_acts[])(struct pfsync_pkt *, struct mbuf *, int, int) = { pfsync_in_clr, /* PFSYNC_ACT_CLR */ - pfsync_in_ins, /* PFSYNC_ACT_INS */ + pfsync_in_error, /* PFSYNC_ACT_OINS */ pfsync_in_iack, /* PFSYNC_ACT_INS_ACK */ - pfsync_in_upd, /* PFSYNC_ACT_UPD */ + pfsync_in_error, /* PFSYNC_ACT_OUPD */ pfsync_in_upd_c, /* PFSYNC_ACT_UPD_C */ pfsync_in_ureq, /* PFSYNC_ACT_UPD_REQ */ pfsync_in_del, /* PFSYNC_ACT_DEL */ @@ -127,7 +127,9 @@ int (*pfsync_acts[])(struct pfsync_pkt *, struct mbuf *, int, int) = { pfsync_in_error, /* PFSYNC_ACT_DEL_F */ pfsync_in_bus, /* PFSYNC_ACT_BUS */ pfsync_in_tdb, /* PFSYNC_ACT_TDB */ - pfsync_in_eof /* PFSYNC_ACT_EOF */ + pfsync_in_eof, /* PFSYNC_ACT_EOF */ + pfsync_in_ins, /* PFSYNC_ACT_INS */ + pfsync_in_upd /* PFSYNC_ACT_UPD */ }; struct pfsync_q { @@ -143,11 +145,11 @@ void pfsync_out_upd_c(struct pf_state *, void *); void pfsync_out_del(struct pf_state *, void *); struct pfsync_q pfsync_qs[] = { - { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_INS }, { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK }, - { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_UPD }, { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C }, - { pfsync_out_del, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C } + { pfsync_out_del, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C }, + { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_INS }, + { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_UPD } }; void pfsync_q_ins(struct pf_state *, int); @@ -401,10 +403,14 @@ pfsync_state_export(struct pfsync_state *sp, struct pf_state *st) sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1]; sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0]; sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1]; + sp->key[PF_SK_WIRE].rdomain = htons(st->key[PF_SK_WIRE]->rdomain); sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0]; sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1]; sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0]; sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1]; + sp->key[PF_SK_STACK].rdomain = htons(st->key[PF_SK_STACK]->rdomain); + sp->rtableid[PF_SK_WIRE] = htonl(st->rtableid[PF_SK_WIRE]); + sp->rtableid[PF_SK_STACK] = htonl(st->rtableid[PF_SK_STACK]); sp->proto = st->key[PF_SK_WIRE]->proto; sp->af = st->key[PF_SK_WIRE]->af; @@ -450,6 +456,9 @@ pfsync_state_export(struct pfsync_state *sp, struct pf_state *st) pf_state_counter_hton(st->bytes[0], sp->bytes[0]); pf_state_counter_hton(st->bytes[1], sp->bytes[1]); + sp->max_mss = htons(st->max_mss); + sp->min_ttl = st->min_ttl; + sp->set_tos = st->set_tos; } int @@ -508,7 +517,8 @@ pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) PF_ANEQ(&sp->key[PF_SK_WIRE].addr[1], &sp->key[PF_SK_STACK].addr[1], sp->af) || sp->key[PF_SK_WIRE].port[0] != sp->key[PF_SK_STACK].port[0] || - sp->key[PF_SK_WIRE].port[1] != sp->key[PF_SK_STACK].port[1]) { + sp->key[PF_SK_WIRE].port[1] != sp->key[PF_SK_STACK].port[1] || + sp->key[PF_SK_WIRE].rdomain != sp->key[PF_SK_STACK].rdomain) { if ((sks = pf_alloc_state_key(pool_flags)) == NULL) goto cleanup; } else @@ -524,6 +534,7 @@ pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) skw->addr[1] = sp->key[PF_SK_WIRE].addr[1]; skw->port[0] = sp->key[PF_SK_WIRE].port[0]; skw->port[1] = sp->key[PF_SK_WIRE].port[1]; + skw->rdomain = ntohs(sp->key[PF_SK_WIRE].rdomain); skw->proto = sp->proto; skw->af = sp->af; if (sks != skw) { @@ -531,9 +542,12 @@ pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) sks->addr[1] = sp->key[PF_SK_STACK].addr[1]; sks->port[0] = sp->key[PF_SK_STACK].port[0]; sks->port[1] = sp->key[PF_SK_STACK].port[1]; + sks->rdomain = ntohs(sp->key[PF_SK_STACK].rdomain); sks->proto = sp->proto; sks->af = sp->af; } + st->rtableid[PF_SK_WIRE] = ntohl(sp->rtableid[PF_SK_WIRE]); + st->rtableid[PF_SK_STACK] = ntohl(sp->rtableid[PF_SK_STACK]); /* copy to state */ bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr)); @@ -549,6 +563,9 @@ pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) st->log = sp->log; st->timeout = sp->timeout; st->state_flags = sp->state_flags; + st->max_mss = ntohs(sp->max_mss); + st->min_ttl = sp->min_ttl; + st->set_tos = sp->set_tos; bcopy(sp->id, &st->id, sizeof(st->id)); st->creatorid = sp->creatorid; @@ -1652,32 +1669,6 @@ pfsync_sendout(void) ph->len = htons(sc->sc_len - sizeof(*ip)); bcopy(pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH); - /* walk the queues */ - for (q = 0; q < PFSYNC_S_COUNT; q++) { - if (TAILQ_EMPTY(&sc->sc_qs[q])) - continue; - - subh = (struct pfsync_subheader *)(m->m_data + offset); - offset += sizeof(*subh); - - count = 0; - TAILQ_FOREACH(st, &sc->sc_qs[q], sync_list) { -#ifdef PFSYNC_DEBUG - KASSERT(st->sync_state == q); -#endif - pfsync_qs[q].write(st, m->m_data + offset); - offset += pfsync_qs[q].len; - - st->sync_state = PFSYNC_S_NONE; - count++; - } - TAILQ_INIT(&sc->sc_qs[q]); - - bzero(subh, sizeof(*subh)); - subh->action = pfsync_qs[q].action; - subh->count = htons(count); - } - if (!TAILQ_EMPTY(&sc->sc_upd_req_list)) { subh = (struct pfsync_subheader *)(m->m_data + offset); offset += sizeof(*subh); @@ -1727,6 +1718,32 @@ pfsync_sendout(void) subh->count = htons(count); } + /* walk the queues */ + for (q = 0; q < PFSYNC_S_COUNT; q++) { + if (TAILQ_EMPTY(&sc->sc_qs[q])) + continue; + + subh = (struct pfsync_subheader *)(m->m_data + offset); + offset += sizeof(*subh); + + count = 0; + TAILQ_FOREACH(st, &sc->sc_qs[q], sync_list) { +#ifdef PFSYNC_DEBUG + KASSERT(st->sync_state == q); +#endif + pfsync_qs[q].write(st, m->m_data + offset); + offset += pfsync_qs[q].len; + + st->sync_state = PFSYNC_S_NONE; + count++; + } + TAILQ_INIT(&sc->sc_qs[q]); + + bzero(subh, sizeof(*subh)); + subh->action = pfsync_qs[q].action; + subh->count = htons(count); + } + subh = (struct pfsync_subheader *)(m->m_data + offset); offset += sizeof(*subh); diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h index 8ffd5ca24c4..d620455fed3 100644 --- a/sys/net/if_pfsync.h +++ b/sys/net/if_pfsync.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.h,v 1.38 2009/06/14 00:16:50 dlg Exp $ */ +/* $OpenBSD: if_pfsync.h,v 1.39 2009/11/03 10:59:04 claudio Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -49,9 +49,9 @@ #define PFSYNC_DFLTTL 255 #define PFSYNC_ACT_CLR 0 /* clear all states */ -#define PFSYNC_ACT_INS 1 /* insert state */ +#define PFSYNC_ACT_OINS 1 /* old insert state */ #define PFSYNC_ACT_INS_ACK 2 /* ack of insterted state */ -#define PFSYNC_ACT_UPD 3 /* update state */ +#define PFSYNC_ACT_OUPD 3 /* old update state */ #define PFSYNC_ACT_UPD_C 4 /* "compressed" update state */ #define PFSYNC_ACT_UPD_REQ 5 /* request "uncompressed" state */ #define PFSYNC_ACT_DEL 6 /* delete state */ @@ -61,12 +61,14 @@ #define PFSYNC_ACT_BUS 10 /* bulk update status */ #define PFSYNC_ACT_TDB 11 /* TDB replay counter update */ #define PFSYNC_ACT_EOF 12 /* end of frame */ -#define PFSYNC_ACT_MAX 13 +#define PFSYNC_ACT_INS 13 /* insert state */ +#define PFSYNC_ACT_UPD 14 /* update state */ +#define PFSYNC_ACT_MAX 15 #define PFSYNC_ACTIONS "CLR ST", \ - "INS ST", \ + "INS ST OLD", \ "INS ST ACK", \ - "UPD ST", \ + "UPD ST OLD", \ "UPD ST COMP", \ "UPD ST REQ", \ "DEL ST", \ @@ -75,7 +77,9 @@ "DEL FR", \ "BULK UPD STAT", \ "TDB UPD", \ - "EOF" + "EOF", \ + "INS ST", \ + "UPD ST" #define PFSYNC_HMAC_LEN 20 @@ -134,6 +138,12 @@ struct pfsync_clr { } __packed; /* + * OINS, OUPD + */ + +/* these messages are deprecated */ + +/* * INS, UPD, DEL */ @@ -272,11 +282,11 @@ struct pfsyncreq { /* * this shows where a pf state is with respect to the syncing. */ -#define PFSYNC_S_INS 0x00 -#define PFSYNC_S_IACK 0x01 -#define PFSYNC_S_UPD 0x02 -#define PFSYNC_S_UPD_C 0x03 -#define PFSYNC_S_DEL 0x04 +#define PFSYNC_S_IACK 0x00 +#define PFSYNC_S_UPD_C 0x01 +#define PFSYNC_S_DEL 0x02 +#define PFSYNC_S_INS 0x03 +#define PFSYNC_S_UPD 0x04 #define PFSYNC_S_COUNT 0x05 #define PFSYNC_S_DEFER 0xfe diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 607c9948a92..5308a4ff8d8 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ppp.c,v 1.54 2009/07/08 15:01:50 claudio Exp $ */ +/* $OpenBSD: if_ppp.c,v 1.55 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: if_ppp.c,v 1.39 1997/05/17 21:11:59 christos Exp $ */ /* @@ -728,12 +728,10 @@ pppoutput(ifp, m0, dst, rtp) } #ifdef DIAGNOSTIC - if (ifp->if_rdomain != m0->m_pkthdr.rdomain) { + if (ifp->if_rdomain != rtable_l2(m0->m_pkthdr.rdomain)) { printf("%s: trying to send packet on wrong domain. " - "%d vs. %d, AF %d\n", ifp->if_xname, ifp->if_rdomain, - m0->m_pkthdr.rdomain, dst->sa_family); - error = ENETDOWN; - goto bad; + "if %d vs. mbuf %d, AF %d\n", ifp->if_xname, ifp->if_rdomain, + rtable_l2(m0->m_pkthdr.rdomain), dst->sa_family); } #endif diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c index 3d45a60b39d..f49c428562e 100644 --- a/sys/net/if_sl.c +++ b/sys/net/if_sl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sl.c,v 1.38 2009/07/19 08:16:06 blambert Exp $ */ +/* $OpenBSD: if_sl.c,v 1.39 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: if_sl.c,v 1.39.4.1 1996/06/02 16:26:31 thorpej Exp $ */ /* @@ -426,12 +426,11 @@ sloutput(ifp, m, dst, rtp) } #ifdef DIAGNOSTIC - if (ifp->if_rdomain != m->m_pkthdr.rdomain) { + if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.rdomain)) { printf("%s: trying to send packet on wrong domain. " - "%d vs. %d, AF %d\n", ifp->if_xname, ifp->if_rdomain, - m->m_pkthdr.rdomain, dst->sa_family); - m_freem(m); - return (ENETDOWN); + "if %d vs. mbuf %d, AF %d\n", ifp->if_xname, + ifp->if_rdomain, rtable_l2(m->m_pkthdr.rdomain), + dst->sa_family); } #endif diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index a95dade30dd..b0d96caa231 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_spppsubr.c,v 1.77 2009/07/27 11:40:59 blambert Exp $ */ +/* $OpenBSD: if_spppsubr.c,v 1.78 2009/11/03 10:59:04 claudio Exp $ */ /* * Synchronous PPP/Cisco link level subroutines. * Keepalive protocol implemented in both Cisco and PPP modes. @@ -699,12 +699,11 @@ sppp_output(struct ifnet *ifp, struct mbuf *m, u_int16_t protocol; #ifdef DIAGNOSTIC - if (ifp->if_rdomain != m->m_pkthdr.rdomain) { + if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.rdomain)) { printf("%s: trying to send packet on wrong domain. " - "%d vs. %d, AF %d\n", ifp->if_xname, ifp->if_rdomain, - m->m_pkthdr.rdomain, dst->sa_family); - m_freem (m); - return (ENETDOWN); + "if %d vs. mbuf %d, AF %d\n", ifp->if_xname, + ifp->if_rdomain, rtable_l2(m->m_pkthdr.rdomain), + dst->sa_family); } #endif diff --git a/sys/net/pf.c b/sys/net/pf.c index 7d56711c2ff..0d0163c9110 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.666 2009/10/29 10:28:27 jsg Exp $ */ +/* $OpenBSD: pf.c,v 1.667 2009/11/03 10:59:04 claudio Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -154,10 +154,10 @@ void pf_send_tcp(const struct pf_rule *, sa_family_t, const struct pf_addr *, const struct pf_addr *, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t, u_int16_t, u_int16_t, u_int8_t, int, - u_int16_t, u_short, struct ether_header *, - struct ifnet *, int); + u_int16_t, u_int, struct ether_header *, + struct ifnet *); void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t, - sa_family_t, struct pf_rule *, int); + sa_family_t, struct pf_rule *, u_int); void pf_detach_state(struct pf_state *); void pf_state_key_detach(struct pf_state *, int); u_int32_t pf_tcp_iss(struct pf_pdesc *); @@ -637,6 +637,9 @@ pf_state_compare_key(struct pf_state_key *a, struct pf_state_key *b) if ((diff = a->port[1] - b->port[1]) != 0) return (diff); + if ((diff = a->rdomain - b->rdomain) != 0) + return (diff); + return (0); } @@ -777,9 +780,10 @@ int pf_state_key_setup(struct pf_pdesc *pd, struct pf_state_key **skw, struct pf_state_key **sks, struct pf_addr **saddr, struct pf_addr **daddr, - u_int16_t *sport, u_int16_t *dport) + u_int16_t *sport, u_int16_t *dport, int rtableid) { struct pf_state_key *sk1, *sk2; + u_int wrdom = pd->rdomain; if ((sk1 = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL) return (ENOMEM); @@ -790,10 +794,14 @@ pf_state_key_setup(struct pf_pdesc *pd, sk1->port[pd->didx] = pd->odport; sk1->proto = pd->proto; sk1->af = pd->af; + sk1->rdomain = pd->rdomain; + if (rtableid >= 0) + wrdom = rtable_l2(rtableid); if (PF_ANEQ(*saddr, pd->src, pd->af) || PF_ANEQ(*daddr, pd->dst, pd->af) || - *sport != pd->osport || *dport != pd->odport) { /* NAT */ + *sport != pd->osport || *dport != pd->odport || + wrdom != pd->rdomain) { /* NAT */ if ((sk2 = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL) return (ENOMEM); /* caller must handle cleanup */ @@ -803,6 +811,7 @@ pf_state_key_setup(struct pf_pdesc *pd, sk2->port[pd->didx] = *dport; sk2->proto = pd->proto; sk2->af = pd->af; + sk2->rdomain = wrdom; } else sk2 = sk1; @@ -888,7 +897,7 @@ pf_compare_state_keys(struct pf_state_key *a, struct pf_state_key *b, PF_AEQ(&a->addr[0], &b->addr[1], a->af) && PF_AEQ(&a->addr[1], &b->addr[0], a->af) && a->port[0] == b->port[1] && - a->port[1] == b->port[0]) + a->port[1] == b->port[0] && a->rdomain == b->rdomain) return (0); else { /* mismatch. must not happen. */ @@ -1109,10 +1118,6 @@ pf_src_tree_remove_state(struct pf_state *s) void pf_unlink_state(struct pf_state *cur) { - /* - * XXX XXX XXX state needs to know routing domain so that states - * XXX XXX XXX can not float between domain. May simplify other code. - */ splsoftassert(IPL_SOFTNET); if (cur->src.state == PF_TCPS_PROXY_DST) { @@ -1123,8 +1128,8 @@ pf_unlink_state(struct pf_state *cur) cur->key[PF_SK_WIRE]->port[1], cur->key[PF_SK_WIRE]->port[0], cur->src.seqhi, cur->src.seqlo + 1, - TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, 0, NULL, NULL, - cur->rtableid); + TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, + cur->key[PF_SK_WIRE]->rdomain, NULL, NULL); } RB_REMOVE(pf_state_tree_id, &tree_id, cur); #if NPFLOW > 0 @@ -1368,13 +1373,13 @@ pf_print_state_parts(struct pf_state *s, break; } if (skw) { - printf(" wire: "); + printf(" wire: (%d) ", skw->rdomain); pf_print_host(&skw->addr[0], skw->port[0], skw->af); printf(" "); pf_print_host(&skw->addr[1], skw->port[1], skw->af); } if (sks) { - printf(" stack: "); + printf(" stack: (%d) ", sks->rdomain); if (sks != skw) { pf_print_host(&sks->addr[0], sks->port[0], sks->af); printf(" "); @@ -1900,8 +1905,7 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af, const struct pf_addr *saddr, const struct pf_addr *daddr, u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag, - u_int16_t rtag, u_short rdom, struct ether_header *eh, struct ifnet *ifp, - int rtableid) + u_int16_t rtag, u_int rdom, struct ether_header *eh, struct ifnet *ifp) { struct mbuf *m; int len, tlen; @@ -1941,9 +1945,6 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af, m->m_pkthdr.pf.tag = rtag; m->m_pkthdr.rdomain = rdom; - if (rtableid >= 0) - m->m_pkthdr.pf.rtableid = rtableid; - #ifdef ALTQ if (r != NULL && r->qid) { m->m_pkthdr.pf.qid = r->qid; @@ -2056,7 +2057,7 @@ pf_send_tcp(const struct pf_rule *r, sa_family_t af, void pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, - struct pf_rule *r, int rtableid) + struct pf_rule *r, u_int rdomain) { struct mbuf *m0; @@ -2064,10 +2065,8 @@ pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, return; m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED; - m0->m_pkthdr.rdomain = m->m_pkthdr.rdomain; - if (rtableid >= 0) - m0->m_pkthdr.pf.rtableid = rtableid; + m0->m_pkthdr.rdomain = rdomain; #ifdef ALTQ if (r->qid) { @@ -2245,7 +2244,7 @@ pf_tag_packet(struct mbuf *m, int tag, int rtableid) if (tag > 0) m->m_pkthdr.pf.tag = tag; if (rtableid >= 0) - m->m_pkthdr.pf.rtableid = rtableid; + m->m_pkthdr.rdomain = rtableid; return (0); } @@ -2427,11 +2426,15 @@ pf_socket_lookup(int direction, struct pf_pdesc *pd) switch (pd->af) { #ifdef INET case AF_INET: + /* + * Fails when rtable is changed while evaluating the ruleset + * The socket looked up will not match the one hit in the end. + */ inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport, - /* XXX */ 0); + pd->rdomain); if (inp == NULL) { inp = in_pcblookup_listen(tb, daddr->v4, dport, 0, - NULL, 0); + NULL, pd->rdomain); if (inp == NULL) return (-1); } @@ -2913,17 +2916,17 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, pf_send_tcp(r, af, pd->dst, pd->src, th->th_dport, th->th_sport, ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, - r->return_ttl, 1, 0, m->m_pkthdr.rdomain, - pd->eh, kif->pfik_ifp, act.rtableid); + r->return_ttl, 1, 0, pd->rdomain, + pd->eh, kif->pfik_ifp); } } else if (pd->proto != IPPROTO_ICMP && af == AF_INET && r->return_icmp) pf_send_icmp(m, r->return_icmp >> 8, - r->return_icmp & 255, af, r, act.rtableid); + r->return_icmp & 255, af, r, pd->rdomain); else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 && r->return_icmp6) pf_send_icmp(m, r->return_icmp6 >> 8, - r->return_icmp6 & 255, af, r, act.rtableid); + r->return_icmp6 & 255, af, r, pd->rdomain); } if (r->action == PF_DROP) @@ -2933,6 +2936,9 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, REASON_SET(&reason, PFRES_MEMORY); goto cleanup; } + if (act.rtableid >= 0 && + rtable_l2(act.rtableid) != pd->rdomain) + pd->destchg = 1; if (!state_icmp && r->keep_state) { int action; @@ -3045,7 +3051,8 @@ pf_create_state(struct pf_rule *r, struct pf_rule *a, struct pf_pdesc *pd, s->log = act->log & PF_LOG_ALL; s->qid = act->qid; s->pqid = act->pqid; - s->rtableid = act->rtableid; + s->rtableid[pd->didx] = act->rtableid; + s->rtableid[pd->sidx] = -1; /* return traffic is routed normaly */ s->min_ttl = act->min_ttl; s->set_tos = act->set_tos; s->max_mss = act->max_mss; @@ -3135,7 +3142,8 @@ pf_create_state(struct pf_rule *r, struct pf_rule *a, struct pf_pdesc *pd, } s->direction = pd->dir; - if (pf_state_key_setup(pd, skw, sks, &saddr, &daddr, &sport, &dport)) + if (pf_state_key_setup(pd, skw, sks, &saddr, &daddr, &sport, &dport, + act->rtableid)) goto csfailed; if (pf_state_insert(BOUND_IFACE(r, kif), *skw, *sks, s)) { @@ -3165,7 +3173,8 @@ pf_create_state(struct pf_rule *r, struct pf_rule *a, struct pf_pdesc *pd, s->src.mss = mss; pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport, th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, - TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, /* XXX */ 0, NULL, NULL, act->rtableid); + TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, pd->rdomain, + NULL, NULL); REASON_SET(&reason, PFRES_SYNPROXY); return (PF_SYNPROXY_DROP); } @@ -3662,8 +3671,7 @@ pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst, th->th_sport, ntohl(th->th_ack), 0, TH_RST, 0, 0, (*state)->rule.ptr->return_ttl, 1, 0, - m->m_pkthdr.rdomain, pd->eh, - kif->pfik_ifp, (*state)->rtableid); + pd->rdomain, pd->eh, kif->pfik_ifp); src->seqlo = 0; src->seqhi = 1; src->max_win = 1; @@ -3777,6 +3785,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd->af; key.proto = IPPROTO_TCP; + key.rdomain = pd->rdomain; if (direction == PF_IN) { /* wire side, straight */ PF_ACPY(&key.addr[0], pd->src, key.af); PF_ACPY(&key.addr[1], pd->dst, key.af); @@ -3815,7 +3824,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, pd->src, th->th_dport, th->th_sport, (*state)->src.seqhi, ntohl(th->th_seq) + 1, TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1, - 0, /* XXX */ 0, NULL, NULL, (*state)->rtableid); + 0, pd->rdomain, NULL, NULL); REASON_SET(reason, PFRES_SYNPROXY); return (PF_SYNPROXY_DROP); } else if (!(th->th_flags & TH_ACK) || @@ -3845,8 +3854,8 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, &sk->addr[pd->sidx], &sk->addr[pd->didx], sk->port[pd->sidx], sk->port[pd->didx], (*state)->dst.seqhi, 0, TH_SYN, 0, - (*state)->src.mss, 0, 0, (*state)->tag, /* XXX */ 0, - NULL, NULL, (*state)->rtableid); + (*state)->src.mss, 0, 0, (*state)->tag, + sk->rdomain, NULL, NULL); REASON_SET(reason, PFRES_SYNPROXY); return (PF_SYNPROXY_DROP); } else if (((th->th_flags & (TH_SYN|TH_ACK)) != @@ -3861,14 +3870,13 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, pd->src, th->th_dport, th->th_sport, ntohl(th->th_ack), ntohl(th->th_seq) + 1, TH_ACK, (*state)->src.max_win, 0, 0, 0, - (*state)->tag, /* XXX */ 0, NULL, NULL, - (*state)->rtableid); + (*state)->tag, pd->rdomain, NULL, NULL); pf_send_tcp((*state)->rule.ptr, pd->af, &sk->addr[pd->sidx], &sk->addr[pd->didx], sk->port[pd->sidx], sk->port[pd->didx], (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, TH_ACK, (*state)->dst.max_win, 0, 0, 1, - 0, /* XXX */ 0, NULL, NULL, (*state)->rtableid); + 0, sk->rdomain, NULL, NULL); (*state)->src.seqdiff = (*state)->dst.seqhi - (*state)->src.seqlo; (*state)->dst.seqdiff = (*state)->src.seqhi - @@ -3920,13 +3928,15 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, &th->th_sum, &nk->addr[pd->sidx], nk->port[pd->sidx], 0, pd->af); - if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af)) + if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || + pd->rdomain != nk->rdomain) pd->destchg = 1; if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || nk->port[pd->didx] != th->th_dport) pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, &th->th_sum, &nk->addr[pd->didx], nk->port[pd->didx], 0, pd->af); + m->m_pkthdr.rdomain = nk->rdomain; copyback = 1; } @@ -3947,6 +3957,7 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd->af; key.proto = IPPROTO_UDP; + key.rdomain = pd->rdomain; if (direction == PF_IN) { /* wire side, straight */ PF_ACPY(&key.addr[0], pd->src, key.af); PF_ACPY(&key.addr[1], pd->dst, key.af); @@ -3992,13 +4003,15 @@ pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, &uh->uh_sum, &nk->addr[pd->sidx], nk->port[pd->sidx], 1, pd->af); - if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af)) + if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || + pd->rdomain != nk->rdomain) pd->destchg = 1; if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || nk->port[pd->didx] != uh->uh_dport) pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, &uh->uh_sum, &nk->addr[pd->didx], nk->port[pd->didx], 1, pd->af); + m->m_pkthdr.rdomain = nk->rdomain; m_copyback(m, off, sizeof(*uh), uh); } @@ -4013,6 +4026,7 @@ pf_icmp_state_lookup(struct pf_state_key_cmp *key, struct pf_pdesc *pd, { key->af = pd->af; key->proto = pd->proto; + key->rdomain = pd->rdomain; if (icmp_dir == PF_IN) { *iidx = pd->sidx; key->port[pd->sidx] = icmpid; @@ -4115,6 +4129,10 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { struct pf_state_key *nk = (*state)->key[pd->didx]; + if (pd->rdomain != nk->rdomain) + pd->destchg = 1; + m->m_pkthdr.rdomain = nk->rdomain; + switch (pd->af) { #ifdef INET case AF_INET: @@ -4189,6 +4207,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, int off2; pd2.af = pd->af; + pd2.rdomain = pd->rdomain; /* Payload packet is from the opposite direction. */ pd2.sidx = (direction == PF_IN) ? 1 : 0; pd2.didx = (direction == PF_IN) ? 0 : 1; @@ -4302,6 +4321,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd2.af; key.proto = IPPROTO_TCP; + key.rdomain = pd2.rdomain; PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); key.port[pd2.sidx] = th.th_sport; @@ -4373,6 +4393,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, pd2.ip_sum, icmpsum, pd->ip_sum, 0, pd2.af); + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], + pd2.af) || pd2.rdomain != nk->rdomain) + pd->destchg = 1; + m->m_pkthdr.rdomain = nk->rdomain; + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], pd2.af) || nk->port[pd2.didx] != th.th_dport) @@ -4424,6 +4449,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd2.af; key.proto = IPPROTO_UDP; + key.rdomain = pd2.rdomain; PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); key.port[pd2.sidx] = uh.uh_sport; @@ -4446,6 +4472,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, pd2.ip_sum, icmpsum, pd->ip_sum, 1, pd2.af); + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], + pd2.af) || pd2.rdomain != nk->rdomain) + pd->destchg = 1; + m->m_pkthdr.rdomain = nk->rdomain; + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], pd2.af) || nk->port[pd2.didx] != uh.uh_dport) @@ -4520,6 +4551,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, pd2.ip_sum, icmpsum, pd->ip_sum, 0, AF_INET); + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], + pd2.af) || pd2.rdomain != nk->rdomain) + pd->destchg = 1; + m->m_pkthdr.rdomain = nk->rdomain; + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], pd2.af)) pf_change_icmp(pd2.dst, NULL, NULL, @@ -4585,6 +4621,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, pd2.ip_sum, icmpsum, pd->ip_sum, 0, AF_INET6); + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], + pd2.af) || pd2.rdomain != nk->rdomain) + pd->destchg = 1; + m->m_pkthdr.rdomain = nk->rdomain; + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], pd2.af)) pf_change_icmp(pd2.dst, NULL, NULL, @@ -4605,6 +4646,7 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, default: { key.af = pd2.af; key.proto = pd2.proto; + key.rdomain = pd2.rdomain; PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); key.port[0] = key.port[1] = 0; @@ -4624,6 +4666,11 @@ pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, pd2.ip_sum, icmpsum, pd->ip_sum, 0, pd2.af); + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], + pd2.af) || pd2.rdomain != nk->rdomain) + pd->destchg = 1; + m->m_pkthdr.rdomain = nk->rdomain; + if (PF_ANEQ(pd2.dst, &nk->addr[pd2.didx], pd2.af)) pf_change_icmp(pd2.src, NULL, @@ -4667,6 +4714,7 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, key.af = pd->af; key.proto = pd->proto; + key.rdomain = pd->rdomain; if (direction == PF_IN) { PF_ACPY(&key.addr[0], pd->src, key.af); PF_ACPY(&key.addr[1], pd->dst, key.af); @@ -4708,6 +4756,7 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, KASSERT(pd); KASSERT(pd->src); KASSERT(pd->dst); + switch (pd->af) { #ifdef INET case AF_INET: @@ -4737,6 +4786,10 @@ pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, break; #endif /* INET6 */ } + if (pd->rdomain != nk->rdomain) + pd->destchg = 1; + + m->m_pkthdr.rdomain = nk->rdomain; } return (PF_PASS); } @@ -5434,6 +5487,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, pd.tos = h->ip_tos; pd.tot_len = ntohs(h->ip_len); pd.eh = eh; + pd.rdomain = rtable_l2(m->m_pkthdr.rdomain); /* handle fragments that didn't get reassembled by normalization */ if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { @@ -5576,13 +5630,14 @@ done: if (s) { pf_scrub_ip(&m, s->state_flags, s->min_ttl, s->set_tos); - pf_tag_packet(m, s->tag, s->rtableid); + pf_tag_packet(m, s->tag, s->rtableid[pd.didx]); if (pqid || (pd.tos & IPTOS_LOWDELAY)) qid = s->pqid; else qid = s->qid; } else { pf_scrub_ip(&m, r->scrub_flags, r->min_ttl, r->set_tos); + /* XXX tag not needed since it is done in pf_test_rule ??? */ pf_tag_packet(m, r->tag, r->rtableid); if (pqid || (pd.tos & IPTOS_LOWDELAY)) qid = r->pqid; @@ -6040,8 +6095,8 @@ done: else pf_scrub_ip6(&m, r->min_ttl); - if (s && (s->tag || s->rtableid)) - pf_tag_packet(m, s ? s->tag : 0, s->rtableid); + if (s && s->tag) + pf_tag_packet(m, s ? s->tag : 0, s->rtableid[pd.didx]); if (dir == PF_IN && s && s->key[PF_SK_STACK]) m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK]; diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 10d10931b2e..75376ae667f 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.222 2009/10/28 20:11:01 jsg Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.223 2009/11/03 10:59:04 claudio Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1591,7 +1591,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } if ((!psk->psk_af || sk->af == psk->psk_af) && (!psk->psk_proto || psk->psk_proto == - sk->proto) && + sk->proto) && psk->psk_rdomain == sk->rdomain && PF_MATCHA(psk->psk_src.neg, &psk->psk_src.addr.v.a.addr, &psk->psk_src.addr.v.a.mask, @@ -1638,6 +1638,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) struct pf_state *s; struct pf_state_cmp id_key; + bzero(&id_key, sizeof(id_key)); bcopy(ps->state.id, &id_key.id, sizeof(id_key.id)); id_key.creatorid = ps->state.creatorid; @@ -1736,11 +1737,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) PF_AZERO(&pnl->daddr, pnl->af) || ((pnl->proto == IPPROTO_TCP || pnl->proto == IPPROTO_UDP) && - (!pnl->dport || !pnl->sport))) + (!pnl->dport || !pnl->sport)) || + pnl->rdomain < 0 || pnl->rdomain > RT_TABLEID_MAX) error = EINVAL; else { key.af = pnl->af; key.proto = pnl->proto; + key.rdomain = pnl->rdomain; PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af); key.port[sidx] = pnl->sport; PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af); diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c index 0a1b0de5f28..d426e96dbc0 100644 --- a/sys/net/pf_lb.c +++ b/sys/net/pf_lb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_lb.c,v 1.7 2009/09/07 08:27:45 sthen Exp $ */ +/* $OpenBSD: pf_lb.c,v 1.8 2009/11/03 10:59:04 claudio Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -104,7 +104,7 @@ void pf_hash(struct pf_addr *, struct pf_addr *, int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *, struct pf_addr *, struct pf_addr *, u_int16_t, struct pf_addr *, u_int16_t *, u_int16_t, u_int16_t, - struct pf_src_node **); + struct pf_src_node **, int); #define mix(a,b,c) \ do { \ @@ -167,7 +167,7 @@ int pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport, struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high, - struct pf_src_node **sn) + struct pf_src_node **sn, int rdomain) { struct pf_state_key_cmp key; struct pf_addr init_addr; @@ -189,6 +189,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, do { key.af = af; key.proto = proto; + key.rdomain = rdomain; PF_ACPY(&key.addr[1], daddr, key.af); PF_ACPY(&key.addr[0], naddr, key.af); key.port[1] = dport; @@ -450,9 +451,11 @@ pf_get_transaddr(struct pf_rule *r, struct pf_pdesc *pd, struct pf_addr *saddr, struct pf_src_node srcnode, *sn = &srcnode; if (!TAILQ_EMPTY(&r->nat.list)) { + /* XXX is this right? what if rtable is changed at the same + * XXX time? where do I need to figure out the sport? */ if (pf_get_sport(pd->af, pd->proto, r, saddr, daddr, *dport, &naddr, &nport, r->nat.proxy_port[0], - r->nat.proxy_port[1], &sn)) { + r->nat.proxy_port[1], &sn, pd->rdomain)) { DPFPRINTF(PF_DEBUG_MISC, ("pf: NAT proxy port allocation " "(%u-%u) failed\n", diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 701dcdc5078..c9f103aa7e6 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.296 2009/10/28 20:11:01 jsg Exp $ */ +/* $OpenBSD: pfvar.h,v 1.297 2009/11/03 10:59:04 claudio Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -722,9 +722,9 @@ TAILQ_HEAD(pf_state_queue, pf_state); struct pf_state_key_cmp { struct pf_addr addr[2]; u_int16_t port[2]; + u_int16_t rdomain; sa_family_t af; u_int8_t proto; - u_int8_t pad[2]; }; struct pf_state_item { @@ -737,9 +737,9 @@ TAILQ_HEAD(pf_statelisthead, pf_state_item); struct pf_state_key { struct pf_addr addr[2]; u_int16_t port[2]; + u_int16_t rdomain; sa_family_t af; u_int8_t proto; - u_int8_t pad[2]; RB_ENTRY(pf_state_key) entry; struct pf_statelisthead states; @@ -801,7 +801,7 @@ struct pf_state { /* XXX */ u_int8_t sync_updates; - int rtableid; + int rtableid[2]; /* rtables stack and wire */ u_int8_t min_ttl; u_int8_t set_tos; u_int16_t max_mss; @@ -834,6 +834,8 @@ struct pfsync_state_peer { struct pfsync_state_key { struct pf_addr addr[2]; u_int16_t port[2]; + u_int16_t rdomain; + u_int8_t pad[2]; }; struct pfsync_state { @@ -851,6 +853,8 @@ struct pfsync_state { u_int32_t packets[2][2]; u_int32_t bytes[2][2]; u_int32_t creatorid; + int32_t rtableid[2]; + u_int16_t max_mss; sa_family_t af; u_int8_t proto; u_int8_t direction; @@ -859,6 +863,9 @@ struct pfsync_state { u_int8_t timeout; u_int8_t sync_flags; u_int8_t updates; + u_int8_t min_ttl; + u_int8_t set_tos; + u_int8_t pad[4]; } __packed; #define PFSYNC_FLAG_SRCNODE 0x04 @@ -1139,6 +1146,7 @@ struct pf_pdesc { u_int16_t odport; u_int32_t p_len; /* total length of payload */ + u_int rdomain; /* original routing domain */ u_int16_t *ip_sum; u_int16_t *proto_sum; @@ -1406,6 +1414,7 @@ struct pfioc_natlook { struct pf_addr daddr; struct pf_addr rsaddr; struct pf_addr rdaddr; + int rdomain; u_int16_t sport; u_int16_t dport; u_int16_t rsport; @@ -1435,6 +1444,7 @@ struct pfioc_state_kill { char psk_ifname[IFNAMSIZ]; char psk_label[PF_RULE_LABEL_SIZE]; u_int psk_killed; + int psk_rdomain; }; struct pfioc_states { @@ -1878,7 +1888,7 @@ int pf_map_addr(sa_family_t, struct pf_rule *, int pf_state_key_setup(struct pf_pdesc *, struct pf_state_key **, struct pf_state_key **, struct pf_addr **, struct pf_addr **, - u_int16_t *, u_int16_t *); + u_int16_t *, u_int16_t *, int); #endif /* _KERNEL */ diff --git a/sys/net/route.c b/sys/net/route.c index d8f9a01b17b..9a798e2fbf3 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.113 2009/10/26 17:14:24 mk Exp $ */ +/* $OpenBSD: route.c,v 1.114 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -140,6 +140,7 @@ struct radix_node_head ***rt_tables; u_int8_t af2rtafidx[AF_MAX+1]; u_int8_t rtafidx_max; u_int rtbl_id_max = 0; +u_int *rt_tab2dom; /* rt table to domain lookup table */ int rttrash; /* routes not in table but not freed */ @@ -218,30 +219,54 @@ route_init() int rtable_add(u_int id) /* must be called at splsoftnet */ { - void *p; + void *p, *q; if (id > RT_TABLEID_MAX) return (-1); if (id == 0 || id > rtbl_id_max) { size_t newlen = sizeof(void *) * (id+1); + size_t newlen2 = sizeof(u_int) * (id+1); if ((p = malloc(newlen, M_RTABLE, M_NOWAIT|M_ZERO)) == NULL) return (-1); + if ((q = malloc(newlen2, M_RTABLE, M_NOWAIT|M_ZERO)) == NULL) { + free(p, M_RTABLE); + return (-1); + } if (rt_tables) { bcopy(rt_tables, p, sizeof(void *) * (rtbl_id_max+1)); + bcopy(rt_tab2dom, q, sizeof(u_int) * (rtbl_id_max+1)); free(rt_tables, M_RTABLE); } rt_tables = p; + rt_tab2dom = q; rtbl_id_max = id; } if (rt_tables[id] != NULL) /* already exists */ return (-1); + rt_tab2dom[id] = 0; /* use main table/domain by default */ return (rtable_init(&rt_tables[id])); } +u_int +rtable_l2(u_int id) +{ + if (id > rtbl_id_max) + return (0); + return (rt_tab2dom[id]); +} + +void +rtable_l2set(u_int id, u_int parent) +{ + if (!rtable_exists(id) || !rtable_exists(parent)) + return; + rt_tab2dom[id] = parent; +} + int rtable_exists(u_int id) /* verify table with that ID exists */ { @@ -616,7 +641,7 @@ rtioctl(u_long req, caddr_t data, struct proc *p) struct ifaddr * ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway, - u_int rdomain) + u_int rtableid) { struct ifaddr *ifa; @@ -641,21 +666,21 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway, */ ifa = NULL; if (flags & RTF_HOST) - ifa = ifa_ifwithdstaddr(dst, rdomain); + ifa = ifa_ifwithdstaddr(dst, rtableid); if (ifa == NULL) - ifa = ifa_ifwithaddr(gateway, rdomain); + ifa = ifa_ifwithaddr(gateway, rtableid); } else { /* * If we are adding a route to a remote net * or host, the gateway may still be on the * other end of a pt to pt link. */ - ifa = ifa_ifwithdstaddr(gateway, rdomain); + ifa = ifa_ifwithdstaddr(gateway, rtableid); } if (ifa == NULL) - ifa = ifa_ifwithnet(gateway, rdomain); + ifa = ifa_ifwithnet(gateway, rtableid); if (ifa == NULL) { - struct rtentry *rt = rtalloc1(gateway, 0, rdomain); + struct rtentry *rt = rtalloc1(gateway, 0, rtable_l2(rtableid)); if (rt == NULL) return (NULL); rt->rt_refcnt--; @@ -678,7 +703,7 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway, #define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) int -rt_getifa(struct rt_addrinfo *info, u_int rdom) +rt_getifa(struct rt_addrinfo *info, u_int rtid) { struct ifaddr *ifa; int error = 0; @@ -690,11 +715,11 @@ rt_getifa(struct rt_addrinfo *info, u_int rdom) if (info->rti_ifp == NULL && info->rti_info[RTAX_IFP] != NULL && info->rti_info[RTAX_IFP]->sa_family == AF_LINK && (ifa = ifa_ifwithnet((struct sockaddr *)info->rti_info[RTAX_IFP], - rdom)) != NULL) + rtid)) != NULL) info->rti_ifp = ifa->ifa_ifp; if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL) - info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rdom); + info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rtid); if (info->rti_ifa == NULL) { struct sockaddr *sa; @@ -710,10 +735,10 @@ rt_getifa(struct rt_addrinfo *info, u_int rdom) info->rti_ifa = ifa_ifwithroute(info->rti_flags, info->rti_info[RTAX_DST], info->rti_info[RTAX_GATEWAY], - rdom); + rtid); else if (sa != NULL) info->rti_ifa = ifa_ifwithroute(info->rti_flags, - sa, sa, rdom); + sa, sa, rtid); } if ((ifa = info->rti_ifa) != NULL) { if (info->rti_ifp == NULL) @@ -823,8 +848,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, goto makeroute; case RTM_ADD: - if (info->rti_ifa == 0 && (error = rt_getifa(info, - /* XXX wrong because only rdomains allowed */ tableid))) + if (info->rti_ifa == 0 && (error = rt_getifa(info, tableid))) senderr(error); ifa = info->rti_ifa; makeroute: @@ -1009,7 +1033,8 @@ rt_setgate(struct rtentry *rt0, struct sockaddr *dst, struct sockaddr *gate, rt->rt_gwroute = NULL; } if (rt->rt_flags & RTF_GATEWAY) { - rt->rt_gwroute = rtalloc1(gate, 1, tableid); + /* XXX is this actually valid to cross tables here? */ + rt->rt_gwroute = rtalloc1(gate, 1, rtable_l2(tableid)); /* * If we switched gateways, grab the MTU from the new * gateway route if the current MTU is 0 or greater diff --git a/sys/net/route.h b/sys/net/route.h index 3756ef599eb..954331a2b21 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.64 2009/09/17 13:27:24 claudio Exp $ */ +/* $OpenBSD: route.h,v 1.65 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -345,6 +345,8 @@ extern const struct sockaddr_rtin rt_defmask4; struct socket; void route_init(void); int rtable_add(u_int); +u_int rtable_l2(u_int); +void rtable_l2set(u_int, u_int); int rtable_exists(u_int); int route_output(struct mbuf *, ...); int route_usrreq(struct socket *, int, struct mbuf *, diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index f36ff5b028d..d162048c049 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.94 2009/09/17 13:27:24 claudio Exp $ */ +/* $OpenBSD: rtsock.c,v 1.95 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -612,22 +612,21 @@ report: * flags may also be different; ifp may be specified * by ll sockaddr when protocol address is ambiguous */ - if ((error = rt_getifa(&info, - /* XXX wrong, only rdomain */ tableid)) != 0) + if ((error = rt_getifa(&info, tableid)) != 0) goto flush; if (gate && rt_setgate(rt, rt_key(rt), gate, tableid)) { error = EDQUOT; goto flush; } - if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr, - /* XXX again rtable vs. rdomain */ tableid)) && + if (ifpaddr && + (ifa = ifa_ifwithnet(ifpaddr, tableid)) && (ifp = ifa->ifa_ifp) && (ifaaddr || gate)) ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate, ifp); - else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr, - /* XXX one more time */ tableid))) || + else if ((ifaaddr && + (ifa = ifa_ifwithaddr(ifaaddr, tableid))) || (gate && (ifa = ifa_ifwithroute(rt->rt_flags, - rt_key(rt), gate, /* XXX again */ tableid)))) + rt_key(rt), gate, tableid)))) ifp = ifa->ifa_ifp; if (ifa) { struct ifaddr *oifa = rt->rt_ifa; diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index f347efc8cb1..b3f2ad6fa3c 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.c,v 1.81 2009/10/17 12:20:17 mpf Exp $ */ +/* $OpenBSD: if_ether.c,v 1.82 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */ /* @@ -704,7 +704,7 @@ in_arpinput(m) goto reply; } la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0, - m->m_pkthdr.rdomain); + rtable_l2(m->m_pkthdr.rdomain)); if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) { if (sdl->sdl_alen) { if (bcmp(ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) { @@ -789,7 +789,7 @@ out: bcopy(enaddr, ea->arp_sha, sizeof(ea->arp_sha)); } else { la = arplookup(itaddr.s_addr, 0, SIN_PROXY, - m->m_pkthdr.rdomain); + rtable_l2(m->m_pkthdr.rdomain)); if (la == 0) goto out; rt = la->la_rt; diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 13e22342aed..894803507a2 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in.c,v 1.54 2009/06/05 00:05:22 claudio Exp $ */ +/* $OpenBSD: in.c,v 1.55 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */ /* @@ -117,6 +117,7 @@ in_localaddr(struct in_addr in, u_int rdomain) { struct in_ifaddr *ia; + rdomain = rtable_l2(rdomain); if (subnetsarelocal) { TAILQ_FOREACH(ia, &in_ifaddr, ia_list) { if (ia->ia_ifp->if_rdomain != rdomain) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 8e68b43cb5d..0e72496653d 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.106 2009/07/26 12:59:16 thib Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.107 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -200,10 +200,11 @@ in_pcballoc(so, v) inp->inp_seclevel[SL_IPCOMP] = ipsec_ipcomp_default_level; s = splnet(); CIRCLEQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); - LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport, inp->inp_rdomain), - inp, inp_lhash); + LIST_INSERT_HEAD(INPCBLHASH(table, inp->inp_lport, + inp->inp_rdomain), inp, inp_lhash); LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr, inp->inp_fport, - &inp->inp_laddr, inp->inp_lport, inp->inp_rdomain), inp, inp_hash); + &inp->inp_laddr, inp->inp_lport, inp->inp_rdomain), + inp, inp_hash); splx(s); so->so_pcb = inp; inp->inp_hops = -1; @@ -677,6 +678,7 @@ in_pcblookup(struct inpcbtable *table, void *faddrp, u_int fport_arg, void *ladd struct in_addr faddr = *(struct in_addr *)faddrp; struct in_addr laddr = *(struct in_addr *)laddrp; + rdomain = rtable_l2(rdomain); for (inp = LIST_FIRST(INPCBLHASH(table, lport, rdomain)); inp; inp = LIST_NEXT(inp, inp_lhash)) { if (inp->inp_rdomain != rdomain) @@ -924,6 +926,7 @@ in_pcbhashlookup(struct inpcbtable *table, struct in_addr faddr, struct inpcb *inp; u_int16_t fport = fport_arg, lport = lport_arg; + rdomain = rtable_l2(rdomain); head = INPCBHASH(table, &faddr, fport, &laddr, lport, rdomain); LIST_FOREACH(inp, head, inp_hash) { #ifdef INET6 @@ -1012,6 +1015,7 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr, struct inpcb *inp; u_int16_t lport = lport_arg; + rdomain = rtable_l2(rdomain); #if NPF > 0 if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) { struct pf_divert *divert; diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index ac078c83fe5..dabb62d11c3 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_var.h,v 1.12 2009/06/05 00:05:22 claudio Exp $ */ +/* $OpenBSD: in_var.h,v 1.13 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: in_var.h,v 1.16 1996/02/13 23:42:15 christos Exp $ */ /* @@ -96,7 +96,7 @@ do { \ struct in_ifaddr *ia; \ \ for (ia = TAILQ_FIRST(&in_ifaddr); ia != TAILQ_END(&in_ifaddr) && \ - (ia->ia_ifp->if_rdomain != rdomain || \ + (ia->ia_ifp->if_rdomain != rtable_l2(rdomain) || \ ia->ia_addr.sin_addr.s_addr != (addr).s_addr); \ ia = TAILQ_NEXT(ia, ia_list)) \ continue; \ diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 2b4847f20c9..c0cc5dbb89d 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_icmp.c,v 1.84 2009/06/09 11:52:54 sthen Exp $ */ +/* $OpenBSD: ip_icmp.c,v 1.85 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ /* @@ -589,7 +589,6 @@ reflect: goto freeit; #endif rt = NULL; - /* XXX rdomain vs. rtable */ rtredirect(sintosa(&icmpsrc), sintosa(&icmpdst), (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST, sintosa(&icmpgw), (struct rtentry **)&rt, @@ -663,7 +662,7 @@ icmp_reflect(struct mbuf *m) * the address which corresponds to the incoming interface. */ TAILQ_FOREACH(ia, &in_ifaddr, ia_list) { - if (ia->ia_ifp->if_rdomain != m->m_pkthdr.rdomain) + if (ia->ia_ifp->if_rdomain != rtable_l2(m->m_pkthdr.rdomain)) continue; if (t.s_addr == ia->ia_addr.sin_addr.s_addr) break; @@ -686,7 +685,7 @@ icmp_reflect(struct mbuf *m) dst->sin_len = sizeof(*dst); dst->sin_addr = ip->ip_src; - /* keep packet in the original VRF instance */ + /* keep packet in the original virtual instance */ ro.ro_rt = rtalloc1(&ro.ro_dst, 1, m->m_pkthdr.rdomain); if (ro.ro_rt == 0) { diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 9c81e44b583..c481333d176 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.171 2009/08/23 20:06:25 david Exp $ */ +/* $OpenBSD: ip_input.c,v 1.172 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -681,6 +681,7 @@ in_iawithaddr(struct in_addr ina, struct mbuf *m, u_int rdomain) { struct in_ifaddr *ia; + rdomain = rtable_l2(rdomain); TAILQ_FOREACH(ia, &in_ifaddr, ia_list) { if (ia->ia_ifp->if_rdomain != rdomain) continue; @@ -1076,8 +1077,7 @@ ip_dooptions(m) ia = (INA)ifa_ifwithnet((SA)&ipaddr, m->m_pkthdr.rdomain); } else - /* keep packet in the original VRF instance */ - /* XXX rdomain or rtableid ??? */ + /* keep packet in the virtual instance */ ia = ip_rtaddr(ipaddr.sin_addr, m->m_pkthdr.rdomain); if (ia == 0) { @@ -1116,8 +1116,7 @@ ip_dooptions(m) /* * locate outgoing interface; if we're the destination, * use the incoming interface (should be same). - * Again keep the packet inside the VRF instance. - * XXX rdomain vs. rtableid ??? + * Again keep the packet inside the virtual instance. */ if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr, m->m_pkthdr.rdomain)) == 0 && @@ -1276,6 +1275,7 @@ ip_weadvertise(u_int32_t addr, u_int rtableid) return 0; } + rtableid = rtable_l2(rtableid); TAILQ_FOREACH(ifp, &ifnet, if_list) { if (ifp->if_rdomain != rtableid) continue; @@ -1445,8 +1445,6 @@ ip_forward(m, srcrt) } rtableid = m->m_pkthdr.rdomain; - if (m->m_pkthdr.pf.rtableid) - rtableid = m->m_pkthdr.pf.rtableid; sin = satosin(&ipforward_rt.ro_dst); if ((rt = ipforward_rt.ro_rt) == 0 || diff --git a/sys/netinet/ip_ipip.c b/sys/netinet/ip_ipip.c index e37cefa04aa..a2e171b8e16 100644 --- a/sys/netinet/ip_ipip.c +++ b/sys/netinet/ip_ipip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipip.c,v 1.43 2009/06/05 00:05:22 claudio Exp $ */ +/* $OpenBSD: ip_ipip.c,v 1.44 2009/11/03 10:59:04 claudio Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -148,6 +148,7 @@ ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) struct ifaddr *ifa; struct ifqueue *ifq = NULL; struct ip *ipo; + u_int rdomain; #ifdef INET6 struct sockaddr_in6 *sin6; struct ip6_hdr *ip6 = NULL; @@ -287,8 +288,9 @@ ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) if ((m->m_pkthdr.rcvif == NULL || !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) && ipip_allow != 2) { + rdomain = rtable_l2(m->m_pkthdr.rdomain); TAILQ_FOREACH(ifp, &ifnet, if_list) { - if (ifp->if_rdomain != m->m_pkthdr.rdomain) + if (ifp->if_rdomain != rdomain) continue; TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { #ifdef INET diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 22e96f50d57..a839325baf4 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.196 2009/10/28 18:02:00 deraadt Exp $ */ +/* $OpenBSD: ip_output.c,v 1.197 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -1422,7 +1422,8 @@ ip_ctloutput(op, so, level, optname, mp) break; } rtid = *mtod(m, u_int *); - if (!rtable_exists(rtid)) { + /* table must exist and be a domain */ + if (!rtable_exists(rtid) || rtid != rtable_l2(rtid)) { error = EINVAL; break; } diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 0cbaa96a5c2..75af8738b6d 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip.c,v 1.47 2009/06/05 00:05:22 claudio Exp $ */ +/* $OpenBSD: raw_ip.c,v 1.48 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */ /* @@ -132,7 +132,7 @@ rip_input(struct mbuf *m, ...) if (inp->inp_flags & INP_IPV6) continue; #endif - if (inp->inp_rdomain != m->m_pkthdr.rdomain) + if (inp->inp_rdomain != rtable_l2(m->m_pkthdr.rdomain)) continue; if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index b4099c3606c..dea6cdf2923 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.228 2009/08/20 13:25:42 bluhm Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.229 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -3579,7 +3579,7 @@ syn_cache_lookup(struct sockaddr *src, struct sockaddr *dst, continue; if (!bcmp(&sc->sc_src, src, src->sa_len) && !bcmp(&sc->sc_dst, dst, dst->sa_len) && - rdomain == sc->sc_rdomain) { + rtable_l2(rdomain) == rtable_l2(sc->sc_rdomain)) { splx(s); return (sc); } @@ -3625,7 +3625,7 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, s = splsoftnet(); if ((sc = syn_cache_lookup(src, dst, &scp, - m->m_pkthdr.rdomain)) == NULL) { + sotoinpcb(so)->inp_rdomain)) == NULL) { splx(s); return (NULL); } @@ -4001,8 +4001,8 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, * If we do, resend the SYN,ACK. We do not count this * as a retransmission (XXX though maybe we should). */ - if ((sc = syn_cache_lookup(src, dst, &scp, m->m_pkthdr.rdomain)) != - NULL) { + if ((sc = syn_cache_lookup(src, dst, &scp, sotoinpcb(so)->inp_rdomain)) + != NULL) { tcpstat.tcps_sc_dupesyn++; if (ipopts) { /* @@ -4036,7 +4036,7 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, bzero(&sc->sc_timer, sizeof(sc->sc_timer)); bcopy(src, &sc->sc_src, src->sa_len); bcopy(dst, &sc->sc_dst, dst->sa_len); - sc->sc_rdomain = m->m_pkthdr.rdomain; + sc->sc_rdomain = sotoinpcb(so)->inp_rdomain; sc->sc_flags = 0; sc->sc_ipopts = ipopts; sc->sc_irs = th->th_seq; diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 92ac414980b..b5d91f7253b 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.107 2009/08/10 10:13:43 claudio Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.108 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -832,8 +832,7 @@ tcp_ctlinput(cmd, sa, v) * route (traditional PMTUD). */ tp->t_flags &= ~TF_PMTUD_PEND; - /* XXX inherit rdomain from PCB */ - icmp_mtudisc(icp, 0); + icmp_mtudisc(icp, inp->inp_rdomain); } else { /* * Record the information got in the ICMP diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 2284ac40b5e..53f253f9037 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.130 2009/06/08 23:07:08 sthen Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.131 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -440,7 +440,7 @@ udp_input(struct mbuf *m, ...) if (!ip6 && (inp->inp_flags & INP_IPV6)) continue; #endif - if (inp->inp_rdomain != m->m_pkthdr.rdomain) + if (inp->inp_rdomain != rtable_l2(m->m_pkthdr.rdomain)) continue; if (inp->inp_lport != uh->uh_dport) continue; diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index 328ccd9bdf2..af1e525f852 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.44 2009/10/06 21:21:48 claudio Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.45 2009/11/03 10:59:04 claudio Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -223,7 +223,7 @@ reroute: #endif /* IPSEC */ #if NPF > 0 - rtableid = m->m_pkthdr.pf.rtableid; + rtableid = m->m_pkthdr.rdomain; #endif /* diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index a0492b1a9ae..c1c778df180 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.91 2009/05/18 20:37:13 bluhm Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.92 2009/11/03 10:59:04 claudio Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -440,7 +440,7 @@ ip6_input(struct mbuf *m) } #if NPF > 0 - rtableid = m->m_pkthdr.pf.rtableid; + rtableid = m->m_pkthdr.rdomain; #endif /* diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 087927aebf1..bf79b4c504d 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mbuf.h,v 1.138 2009/10/06 21:21:48 claudio Exp $ */ +/* $OpenBSD: mbuf.h,v 1.139 2009/11/03 10:59:04 claudio Exp $ */ /* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */ /* @@ -79,7 +79,6 @@ struct pkthdr_pf { void *hdr; /* saved hdr pos in mbuf, for ECN */ void *statekey; /* pf stackside statekey */ u_int32_t qid; /* queue id */ - u_int rtableid; /* alternate routing table id */ u_int16_t tag; /* tag id */ u_int8_t flags; u_int8_t routed; |