aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Yasevich <vyasevic@redhat.com>2012-11-15 03:49:22 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-15 17:39:24 -0500
commitc6b641a4c6b32f39db678c2441cb1ef824110d74 (patch)
tree251c4f988a2aca2b9b031afe192f3ae4705d3692
parent808a8f884554f93315f663b2694addb4a177c578 (diff)
ipv6: Pull IPv6 GSO registration out of the module
Sing GSO support is now separate, pull it out of the module and make it its own init call. Remove the cleanup functions as they are no longer called. Signed-off-by: Vlad Yasevich <vyasevic@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/protocol.h11
-rw-r--r--net/ipv6/Makefile6
-rw-r--r--net/ipv6/af_inet6.c3
-rw-r--r--net/ipv6/exthdrs.c10
-rw-r--r--net/ipv6/exthdrs_offload.c6
-rw-r--r--net/ipv6/ip6_offload.c17
-rw-r--r--net/ipv6/ip6_offload.h8
-rw-r--r--net/ipv6/protocol.c20
-rw-r--r--net/ipv6/tcp_ipv6.c10
-rw-r--r--net/ipv6/tcpv6_offload.c5
-rw-r--r--net/ipv6/udp.c10
-rw-r--r--net/ipv6/udp_offload.c5
12 files changed, 36 insertions, 75 deletions
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 7019c1637848..2c90794c139d 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -25,6 +25,7 @@
25#define _PROTOCOL_H 25#define _PROTOCOL_H
26 26
27#include <linux/in6.h> 27#include <linux/in6.h>
28#include <linux/skbuff.h>
28#if IS_ENABLED(CONFIG_IPV6) 29#if IS_ENABLED(CONFIG_IPV6)
29#include <linux/ipv6.h> 30#include <linux/ipv6.h>
30#endif 31#endif
@@ -59,8 +60,6 @@ struct inet6_protocol {
59 60
60#define INET6_PROTO_NOPOLICY 0x1 61#define INET6_PROTO_NOPOLICY 0x1
61#define INET6_PROTO_FINAL 0x2 62#define INET6_PROTO_FINAL 0x2
62/* This should be set for any extension header which is compatible with GSO. */
63#define INET6_PROTO_GSO_EXTHDR 0x4
64#endif 63#endif
65 64
66struct net_offload { 65struct net_offload {
@@ -72,6 +71,8 @@ struct net_offload {
72 int (*gro_complete)(struct sk_buff *skb); 71 int (*gro_complete)(struct sk_buff *skb);
73 unsigned int flags; /* Flags used by IPv6 for now */ 72 unsigned int flags; /* Flags used by IPv6 for now */
74}; 73};
74/* This should be set for any extension header which is compatible with GSO. */
75#define INET6_PROTO_GSO_EXTHDR 0x1
75 76
76/* This is used to register socket interfaces for IP protocols. */ 77/* This is used to register socket interfaces for IP protocols. */
77struct inet_protosw { 78struct inet_protosw {
@@ -93,10 +94,10 @@ struct inet_protosw {
93 94
94extern const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS]; 95extern const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS];
95extern const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS]; 96extern const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS];
97extern const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS];
96 98
97#if IS_ENABLED(CONFIG_IPV6) 99#if IS_ENABLED(CONFIG_IPV6)
98extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS]; 100extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS];
99extern const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS];
100#endif 101#endif
101 102
102extern int inet_add_protocol(const struct net_protocol *prot, unsigned char num); 103extern int inet_add_protocol(const struct net_protocol *prot, unsigned char num);
@@ -109,10 +110,10 @@ extern void inet_unregister_protosw(struct inet_protosw *p);
109#if IS_ENABLED(CONFIG_IPV6) 110#if IS_ENABLED(CONFIG_IPV6)
110extern int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num); 111extern int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num);
111extern int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num); 112extern int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num);
112extern int inet6_add_offload(const struct net_offload *prot, unsigned char num);
113extern int inet6_del_offload(const struct net_offload *prot, unsigned char num);
114extern int inet6_register_protosw(struct inet_protosw *p); 113extern int inet6_register_protosw(struct inet_protosw *p);
115extern void inet6_unregister_protosw(struct inet_protosw *p); 114extern void inet6_unregister_protosw(struct inet_protosw *p);
116#endif 115#endif
116extern int inet6_add_offload(const struct net_offload *prot, unsigned char num);
117extern int inet6_del_offload(const struct net_offload *prot, unsigned char num);
117 118
118#endif /* _PROTOCOL_H */ 119#endif /* _PROTOCOL_H */
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index cdca302f395c..04a475df98ad 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_IPV6) += ipv6.o
7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ 7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
8 addrlabel.o \ 8 addrlabel.o \
9 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \ 9 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
10 raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ 10 raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
11 exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o 11 exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o
12 12
13ipv6-offload := ip6_offload.o tcpv6_offload.o udp_offload.o exthdrs_offload.o 13ipv6-offload := ip6_offload.o tcpv6_offload.o udp_offload.o exthdrs_offload.o
@@ -23,7 +23,6 @@ ipv6-$(CONFIG_PROC_FS) += proc.o
23ipv6-$(CONFIG_SYN_COOKIES) += syncookies.o 23ipv6-$(CONFIG_SYN_COOKIES) += syncookies.o
24 24
25ipv6-objs += $(ipv6-y) 25ipv6-objs += $(ipv6-y)
26ipv6-objs += $(ipv6-offload)
27 26
28obj-$(CONFIG_INET6_AH) += ah6.o 27obj-$(CONFIG_INET6_AH) += ah6.o
29obj-$(CONFIG_INET6_ESP) += esp6.o 28obj-$(CONFIG_INET6_ESP) += esp6.o
@@ -41,6 +40,7 @@ obj-$(CONFIG_IPV6_SIT) += sit.o
41obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o 40obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
42obj-$(CONFIG_IPV6_GRE) += ip6_gre.o 41obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
43 42
44obj-y += addrconf_core.o exthdrs_core.o output_core.o 43obj-y += addrconf_core.o exthdrs_core.o output_core.o protocol.o
44obj-y += $(ipv6-offload)
45 45
46obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o 46obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index c84d5ba60cdd..7bafc51cda11 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -62,7 +62,6 @@
62 62
63#include <asm/uaccess.h> 63#include <asm/uaccess.h>
64#include <linux/mroute6.h> 64#include <linux/mroute6.h>
65#include "ip6_offload.h"
66 65
67MODULE_AUTHOR("Cast of dozens"); 66MODULE_AUTHOR("Cast of dozens");
68MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); 67MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
@@ -707,14 +706,12 @@ static struct packet_type ipv6_packet_type __read_mostly = {
707 706
708static int __init ipv6_packet_init(void) 707static int __init ipv6_packet_init(void)
709{ 708{
710 ipv6_offload_init();
711 dev_add_pack(&ipv6_packet_type); 709 dev_add_pack(&ipv6_packet_type);
712 return 0; 710 return 0;
713} 711}
714 712
715static void ipv6_packet_cleanup(void) 713static void ipv6_packet_cleanup(void)
716{ 714{
717 ipv6_offload_cleanup();
718 dev_remove_pack(&ipv6_packet_type); 715 dev_remove_pack(&ipv6_packet_type);
719} 716}
720 717
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index a786a20ad823..473f628f9f20 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -48,7 +48,6 @@
48#endif 48#endif
49 49
50#include <asm/uaccess.h> 50#include <asm/uaccess.h>
51#include "ip6_offload.h"
52 51
53/* 52/*
54 * Parsing tlv encoded headers. 53 * Parsing tlv encoded headers.
@@ -502,13 +501,9 @@ int __init ipv6_exthdrs_init(void)
502{ 501{
503 int ret; 502 int ret;
504 503
505 ret = ipv6_exthdrs_offload_init();
506 if (ret)
507 goto out;
508
509 ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING); 504 ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING);
510 if (ret) 505 if (ret)
511 goto out_offload; 506 goto out;
512 507
513 ret = inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS); 508 ret = inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
514 if (ret) 509 if (ret)
@@ -524,14 +519,11 @@ out_destopt:
524 inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS); 519 inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
525out_rthdr: 520out_rthdr:
526 inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING); 521 inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);
527out_offload:
528 ipv6_exthdrs_offload_exit();
529 goto out; 522 goto out;
530}; 523};
531 524
532void ipv6_exthdrs_exit(void) 525void ipv6_exthdrs_exit(void)
533{ 526{
534 ipv6_exthdrs_offload_exit();
535 inet6_del_protocol(&nodata_protocol, IPPROTO_NONE); 527 inet6_del_protocol(&nodata_protocol, IPPROTO_NONE);
536 inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS); 528 inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
537 inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING); 529 inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);
diff --git a/net/ipv6/exthdrs_offload.c b/net/ipv6/exthdrs_offload.c
index 271bf4a97023..cf77f3abfd06 100644
--- a/net/ipv6/exthdrs_offload.c
+++ b/net/ipv6/exthdrs_offload.c
@@ -39,9 +39,3 @@ out_rt:
39 inet_del_offload(&rthdr_offload, IPPROTO_ROUTING); 39 inet_del_offload(&rthdr_offload, IPPROTO_ROUTING);
40 goto out; 40 goto out;
41} 41}
42
43void ipv6_exthdrs_offload_exit(void)
44{
45 inet_del_offload(&rthdr_offload, IPPROTO_ROUTING);
46 inet_del_offload(&rthdr_offload, IPPROTO_DSTOPTS);
47}
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
index 01cf9835a581..63d79d9005bd 100644
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -12,6 +12,7 @@
12#include <linux/socket.h> 12#include <linux/socket.h>
13#include <linux/netdevice.h> 13#include <linux/netdevice.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/printk.h>
15 16
16#include <net/protocol.h> 17#include <net/protocol.h>
17#include <net/ipv6.h> 18#include <net/ipv6.h>
@@ -262,12 +263,18 @@ static struct packet_offload ipv6_packet_offload __read_mostly = {
262 .gro_complete = ipv6_gro_complete, 263 .gro_complete = ipv6_gro_complete,
263}; 264};
264 265
265void __init ipv6_offload_init(void) 266static int __init ipv6_offload_init(void)
266{ 267{
268
269 if (tcpv6_offload_init() < 0)
270 pr_crit("%s: Cannot add TCP protocol offload\n", __func__);
271 if (udp_offload_init() < 0)
272 pr_crit("%s: Cannot add UDP protocol offload\n", __func__);
273 if (ipv6_exthdrs_offload_init() < 0)
274 pr_crit("%s: Cannot add EXTHDRS protocol offload\n", __func__);
275
267 dev_add_offload(&ipv6_packet_offload); 276 dev_add_offload(&ipv6_packet_offload);
277 return 0;
268} 278}
269 279
270void ipv6_offload_cleanup(void) 280fs_initcall(ipv6_offload_init);
271{
272 dev_remove_offload(&ipv6_packet_offload);
273}
diff --git a/net/ipv6/ip6_offload.h b/net/ipv6/ip6_offload.h
index 4e88ddb52a2c..2e155c651b35 100644
--- a/net/ipv6/ip6_offload.h
+++ b/net/ipv6/ip6_offload.h
@@ -12,15 +12,7 @@
12#define __ip6_offload_h 12#define __ip6_offload_h
13 13
14int ipv6_exthdrs_offload_init(void); 14int ipv6_exthdrs_offload_init(void);
15void ipv6_exthdrs_offload_exit(void);
16
17int udp_offload_init(void); 15int udp_offload_init(void);
18void udp_offload_cleanup(void);
19
20int tcpv6_offload_init(void); 16int tcpv6_offload_init(void);
21void tcpv6_offload_cleanup(void);
22
23extern void ipv6_offload_init(void);
24extern void ipv6_offload_cleanup(void);
25 17
26#endif 18#endif
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index f7c53a7d5cb0..22d1bd4670da 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -25,8 +25,9 @@
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <net/protocol.h> 26#include <net/protocol.h>
27 27
28#if IS_ENABLED(CONFIG_IPV6)
28const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly; 29const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly;
29const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly; 30EXPORT_SYMBOL(inet6_protos);
30 31
31int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) 32int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
32{ 33{
@@ -35,13 +36,6 @@ int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol
35} 36}
36EXPORT_SYMBOL(inet6_add_protocol); 37EXPORT_SYMBOL(inet6_add_protocol);
37 38
38int inet6_add_offload(const struct net_offload *prot, unsigned char protocol)
39{
40 return !cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
41 NULL, prot) ? 0 : -1;
42}
43EXPORT_SYMBOL(inet6_add_offload);
44
45/* 39/*
46 * Remove a protocol from the hash tables. 40 * Remove a protocol from the hash tables.
47 */ 41 */
@@ -58,6 +52,16 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol
58 return ret; 52 return ret;
59} 53}
60EXPORT_SYMBOL(inet6_del_protocol); 54EXPORT_SYMBOL(inet6_del_protocol);
55#endif
56
57const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;
58
59int inet6_add_offload(const struct net_offload *prot, unsigned char protocol)
60{
61 return !cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
62 NULL, prot) ? 0 : -1;
63}
64EXPORT_SYMBOL(inet6_add_offload);
61 65
62int inet6_del_offload(const struct net_offload *prot, unsigned char protocol) 66int inet6_del_offload(const struct net_offload *prot, unsigned char protocol)
63{ 67{
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5bed594b429d..6c0f2526f3f1 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -71,7 +71,6 @@
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"
75 74
76static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); 75static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
77static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, 76static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
@@ -2007,13 +2006,9 @@ int __init tcpv6_init(void)
2007{ 2006{
2008 int ret; 2007 int ret;
2009 2008
2010 ret = tcpv6_offload_init();
2011 if (ret)
2012 goto out;
2013
2014 ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP); 2009 ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP);
2015 if (ret) 2010 if (ret)
2016 goto out_offload; 2011 goto out;
2017 2012
2018 /* register inet6 protocol */ 2013 /* register inet6 protocol */
2019 ret = inet6_register_protosw(&tcpv6_protosw); 2014 ret = inet6_register_protosw(&tcpv6_protosw);
@@ -2030,8 +2025,6 @@ out_tcpv6_protosw:
2030 inet6_unregister_protosw(&tcpv6_protosw); 2025 inet6_unregister_protosw(&tcpv6_protosw);
2031out_tcpv6_protocol: 2026out_tcpv6_protocol:
2032 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); 2027 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
2033out_offload:
2034 tcpv6_offload_cleanup();
2035 goto out; 2028 goto out;
2036} 2029}
2037 2030
@@ -2040,5 +2033,4 @@ void tcpv6_exit(void)
2040 unregister_pernet_subsys(&tcpv6_net_ops); 2033 unregister_pernet_subsys(&tcpv6_net_ops);
2041 inet6_unregister_protosw(&tcpv6_protosw); 2034 inet6_unregister_protosw(&tcpv6_protosw);
2042 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); 2035 inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
2043 tcpv6_offload_cleanup();
2044} 2036}
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
index edeafedba470..3a27fe685c8e 100644
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -91,8 +91,3 @@ int __init tcpv6_offload_init(void)
91{ 91{
92 return inet6_add_offload(&tcpv6_offload, IPPROTO_TCP); 92 return inet6_add_offload(&tcpv6_offload, IPPROTO_TCP);
93} 93}
94
95void tcpv6_offload_cleanup(void)
96{
97 inet6_del_offload(&tcpv6_offload, IPPROTO_TCP);
98}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 013fef740d51..dfaa29b8b293 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -50,7 +50,6 @@
50#include <linux/seq_file.h> 50#include <linux/seq_file.h>
51#include <trace/events/skb.h> 51#include <trace/events/skb.h>
52#include "udp_impl.h" 52#include "udp_impl.h"
53#include "ip6_offload.h"
54 53
55int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) 54int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
56{ 55{
@@ -1472,13 +1471,9 @@ int __init udpv6_init(void)
1472{ 1471{
1473 int ret; 1472 int ret;
1474 1473
1475 ret = udp_offload_init();
1476 if (ret)
1477 goto out;
1478
1479 ret = inet6_add_protocol(&udpv6_protocol, IPPROTO_UDP); 1474 ret = inet6_add_protocol(&udpv6_protocol, IPPROTO_UDP);
1480 if (ret) 1475 if (ret)
1481 goto out_offload; 1476 goto out;
1482 1477
1483 ret = inet6_register_protosw(&udpv6_protosw); 1478 ret = inet6_register_protosw(&udpv6_protosw);
1484 if (ret) 1479 if (ret)
@@ -1488,8 +1483,6 @@ out:
1488 1483
1489out_udpv6_protocol: 1484out_udpv6_protocol:
1490 inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP); 1485 inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP);
1491out_offload:
1492 udp_offload_cleanup();
1493 goto out; 1486 goto out;
1494} 1487}
1495 1488
@@ -1497,5 +1490,4 @@ void udpv6_exit(void)
1497{ 1490{
1498 inet6_unregister_protosw(&udpv6_protosw); 1491 inet6_unregister_protosw(&udpv6_protosw);
1499 inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP); 1492 inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP);
1500 udp_offload_cleanup();
1501} 1493}
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index f964d2b366c8..979e4ab63a8b 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -115,8 +115,3 @@ int __init udp_offload_init(void)
115{ 115{
116 return inet6_add_offload(&udpv6_offload, IPPROTO_UDP); 116 return inet6_add_offload(&udpv6_offload, IPPROTO_UDP);
117} 117}
118
119void udp_offload_cleanup(void)
120{
121 inet6_del_offload(&udpv6_offload, IPPROTO_UDP);
122}