summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2006-11-27 12:27:46 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2006-11-27 12:27:46 +0000
commit840004135aa5ae51a122a1f689d6726b5c2e45ff (patch)
tree09b4562be58e3e35a3863d55f2e0721d902e2549
parent260cd8ce709a413c6a5adab22ec07153aa64354a (diff)
make use of multiple routing tables.
hook up looking up routes in alternate tables to the packet forwarding path. alternate routing tables are mintained with route(8), table selection via pf. mostly hacked on a train ride with ryan some time ago, ok mcbride claudio
-rw-r--r--sys/netinet/ip_input.c19
-rw-r--r--sys/netinet6/ip6_forward.c18
-rw-r--r--sys/netinet6/ip6_input.c17
3 files changed, 43 insertions, 11 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 366fb593b16..d49d43e8687 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.144 2006/10/11 09:29:20 henning Exp $ */
+/* $OpenBSD: ip_input.c,v 1.145 2006/11/27 12:27:45 henning Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -239,6 +239,7 @@ ip_init()
struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
struct route ipforward_rt;
+int ipforward_rtableid;
void
ipintr()
@@ -1407,9 +1408,12 @@ ip_forward(m, srcrt)
struct ip *ip = mtod(m, struct ip *);
struct sockaddr_in *sin;
struct rtentry *rt;
- int error, type = 0, code = 0, destmtu = 0;
+ int error, type = 0, code = 0, destmtu = 0, rtableid = 0;
struct mbuf *mcopy;
n_long dest;
+#if NPF > 0
+ struct pf_mtag *pft;
+#endif
dest = 0;
#ifdef DIAGNOSTIC
@@ -1427,9 +1431,15 @@ ip_forward(m, srcrt)
return;
}
+#if NPF > 0
+ if ((pft = pf_find_mtag(m)) != NULL)
+ rtableid = pft->rtableid;
+#endif
+
sin = satosin(&ipforward_rt.ro_dst);
if ((rt = ipforward_rt.ro_rt) == 0 ||
- ip->ip_dst.s_addr != sin->sin_addr.s_addr) {
+ ip->ip_dst.s_addr != sin->sin_addr.s_addr ||
+ rtableid != ipforward_rtableid) {
if (ipforward_rt.ro_rt) {
RTFREE(ipforward_rt.ro_rt);
ipforward_rt.ro_rt = 0;
@@ -1438,11 +1448,12 @@ ip_forward(m, srcrt)
sin->sin_len = sizeof(*sin);
sin->sin_addr = ip->ip_dst;
- rtalloc_mpath(&ipforward_rt, &ip->ip_src.s_addr, 0);
+ rtalloc_mpath(&ipforward_rt, &ip->ip_src.s_addr, rtableid);
if (ipforward_rt.ro_rt == 0) {
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
return;
}
+ ipforward_rtableid = rtableid;
rt = ipforward_rt.ro_rt;
}
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index 4b3ec716eef..7448d6f3f59 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_forward.c,v 1.36 2006/11/17 01:11:23 itojun Exp $ */
+/* $OpenBSD: ip6_forward.c,v 1.37 2006/11/27 12:27:45 henning Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/*
@@ -69,6 +69,7 @@
#endif
struct route_in6 ip6_forward_rt;
+int ip6_forward_rtableid;
/*
* Forward a packet. If some error occurs return the sender
@@ -103,6 +104,10 @@ ip6_forward(m, srcrt)
struct tdb *tdb;
int s;
#endif /* IPSEC */
+#if NPF > 0
+ struct pf_mtag *pft;
+#endif
+ int rtableid = 0;
/*
* Do not forward packets to multicast destination (should be handled
@@ -214,6 +219,11 @@ ip6_forward(m, srcrt)
done_spd:
#endif /* IPSEC */
+#if NPF > 0
+ if ((pft = pf_find_mtag(m)) != NULL)
+ rtableid = pft->rtableid;
+#endif
+
/*
* Save at most ICMPV6_PLD_MAXLEN (= the min IPv6 MTU -
* size of IPv6 + ICMPv6 headers) bytes of the packet in case
@@ -231,14 +241,16 @@ ip6_forward(m, srcrt)
* ip6_forward_rt.ro_dst.sin6_addr is equal to ip6->ip6_dst
*/
if (ip6_forward_rt.ro_rt == 0 ||
- (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) == 0) {
+ (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) == 0 ||
+ ip6_forward_rtableid != rtableid) {
if (ip6_forward_rt.ro_rt) {
RTFREE(ip6_forward_rt.ro_rt);
ip6_forward_rt.ro_rt = 0;
}
/* this probably fails but give it a try again */
rtalloc_mpath((struct route *)&ip6_forward_rt,
- &ip6->ip6_src.s6_addr32[0], 0);
+ &ip6->ip6_src.s6_addr32[0], rtableid);
+ ip6_forward_rtableid = rtableid;
}
if (ip6_forward_rt.ro_rt == 0) {
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 3f7b5dc09be..67b01130451 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.69 2006/11/17 01:11:23 itojun Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.70 2006/11/27 12:27:45 henning Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -185,6 +185,7 @@ ip6intr()
}
extern struct route_in6 ip6_forward_rt;
+extern int ip6_forward_rtableid;
void
ip6_input(m)
@@ -198,8 +199,9 @@ ip6_input(m)
struct ifnet *deliverifp = NULL;
#if NPF > 0
struct in6_addr odst;
+ struct pf_mtag *pft;
#endif
- int srcrt = 0;
+ int srcrt = 0, rtableid = 0;
/*
* mbuf statistics by kazu
@@ -390,13 +392,19 @@ ip6_input(m)
goto hbhcheck;
}
+#if NPF > 0
+ if ((pft = pf_find_mtag(m)) != NULL)
+ rtableid = pft->rtableid;
+#endif
+
/*
* Unicast check
*/
if (ip6_forward_rt.ro_rt != NULL &&
(ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 &&
IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
- &ip6_forward_rt.ro_dst.sin6_addr))
+ &ip6_forward_rt.ro_dst.sin6_addr) &&
+ rtableid == ip6_forward_rtableid)
ip6stat.ip6s_forward_cachehit++;
else {
if (ip6_forward_rt.ro_rt) {
@@ -410,9 +418,10 @@ ip6_input(m)
ip6_forward_rt.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
ip6_forward_rt.ro_dst.sin6_family = AF_INET6;
ip6_forward_rt.ro_dst.sin6_addr = ip6->ip6_dst;
+ ip6_forward_rtableid = rtableid;
rtalloc_mpath((struct route *)&ip6_forward_rt,
- &ip6->ip6_src.s6_addr32[0], 0);
+ &ip6->ip6_src.s6_addr32[0], rtableid);
}
#define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key))