Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab95bfe0 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

net: replace hooks in __netif_receive_skb V5



What this patch does is it removes two receive frame hooks (for bridge and for
macvlan) from __netif_receive_skb. These are replaced them with a single
hook for both. It only supports one hook per device because it makes no
sense to do bridging and macvlan on the same device.

Then a network driver (of virtual netdev like macvlan or bridge) can register
an rx_handler for needed net device.

Signed-off-by: default avatarJiri Pirko <jpirko@redhat.com>
Signed-off-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 20c59de2
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -145,15 +145,16 @@ static void macvlan_broadcast(struct sk_buff *skb,
}

/* called under rcu_read_lock() from netif_receive_skb */
static struct sk_buff *macvlan_handle_frame(struct macvlan_port *port,
					    struct sk_buff *skb)
static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
{
	struct macvlan_port *port;
	const struct ethhdr *eth = eth_hdr(skb);
	const struct macvlan_dev *vlan;
	const struct macvlan_dev *src;
	struct net_device *dev;
	unsigned int len;

	port = rcu_dereference(skb->dev->macvlan_port);
	if (is_multicast_ether_addr(eth->h_dest)) {
		src = macvlan_hash_lookup(port, eth->h_source);
		if (!src)
@@ -515,6 +516,7 @@ static int macvlan_port_create(struct net_device *dev)
{
	struct macvlan_port *port;
	unsigned int i;
	int err;

	if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK)
		return -EINVAL;
@@ -528,13 +530,21 @@ static int macvlan_port_create(struct net_device *dev)
	for (i = 0; i < MACVLAN_HASH_SIZE; i++)
		INIT_HLIST_HEAD(&port->vlan_hash[i]);
	rcu_assign_pointer(dev->macvlan_port, port);
	return 0;

	err = netdev_rx_handler_register(dev, macvlan_handle_frame);
	if (err) {
		rcu_assign_pointer(dev->macvlan_port, NULL);
		kfree(port);
	}

	return err;
}

static void macvlan_port_destroy(struct net_device *dev)
{
	struct macvlan_port *port = dev->macvlan_port;

	netdev_rx_handler_unregister(dev);
	rcu_assign_pointer(dev->macvlan_port, NULL);
	synchronize_rcu();
	kfree(port);
@@ -767,14 +777,12 @@ static int __init macvlan_init_module(void)
	int err;

	register_netdevice_notifier(&macvlan_notifier_block);
	macvlan_handle_frame_hook = macvlan_handle_frame;

	err = macvlan_link_register(&macvlan_link_ops);
	if (err < 0)
		goto err1;
	return 0;
err1:
	macvlan_handle_frame_hook = NULL;
	unregister_netdevice_notifier(&macvlan_notifier_block);
	return err;
}
@@ -782,7 +790,6 @@ err1:
static void __exit macvlan_cleanup_module(void)
{
	rtnl_link_unregister(&macvlan_link_ops);
	macvlan_handle_frame_hook = NULL;
	unregister_netdevice_notifier(&macvlan_notifier_block);
}

+0 −2
Original line number Diff line number Diff line
@@ -102,8 +102,6 @@ struct __fdb_entry {
#include <linux/netdevice.h>

extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
					       struct sk_buff *skb);
extern int (*br_should_route_hook)(struct sk_buff *skb);

#endif
+0 −4
Original line number Diff line number Diff line
@@ -84,8 +84,4 @@ extern int macvlan_link_register(struct rtnl_link_ops *ops);
extern netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
				      struct net_device *dev);


extern struct sk_buff *(*macvlan_handle_frame_hook)(struct macvlan_port *,
						    struct sk_buff *);

#endif /* _LINUX_IF_MACVLAN_H */
+7 −0
Original line number Diff line number Diff line
@@ -381,6 +381,8 @@ enum gro_result {
};
typedef enum gro_result gro_result_t;

typedef struct sk_buff *rx_handler_func_t(struct sk_buff *skb);

extern void __napi_schedule(struct napi_struct *n);

static inline int napi_disable_pending(struct napi_struct *n)
@@ -957,6 +959,7 @@ struct net_device {
#endif

	struct netdev_queue	rx_queue;
	rx_handler_func_t	*rx_handler;

	struct netdev_queue	*_tx ____cacheline_aligned_in_smp;

@@ -1689,6 +1692,10 @@ static inline void napi_free_frags(struct napi_struct *napi)
	napi->skb = NULL;
}

extern int netdev_rx_handler_register(struct net_device *dev,
				      rx_handler_func_t *rx_handler);
extern void netdev_rx_handler_unregister(struct net_device *dev);

extern void		netif_nit_deliver(struct sk_buff *skb);
extern int		dev_valid_name(const char *name);
extern int		dev_ioctl(struct net *net, unsigned int cmd, void __user *);
+0 −2
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ static int __init br_init(void)
		goto err_out4;

	brioctl_set(br_ioctl_deviceless_stub);
	br_handle_frame_hook = br_handle_frame;

#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
	br_fdb_test_addr_hook = br_fdb_test_addr;
@@ -100,7 +99,6 @@ static void __exit br_deinit(void)
	br_fdb_test_addr_hook = NULL;
#endif

	br_handle_frame_hook = NULL;
	br_fdb_fini();
}

Loading