Messages in this thread Patch in this message | | | Date | Fri, 25 Jul 2003 22:50:48 +0200 | From | Harald Welte <> | Subject | [PATCH 2.4] iptables MIRROR target fixes |
| |
Hi Dave!
This is the first of a set of bugfixes (all tested against 2.4.22-pre7). You might need to apply them incrementally (didn't test it in a different order). You will receive 2.6 merges of those patches soon.
Author: Patrick McHardy <kaber@trash.net>
This patch fixes various problems with the experimental iptables MIRROR target:
- check TTL before rewriting so icmp_send gets clean packet - skb_copy_expand(skb) for tcpdump and asymmetric routing - inline some function - remove unneccessary 'struct in_device' declaration - remove RTO_CONN
Please apply,
diff -Nru a/net/ipv4/netfilter/ipt_MIRROR.c b/net/ipv4/netfilter/ipt_MIRROR.c --- a/net/ipv4/netfilter/ipt_MIRROR.c Mon Apr 21 21:26:42 2003 +++ b/net/ipv4/netfilter/ipt_MIRROR.c Mon Apr 21 21:26:42 2003 @@ -32,7 +32,6 @@ #include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netdevice.h> #include <linux/route.h> -struct in_device; #include <net/route.h> #if 0 @@ -41,31 +40,20 @@ #define DEBUGP(format, args...) #endif -static int route_mirror(struct sk_buff *skb) +static inline struct rtable *route_mirror(struct sk_buff *skb) { struct iphdr *iph = skb->nh.iph; struct rtable *rt; /* Backwards */ if (ip_route_output(&rt, iph->saddr, iph->daddr, - RT_TOS(iph->tos) | RTO_CONN, - 0)) { - return 0; - } + RT_TOS(iph->tos), 0)) + return NULL; - /* check if the interface we are leaving by is the same as the - one we arrived on */ - if (skb->dev == rt->u.dst.dev) { - /* Drop old route. */ - dst_release(skb->dst); - skb->dst = &rt->u.dst; - return 1; - } - return 0; + return rt; } -static void -ip_rewrite(struct sk_buff *skb) +static inline void ip_rewrite(struct sk_buff *skb) { struct iphdr *iph = skb->nh.iph; u32 odaddr = iph->saddr; @@ -105,32 +93,48 @@ const void *targinfo, void *userinfo) { - if (((*pskb)->dst != NULL) && - route_mirror(*pskb)) { - - ip_rewrite(*pskb); + struct rtable *rt; + struct sk_buff *nskb; + unsigned int hh_len; - /* If we are not at FORWARD hook (INPUT/PREROUTING), - * the TTL isn't decreased by the IP stack */ - if (hooknum != NF_IP_FORWARD) { - struct iphdr *iph = (*pskb)->nh.iph; - if (iph->ttl <= 1) { - /* this will traverse normal stack, and - * thus call conntrack on the icmp packet */ - icmp_send(*pskb, ICMP_TIME_EXCEEDED, - ICMP_EXC_TTL, 0); - return NF_DROP; - } - ip_decrease_ttl(iph); + /* If we are not at FORWARD hook (INPUT/PREROUTING), + * the TTL isn't decreased by the IP stack */ + if (hooknum != NF_IP_FORWARD) { + struct iphdr *iph = (*pskb)->nh.iph; + if (iph->ttl <= 1) { + /* this will traverse normal stack, and + * thus call conntrack on the icmp packet */ + icmp_send(*pskb, ICMP_TIME_EXCEEDED, + ICMP_EXC_TTL, 0); + return NF_DROP; } + ip_decrease_ttl(iph); + } - /* Don't let conntrack code see this packet: - it will think we are starting a new - connection! --RR */ - ip_direct_send(*pskb); + if ((rt = route_mirror(*pskb)) == NULL) + return NF_DROP; - return NF_STOLEN; + hh_len = (rt->u.dst.dev->hard_header_len + 15) & ~15; + + /* Copy skb (even if skb is about to be dropped, we can't just + * clone it because there may be other things, such as tcpdump, + * interested in it). We also need to expand headroom in case + * hh_len of incoming interface < hh_len of outgoing interface */ + nskb = skb_copy_expand(*pskb, hh_len, skb_tailroom(*pskb), GFP_ATOMIC); + if (nskb == NULL) { + dst_release(&rt->u.dst); + return NF_DROP; } + + dst_release(nskb->dst); + nskb->dst = &rt->u.dst; + + ip_rewrite(nskb); + /* Don't let conntrack code see this packet: + it will think we are starting a new + connection! --RR */ + ip_direct_send(nskb); + return NF_DROP; } -- - 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[unhandled content-type:application/pgp-signature] | |