diff options
author | Vlad Yasevich <vyasevic@redhat.com> | 2012-11-15 03:49:13 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-15 17:36:17 -0500 |
commit | 8ca896cfdd17f32f5aa2747644733ebf3725360d (patch) | |
tree | 64a6ad61af635285a26a039f42bdc78ae8855979 | |
parent | de27d001d187721de775ed9e0c485aa6f517c745 (diff) |
ipv6: Add new offload registration infrastructure.
Create a new data structure for IPv6 protocols that holds GRO/GSO
callbacks and a new array to track the protocols that register GRO/GSO.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/protocol.h | 4 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 8 | ||||
-rw-r--r-- | net/ipv6/protocol.c | 21 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 7 | ||||
-rw-r--r-- | net/ipv6/udp.c | 5 |
5 files changed, 45 insertions, 0 deletions
diff --git a/include/net/protocol.h b/include/net/protocol.h index d8ecb17b1231..637e1bb6a76e 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h | |||
@@ -84,6 +84,7 @@ struct net_offload { | |||
84 | struct sk_buff **(*gro_receive)(struct sk_buff **head, | 84 | struct sk_buff **(*gro_receive)(struct sk_buff **head, |
85 | struct sk_buff *skb); | 85 | struct sk_buff *skb); |
86 | int (*gro_complete)(struct sk_buff *skb); | 86 | int (*gro_complete)(struct sk_buff *skb); |
87 | unsigned int flags; /* Flags used by IPv6 for now */ | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | /* This is used to register socket interfaces for IP protocols. */ | 90 | /* This is used to register socket interfaces for IP protocols. */ |
@@ -109,6 +110,7 @@ extern const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS]; | |||
109 | 110 | ||
110 | #if IS_ENABLED(CONFIG_IPV6) | 111 | #if IS_ENABLED(CONFIG_IPV6) |
111 | extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS]; | 112 | extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS]; |
113 | extern const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS]; | ||
112 | #endif | 114 | #endif |
113 | 115 | ||
114 | extern int inet_add_protocol(const struct net_protocol *prot, unsigned char num); | 116 | extern int inet_add_protocol(const struct net_protocol *prot, unsigned char num); |
@@ -121,6 +123,8 @@ extern void inet_unregister_protosw(struct inet_protosw *p); | |||
121 | #if IS_ENABLED(CONFIG_IPV6) | 123 | #if IS_ENABLED(CONFIG_IPV6) |
122 | extern int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num); | 124 | extern int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num); |
123 | extern int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num); | 125 | extern int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num); |
126 | extern int inet6_add_offload(const struct net_offload *prot, unsigned char num); | ||
127 | extern int inet6_del_offload(const struct net_offload *prot, unsigned char num); | ||
124 | extern int inet6_register_protosw(struct inet_protosw *p); | 128 | extern int inet6_register_protosw(struct inet_protosw *p); |
125 | extern void inet6_unregister_protosw(struct inet_protosw *p); | 129 | extern void inet6_unregister_protosw(struct inet_protosw *p); |
126 | #endif | 130 | #endif |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index f005acc58b2a..cb6f0828ca44 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -531,11 +531,19 @@ static const struct inet6_protocol rthdr_protocol = { | |||
531 | .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, | 531 | .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, |
532 | }; | 532 | }; |
533 | 533 | ||
534 | static const struct net_offload rthdr_offload = { | ||
535 | .flags = INET6_PROTO_GSO_EXTHDR, | ||
536 | }; | ||
537 | |||
534 | static const struct inet6_protocol destopt_protocol = { | 538 | static const struct inet6_protocol destopt_protocol = { |
535 | .handler = ipv6_destopt_rcv, | 539 | .handler = ipv6_destopt_rcv, |
536 | .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, | 540 | .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, |
537 | }; | 541 | }; |
538 | 542 | ||
543 | static const struct net_offload dstopt_offload = { | ||
544 | .flags = INET6_PROTO_GSO_EXTHDR, | ||
545 | }; | ||
546 | |||
539 | static const struct inet6_protocol nodata_protocol = { | 547 | static const struct inet6_protocol nodata_protocol = { |
540 | .handler = dst_discard, | 548 | .handler = dst_discard, |
541 | .flags = INET6_PROTO_NOPOLICY, | 549 | .flags = INET6_PROTO_NOPOLICY, |
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 053082dfc93e..f7c53a7d5cb0 100644 --- a/net/ipv6/protocol.c +++ b/net/ipv6/protocol.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <net/protocol.h> | 26 | #include <net/protocol.h> |
27 | 27 | ||
28 | const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly; | 28 | const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly; |
29 | const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly; | ||
29 | 30 | ||
30 | int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) | 31 | int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) |
31 | { | 32 | { |
@@ -34,6 +35,13 @@ int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol | |||
34 | } | 35 | } |
35 | EXPORT_SYMBOL(inet6_add_protocol); | 36 | EXPORT_SYMBOL(inet6_add_protocol); |
36 | 37 | ||
38 | int 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 | } | ||
43 | EXPORT_SYMBOL(inet6_add_offload); | ||
44 | |||
37 | /* | 45 | /* |
38 | * Remove a protocol from the hash tables. | 46 | * Remove a protocol from the hash tables. |
39 | */ | 47 | */ |
@@ -50,3 +58,16 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol | |||
50 | return ret; | 58 | return ret; |
51 | } | 59 | } |
52 | EXPORT_SYMBOL(inet6_del_protocol); | 60 | EXPORT_SYMBOL(inet6_del_protocol); |
61 | |||
62 | int inet6_del_offload(const struct net_offload *prot, unsigned char protocol) | ||
63 | { | ||
64 | int ret; | ||
65 | |||
66 | ret = (cmpxchg((const struct net_offload **)&inet6_offloads[protocol], | ||
67 | prot, NULL) == prot) ? 0 : -1; | ||
68 | |||
69 | synchronize_net(); | ||
70 | |||
71 | return ret; | ||
72 | } | ||
73 | EXPORT_SYMBOL(inet6_del_offload); | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c73d0ebde9c8..6884a95be433 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -2073,6 +2073,13 @@ static const struct inet6_protocol tcpv6_protocol = { | |||
2073 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 2073 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
2074 | }; | 2074 | }; |
2075 | 2075 | ||
2076 | static const struct net_offload tcpv6_offload = { | ||
2077 | .gso_send_check = tcp_v6_gso_send_check, | ||
2078 | .gso_segment = tcp_tso_segment, | ||
2079 | .gro_receive = tcp6_gro_receive, | ||
2080 | .gro_complete = tcp6_gro_complete, | ||
2081 | }; | ||
2082 | |||
2076 | static struct inet_protosw tcpv6_protosw = { | 2083 | static struct inet_protosw tcpv6_protosw = { |
2077 | .type = SOCK_STREAM, | 2084 | .type = SOCK_STREAM, |
2078 | .protocol = IPPROTO_TCP, | 2085 | .protocol = IPPROTO_TCP, |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index fc9997260a6b..3ad44e176503 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1443,6 +1443,11 @@ static const struct inet6_protocol udpv6_protocol = { | |||
1443 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 1443 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
1444 | }; | 1444 | }; |
1445 | 1445 | ||
1446 | static const struct net_offload udpv6_offload = { | ||
1447 | .gso_send_check = udp6_ufo_send_check, | ||
1448 | .gso_segment = udp6_ufo_fragment, | ||
1449 | }; | ||
1450 | |||
1446 | /* ------------------------------------------------------------------------ */ | 1451 | /* ------------------------------------------------------------------------ */ |
1447 | #ifdef CONFIG_PROC_FS | 1452 | #ifdef CONFIG_PROC_FS |
1448 | 1453 | ||