diff options
Diffstat (limited to 'net/netfilter/ipvs/ip_vs_proto_sctp.c')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_proto_sctp.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index 4c0855c..1ea96bc 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -31,6 +31,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, if ((sch->type == SCTP_CID_INIT) && (svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr, sh->dest))) { + int ignored; + if (ip_vs_todrop()) { /* * It seems that we are very loaded. @@ -44,8 +46,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, * Let the virtual server select a real server for the * incoming connection, and create a connection entry. */ - *cpp = ip_vs_schedule(svc, skb); - if (!*cpp) { + *cpp = ip_vs_schedule(svc, skb, pp, &ignored); + if (!*cpp && !ignored) { *verdict = ip_vs_leave(svc, skb, pp); return 0; } @@ -61,6 +63,7 @@ sctp_snat_handler(struct sk_buff *skb, { sctp_sctphdr_t *sctph; unsigned int sctphoff; + struct sk_buff *iter; __be32 crc32; #ifdef CONFIG_IP_VS_IPV6 @@ -89,8 +92,8 @@ sctp_snat_handler(struct sk_buff *skb, /* Calculate the checksum */ crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff); - for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) - crc32 = sctp_update_cksum((u8 *) skb->data, skb_headlen(skb), + skb_walk_frags(skb, iter) + crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter), crc32); crc32 = sctp_end_cksum(crc32); sctph->checksum = crc32; @@ -102,9 +105,9 @@ static int sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, struct ip_vs_conn *cp) { - sctp_sctphdr_t *sctph; unsigned int sctphoff; + struct sk_buff *iter; __be32 crc32; #ifdef CONFIG_IP_VS_IPV6 @@ -133,8 +136,8 @@ sctp_dnat_handler(struct sk_buff *skb, /* Calculate the checksum */ crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff); - for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) - crc32 = sctp_update_cksum((u8 *) skb->data, skb_headlen(skb), + skb_walk_frags(skb, iter) + crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter), crc32); crc32 = sctp_end_cksum(crc32); sctph->checksum = crc32; @@ -145,9 +148,9 @@ sctp_dnat_handler(struct sk_buff *skb, static int sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) { - struct sk_buff *list = skb_shinfo(skb)->frag_list; unsigned int sctphoff; struct sctphdr *sh, _sctph; + struct sk_buff *iter; __le32 cmp; __le32 val; __u32 tmp; @@ -166,15 +169,15 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) cmp = sh->checksum; tmp = sctp_start_cksum((__u8 *) sh, skb_headlen(skb)); - for (; list; list = list->next) - tmp = sctp_update_cksum((__u8 *) list->data, - skb_headlen(list), tmp); + skb_walk_frags(skb, iter) + tmp = sctp_update_cksum((__u8 *) iter->data, + skb_headlen(iter), tmp); val = sctp_end_cksum(tmp); if (val != cmp) { /* CRC failure, dump it. */ - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } |