diff options
| author | Vlad Yasevich <vyasevic@redhat.com> | 2012-11-15 08:49:15 +0000 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-11-15 17:36:17 -0500 | 
| commit | 3336288a9feaa809839adbaf05778dc2f16665dc (patch) | |
| tree | f536f807902ea4268cc211054a1b234776f5f858 | |
| parent | bca49f843eac59cbb1ddd1f4a5d65fcc23b62efd (diff) | |
| download | olio-linux-3.10-3336288a9feaa809839adbaf05778dc2f16665dc.tar.xz olio-linux-3.10-3336288a9feaa809839adbaf05778dc2f16665dc.zip  | |
ipv6: Switch to using new offload infrastructure.
Switch IPv6 protocol to using the new GRO/GSO calls and data.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/net/protocol.h | 8 | ||||
| -rw-r--r-- | net/ipv6/af_inet6.c | 22 | ||||
| -rw-r--r-- | net/ipv6/exthdrs.c | 38 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 17 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 11 | 
5 files changed, 64 insertions, 32 deletions
diff --git a/include/net/protocol.h b/include/net/protocol.h index 3bb70510b68..7019c163784 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -54,14 +54,6 @@ struct inet6_protocol {  			       struct inet6_skb_parm *opt,  			       u8 type, u8 code, int offset,  			       __be32 info); - -	int	(*gso_send_check)(struct sk_buff *skb); -	struct sk_buff *(*gso_segment)(struct sk_buff *skb, -				       netdev_features_t features); -	struct sk_buff **(*gro_receive)(struct sk_buff **head, -					struct sk_buff *skb); -	int	(*gro_complete)(struct sk_buff *skb); -  	unsigned int	flags;	/* INET6_PROTO_xxx */  }; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 6e245177608..eb63dac6872 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -701,14 +701,14 @@ EXPORT_SYMBOL_GPL(ipv6_opt_accepted);  static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)  { -	const struct inet6_protocol *ops = NULL; +	const struct net_offload *ops = NULL;  	for (;;) {  		struct ipv6_opt_hdr *opth;  		int len;  		if (proto != NEXTHDR_HOP) { -			ops = rcu_dereference(inet6_protos[proto]); +			ops = rcu_dereference(inet6_offloads[proto]);  			if (unlikely(!ops))  				break; @@ -736,7 +736,7 @@ static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)  static int ipv6_gso_send_check(struct sk_buff *skb)  {  	const struct ipv6hdr *ipv6h; -	const struct inet6_protocol *ops; +	const struct net_offload *ops;  	int err = -EINVAL;  	if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) @@ -747,7 +747,7 @@ static int ipv6_gso_send_check(struct sk_buff *skb)  	err = -EPROTONOSUPPORT;  	rcu_read_lock(); -	ops = rcu_dereference(inet6_protos[ +	ops = rcu_dereference(inet6_offloads[  		ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr)]);  	if (likely(ops && ops->gso_send_check)) { @@ -765,7 +765,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,  {  	struct sk_buff *segs = ERR_PTR(-EINVAL);  	struct ipv6hdr *ipv6h; -	const struct inet6_protocol *ops; +	const struct net_offload *ops;  	int proto;  	struct frag_hdr *fptr;  	unsigned int unfrag_ip6hlen; @@ -792,7 +792,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,  	proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);  	rcu_read_lock(); -	ops = rcu_dereference(inet6_protos[proto]); +	ops = rcu_dereference(inet6_offloads[proto]);  	if (likely(ops && ops->gso_segment)) {  		skb_reset_transport_header(skb);  		segs = ops->gso_segment(skb, features); @@ -825,7 +825,7 @@ out:  static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,  					 struct sk_buff *skb)  { -	const struct inet6_protocol *ops; +	const struct net_offload *ops;  	struct sk_buff **pp = NULL;  	struct sk_buff *p;  	struct ipv6hdr *iph; @@ -852,7 +852,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,  	rcu_read_lock();  	proto = iph->nexthdr; -	ops = rcu_dereference(inet6_protos[proto]); +	ops = rcu_dereference(inet6_offloads[proto]);  	if (!ops || !ops->gro_receive) {  		__pskb_pull(skb, skb_gro_offset(skb));  		proto = ipv6_gso_pull_exthdrs(skb, proto); @@ -860,7 +860,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,  		skb_reset_transport_header(skb);  		__skb_push(skb, skb_gro_offset(skb)); -		ops = rcu_dereference(inet6_protos[proto]); +		ops = rcu_dereference(inet6_offloads[proto]);  		if (!ops || !ops->gro_receive)  			goto out_unlock; @@ -915,7 +915,7 @@ out:  static int ipv6_gro_complete(struct sk_buff *skb)  { -	const struct inet6_protocol *ops; +	const struct net_offload *ops;  	struct ipv6hdr *iph = ipv6_hdr(skb);  	int err = -ENOSYS; @@ -923,7 +923,7 @@ static int ipv6_gro_complete(struct sk_buff *skb)  				 sizeof(*iph));  	rcu_read_lock(); -	ops = rcu_dereference(inet6_protos[NAPI_GRO_CB(skb)->proto]); +	ops = rcu_dereference(inet6_offloads[NAPI_GRO_CB(skb)->proto]);  	if (WARN_ON(!ops || !ops->gro_complete))  		goto out_unlock; diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index cb6f0828ca4..de6559e3aa0 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -549,14 +549,44 @@ static const struct inet6_protocol nodata_protocol = {  	.flags		=	INET6_PROTO_NOPOLICY,  }; +static int ipv6_exthdrs_offload_init(void) +{ +	int ret; + +	ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING); +	if (!ret) +		goto out; + +	ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS); +	if (!ret) +		goto out_rt; + +out: +	return ret; + +out_rt: +	inet_del_offload(&rthdr_offload, IPPROTO_ROUTING); +	goto out; +} + +static void ipv6_exthdrs_offload_exit(void) +{ +	inet_del_offload(&rthdr_offload, IPPROTO_ROUTING); +	inet_del_offload(&rthdr_offload, IPPROTO_DSTOPTS); +} +  int __init ipv6_exthdrs_init(void)  {  	int ret; -	ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING); +	ret = ipv6_exthdrs_offload_init();  	if (ret)  		goto out; +	ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING); +	if (ret) +		goto out_offload; +  	ret = inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS);  	if (ret)  		goto out_rthdr; @@ -567,10 +597,12 @@ int __init ipv6_exthdrs_init(void)  out:  	return ret; -out_rthdr: -	inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);  out_destopt:  	inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS); +out_rthdr: +	inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING); +out_offload: +	ipv6_exthdrs_offload_exit();  	goto out;  }; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 6884a95be43..635206e8987 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -2066,10 +2066,6 @@ static const struct inet6_protocol tcpv6_protocol = {  	.early_demux	=	tcp_v6_early_demux,  	.handler	=	tcp_v6_rcv,  	.err_handler	=	tcp_v6_err, -	.gso_send_check	=	tcp_v6_gso_send_check, -	.gso_segment	=	tcp_tso_segment, -	.gro_receive	=	tcp6_gro_receive, -	.gro_complete	=	tcp6_gro_complete,  	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,  }; @@ -2116,10 +2112,14 @@ int __init tcpv6_init(void)  {  	int ret; -	ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP); +	ret = inet6_add_offload(&tcpv6_offload, IPPROTO_TCP);  	if (ret)  		goto out; +	ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP); +	if (ret) +		goto out_offload; +  	/* register inet6 protocol */  	ret = inet6_register_protosw(&tcpv6_protosw);  	if (ret) @@ -2131,10 +2131,12 @@ int __init tcpv6_init(void)  out:  	return ret; -out_tcpv6_protocol: -	inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);  out_tcpv6_protosw:  	inet6_unregister_protosw(&tcpv6_protosw); +out_tcpv6_protocol: +	inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); +out_offload: +	inet6_del_offload(&tcpv6_offload, IPPROTO_TCP);  	goto out;  } @@ -2143,4 +2145,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);  } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 3ad44e17650..e4cc1f41012 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1438,8 +1438,6 @@ out:  static const struct inet6_protocol udpv6_protocol = {  	.handler	=	udpv6_rcv,  	.err_handler	=	udpv6_err, -	.gso_send_check =	udp6_ufo_send_check, -	.gso_segment	=	udp6_ufo_fragment,  	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,  }; @@ -1570,10 +1568,14 @@ int __init udpv6_init(void)  {  	int ret; -	ret = inet6_add_protocol(&udpv6_protocol, IPPROTO_UDP); +	ret = inet6_add_offload(&udpv6_offload, IPPROTO_UDP);  	if (ret)  		goto out; +	ret = inet6_add_protocol(&udpv6_protocol, IPPROTO_UDP); +	if (ret) +		goto out_offload; +  	ret = inet6_register_protosw(&udpv6_protosw);  	if (ret)  		goto out_udpv6_protocol; @@ -1582,6 +1584,8 @@ out:  out_udpv6_protocol:  	inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP); +out_offload: +	inet6_del_offload(&udpv6_offload, IPPROTO_UDP);  	goto out;  } @@ -1589,4 +1593,5 @@ void udpv6_exit(void)  {  	inet6_unregister_protosw(&udpv6_protosw);  	inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP); +	inet6_del_offload(&udpv6_offload, IPPROTO_UDP);  }  |