Skip to content

Commit

Permalink
ipv6: Add new offload registration infrastructure.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Vlad Yasevich authored and David S. Miller committed Nov 15, 2012
1 parent de27d00 commit 8ca896c
Showing 5 changed files with 45 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/net/protocol.h
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ struct net_offload {
struct sk_buff **(*gro_receive)(struct sk_buff **head,
struct sk_buff *skb);
int (*gro_complete)(struct sk_buff *skb);
unsigned int flags; /* Flags used by IPv6 for now */
};

/* 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];

#if IS_ENABLED(CONFIG_IPV6)
extern const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS];
extern const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS];
#endif

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);
#if IS_ENABLED(CONFIG_IPV6)
extern int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num);
extern int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num);
extern int inet6_add_offload(const struct net_offload *prot, unsigned char num);
extern int inet6_del_offload(const struct net_offload *prot, unsigned char num);
extern int inet6_register_protosw(struct inet_protosw *p);
extern void inet6_unregister_protosw(struct inet_protosw *p);
#endif
8 changes: 8 additions & 0 deletions net/ipv6/exthdrs.c
Original file line number Diff line number Diff line change
@@ -531,11 +531,19 @@ static const struct inet6_protocol rthdr_protocol = {
.flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
};

static const struct net_offload rthdr_offload = {
.flags = INET6_PROTO_GSO_EXTHDR,
};

static const struct inet6_protocol destopt_protocol = {
.handler = ipv6_destopt_rcv,
.flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
};

static const struct net_offload dstopt_offload = {
.flags = INET6_PROTO_GSO_EXTHDR,
};

static const struct inet6_protocol nodata_protocol = {
.handler = dst_discard,
.flags = INET6_PROTO_NOPOLICY,
21 changes: 21 additions & 0 deletions net/ipv6/protocol.c
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@
#include <net/protocol.h>

const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly;
const struct net_offload __rcu *inet6_offloads[MAX_INET_PROTOS] __read_mostly;

int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
{
@@ -34,6 +35,13 @@ int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol
}
EXPORT_SYMBOL(inet6_add_protocol);

int inet6_add_offload(const struct net_offload *prot, unsigned char protocol)
{
return !cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
NULL, prot) ? 0 : -1;
}
EXPORT_SYMBOL(inet6_add_offload);

/*
* Remove a protocol from the hash tables.
*/
@@ -50,3 +58,16 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol
return ret;
}
EXPORT_SYMBOL(inet6_del_protocol);

int inet6_del_offload(const struct net_offload *prot, unsigned char protocol)
{
int ret;

ret = (cmpxchg((const struct net_offload **)&inet6_offloads[protocol],
prot, NULL) == prot) ? 0 : -1;

synchronize_net();

return ret;
}
EXPORT_SYMBOL(inet6_del_offload);
7 changes: 7 additions & 0 deletions net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
@@ -2073,6 +2073,13 @@ 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,
5 changes: 5 additions & 0 deletions net/ipv6/udp.c
Original file line number Diff line number Diff line change
@@ -1443,6 +1443,11 @@ static const struct inet6_protocol udpv6_protocol = {
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};

static const struct net_offload udpv6_offload = {
.gso_send_check = udp6_ufo_send_check,
.gso_segment = udp6_ufo_fragment,
};

/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS

0 comments on commit 8ca896c

Please sign in to comment.