diff options
author | Jesper Dangaard Brouer <brouer@redhat.com> | 2012-09-26 08:07:33 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2012-09-27 22:37:16 -0400 |
commit | 92eec78d25aee6bbc9bd295f51c022ddfa80cdd9 (patch) | |
tree | 78f165d30968b9f131be5c07363f63a756ca5aef /net/netfilter | |
parent | d4383f04d145cce8b855c463f40020639ef83ea0 (diff) |
ipvs: SIP fragment handling
Use the nfct_reasm SKB if available.
Based on part of a patch from: Hans Schillstrom
I have left Hans'es comment in the patch (marked /HS)
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
[ horms@verge.net.au: Fix comment style ]
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_pe_sip.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c index ee4e2e3cc086..12475ef88daf 100644 --- a/net/netfilter/ipvs/ip_vs_pe_sip.c +++ b/net/netfilter/ipvs/ip_vs_pe_sip.c | |||
@@ -68,6 +68,7 @@ static int get_callid(const char *dptr, unsigned int dataoff, | |||
68 | static int | 68 | static int |
69 | ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb) | 69 | ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb) |
70 | { | 70 | { |
71 | struct sk_buff *reasm = skb_nfct_reasm(skb); | ||
71 | struct ip_vs_iphdr iph; | 72 | struct ip_vs_iphdr iph; |
72 | unsigned int dataoff, datalen, matchoff, matchlen; | 73 | unsigned int dataoff, datalen, matchoff, matchlen; |
73 | const char *dptr; | 74 | const char *dptr; |
@@ -78,13 +79,20 @@ ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb) | |||
78 | /* Only useful with UDP */ | 79 | /* Only useful with UDP */ |
79 | if (iph.protocol != IPPROTO_UDP) | 80 | if (iph.protocol != IPPROTO_UDP) |
80 | return -EINVAL; | 81 | return -EINVAL; |
82 | /* todo: IPv6 fragments: | ||
83 | * I think this only should be done for the first fragment. /HS | ||
84 | */ | ||
85 | if (reasm) { | ||
86 | skb = reasm; | ||
87 | dataoff = iph.thoff_reasm + sizeof(struct udphdr); | ||
88 | } else | ||
89 | dataoff = iph.len + sizeof(struct udphdr); | ||
81 | 90 | ||
82 | /* No Data ? */ | ||
83 | dataoff = iph.len + sizeof(struct udphdr); | ||
84 | if (dataoff >= skb->len) | 91 | if (dataoff >= skb->len) |
85 | return -EINVAL; | 92 | return -EINVAL; |
86 | 93 | /* todo: Check if this will mess-up the reasm skb !!! /HS */ | |
87 | if ((retc=skb_linearize(skb)) < 0) | 94 | retc = skb_linearize(skb); |
95 | if (retc < 0) | ||
88 | return retc; | 96 | return retc; |
89 | dptr = skb->data + dataoff; | 97 | dptr = skb->data + dataoff; |
90 | datalen = skb->len - dataoff; | 98 | datalen = skb->len - dataoff; |