* [PATCH 3/3] policy routing fixes
@ 2003-04-22 11:01 Patrick McHardy
2003-04-22 23:11 ` Harald Welte
0 siblings, 1 reply; 3+ messages in thread
From: Patrick McHardy @ 2003-04-22 11:01 UTC (permalink / raw)
To: Harald Welte; +Cc: Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 660 bytes --]
This patch corrects routing in REJECT, MIRROR and ip_route_me_harder.
Currently netfilter does not obey rules like "from x.x.x.x/x lookup x"
because
it src=0 when doing routing lookups for non-local addresses. With this
patch,
netfilter uses ip_route_input if source if non-local. Also
route_me_harder doesn't
return the exact error anymore, noone seemed to care about it. i also
removed
the printks, i think a missing route is nothing so abnormal it justifies
confusing
the user, and almost everyone i know has asked me at least once "what
the hell
is ip_route_me_harder" ;). This patch is incremental to the two i sent
before.
Best regards,
Patrick
[-- Attachment #2: 03-netfilter-policy-routing.diff --]
[-- Type: text/plain, Size: 6973 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1103 -> 1.1104
# net/ipv4/netfilter/ipt_REJECT.c 1.11 -> 1.12
# net/core/netfilter.c 1.7 -> 1.8
# net/ipv4/netfilter/ipt_MIRROR.c 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/04/22 kaber@trash.net 1.1104
# [NETFILTER] make netfilter policy-routing aware
# --------------------------------------------
#
diff -Nru a/net/core/netfilter.c b/net/core/netfilter.c
--- a/net/core/netfilter.c Tue Apr 22 01:07:31 2003
+++ b/net/core/netfilter.c Tue Apr 22 01:07:31 2003
@@ -563,64 +563,62 @@
{
struct iphdr *iph = (*pskb)->nh.iph;
struct rtable *rt;
- struct rt_key key = { dst:iph->daddr,
- src:iph->saddr,
- oif:(*pskb)->sk ? (*pskb)->sk->bound_dev_if : 0,
- tos:RT_TOS(iph->tos)|RTO_CONN,
+ struct rt_key key = {};
+ struct dst_entry *odst;
+ unsigned int hh_len;
+
+ /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
+ * packets with foreign saddr to be appear on the NF_IP_LOCAL_OUT hook.
+ */
+ if (inet_addr_type(iph->saddr) == RTN_LOCAL) {
+ key.dst = iph->daddr;
+ key.src = iph->saddr;
+ key.oif = (*pskb)->sk ? (*pskb)->sk->bound_dev_if : 0;
+ key.tos = RT_TOS(iph->tos);
#ifdef CONFIG_IP_ROUTE_FWMARK
- fwmark:(*pskb)->nfmark
+ key.fwmark = (*pskb)->nfmark;
#endif
- };
- struct net_device *dev_src = NULL;
- int err;
-
- /* accomodate ip_route_output_slow(), which expects the key src to be
- 0 or a local address; however some non-standard hacks like
- ipt_REJECT.c:send_reset() can cause packets with foreign
- saddr to be appear on the NF_IP_LOCAL_OUT hook -MB */
- if(key.src && !(dev_src = ip_dev_find(key.src)))
- key.src = 0;
-
- if ((err=ip_route_output_key(&rt, &key)) != 0) {
- printk("route_me_harder: ip_route_output_key(dst=%u.%u.%u.%u, src=%u.%u.%u.%u, oif=%d, tos=0x%x, fwmark=0x%lx) error %d\n",
- NIPQUAD(iph->daddr), NIPQUAD(iph->saddr),
- (*pskb)->sk ? (*pskb)->sk->bound_dev_if : 0,
- RT_TOS(iph->tos)|RTO_CONN,
-#ifdef CONFIG_IP_ROUTE_FWMARK
- (*pskb)->nfmark,
-#else
- 0UL,
-#endif
- err);
- goto out;
- }
-
- /* Drop old route. */
- dst_release((*pskb)->dst);
+ if (ip_route_output_key(&rt, &key) != 0)
+ return -1;
- (*pskb)->dst = &rt->u.dst;
+ /* Drop old route. */
+ dst_release((*pskb)->dst);
+ (*pskb)->dst = &rt->u.dst;
+ } else {
+ /* non-local src, find valid iif to satisfy
+ * rp-filter when calling ip_route_input. */
+ key.dst = iph->saddr;
+ if (ip_route_output_key(&rt, &key) != 0)
+ return -1;
+
+ odst = (*pskb)->dst;
+ if (ip_route_input(*pskb, iph->daddr, iph->saddr,
+ RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
+ dst_release(&rt->u.dst);
+ return -1;
+ }
+ dst_release(&rt->u.dst);
+ dst_release(odst);
+ }
+
+ if ((*pskb)->dst->error)
+ return -1;
/* Change in oif may mean change in hh_len. */
- if (skb_headroom(*pskb) < (*pskb)->dst->dev->hard_header_len) {
+ hh_len = (*pskb)->dst->dev->hard_header_len;
+ if (skb_headroom(*pskb) < hh_len) {
struct sk_buff *nskb;
- nskb = skb_realloc_headroom(*pskb,
- (*pskb)->dst->dev->hard_header_len);
- if (!nskb) {
- err = -ENOMEM;
- goto out;
- }
+ nskb = skb_realloc_headroom(*pskb, hh_len);
+ if (!nskb)
+ return -1;
if ((*pskb)->sk)
skb_set_owner_w(nskb, (*pskb)->sk);
kfree_skb(*pskb);
*pskb = nskb;
}
-out:
- if (dev_src)
- dev_put(dev_src);
-
- return err;
+ return 0;
}
#endif /*CONFIG_INET*/
diff -Nru a/net/ipv4/netfilter/ipt_MIRROR.c b/net/ipv4/netfilter/ipt_MIRROR.c
--- a/net/ipv4/netfilter/ipt_MIRROR.c Tue Apr 22 01:07:31 2003
+++ b/net/ipv4/netfilter/ipt_MIRROR.c Tue Apr 22 01:07:31 2003
@@ -40,15 +40,42 @@
#define DEBUGP(format, args...)
#endif
-static inline struct rtable *route_mirror(struct sk_buff *skb)
+static inline struct rtable *route_mirror(struct sk_buff *skb, int local)
{
struct iphdr *iph = skb->nh.iph;
+ struct dst_entry *odst;
+ struct rt_key key = {};
struct rtable *rt;
- /* Backwards */
- if (ip_route_output(&rt, iph->saddr, iph->daddr,
- RT_TOS(iph->tos), 0))
- return NULL;
+ if (local) {
+ key.dst = iph->saddr;
+ key.src = iph->daddr;
+ key.tos = RT_TOS(iph->tos);
+
+ if (ip_route_output_key(&rt, &key) != 0)
+ return NULL;
+ } else {
+ /* non-local src, find valid iif to satisfy
+ * rp-filter when calling ip_route_input. */
+ key.dst = iph->daddr;
+ if (ip_route_output_key(&rt, &key) != 0)
+ return NULL;
+
+ odst = skb->dst;
+ if (ip_route_input(skb, iph->saddr, iph->daddr,
+ RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
+ dst_release(&rt->u.dst);
+ return NULL;
+ }
+ dst_release(&rt->u.dst);
+ rt = (struct rtable *)skb->dst;
+ skb->dst = odst;
+ }
+
+ if (rt->u.dst.error) {
+ dst_release(&rt->u.dst);
+ rt = NULL;
+ }
return rt;
}
@@ -111,7 +138,7 @@
ip_decrease_ttl(iph);
}
- if ((rt = route_mirror(*pskb)) == NULL)
+ if ((rt = route_mirror(*pskb, hooknum == NF_IP_LOCAL_IN)) == NULL)
return NF_DROP;
hh_len = (rt->u.dst.dev->hard_header_len + 15) & ~15;
diff -Nru a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
--- a/net/ipv4/netfilter/ipt_REJECT.c Tue Apr 22 01:07:31 2003
+++ b/net/ipv4/netfilter/ipt_REJECT.c Tue Apr 22 01:07:31 2003
@@ -33,6 +33,46 @@
attach(new_skb, nfct);
}
+static inline struct rtable *route_reverse(struct sk_buff *skb, int local)
+{
+ struct iphdr *iph = skb->nh.iph;
+ struct dst_entry *odst;
+ struct rt_key key = {};
+ struct rtable *rt;
+
+ if (local) {
+ key.dst = iph->saddr;
+ key.src = iph->daddr;
+ key.tos = RT_TOS(iph->tos);
+
+ if (ip_route_output_key(&rt, &key) != 0)
+ return NULL;
+ } else {
+ /* non-local src, find valid iif to satisfy
+ * rp-filter when calling ip_route_input. */
+ key.dst = iph->daddr;
+ if (ip_route_output_key(&rt, &key) != 0)
+ return NULL;
+
+ odst = skb->dst;
+ if (ip_route_input(skb, iph->saddr, iph->daddr,
+ RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
+ dst_release(&rt->u.dst);
+ return NULL;
+ }
+ dst_release(&rt->u.dst);
+ rt = (struct rtable *)skb->dst;
+ skb->dst = odst;
+ }
+
+ if (rt->u.dst.error) {
+ dst_release(&rt->u.dst);
+ rt = NULL;
+ }
+
+ return rt;
+}
+
/* Send RST reply */
static void send_reset(struct sk_buff *oldskb, int local)
{
@@ -63,10 +103,7 @@
csum_partial((char *)otcph, otcplen, 0)) != 0)
return;
- /* Routing: if not headed for us, route won't like source */
- if (ip_route_output(&rt, oldskb->nh.iph->saddr,
- local ? oldskb->nh.iph->daddr : 0,
- RT_TOS(oldskb->nh.iph->tos), 0) != 0)
+ if ((rt = route_reverse(oldskb, local)) == NULL)
return;
hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH 3/3] policy routing fixes
2003-04-22 11:01 [PATCH 3/3] policy routing fixes Patrick McHardy
@ 2003-04-22 23:11 ` Harald Welte
2003-04-30 18:19 ` Patrick McHardy
0 siblings, 1 reply; 3+ messages in thread
From: Harald Welte @ 2003-04-22 23:11 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 700 bytes --]
On Tue, Apr 22, 2003 at 01:01:05PM +0200, Patrick McHardy wrote:
> This patch corrects routing in REJECT, MIRROR and ip_route_me_harder.
thanks, I will put this into 'pending'. The change is intrusive enough
to have this fix in patch-o-matic for a while before submitting it to
the kernel.
> Best regards,
> Patrick
--
- Harald Welte <laforge@netfilter.org> http://www.netfilter.org/
============================================================================
"Fragmentation is like classful addressing -- an interesting early
architectural error that shows how much experimentation was going
on while IP was being designed." -- Paul Vixie
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 3/3] policy routing fixes
2003-04-22 23:11 ` Harald Welte
@ 2003-04-30 18:19 ` Patrick McHardy
0 siblings, 0 replies; 3+ messages in thread
From: Patrick McHardy @ 2003-04-30 18:19 UTC (permalink / raw)
To: Harald Welte; +Cc: Netfilter Development Mailinglist
Harald Welte wrote:
>thanks, I will put this into 'pending'. The change is intrusive enough
>to have this fix in patch-o-matic for a while before submitting it to
>the kernel.
>
Hi Harald,
i just wanted to make sure you didn't forgot. I see the first patch in
CVS and
some new stuff, but the second and third one are still missing ..
Best regards,
Patrick
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-04-30 18:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-22 11:01 [PATCH 3/3] policy routing fixes Patrick McHardy
2003-04-22 23:11 ` Harald Welte
2003-04-30 18:19 ` Patrick McHardy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.