diff options
author | Vlad Yasevich <vyasevic@redhat.com> | 2012-11-15 08:49:17 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-15 17:36:18 -0500 |
commit | 8663e02aba154e04679c9bb1665af52021d32547 (patch) | |
tree | 901900f79125e60134c2663b409c2d8170870dfb /net/ipv6/tcp_ipv6.c | |
parent | d1da932ed4ecad2a14cbcc01ed589d617d0f0f09 (diff) | |
download | blackbird-op-linux-8663e02aba154e04679c9bb1665af52021d32547.tar.gz blackbird-op-linux-8663e02aba154e04679c9bb1665af52021d32547.zip |
ipv6: Separate tcp offload functionality
Pull TCPv6 offload functionality into its won file in preparation
for moving it out of the module.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 113 |
1 files changed, 4 insertions, 109 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 635206e8987e..5bed594b429d 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -71,15 +71,13 @@ #include <linux/crypto.h> #include <linux/scatterlist.h> +#include "ip6_offload.h" static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, struct request_sock *req); static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -static void __tcp_v6_send_check(struct sk_buff *skb, - const struct in6_addr *saddr, - const struct in6_addr *daddr); static const struct inet_connection_sock_af_ops ipv6_mapped; static const struct inet_connection_sock_af_ops ipv6_specific; @@ -119,14 +117,6 @@ static void tcp_v6_hash(struct sock *sk) } } -static __inline__ __sum16 tcp_v6_check(int len, - const struct in6_addr *saddr, - const struct in6_addr *daddr, - __wsum base) -{ - return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base); -} - static __u32 tcp_v6_init_sequence(const struct sk_buff *skb) { return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, @@ -722,94 +712,6 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { }; #endif -static void __tcp_v6_send_check(struct sk_buff *skb, - const struct in6_addr *saddr, const struct in6_addr *daddr) -{ - struct tcphdr *th = tcp_hdr(skb); - - if (skb->ip_summed == CHECKSUM_PARTIAL) { - th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0); - skb->csum_start = skb_transport_header(skb) - skb->head; - skb->csum_offset = offsetof(struct tcphdr, check); - } else { - th->check = tcp_v6_check(skb->len, saddr, daddr, - csum_partial(th, th->doff << 2, - skb->csum)); - } -} - -static void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb) -{ - struct ipv6_pinfo *np = inet6_sk(sk); - - __tcp_v6_send_check(skb, &np->saddr, &np->daddr); -} - -static int tcp_v6_gso_send_check(struct sk_buff *skb) -{ - const struct ipv6hdr *ipv6h; - struct tcphdr *th; - - if (!pskb_may_pull(skb, sizeof(*th))) - return -EINVAL; - - ipv6h = ipv6_hdr(skb); - th = tcp_hdr(skb); - - th->check = 0; - skb->ip_summed = CHECKSUM_PARTIAL; - __tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr); - return 0; -} - -static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, - struct sk_buff *skb) -{ - const struct ipv6hdr *iph = skb_gro_network_header(skb); - __wsum wsum; - __sum16 sum; - - switch (skb->ip_summed) { - case CHECKSUM_COMPLETE: - if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr, - skb->csum)) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - break; - } -flush: - NAPI_GRO_CB(skb)->flush = 1; - return NULL; - - case CHECKSUM_NONE: - wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr, - skb_gro_len(skb), - IPPROTO_TCP, 0)); - sum = csum_fold(skb_checksum(skb, - skb_gro_offset(skb), - skb_gro_len(skb), - wsum)); - if (sum) - goto flush; - - skb->ip_summed = CHECKSUM_UNNECESSARY; - break; - } - - return tcp_gro_receive(head, skb); -} - -static int tcp6_gro_complete(struct sk_buff *skb) -{ - const struct ipv6hdr *iph = ipv6_hdr(skb); - struct tcphdr *th = tcp_hdr(skb); - - th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb), - &iph->saddr, &iph->daddr, 0); - skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; - - return tcp_gro_complete(skb); -} - static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass) { @@ -2069,13 +1971,6 @@ static const struct inet6_protocol tcpv6_protocol = { .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; -static const struct net_offload tcpv6_offload = { - .gso_send_check = tcp_v6_gso_send_check, - .gso_segment = tcp_tso_segment, - .gro_receive = tcp6_gro_receive, - .gro_complete = tcp6_gro_complete, -}; - static struct inet_protosw tcpv6_protosw = { .type = SOCK_STREAM, .protocol = IPPROTO_TCP, @@ -2112,7 +2007,7 @@ int __init tcpv6_init(void) { int ret; - ret = inet6_add_offload(&tcpv6_offload, IPPROTO_TCP); + ret = tcpv6_offload_init(); if (ret) goto out; @@ -2136,7 +2031,7 @@ out_tcpv6_protosw: out_tcpv6_protocol: inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); out_offload: - inet6_del_offload(&tcpv6_offload, IPPROTO_TCP); + tcpv6_offload_cleanup(); goto out; } @@ -2145,5 +2040,5 @@ void tcpv6_exit(void) unregister_pernet_subsys(&tcpv6_net_ops); inet6_unregister_protosw(&tcpv6_protosw); inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); - inet6_del_offload(&tcpv6_offload, IPPROTO_TCP); + tcpv6_offload_cleanup(); } |