net: Add generic packet offload infrastructure.
Create a new data structure to contain the GRO/GSO callbacks and add a new registration mechanism. Singed-off-by: Vlad Yasevich <vyasevic@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
efad0c14b7
commit
62532da9d5
|
@ -1521,6 +1521,17 @@ struct packet_type {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct packet_offload {
|
||||||
|
__be16 type; /* This is really htons(ether_type). */
|
||||||
|
struct sk_buff *(*gso_segment)(struct sk_buff *skb,
|
||||||
|
netdev_features_t features);
|
||||||
|
int (*gso_send_check)(struct sk_buff *skb);
|
||||||
|
struct sk_buff **(*gro_receive)(struct sk_buff **head,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
int (*gro_complete)(struct sk_buff *skb);
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
|
|
||||||
/* netdevice notifier chain. Please remember to update the rtnetlink
|
/* netdevice notifier chain. Please remember to update the rtnetlink
|
||||||
|
@ -1615,6 +1626,9 @@ extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short
|
||||||
extern void dev_add_pack(struct packet_type *pt);
|
extern void dev_add_pack(struct packet_type *pt);
|
||||||
extern void dev_remove_pack(struct packet_type *pt);
|
extern void dev_remove_pack(struct packet_type *pt);
|
||||||
extern void __dev_remove_pack(struct packet_type *pt);
|
extern void __dev_remove_pack(struct packet_type *pt);
|
||||||
|
extern void dev_add_offload(struct packet_offload *po);
|
||||||
|
extern void dev_remove_offload(struct packet_offload *po);
|
||||||
|
extern void __dev_remove_offload(struct packet_offload *po);
|
||||||
|
|
||||||
extern struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short flags,
|
extern struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short flags,
|
||||||
unsigned short mask);
|
unsigned short mask);
|
||||||
|
|
|
@ -176,8 +176,10 @@
|
||||||
#define PTYPE_HASH_MASK (PTYPE_HASH_SIZE - 1)
|
#define PTYPE_HASH_MASK (PTYPE_HASH_SIZE - 1)
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(ptype_lock);
|
static DEFINE_SPINLOCK(ptype_lock);
|
||||||
|
static DEFINE_SPINLOCK(offload_lock);
|
||||||
static struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
|
static struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
|
||||||
static struct list_head ptype_all __read_mostly; /* Taps */
|
static struct list_head ptype_all __read_mostly; /* Taps */
|
||||||
|
static struct list_head offload_base __read_mostly;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
|
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
|
||||||
|
@ -470,6 +472,82 @@ void dev_remove_pack(struct packet_type *pt)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dev_remove_pack);
|
EXPORT_SYMBOL(dev_remove_pack);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dev_add_offload - register offload handlers
|
||||||
|
* @po: protocol offload declaration
|
||||||
|
*
|
||||||
|
* Add protocol offload handlers to the networking stack. The passed
|
||||||
|
* &proto_offload is linked into kernel lists and may not be freed until
|
||||||
|
* it has been removed from the kernel lists.
|
||||||
|
*
|
||||||
|
* This call does not sleep therefore it can not
|
||||||
|
* guarantee all CPU's that are in middle of receiving packets
|
||||||
|
* will see the new offload handlers (until the next received packet).
|
||||||
|
*/
|
||||||
|
void dev_add_offload(struct packet_offload *po)
|
||||||
|
{
|
||||||
|
struct list_head *head = &offload_base;
|
||||||
|
|
||||||
|
spin_lock(&offload_lock);
|
||||||
|
list_add_rcu(&po->list, head);
|
||||||
|
spin_unlock(&offload_lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dev_add_offload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __dev_remove_offload - remove offload handler
|
||||||
|
* @po: packet offload declaration
|
||||||
|
*
|
||||||
|
* Remove a protocol offload handler that was previously added to the
|
||||||
|
* kernel offload handlers by dev_add_offload(). The passed &offload_type
|
||||||
|
* is removed from the kernel lists and can be freed or reused once this
|
||||||
|
* function returns.
|
||||||
|
*
|
||||||
|
* The packet type might still be in use by receivers
|
||||||
|
* and must not be freed until after all the CPU's have gone
|
||||||
|
* through a quiescent state.
|
||||||
|
*/
|
||||||
|
void __dev_remove_offload(struct packet_offload *po)
|
||||||
|
{
|
||||||
|
struct list_head *head = &offload_base;
|
||||||
|
struct packet_offload *po1;
|
||||||
|
|
||||||
|
spin_lock(&ptype_lock);
|
||||||
|
|
||||||
|
list_for_each_entry(po1, head, list) {
|
||||||
|
if (po == po1) {
|
||||||
|
list_del_rcu(&po->list);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_warn("dev_remove_offload: %p not found\n", po);
|
||||||
|
out:
|
||||||
|
spin_unlock(&ptype_lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__dev_remove_offload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dev_remove_offload - remove packet offload handler
|
||||||
|
* @po: packet offload declaration
|
||||||
|
*
|
||||||
|
* Remove a packet offload handler that was previously added to the kernel
|
||||||
|
* offload handlers by dev_add_offload(). The passed &offload_type is
|
||||||
|
* removed from the kernel lists and can be freed or reused once this
|
||||||
|
* function returns.
|
||||||
|
*
|
||||||
|
* This call sleeps to guarantee that no CPU is looking at the packet
|
||||||
|
* type after return.
|
||||||
|
*/
|
||||||
|
void dev_remove_offload(struct packet_offload *po)
|
||||||
|
{
|
||||||
|
__dev_remove_offload(po);
|
||||||
|
|
||||||
|
synchronize_net();
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dev_remove_offload);
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
||||||
Device Boot-time Settings Routines
|
Device Boot-time Settings Routines
|
||||||
|
@ -6661,6 +6739,8 @@ static int __init net_dev_init(void)
|
||||||
for (i = 0; i < PTYPE_HASH_SIZE; i++)
|
for (i = 0; i < PTYPE_HASH_SIZE; i++)
|
||||||
INIT_LIST_HEAD(&ptype_base[i]);
|
INIT_LIST_HEAD(&ptype_base[i]);
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&offload_base);
|
||||||
|
|
||||||
if (register_pernet_subsys(&netdev_net_ops))
|
if (register_pernet_subsys(&netdev_net_ops))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue