aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorVlad Yasevich <vyasevic@redhat.com>2012-11-15 03:49:17 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-15 17:36:18 -0500
commit8663e02aba154e04679c9bb1665af52021d32547 (patch)
tree901900f79125e60134c2663b409c2d8170870dfb /net/ipv6/tcp_ipv6.c
parentd1da932ed4ecad2a14cbcc01ed589d617d0f0f09 (diff)
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.c113
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 @@
71 71
72#include <linux/crypto.h> 72#include <linux/crypto.h>
73#include <linux/scatterlist.h> 73#include <linux/scatterlist.h>
74#include "ip6_offload.h"
74 75
75static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); 76static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
76static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, 77static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
77 struct request_sock *req); 78 struct request_sock *req);
78 79
79static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); 80static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
80static void __tcp_v6_send_check(struct sk_buff *skb,
81 const struct in6_addr *saddr,
82 const struct in6_addr *daddr);
83 81
84static const struct inet_connection_sock_af_ops ipv6_mapped; 82static const struct inet_connection_sock_af_ops ipv6_mapped;
85static const struct inet_connection_sock_af_ops ipv6_specific; 83static const struct inet_connection_sock_af_ops ipv6_specific;
@@ -119,14 +117,6 @@ static void tcp_v6_hash(struct sock *sk)
119 } 117 }
120} 118}
121 119
122static __inline__ __sum16 tcp_v6_check(int len,
123 const struct in6_addr *saddr,
124 const struct in6_addr *daddr,
125 __wsum base)
126{
127 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base);
128}
129
130static __u32 tcp_v6_init_sequence(const struct sk_buff *skb) 120static __u32 tcp_v6_init_sequence(const struct sk_buff *skb)
131{ 121{
132 return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, 122 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 = {
722}; 712};
723#endif 713#endif
724 714
725static void __tcp_v6_send_check(struct sk_buff *skb,
726 const struct in6_addr *saddr, const struct in6_addr *daddr)
727{
728 struct tcphdr *th = tcp_hdr(skb);
729
730 if (skb->ip_summed == CHECKSUM_PARTIAL) {
731 th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0);
732 skb->csum_start = skb_transport_header(skb) - skb->head;
733 skb->csum_offset = offsetof(struct tcphdr, check);
734 } else {
735 th->check = tcp_v6_check(skb->len, saddr, daddr,
736 csum_partial(th, th->doff << 2,
737 skb->csum));
738 }
739}
740
741static void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb)
742{
743 struct ipv6_pinfo *np = inet6_sk(sk);
744
745 __tcp_v6_send_check(skb, &np->saddr, &np->daddr);
746}
747
748static int tcp_v6_gso_send_check(struct sk_buff *skb)
749{
750 const struct ipv6hdr *ipv6h;
751 struct tcphdr *th;
752
753 if (!pskb_may_pull(skb, sizeof(*th)))
754 return -EINVAL;
755
756 ipv6h = ipv6_hdr(skb);
757 th = tcp_hdr(skb);
758
759 th->check = 0;
760 skb->ip_summed = CHECKSUM_PARTIAL;
761 __tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr);
762 return 0;
763}
764
765static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
766 struct sk_buff *skb)
767{
768 const struct ipv6hdr *iph = skb_gro_network_header(skb);
769 __wsum wsum;
770 __sum16 sum;
771
772 switch (skb->ip_summed) {
773 case CHECKSUM_COMPLETE:
774 if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
775 skb->csum)) {
776 skb->ip_summed = CHECKSUM_UNNECESSARY;
777 break;
778 }
779flush:
780 NAPI_GRO_CB(skb)->flush = 1;
781 return NULL;
782
783 case CHECKSUM_NONE:
784 wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
785 skb_gro_len(skb),
786 IPPROTO_TCP, 0));
787 sum = csum_fold(skb_checksum(skb,
788 skb_gro_offset(skb),
789 skb_gro_len(skb),
790 wsum));
791 if (sum)
792 goto flush;
793
794 skb->ip_summed = CHECKSUM_UNNECESSARY;
795 break;
796 }
797
798 return tcp_gro_receive(head, skb);
799}
800
801static int tcp6_gro_complete(struct sk_buff *skb)
802{
803 const struct ipv6hdr *iph = ipv6_hdr(skb);
804 struct tcphdr *th = tcp_hdr(skb);
805
806 th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb),
807 &iph->saddr, &iph->daddr, 0);
808 skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
809
810 return tcp_gro_complete(skb);
811}
812
813static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, 715static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
814 u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass) 716 u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass)
815{ 717{
@@ -2069,13 +1971,6 @@ static const struct inet6_protocol tcpv6_protocol = {
2069 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 1971 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
2070}; 1972};
2071 1973
2072static const struct net_offload tcpv6_offload = {
2073 .gso_send_check = tcp_v6_gso_send_check,
2074 .gso_segment = tcp_tso_segment,
2075 .gro_receive = tcp6_gro_receive,
2076 .gro_complete = tcp6_gro_complete,
2077};
2078
2079static struct inet_protosw tcpv6_protosw = { 1974static struct inet_protosw tcpv6_protosw = {
2080 .type = SOCK_STREAM, 1975 .type = SOCK_STREAM,
2081 .protocol = IPPROTO_TCP, 1976 .protocol = IPPROTO_TCP,
@@ -2112,7 +2007,7 @@ int __init tcpv6_init(void)
2112{ 2007{
2113 int ret; 2008 int ret;
2114 2009
2115 ret = inet6_add_offload(&tcpv6_offload, IPPROTO_TCP); 2010 ret = tcpv6_offload_init();
2116 if (ret) 2011 if (ret)
2117 goto out; 2012 goto out;
2118 2013
@@ -2136,7 +2031,7 @@ out_tcpv6_protosw:
2136out_tcpv6_protocol: 2031out_tcpv6_protocol:
2137 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); 2032 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
2138out_offload: 2033out_offload:
2139 inet6_del_offload(&tcpv6_offload, IPPROTO_TCP); 2034 tcpv6_offload_cleanup();
2140 goto out; 2035 goto out;
2141} 2036}
2142 2037
@@ -2145,5 +2040,5 @@ void tcpv6_exit(void)
2145 unregister_pernet_subsys(&tcpv6_net_ops); 2040 unregister_pernet_subsys(&tcpv6_net_ops);
2146 inet6_unregister_protosw(&tcpv6_protosw); 2041 inet6_unregister_protosw(&tcpv6_protosw);
2147 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); 2042 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
2148 inet6_del_offload(&tcpv6_offload, IPPROTO_TCP); 2043 tcpv6_offload_cleanup();
2149} 2044}