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

Commit 681e683f authored by Hannes Frederic Sowa's avatar Hannes Frederic Sowa Committed by David S. Miller
Browse files

geneve: break dependency with netdev drivers



Equivalent to "vxlan: break dependency with netdev drivers", don't
autoload geneve module in case the driver is loaded. Instead make the
coupling weaker by using netdevice notifiers as proxy.

Cc: Jesse Gross <jesse@kernel.org>
Signed-off-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b7aade15
Loading
Loading
Loading
Loading
+28 −3
Original line number Original line Diff line number Diff line
@@ -1172,7 +1172,7 @@ static struct device_type geneve_type = {
 * supply the listening GENEVE udp ports. Callers are expected
 * supply the listening GENEVE udp ports. Callers are expected
 * to implement the ndo_add_geneve_port.
 * to implement the ndo_add_geneve_port.
 */
 */
void geneve_get_rx_port(struct net_device *dev)
static void geneve_push_rx_ports(struct net_device *dev)
{
{
	struct net *net = dev_net(dev);
	struct net *net = dev_net(dev);
	struct geneve_net *gn = net_generic(net, geneve_net_id);
	struct geneve_net *gn = net_generic(net, geneve_net_id);
@@ -1181,6 +1181,9 @@ void geneve_get_rx_port(struct net_device *dev)
	struct sock *sk;
	struct sock *sk;
	__be16 port;
	__be16 port;


	if (!dev->netdev_ops->ndo_add_geneve_port)
		return;

	rcu_read_lock();
	rcu_read_lock();
	list_for_each_entry_rcu(gs, &gn->sock_list, list) {
	list_for_each_entry_rcu(gs, &gn->sock_list, list) {
		sk = gs->sock->sk;
		sk = gs->sock->sk;
@@ -1190,7 +1193,6 @@ void geneve_get_rx_port(struct net_device *dev)
	}
	}
	rcu_read_unlock();
	rcu_read_unlock();
}
}
EXPORT_SYMBOL_GPL(geneve_get_rx_port);


/* Initialize the device structure. */
/* Initialize the device structure. */
static void geneve_setup(struct net_device *dev)
static void geneve_setup(struct net_device *dev)
@@ -1538,6 +1540,21 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
}
}
EXPORT_SYMBOL_GPL(geneve_dev_create_fb);
EXPORT_SYMBOL_GPL(geneve_dev_create_fb);


static int geneve_netdevice_event(struct notifier_block *unused,
				  unsigned long event, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);

	if (event == NETDEV_OFFLOAD_PUSH_GENEVE)
		geneve_push_rx_ports(dev);

	return NOTIFY_DONE;
}

static struct notifier_block geneve_notifier_block __read_mostly = {
	.notifier_call = geneve_netdevice_event,
};

static __net_init int geneve_init_net(struct net *net)
static __net_init int geneve_init_net(struct net *net)
{
{
	struct geneve_net *gn = net_generic(net, geneve_net_id);
	struct geneve_net *gn = net_generic(net, geneve_net_id);
@@ -1590,11 +1607,18 @@ static int __init geneve_init_module(void)
	if (rc)
	if (rc)
		goto out1;
		goto out1;


	rc = rtnl_link_register(&geneve_link_ops);
	rc = register_netdevice_notifier(&geneve_notifier_block);
	if (rc)
	if (rc)
		goto out2;
		goto out2;


	rc = rtnl_link_register(&geneve_link_ops);
	if (rc)
		goto out3;

	return 0;
	return 0;

out3:
	unregister_netdevice_notifier(&geneve_notifier_block);
out2:
out2:
	unregister_pernet_subsys(&geneve_net_ops);
	unregister_pernet_subsys(&geneve_net_ops);
out1:
out1:
@@ -1605,6 +1629,7 @@ late_initcall(geneve_init_module);
static void __exit geneve_cleanup_module(void)
static void __exit geneve_cleanup_module(void)
{
{
	rtnl_link_unregister(&geneve_link_ops);
	rtnl_link_unregister(&geneve_link_ops);
	unregister_netdevice_notifier(&geneve_notifier_block);
	unregister_pernet_subsys(&geneve_net_ops);
	unregister_pernet_subsys(&geneve_net_ops);
}
}
module_exit(geneve_cleanup_module);
module_exit(geneve_cleanup_module);
+1 −0
Original line number Original line Diff line number Diff line
@@ -2245,6 +2245,7 @@ struct netdev_lag_lower_state_info {
#define NETDEV_PRECHANGEUPPER	0x001A
#define NETDEV_PRECHANGEUPPER	0x001A
#define NETDEV_CHANGELOWERSTATE	0x001B
#define NETDEV_CHANGELOWERSTATE	0x001B
#define NETDEV_OFFLOAD_PUSH_VXLAN	0x001C
#define NETDEV_OFFLOAD_PUSH_VXLAN	0x001C
#define NETDEV_OFFLOAD_PUSH_GENEVE	0x001D


int register_netdevice_notifier(struct notifier_block *nb);
int register_netdevice_notifier(struct notifier_block *nb);
int unregister_netdevice_notifier(struct notifier_block *nb);
int unregister_netdevice_notifier(struct notifier_block *nb);
+2 −4
Original line number Original line Diff line number Diff line
@@ -62,13 +62,11 @@ struct genevehdr {
	struct geneve_opt options[];
	struct geneve_opt options[];
};
};


#if IS_ENABLED(CONFIG_GENEVE)
void geneve_get_rx_port(struct net_device *netdev);
#else
static inline void geneve_get_rx_port(struct net_device *netdev)
static inline void geneve_get_rx_port(struct net_device *netdev)
{
{
	ASSERT_RTNL();
	call_netdevice_notifiers(NETDEV_OFFLOAD_PUSH_GENEVE, netdev);
}
}
#endif


#ifdef CONFIG_INET
#ifdef CONFIG_INET
struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
struct net_device *geneve_dev_create_fb(struct net *net, const char *name,