diff options
author | Julius Volz <juliusv@google.com> | 2008-09-02 09:55:40 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2008-09-04 21:17:06 -0400 |
commit | 51ef348b14183789e4cb3444d05ce83b1b69d8fb (patch) | |
tree | e14e54ce262073b63a3343c764b8174b1041b577 /net/ipv4/ipvs/ip_vs_proto_tcp.c | |
parent | b14198f6c1bea1687d20723db35d8effecd9d899 (diff) |
IPVS: Add 'af' args to protocol handler functions
Add 'af' arguments to conn_schedule(), conn_in_get(), conn_out_get() and
csum_check() function pointers in struct ip_vs_protocol. Extend the
respective functions for TCP, UDP, AH and ESP and adjust the callers.
The changes in the callers need to be somewhat extensive, since they now
need to pass a filled out struct ip_vs_iphdr * to the modified functions
instead of a struct iphdr *.
Signed-off-by: Julius Volz <juliusv@google.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/ipv4/ipvs/ip_vs_proto_tcp.c')
-rw-r--r-- | net/ipv4/ipvs/ip_vs_proto_tcp.c | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index fe93c9e6ff6..9211afa8f30 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c | |||
@@ -25,8 +25,9 @@ | |||
25 | 25 | ||
26 | 26 | ||
27 | static struct ip_vs_conn * | 27 | static struct ip_vs_conn * |
28 | tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, | 28 | tcp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, |
29 | const struct iphdr *iph, unsigned int proto_off, int inverse) | 29 | const struct ip_vs_iphdr *iph, unsigned int proto_off, |
30 | int inverse) | ||
30 | { | 31 | { |
31 | __be16 _ports[2], *pptr; | 32 | __be16 _ports[2], *pptr; |
32 | 33 | ||
@@ -36,18 +37,19 @@ tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
36 | 37 | ||
37 | if (likely(!inverse)) { | 38 | if (likely(!inverse)) { |
38 | return ip_vs_conn_in_get(iph->protocol, | 39 | return ip_vs_conn_in_get(iph->protocol, |
39 | iph->saddr, pptr[0], | 40 | iph->saddr.ip, pptr[0], |
40 | iph->daddr, pptr[1]); | 41 | iph->daddr.ip, pptr[1]); |
41 | } else { | 42 | } else { |
42 | return ip_vs_conn_in_get(iph->protocol, | 43 | return ip_vs_conn_in_get(iph->protocol, |
43 | iph->daddr, pptr[1], | 44 | iph->daddr.ip, pptr[1], |
44 | iph->saddr, pptr[0]); | 45 | iph->saddr.ip, pptr[0]); |
45 | } | 46 | } |
46 | } | 47 | } |
47 | 48 | ||
48 | static struct ip_vs_conn * | 49 | static struct ip_vs_conn * |
49 | tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, | 50 | tcp_conn_out_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, |
50 | const struct iphdr *iph, unsigned int proto_off, int inverse) | 51 | const struct ip_vs_iphdr *iph, unsigned int proto_off, |
52 | int inverse) | ||
51 | { | 53 | { |
52 | __be16 _ports[2], *pptr; | 54 | __be16 _ports[2], *pptr; |
53 | 55 | ||
@@ -57,26 +59,25 @@ tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
57 | 59 | ||
58 | if (likely(!inverse)) { | 60 | if (likely(!inverse)) { |
59 | return ip_vs_conn_out_get(iph->protocol, | 61 | return ip_vs_conn_out_get(iph->protocol, |
60 | iph->saddr, pptr[0], | 62 | iph->saddr.ip, pptr[0], |
61 | iph->daddr, pptr[1]); | 63 | iph->daddr.ip, pptr[1]); |
62 | } else { | 64 | } else { |
63 | return ip_vs_conn_out_get(iph->protocol, | 65 | return ip_vs_conn_out_get(iph->protocol, |
64 | iph->daddr, pptr[1], | 66 | iph->daddr.ip, pptr[1], |
65 | iph->saddr, pptr[0]); | 67 | iph->saddr.ip, pptr[0]); |
66 | } | 68 | } |
67 | } | 69 | } |
68 | 70 | ||
69 | 71 | ||
70 | static int | 72 | static int |
71 | tcp_conn_schedule(struct sk_buff *skb, | 73 | tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, |
72 | struct ip_vs_protocol *pp, | ||
73 | int *verdict, struct ip_vs_conn **cpp) | 74 | int *verdict, struct ip_vs_conn **cpp) |
74 | { | 75 | { |
75 | struct ip_vs_service *svc; | 76 | struct ip_vs_service *svc; |
76 | struct tcphdr _tcph, *th; | 77 | struct tcphdr _tcph, *th; |
77 | struct ip_vs_iphdr iph; | 78 | struct ip_vs_iphdr iph; |
78 | 79 | ||
79 | ip_vs_fill_iphdr(AF_INET, skb_network_header(skb), &iph); | 80 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); |
80 | 81 | ||
81 | th = skb_header_pointer(skb, iph.len, sizeof(_tcph), &_tcph); | 82 | th = skb_header_pointer(skb, iph.len, sizeof(_tcph), &_tcph); |
82 | if (th == NULL) { | 83 | if (th == NULL) { |
@@ -85,8 +86,8 @@ tcp_conn_schedule(struct sk_buff *skb, | |||
85 | } | 86 | } |
86 | 87 | ||
87 | if (th->syn && | 88 | if (th->syn && |
88 | (svc = ip_vs_service_get(AF_INET, skb->mark, iph.protocol, | 89 | (svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr, |
89 | &iph.daddr, th->dest))) { | 90 | th->dest))) { |
90 | if (ip_vs_todrop()) { | 91 | if (ip_vs_todrop()) { |
91 | /* | 92 | /* |
92 | * It seems that we are very loaded. | 93 | * It seems that we are very loaded. |
@@ -136,7 +137,7 @@ tcp_snat_handler(struct sk_buff *skb, | |||
136 | 137 | ||
137 | if (unlikely(cp->app != NULL)) { | 138 | if (unlikely(cp->app != NULL)) { |
138 | /* Some checks before mangling */ | 139 | /* Some checks before mangling */ |
139 | if (pp->csum_check && !pp->csum_check(skb, pp)) | 140 | if (pp->csum_check && !pp->csum_check(AF_INET, skb, pp)) |
140 | return 0; | 141 | return 0; |
141 | 142 | ||
142 | /* Call application helper if needed */ | 143 | /* Call application helper if needed */ |
@@ -182,7 +183,7 @@ tcp_dnat_handler(struct sk_buff *skb, | |||
182 | 183 | ||
183 | if (unlikely(cp->app != NULL)) { | 184 | if (unlikely(cp->app != NULL)) { |
184 | /* Some checks before mangling */ | 185 | /* Some checks before mangling */ |
185 | if (pp->csum_check && !pp->csum_check(skb, pp)) | 186 | if (pp->csum_check && !pp->csum_check(AF_INET, skb, pp)) |
186 | return 0; | 187 | return 0; |
187 | 188 | ||
188 | /* | 189 | /* |
@@ -219,21 +220,43 @@ tcp_dnat_handler(struct sk_buff *skb, | |||
219 | 220 | ||
220 | 221 | ||
221 | static int | 222 | static int |
222 | tcp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) | 223 | tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) |
223 | { | 224 | { |
224 | const unsigned int tcphoff = ip_hdrlen(skb); | 225 | unsigned int tcphoff; |
226 | |||
227 | #ifdef CONFIG_IP_VS_IPV6 | ||
228 | if (af == AF_INET6) | ||
229 | tcphoff = sizeof(struct ipv6hdr); | ||
230 | else | ||
231 | #endif | ||
232 | tcphoff = ip_hdrlen(skb); | ||
225 | 233 | ||
226 | switch (skb->ip_summed) { | 234 | switch (skb->ip_summed) { |
227 | case CHECKSUM_NONE: | 235 | case CHECKSUM_NONE: |
228 | skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0); | 236 | skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0); |
229 | case CHECKSUM_COMPLETE: | 237 | case CHECKSUM_COMPLETE: |
230 | if (csum_tcpudp_magic(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, | 238 | #ifdef CONFIG_IP_VS_IPV6 |
231 | skb->len - tcphoff, | 239 | if (af == AF_INET6) { |
232 | ip_hdr(skb)->protocol, skb->csum)) { | 240 | if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, |
233 | IP_VS_DBG_RL_PKT(0, pp, skb, 0, | 241 | &ipv6_hdr(skb)->daddr, |
234 | "Failed checksum for"); | 242 | skb->len - tcphoff, |
235 | return 0; | 243 | ipv6_hdr(skb)->nexthdr, |
236 | } | 244 | skb->csum)) { |
245 | IP_VS_DBG_RL_PKT(0, pp, skb, 0, | ||
246 | "Failed checksum for"); | ||
247 | return 0; | ||
248 | } | ||
249 | } else | ||
250 | #endif | ||
251 | if (csum_tcpudp_magic(ip_hdr(skb)->saddr, | ||
252 | ip_hdr(skb)->daddr, | ||
253 | skb->len - tcphoff, | ||
254 | ip_hdr(skb)->protocol, | ||
255 | skb->csum)) { | ||
256 | IP_VS_DBG_RL_PKT(0, pp, skb, 0, | ||
257 | "Failed checksum for"); | ||
258 | return 0; | ||
259 | } | ||
237 | break; | 260 | break; |
238 | default: | 261 | default: |
239 | /* No need to checksum. */ | 262 | /* No need to checksum. */ |