diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 14:06:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 14:06:58 -0700 |
commit | a52cefc80fc92981592c688d1c8067442afe4cec (patch) | |
tree | ad119b5a4f5e4a257779c0ef324b5c9354c915f1 /net/ipv4/netfilter.c | |
parent | fba956c46a72f9e7503fd464ffee43c632307e31 (diff) | |
parent | 4acad72ded8e3f0211bd2a762e23c28229c61a51 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (42 commits)
[IPV6]: Consolidate the ip6_pol_route_(input|output) pair
[TCP]: Make snd_cwnd_cnt 32-bit
[TCP]: Update the /proc/net/tcp documentation
[NETNS]: Don't panic on creating the namespace's loopback
[NEIGH]: Ensure that pneigh_lookup is protected with RTNL
[INET]: kmalloc+memset -> kzalloc in frag_alloc_queue
[ISDN]: Fix compile with CONFIG_ISDN_X25 disabled.
[IPV6]: Replace sk_buff ** with sk_buff * in input handlers
[SELINUX]: Update for netfilter ->hook() arg changes.
[INET]: Consolidate the xxx_put
[INET]: Small cleanup for xxx_put after evictor consolidation
[INET]: Consolidate the xxx_evictor
[INET]: Consolidate the xxx_frag_destroy
[INET]: Consolidate xxx_the secret_rebuild
[INET]: Consolidate the xxx_frag_kill
[INET]: Collect common frag sysctl variables together
[INET]: Collect frag queues management objects together
[INET]: Move common fields from frag_queues in one place.
[TG3]: Fix performance regression on 5705.
[ISDN]: Remove local copy of device name to make sure renames work.
...
Diffstat (limited to 'net/ipv4/netfilter.c')
-rw-r--r-- | net/ipv4/netfilter.c | 77 |
1 files changed, 31 insertions, 46 deletions
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index b44192924f9..5539debf497 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -3,14 +3,15 @@ #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <linux/ip.h> +#include <linux/skbuff.h> #include <net/route.h> #include <net/xfrm.h> #include <net/ip.h> /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ -int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type) +int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) { - const struct iphdr *iph = ip_hdr(*pskb); + const struct iphdr *iph = ip_hdr(skb); struct rtable *rt; struct flowi fl = {}; struct dst_entry *odst; @@ -29,14 +30,14 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type) if (type == RTN_LOCAL) fl.nl_u.ip4_u.saddr = iph->saddr; fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); - fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if : 0; - fl.mark = (*pskb)->mark; + fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; + fl.mark = skb->mark; if (ip_route_output_key(&rt, &fl) != 0) return -1; /* Drop old route. */ - dst_release((*pskb)->dst); - (*pskb)->dst = &rt->u.dst; + dst_release(skb->dst); + skb->dst = &rt->u.dst; } else { /* non-local src, find valid iif to satisfy * rp-filter when calling ip_route_input. */ @@ -44,8 +45,8 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type) if (ip_route_output_key(&rt, &fl) != 0) return -1; - odst = (*pskb)->dst; - if (ip_route_input(*pskb, iph->daddr, iph->saddr, + odst = skb->dst; + if (ip_route_input(skb, iph->daddr, iph->saddr, RT_TOS(iph->tos), rt->u.dst.dev) != 0) { dst_release(&rt->u.dst); return -1; @@ -54,70 +55,54 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type) dst_release(odst); } - if ((*pskb)->dst->error) + if (skb->dst->error) return -1; #ifdef CONFIG_XFRM - if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) && - xfrm_decode_session(*pskb, &fl, AF_INET) == 0) - if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0)) + if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && + xfrm_decode_session(skb, &fl, AF_INET) == 0) + if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0)) return -1; #endif /* Change in oif may mean change in hh_len. */ - hh_len = (*pskb)->dst->dev->hard_header_len; - if (skb_headroom(*pskb) < hh_len) { - struct sk_buff *nskb; - - 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; - } + hh_len = skb->dst->dev->hard_header_len; + if (skb_headroom(skb) < hh_len && + pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) + return -1; return 0; } EXPORT_SYMBOL(ip_route_me_harder); #ifdef CONFIG_XFRM -int ip_xfrm_me_harder(struct sk_buff **pskb) +int ip_xfrm_me_harder(struct sk_buff *skb) { struct flowi fl; unsigned int hh_len; struct dst_entry *dst; - if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) + if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) return 0; - if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0) + if (xfrm_decode_session(skb, &fl, AF_INET) < 0) return -1; - dst = (*pskb)->dst; + dst = skb->dst; if (dst->xfrm) dst = ((struct xfrm_dst *)dst)->route; dst_hold(dst); - if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0) + if (xfrm_lookup(&dst, &fl, skb->sk, 0) < 0) return -1; - dst_release((*pskb)->dst); - (*pskb)->dst = dst; + dst_release(skb->dst); + skb->dst = dst; /* Change in oif may mean change in hh_len. */ - hh_len = (*pskb)->dst->dev->hard_header_len; - if (skb_headroom(*pskb) < hh_len) { - struct sk_buff *nskb; - - 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; - } + hh_len = skb->dst->dev->hard_header_len; + if (skb_headroom(skb) < hh_len && + pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) + return -1; return 0; } EXPORT_SYMBOL(ip_xfrm_me_harder); @@ -150,17 +135,17 @@ static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info) } } -static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info) +static int nf_ip_reroute(struct sk_buff *skb, const struct nf_info *info) { const struct ip_rt_info *rt_info = nf_info_reroute(info); if (info->hook == NF_IP_LOCAL_OUT) { - const struct iphdr *iph = ip_hdr(*pskb); + const struct iphdr *iph = ip_hdr(skb); if (!(iph->tos == rt_info->tos && iph->daddr == rt_info->daddr && iph->saddr == rt_info->saddr)) - return ip_route_me_harder(pskb, RTN_UNSPEC); + return ip_route_me_harder(skb, RTN_UNSPEC); } return 0; } |