4343#include <net/pkt_sched.h>
4444#include <net/checksum.h>
4545#include <net/ip6_checksum.h>
46+ #include <net/failover.h>
4647
4748#include "hyperv_net.h"
4849
@@ -1779,46 +1780,6 @@ static void netvsc_link_change(struct work_struct *w)
17791780 rtnl_unlock ();
17801781}
17811782
1782- static struct net_device * get_netvsc_bymac (const u8 * mac )
1783- {
1784- struct net_device * dev ;
1785-
1786- ASSERT_RTNL ();
1787-
1788- for_each_netdev (& init_net , dev ) {
1789- if (dev -> netdev_ops != & device_ops )
1790- continue ; /* not a netvsc device */
1791-
1792- if (ether_addr_equal (mac , dev -> perm_addr ))
1793- return dev ;
1794- }
1795-
1796- return NULL ;
1797- }
1798-
1799- static struct net_device * get_netvsc_byref (struct net_device * vf_netdev )
1800- {
1801- struct net_device * dev ;
1802-
1803- ASSERT_RTNL ();
1804-
1805- for_each_netdev (& init_net , dev ) {
1806- struct net_device_context * net_device_ctx ;
1807-
1808- if (dev -> netdev_ops != & device_ops )
1809- continue ; /* not a netvsc device */
1810-
1811- net_device_ctx = netdev_priv (dev );
1812- if (!rtnl_dereference (net_device_ctx -> nvdev ))
1813- continue ; /* device is removed */
1814-
1815- if (rtnl_dereference (net_device_ctx -> vf_netdev ) == vf_netdev )
1816- return dev ; /* a match */
1817- }
1818-
1819- return NULL ;
1820- }
1821-
18221783/* Called when VF is injecting data into network stack.
18231784 * Change the associated network device from VF to netvsc.
18241785 * note: already called with rcu_read_lock
@@ -1841,46 +1802,6 @@ static rx_handler_result_t netvsc_vf_handle_frame(struct sk_buff **pskb)
18411802 return RX_HANDLER_ANOTHER ;
18421803}
18431804
1844- static int netvsc_vf_join (struct net_device * vf_netdev ,
1845- struct net_device * ndev )
1846- {
1847- struct net_device_context * ndev_ctx = netdev_priv (ndev );
1848- int ret ;
1849-
1850- ret = netdev_rx_handler_register (vf_netdev ,
1851- netvsc_vf_handle_frame , ndev );
1852- if (ret != 0 ) {
1853- netdev_err (vf_netdev ,
1854- "can not register netvsc VF receive handler (err = %d)\n" ,
1855- ret );
1856- goto rx_handler_failed ;
1857- }
1858-
1859- ret = netdev_master_upper_dev_link (vf_netdev , ndev ,
1860- NULL , NULL , NULL );
1861- if (ret != 0 ) {
1862- netdev_err (vf_netdev ,
1863- "can not set master device %s (err = %d)\n" ,
1864- ndev -> name , ret );
1865- goto upper_link_failed ;
1866- }
1867-
1868- /* set slave flag before open to prevent IPv6 addrconf */
1869- vf_netdev -> flags |= IFF_SLAVE ;
1870-
1871- schedule_delayed_work (& ndev_ctx -> vf_takeover , VF_TAKEOVER_INT );
1872-
1873- call_netdevice_notifiers (NETDEV_JOIN , vf_netdev );
1874-
1875- netdev_info (vf_netdev , "joined to %s\n" , ndev -> name );
1876- return 0 ;
1877-
1878- upper_link_failed :
1879- netdev_rx_handler_unregister (vf_netdev );
1880- rx_handler_failed :
1881- return ret ;
1882- }
1883-
18841805static void __netvsc_vf_setup (struct net_device * ndev ,
18851806 struct net_device * vf_netdev )
18861807{
@@ -1931,85 +1852,95 @@ static void netvsc_vf_setup(struct work_struct *w)
19311852 rtnl_unlock ();
19321853}
19331854
1934- static int netvsc_register_vf (struct net_device * vf_netdev )
1855+ static int netvsc_pre_register_vf (struct net_device * vf_netdev ,
1856+ struct net_device * ndev )
19351857{
1936- struct net_device * ndev ;
19371858 struct net_device_context * net_device_ctx ;
19381859 struct netvsc_device * netvsc_dev ;
19391860
1940- if (vf_netdev -> addr_len != ETH_ALEN )
1941- return NOTIFY_DONE ;
1942-
1943- /*
1944- * We will use the MAC address to locate the synthetic interface to
1945- * associate with the VF interface. If we don't find a matching
1946- * synthetic interface, move on.
1947- */
1948- ndev = get_netvsc_bymac (vf_netdev -> perm_addr );
1949- if (!ndev )
1950- return NOTIFY_DONE ;
1951-
19521861 net_device_ctx = netdev_priv (ndev );
19531862 netvsc_dev = rtnl_dereference (net_device_ctx -> nvdev );
19541863 if (!netvsc_dev || rtnl_dereference (net_device_ctx -> vf_netdev ))
1955- return NOTIFY_DONE ;
1864+ return - ENODEV ;
1865+
1866+ return 0 ;
1867+ }
1868+
1869+ static int netvsc_register_vf (struct net_device * vf_netdev ,
1870+ struct net_device * ndev )
1871+ {
1872+ struct net_device_context * ndev_ctx = netdev_priv (ndev );
19561873
1957- if ( netvsc_vf_join ( vf_netdev , ndev ) != 0 )
1958- return NOTIFY_DONE ;
1874+ /* set slave flag before open to prevent IPv6 addrconf */
1875+ vf_netdev -> flags |= IFF_SLAVE ;
19591876
1960- netdev_info (ndev , "VF registering: %s\n" , vf_netdev -> name );
1877+ schedule_delayed_work (& ndev_ctx -> vf_takeover , VF_TAKEOVER_INT );
1878+
1879+ call_netdevice_notifiers (NETDEV_JOIN , vf_netdev );
1880+
1881+ netdev_info (vf_netdev , "joined to %s\n" , ndev -> name );
19611882
19621883 dev_hold (vf_netdev );
1963- rcu_assign_pointer (net_device_ctx -> vf_netdev , vf_netdev );
1964- return NOTIFY_OK ;
1884+ rcu_assign_pointer (ndev_ctx -> vf_netdev , vf_netdev );
1885+
1886+ return 0 ;
19651887}
19661888
19671889/* VF up/down change detected, schedule to change data path */
1968- static int netvsc_vf_changed (struct net_device * vf_netdev )
1890+ static int netvsc_vf_changed (struct net_device * vf_netdev ,
1891+ struct net_device * ndev )
19691892{
19701893 struct net_device_context * net_device_ctx ;
19711894 struct netvsc_device * netvsc_dev ;
1972- struct net_device * ndev ;
19731895 bool vf_is_up = netif_running (vf_netdev );
19741896
1975- ndev = get_netvsc_byref (vf_netdev );
1976- if (!ndev )
1977- return NOTIFY_DONE ;
1978-
19791897 net_device_ctx = netdev_priv (ndev );
19801898 netvsc_dev = rtnl_dereference (net_device_ctx -> nvdev );
19811899 if (!netvsc_dev )
1982- return NOTIFY_DONE ;
1900+ return - ENODEV ;
19831901
19841902 netvsc_switch_datapath (ndev , vf_is_up );
19851903 netdev_info (ndev , "Data path switched %s VF: %s\n" ,
19861904 vf_is_up ? "to" : "from" , vf_netdev -> name );
19871905
1988- return NOTIFY_OK ;
1906+ return 0 ;
19891907}
19901908
1991- static int netvsc_unregister_vf (struct net_device * vf_netdev )
1909+ static int netvsc_pre_unregister_vf (struct net_device * vf_netdev ,
1910+ struct net_device * ndev )
19921911{
1993- struct net_device * ndev ;
19941912 struct net_device_context * net_device_ctx ;
19951913
1996- ndev = get_netvsc_byref (vf_netdev );
1997- if (!ndev )
1998- return NOTIFY_DONE ;
1999-
20001914 net_device_ctx = netdev_priv (ndev );
20011915 cancel_delayed_work_sync (& net_device_ctx -> vf_takeover );
20021916
1917+ return 0 ;
1918+ }
1919+
1920+ static int netvsc_unregister_vf (struct net_device * vf_netdev ,
1921+ struct net_device * ndev )
1922+ {
1923+ struct net_device_context * net_device_ctx ;
1924+
1925+ net_device_ctx = netdev_priv (ndev );
1926+
20031927 netdev_info (ndev , "VF unregistering: %s\n" , vf_netdev -> name );
20041928
2005- netdev_rx_handler_unregister (vf_netdev );
2006- netdev_upper_dev_unlink (vf_netdev , ndev );
20071929 RCU_INIT_POINTER (net_device_ctx -> vf_netdev , NULL );
20081930 dev_put (vf_netdev );
20091931
2010- return NOTIFY_OK ;
1932+ return 0 ;
20111933}
20121934
1935+ static struct failover_ops netvsc_failover_ops = {
1936+ .slave_pre_register = netvsc_pre_register_vf ,
1937+ .slave_register = netvsc_register_vf ,
1938+ .slave_pre_unregister = netvsc_pre_unregister_vf ,
1939+ .slave_unregister = netvsc_unregister_vf ,
1940+ .slave_link_change = netvsc_vf_changed ,
1941+ .slave_handle_frame = netvsc_vf_handle_frame ,
1942+ };
1943+
20131944static int netvsc_probe (struct hv_device * dev ,
20141945 const struct hv_vmbus_device_id * dev_id )
20151946{
@@ -2099,8 +2030,14 @@ static int netvsc_probe(struct hv_device *dev,
20992030 goto register_failed ;
21002031 }
21012032
2033+ net_device_ctx -> failover = failover_register (net , & netvsc_failover_ops );
2034+ if (IS_ERR (net_device_ctx -> failover ))
2035+ goto err_failover ;
2036+
21022037 return ret ;
21032038
2039+ err_failover :
2040+ unregister_netdev (net );
21042041register_failed :
21052042 rndis_filter_device_remove (dev , nvdev );
21062043rndis_failed :
@@ -2141,13 +2078,15 @@ static int netvsc_remove(struct hv_device *dev)
21412078 rtnl_lock ();
21422079 vf_netdev = rtnl_dereference (ndev_ctx -> vf_netdev );
21432080 if (vf_netdev )
2144- netvsc_unregister_vf (vf_netdev );
2081+ failover_slave_unregister (vf_netdev );
21452082
21462083 if (nvdev )
21472084 rndis_filter_device_remove (dev , nvdev );
21482085
21492086 unregister_netdevice (net );
21502087
2088+ failover_unregister (ndev_ctx -> failover );
2089+
21512090 rtnl_unlock ();
21522091 rcu_read_unlock ();
21532092
@@ -2174,54 +2113,8 @@ static struct hv_driver netvsc_drv = {
21742113 .remove = netvsc_remove ,
21752114};
21762115
2177- /*
2178- * On Hyper-V, every VF interface is matched with a corresponding
2179- * synthetic interface. The synthetic interface is presented first
2180- * to the guest. When the corresponding VF instance is registered,
2181- * we will take care of switching the data path.
2182- */
2183- static int netvsc_netdev_event (struct notifier_block * this ,
2184- unsigned long event , void * ptr )
2185- {
2186- struct net_device * event_dev = netdev_notifier_info_to_dev (ptr );
2187-
2188- /* Skip our own events */
2189- if (event_dev -> netdev_ops == & device_ops )
2190- return NOTIFY_DONE ;
2191-
2192- /* Avoid non-Ethernet type devices */
2193- if (event_dev -> type != ARPHRD_ETHER )
2194- return NOTIFY_DONE ;
2195-
2196- /* Avoid Vlan dev with same MAC registering as VF */
2197- if (is_vlan_dev (event_dev ))
2198- return NOTIFY_DONE ;
2199-
2200- /* Avoid Bonding master dev with same MAC registering as VF */
2201- if ((event_dev -> priv_flags & IFF_BONDING ) &&
2202- (event_dev -> flags & IFF_MASTER ))
2203- return NOTIFY_DONE ;
2204-
2205- switch (event ) {
2206- case NETDEV_REGISTER :
2207- return netvsc_register_vf (event_dev );
2208- case NETDEV_UNREGISTER :
2209- return netvsc_unregister_vf (event_dev );
2210- case NETDEV_UP :
2211- case NETDEV_DOWN :
2212- return netvsc_vf_changed (event_dev );
2213- default :
2214- return NOTIFY_DONE ;
2215- }
2216- }
2217-
2218- static struct notifier_block netvsc_netdev_notifier = {
2219- .notifier_call = netvsc_netdev_event ,
2220- };
2221-
22222116static void __exit netvsc_drv_exit (void )
22232117{
2224- unregister_netdevice_notifier (& netvsc_netdev_notifier );
22252118 vmbus_driver_unregister (& netvsc_drv );
22262119}
22272120
@@ -2241,7 +2134,6 @@ static int __init netvsc_drv_init(void)
22412134 if (ret )
22422135 return ret ;
22432136
2244- register_netdevice_notifier (& netvsc_netdev_notifier );
22452137 return 0 ;
22462138}
22472139
0 commit comments