summaryrefslogtreecommitdiff
path: root/net/ipv4/ipvs/ip_vs_proto_udp.c
diff options
context:
space:
mode:
authorJulius Volz <juliusv@google.com>2008-09-02 15:55:40 +0200
committerSimon Horman <horms@verge.net.au>2008-09-05 11:17:06 +1000
commit51ef348b14183789e4cb3444d05ce83b1b69d8fb (patch)
treee14e54ce262073b63a3343c764b8174b1041b577 /net/ipv4/ipvs/ip_vs_proto_udp.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_udp.c')
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c81
1 files changed, 51 insertions, 30 deletions
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index d208ed6eb9f..d3a1b1f2d10 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -24,8 +24,9 @@
#include <net/ip.h>
static struct ip_vs_conn *
-udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
- const struct iphdr *iph, unsigned int proto_off, int inverse)
+udp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
+ const struct ip_vs_iphdr *iph, unsigned int proto_off,
+ int inverse)
{
struct ip_vs_conn *cp;
__be16 _ports[2], *pptr;
@@ -36,12 +37,12 @@ udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
if (likely(!inverse)) {
cp = ip_vs_conn_in_get(iph->protocol,
- iph->saddr, pptr[0],
- iph->daddr, pptr[1]);
+ iph->saddr.ip, pptr[0],
+ iph->daddr.ip, pptr[1]);
} else {
cp = ip_vs_conn_in_get(iph->protocol,
- iph->daddr, pptr[1],
- iph->saddr, pptr[0]);
+ iph->daddr.ip, pptr[1],
+ iph->saddr.ip, pptr[0]);
}
return cp;
@@ -49,25 +50,25 @@ udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
static struct ip_vs_conn *
-udp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
- const struct iphdr *iph, unsigned int proto_off, int inverse)
+udp_conn_out_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
+ const struct ip_vs_iphdr *iph, unsigned int proto_off,
+ int inverse)
{
struct ip_vs_conn *cp;
__be16 _ports[2], *pptr;
- pptr = skb_header_pointer(skb, ip_hdrlen(skb),
- sizeof(_ports), _ports);
+ pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
if (pptr == NULL)
return NULL;
if (likely(!inverse)) {
cp = ip_vs_conn_out_get(iph->protocol,
- iph->saddr, pptr[0],
- iph->daddr, pptr[1]);
+ iph->saddr.ip, pptr[0],
+ iph->daddr.ip, pptr[1]);
} else {
cp = ip_vs_conn_out_get(iph->protocol,
- iph->daddr, pptr[1],
- iph->saddr, pptr[0]);
+ iph->daddr.ip, pptr[1],
+ iph->saddr.ip, pptr[0]);
}
return cp;
@@ -75,14 +76,14 @@ udp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
static int
-udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
+udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
int *verdict, struct ip_vs_conn **cpp)
{
struct ip_vs_service *svc;
struct udphdr _udph, *uh;
struct ip_vs_iphdr iph;
- ip_vs_fill_iphdr(AF_INET, skb_network_header(skb), &iph);
+ ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
uh = skb_header_pointer(skb, iph.len, sizeof(_udph), &_udph);
if (uh == NULL) {
@@ -90,7 +91,7 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
return 0;
}
- svc = ip_vs_service_get(AF_INET, skb->mark, iph.protocol,
+ svc = ip_vs_service_get(af, skb->mark, iph.protocol,
&iph.daddr, uh->dest);
if (svc) {
if (ip_vs_todrop()) {
@@ -143,7 +144,7 @@ udp_snat_handler(struct sk_buff *skb,
if (unlikely(cp->app != NULL)) {
/* Some checks before mangling */
- if (pp->csum_check && !pp->csum_check(skb, pp))
+ if (pp->csum_check && !pp->csum_check(AF_INET, skb, pp))
return 0;
/*
@@ -195,7 +196,7 @@ udp_dnat_handler(struct sk_buff *skb,
if (unlikely(cp->app != NULL)) {
/* Some checks before mangling */
- if (pp->csum_check && !pp->csum_check(skb, pp))
+ if (pp->csum_check && !pp->csum_check(AF_INET, skb, pp))
return 0;
/*
@@ -234,10 +235,17 @@ udp_dnat_handler(struct sk_buff *skb,
static int
-udp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
+udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
{
struct udphdr _udph, *uh;
- const unsigned int udphoff = ip_hdrlen(skb);
+ unsigned int udphoff;
+
+#ifdef CONFIG_IP_VS_IPV6
+ if (af == AF_INET6)
+ udphoff = sizeof(struct ipv6hdr);
+ else
+#endif
+ udphoff = ip_hdrlen(skb);
uh = skb_header_pointer(skb, udphoff, sizeof(_udph), &_udph);
if (uh == NULL)
@@ -249,15 +257,28 @@ udp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
skb->csum = skb_checksum(skb, udphoff,
skb->len - udphoff, 0);
case CHECKSUM_COMPLETE:
- if (csum_tcpudp_magic(ip_hdr(skb)->saddr,
- ip_hdr(skb)->daddr,
- skb->len - udphoff,
- ip_hdr(skb)->protocol,
- skb->csum)) {
- IP_VS_DBG_RL_PKT(0, pp, skb, 0,
- "Failed checksum for");
- return 0;
- }
+#ifdef CONFIG_IP_VS_IPV6
+ if (af == AF_INET6) {
+ if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ skb->len - udphoff,
+ ipv6_hdr(skb)->nexthdr,
+ skb->csum)) {
+ IP_VS_DBG_RL_PKT(0, pp, skb, 0,
+ "Failed checksum for");
+ return 0;
+ }
+ } else
+#endif
+ if (csum_tcpudp_magic(ip_hdr(skb)->saddr,
+ ip_hdr(skb)->daddr,
+ skb->len - udphoff,
+ ip_hdr(skb)->protocol,
+ skb->csum)) {
+ IP_VS_DBG_RL_PKT(0, pp, skb, 0,
+ "Failed checksum for");
+ return 0;
+ }
break;
default:
/* No need to checksum. */