aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipvs/ip_vs_proto_tcp.c
diff options
context:
space:
mode:
authorJulius Volz <juliusv@google.com>2008-09-02 09:55:40 -0400
committerSimon Horman <horms@verge.net.au>2008-09-04 21:17:06 -0400
commit51ef348b14183789e4cb3444d05ce83b1b69d8fb (patch)
treee14e54ce262073b63a3343c764b8174b1041b577 /net/ipv4/ipvs/ip_vs_proto_tcp.c
parentb14198f6c1bea1687d20723db35d8effecd9d899 (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.c79
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
27static struct ip_vs_conn * 27static struct ip_vs_conn *
28tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, 28tcp_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
48static struct ip_vs_conn * 49static struct ip_vs_conn *
49tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, 50tcp_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
70static int 72static int
71tcp_conn_schedule(struct sk_buff *skb, 73tcp_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
221static int 222static int
222tcp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) 223tcp_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. */