diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2016-04-18 15:19:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-21 15:35:44 -0400 |
commit | 681e683ff30ada19f73c17c38a528528dd8824f1 (patch) | |
tree | dfb1140e166ecf89f994f667e0cb9e73969845e8 | |
parent | b7aade15485a660cbf5161962c284131324a9534 (diff) |
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: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/geneve.c | 31 | ||||
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | include/net/geneve.h | 6 |
3 files changed, 31 insertions, 7 deletions
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 512dbe013713..9c40b88fabd5 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c | |||
@@ -1172,7 +1172,7 @@ static struct device_type geneve_type = { | |||
1172 | * supply the listening GENEVE udp ports. Callers are expected | 1172 | * supply the listening GENEVE udp ports. Callers are expected |
1173 | * to implement the ndo_add_geneve_port. | 1173 | * to implement the ndo_add_geneve_port. |
1174 | */ | 1174 | */ |
1175 | void geneve_get_rx_port(struct net_device *dev) | 1175 | static void geneve_push_rx_ports(struct net_device *dev) |
1176 | { | 1176 | { |
1177 | struct net *net = dev_net(dev); | 1177 | struct net *net = dev_net(dev); |
1178 | struct geneve_net *gn = net_generic(net, geneve_net_id); | 1178 | struct geneve_net *gn = net_generic(net, geneve_net_id); |
@@ -1181,6 +1181,9 @@ void geneve_get_rx_port(struct net_device *dev) | |||
1181 | struct sock *sk; | 1181 | struct sock *sk; |
1182 | __be16 port; | 1182 | __be16 port; |
1183 | 1183 | ||
1184 | if (!dev->netdev_ops->ndo_add_geneve_port) | ||
1185 | return; | ||
1186 | |||
1184 | rcu_read_lock(); | 1187 | rcu_read_lock(); |
1185 | list_for_each_entry_rcu(gs, &gn->sock_list, list) { | 1188 | list_for_each_entry_rcu(gs, &gn->sock_list, list) { |
1186 | sk = gs->sock->sk; | 1189 | sk = gs->sock->sk; |
@@ -1190,7 +1193,6 @@ void geneve_get_rx_port(struct net_device *dev) | |||
1190 | } | 1193 | } |
1191 | rcu_read_unlock(); | 1194 | rcu_read_unlock(); |
1192 | } | 1195 | } |
1193 | EXPORT_SYMBOL_GPL(geneve_get_rx_port); | ||
1194 | 1196 | ||
1195 | /* Initialize the device structure. */ | 1197 | /* Initialize the device structure. */ |
1196 | static void geneve_setup(struct net_device *dev) | 1198 | 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, | |||
1538 | } | 1540 | } |
1539 | EXPORT_SYMBOL_GPL(geneve_dev_create_fb); | 1541 | EXPORT_SYMBOL_GPL(geneve_dev_create_fb); |
1540 | 1542 | ||
1543 | static int geneve_netdevice_event(struct notifier_block *unused, | ||
1544 | unsigned long event, void *ptr) | ||
1545 | { | ||
1546 | struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||
1547 | |||
1548 | if (event == NETDEV_OFFLOAD_PUSH_GENEVE) | ||
1549 | geneve_push_rx_ports(dev); | ||
1550 | |||
1551 | return NOTIFY_DONE; | ||
1552 | } | ||
1553 | |||
1554 | static struct notifier_block geneve_notifier_block __read_mostly = { | ||
1555 | .notifier_call = geneve_netdevice_event, | ||
1556 | }; | ||
1557 | |||
1541 | static __net_init int geneve_init_net(struct net *net) | 1558 | static __net_init int geneve_init_net(struct net *net) |
1542 | { | 1559 | { |
1543 | struct geneve_net *gn = net_generic(net, geneve_net_id); | 1560 | struct geneve_net *gn = net_generic(net, geneve_net_id); |
@@ -1590,11 +1607,18 @@ static int __init geneve_init_module(void) | |||
1590 | if (rc) | 1607 | if (rc) |
1591 | goto out1; | 1608 | goto out1; |
1592 | 1609 | ||
1593 | rc = rtnl_link_register(&geneve_link_ops); | 1610 | rc = register_netdevice_notifier(&geneve_notifier_block); |
1594 | if (rc) | 1611 | if (rc) |
1595 | goto out2; | 1612 | goto out2; |
1596 | 1613 | ||
1614 | rc = rtnl_link_register(&geneve_link_ops); | ||
1615 | if (rc) | ||
1616 | goto out3; | ||
1617 | |||
1597 | return 0; | 1618 | return 0; |
1619 | |||
1620 | out3: | ||
1621 | unregister_netdevice_notifier(&geneve_notifier_block); | ||
1598 | out2: | 1622 | out2: |
1599 | unregister_pernet_subsys(&geneve_net_ops); | 1623 | unregister_pernet_subsys(&geneve_net_ops); |
1600 | out1: | 1624 | out1: |
@@ -1605,6 +1629,7 @@ late_initcall(geneve_init_module); | |||
1605 | static void __exit geneve_cleanup_module(void) | 1629 | static void __exit geneve_cleanup_module(void) |
1606 | { | 1630 | { |
1607 | rtnl_link_unregister(&geneve_link_ops); | 1631 | rtnl_link_unregister(&geneve_link_ops); |
1632 | unregister_netdevice_notifier(&geneve_notifier_block); | ||
1608 | unregister_pernet_subsys(&geneve_net_ops); | 1633 | unregister_pernet_subsys(&geneve_net_ops); |
1609 | } | 1634 | } |
1610 | module_exit(geneve_cleanup_module); | 1635 | module_exit(geneve_cleanup_module); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d4c8cd424f8d..1f6d5db471a2 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -2245,6 +2245,7 @@ struct netdev_lag_lower_state_info { | |||
2245 | #define NETDEV_PRECHANGEUPPER 0x001A | 2245 | #define NETDEV_PRECHANGEUPPER 0x001A |
2246 | #define NETDEV_CHANGELOWERSTATE 0x001B | 2246 | #define NETDEV_CHANGELOWERSTATE 0x001B |
2247 | #define NETDEV_OFFLOAD_PUSH_VXLAN 0x001C | 2247 | #define NETDEV_OFFLOAD_PUSH_VXLAN 0x001C |
2248 | #define NETDEV_OFFLOAD_PUSH_GENEVE 0x001D | ||
2248 | 2249 | ||
2249 | int register_netdevice_notifier(struct notifier_block *nb); | 2250 | int register_netdevice_notifier(struct notifier_block *nb); |
2250 | int unregister_netdevice_notifier(struct notifier_block *nb); | 2251 | int unregister_netdevice_notifier(struct notifier_block *nb); |
diff --git a/include/net/geneve.h b/include/net/geneve.h index e6c23dc765f7..cb544a530146 100644 --- a/include/net/geneve.h +++ b/include/net/geneve.h | |||
@@ -62,13 +62,11 @@ struct genevehdr { | |||
62 | struct geneve_opt options[]; | 62 | struct geneve_opt options[]; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | #if IS_ENABLED(CONFIG_GENEVE) | ||
66 | void geneve_get_rx_port(struct net_device *netdev); | ||
67 | #else | ||
68 | static inline void geneve_get_rx_port(struct net_device *netdev) | 65 | static inline void geneve_get_rx_port(struct net_device *netdev) |
69 | { | 66 | { |
67 | ASSERT_RTNL(); | ||
68 | call_netdevice_notifiers(NETDEV_OFFLOAD_PUSH_GENEVE, netdev); | ||
70 | } | 69 | } |
71 | #endif | ||
72 | 70 | ||
73 | #ifdef CONFIG_INET | 71 | #ifdef CONFIG_INET |
74 | struct net_device *geneve_dev_create_fb(struct net *net, const char *name, | 72 | struct net_device *geneve_dev_create_fb(struct net *net, const char *name, |