diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-11-03 10:59:05 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-11-03 10:59:05 +0000 |
commit | aa799beefd4c8fce27ceb0fd6ed143fb40859be2 (patch) | |
tree | 6e6ca07fa0c49af532b084c80a89d926a9a3bd0f /sys/net/if.c | |
parent | e5888cd56b381838e11260d5af85260b96ce1f4e (diff) |
rtables are stacked on rdomains (it is possible to have multiple routing
tables on top of a rdomain) but until now our code was a crazy mix so that
it was impossible to correctly use rtables in that case. Additionally pf(4)
only knows about rtables and not about rdomains. This is especially bad when
tracking (possibly conflicting) states in various domains.
This diff fixes all or most of these issues. It adds a lookup function to
get the rdomain id based on a rtable id. Makes pf understand rdomains and
allows pf to move packets between rdomains (it is similar to NAT).
Because pf states now track the rdomain id as well it is necessary to modify
the pfsync wire format. So old and new systems will not sync up.
A lot of help by dlg@, tested by sthen@, jsg@ and probably more
OK dlg@, mpf@, deraadt@
Diffstat (limited to 'sys/net/if.c')
-rw-r--r-- | sys/net/if.c | 11 |
1 files changed, 10 insertions, 1 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; |