|
@@ -61,14 +61,27 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+static void sctp_nat_csum(struct sk_buff *skb, sctp_sctphdr_t *sctph,
|
|
|
+ unsigned int sctphoff)
|
|
|
+{
|
|
|
+ __u32 crc32;
|
|
|
+ struct sk_buff *iter;
|
|
|
+
|
|
|
+ crc32 = sctp_start_cksum((__u8 *)sctph, skb_headlen(skb) - sctphoff);
|
|
|
+ skb_walk_frags(skb, iter)
|
|
|
+ crc32 = sctp_update_cksum((u8 *) iter->data,
|
|
|
+ skb_headlen(iter), crc32);
|
|
|
+ sctph->checksum = sctp_end_cksum(crc32);
|
|
|
+
|
|
|
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
|
|
|
struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)
|
|
|
{
|
|
|
sctp_sctphdr_t *sctph;
|
|
|
unsigned int sctphoff = iph->len;
|
|
|
- struct sk_buff *iter;
|
|
|
- __be32 crc32;
|
|
|
|
|
|
#ifdef CONFIG_IP_VS_IPV6
|
|
|
if (cp->af == AF_INET6 && iph->fragoffs)
|
|
@@ -92,13 +105,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
|
|
|
sctph = (void *) skb_network_header(skb) + sctphoff;
|
|
|
sctph->source = cp->vport;
|
|
|
|
|
|
- /* Calculate the checksum */
|
|
|
- crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
|
|
|
- skb_walk_frags(skb, iter)
|
|
|
- crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
|
|
|
- crc32);
|
|
|
- crc32 = sctp_end_cksum(crc32);
|
|
|
- sctph->checksum = crc32;
|
|
|
+ sctp_nat_csum(skb, sctph, sctphoff);
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
@@ -109,8 +116,6 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
|
|
|
{
|
|
|
sctp_sctphdr_t *sctph;
|
|
|
unsigned int sctphoff = iph->len;
|
|
|
- struct sk_buff *iter;
|
|
|
- __be32 crc32;
|
|
|
|
|
|
#ifdef CONFIG_IP_VS_IPV6
|
|
|
if (cp->af == AF_INET6 && iph->fragoffs)
|
|
@@ -134,13 +139,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
|
|
|
sctph = (void *) skb_network_header(skb) + sctphoff;
|
|
|
sctph->dest = cp->dport;
|
|
|
|
|
|
- /* Calculate the checksum */
|
|
|
- crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff);
|
|
|
- skb_walk_frags(skb, iter)
|
|
|
- crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter),
|
|
|
- crc32);
|
|
|
- crc32 = sctp_end_cksum(crc32);
|
|
|
- sctph->checksum = crc32;
|
|
|
+ sctp_nat_csum(skb, sctph, sctphoff);
|
|
|
|
|
|
return 1;
|
|
|
}
|