summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c11
-rw-r--r--sys/net/if_atmsubr.c10
-rw-r--r--sys/net/if_ethersubr.c13
-rw-r--r--sys/net/if_fddisubr.c10
-rw-r--r--sys/net/if_pfsync.c89
-rw-r--r--sys/net/if_pfsync.h34
-rw-r--r--sys/net/if_ppp.c10
-rw-r--r--sys/net/if_sl.c11
-rw-r--r--sys/net/if_spppsubr.c11
-rw-r--r--sys/net/pf.c149
-rw-r--r--sys/net/pf_ioctl.c9
-rw-r--r--sys/net/pf_lb.c11
-rw-r--r--sys/net/pfvar.h20
-rw-r--r--sys/net/route.c57
-rw-r--r--sys/net/route.h4
-rw-r--r--sys/net/rtsock.c15
16 files changed, 296 insertions, 168 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;