4242#include <net/pkt_sched.h>
4343#include <net/checksum.h>
4444#include <net/ip6_checksum.h>
45- #include <net/failover.h>
4645
4746#include "hyperv_net.h"
4847
@@ -1780,6 +1779,46 @@ static void netvsc_link_change(struct work_struct *w)
17801779 rtnl_unlock ();
17811780}
17821781
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+
17831822/* Called when VF is injecting data into network stack.
17841823 * Change the associated network device from VF to netvsc.
17851824 * note: already called with rcu_read_lock
@@ -1802,6 +1841,46 @@ static rx_handler_result_t netvsc_vf_handle_frame(struct sk_buff **pskb)
18021841 return RX_HANDLER_ANOTHER ;
18031842}
18041843
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+
18051884static void __netvsc_vf_setup (struct net_device * ndev ,
18061885 struct net_device * vf_netdev )
18071886{
@@ -1852,95 +1931,85 @@ static void netvsc_vf_setup(struct work_struct *w)
18521931 rtnl_unlock ();
18531932}
18541933
1855- static int netvsc_pre_register_vf (struct net_device * vf_netdev ,
1856- struct net_device * ndev )
1934+ static int netvsc_register_vf (struct net_device * vf_netdev )
18571935{
1936+ struct net_device * ndev ;
18581937 struct net_device_context * net_device_ctx ;
18591938 struct netvsc_device * netvsc_dev ;
18601939
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+
18611952 net_device_ctx = netdev_priv (ndev );
18621953 netvsc_dev = rtnl_dereference (net_device_ctx -> nvdev );
18631954 if (!netvsc_dev || rtnl_dereference (net_device_ctx -> vf_netdev ))
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 );
1873-
1874- /* set slave flag before open to prevent IPv6 addrconf */
1875- vf_netdev -> flags |= IFF_SLAVE ;
1955+ return NOTIFY_DONE ;
18761956
1877- schedule_delayed_work (& ndev_ctx -> vf_takeover , VF_TAKEOVER_INT );
1957+ if (netvsc_vf_join (vf_netdev , ndev ) != 0 )
1958+ return NOTIFY_DONE ;
18781959
1879- call_netdevice_notifiers (NETDEV_JOIN , vf_netdev );
1880-
1881- netdev_info (vf_netdev , "joined to %s\n" , ndev -> name );
1960+ netdev_info (ndev , "VF registering: %s\n" , vf_netdev -> name );
18821961
18831962 dev_hold (vf_netdev );
1884- rcu_assign_pointer (ndev_ctx -> vf_netdev , vf_netdev );
1885-
1886- return 0 ;
1963+ rcu_assign_pointer (net_device_ctx -> vf_netdev , vf_netdev );
1964+ return NOTIFY_OK ;
18871965}
18881966
18891967/* VF up/down change detected, schedule to change data path */
1890- static int netvsc_vf_changed (struct net_device * vf_netdev ,
1891- struct net_device * ndev )
1968+ static int netvsc_vf_changed (struct net_device * vf_netdev )
18921969{
18931970 struct net_device_context * net_device_ctx ;
18941971 struct netvsc_device * netvsc_dev ;
1972+ struct net_device * ndev ;
18951973 bool vf_is_up = netif_running (vf_netdev );
18961974
1975+ ndev = get_netvsc_byref (vf_netdev );
1976+ if (!ndev )
1977+ return NOTIFY_DONE ;
1978+
18971979 net_device_ctx = netdev_priv (ndev );
18981980 netvsc_dev = rtnl_dereference (net_device_ctx -> nvdev );
18991981 if (!netvsc_dev )
1900- return - ENODEV ;
1982+ return NOTIFY_DONE ;
19011983
19021984 netvsc_switch_datapath (ndev , vf_is_up );
19031985 netdev_info (ndev , "Data path switched %s VF: %s\n" ,
19041986 vf_is_up ? "to" : "from" , vf_netdev -> name );
19051987
1906- return 0 ;
1988+ return NOTIFY_OK ;
19071989}
19081990
1909- static int netvsc_pre_unregister_vf (struct net_device * vf_netdev ,
1910- struct net_device * ndev )
1991+ static int netvsc_unregister_vf (struct net_device * vf_netdev )
19111992{
1993+ struct net_device * ndev ;
19121994 struct net_device_context * net_device_ctx ;
19131995
1914- net_device_ctx = netdev_priv (ndev );
1915- cancel_delayed_work_sync (& net_device_ctx -> vf_takeover );
1916-
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 ;
1996+ ndev = get_netvsc_byref (vf_netdev );
1997+ if (!ndev )
1998+ return NOTIFY_DONE ;
19241999
19252000 net_device_ctx = netdev_priv (ndev );
2001+ cancel_delayed_work_sync (& net_device_ctx -> vf_takeover );
19262002
19272003 netdev_info (ndev , "VF unregistering: %s\n" , vf_netdev -> name );
19282004
2005+ netdev_rx_handler_unregister (vf_netdev );
2006+ netdev_upper_dev_unlink (vf_netdev , ndev );
19292007 RCU_INIT_POINTER (net_device_ctx -> vf_netdev , NULL );
19302008 dev_put (vf_netdev );
19312009
1932- return 0 ;
2010+ return NOTIFY_OK ;
19332011}
19342012
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-
19442013static int netvsc_probe (struct hv_device * dev ,
19452014 const struct hv_vmbus_device_id * dev_id )
19462015{
@@ -2030,16 +2099,8 @@ static int netvsc_probe(struct hv_device *dev,
20302099 goto register_failed ;
20312100 }
20322101
2033- net_device_ctx -> failover = failover_register (net , & netvsc_failover_ops );
2034- if (IS_ERR (net_device_ctx -> failover )) {
2035- ret = PTR_ERR (net_device_ctx -> failover );
2036- goto err_failover ;
2037- }
2038-
20392102 return ret ;
20402103
2041- err_failover :
2042- unregister_netdev (net );
20432104register_failed :
20442105 rndis_filter_device_remove (dev , nvdev );
20452106rndis_failed :
@@ -2080,15 +2141,13 @@ static int netvsc_remove(struct hv_device *dev)
20802141 rtnl_lock ();
20812142 vf_netdev = rtnl_dereference (ndev_ctx -> vf_netdev );
20822143 if (vf_netdev )
2083- failover_slave_unregister (vf_netdev );
2144+ netvsc_unregister_vf (vf_netdev );
20842145
20852146 if (nvdev )
20862147 rndis_filter_device_remove (dev , nvdev );
20872148
20882149 unregister_netdevice (net );
20892150
2090- failover_unregister (ndev_ctx -> failover );
2091-
20922151 rtnl_unlock ();
20932152 rcu_read_unlock ();
20942153
@@ -2115,8 +2174,54 @@ static struct hv_driver netvsc_drv = {
21152174 .remove = netvsc_remove ,
21162175};
21172176
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+
21182222static void __exit netvsc_drv_exit (void )
21192223{
2224+ unregister_netdevice_notifier (& netvsc_netdev_notifier );
21202225 vmbus_driver_unregister (& netvsc_drv );
21212226}
21222227
@@ -2135,6 +2240,7 @@ static int __init netvsc_drv_init(void)
21352240 if (ret )
21362241 return ret ;
21372242
2243+ register_netdevice_notifier (& netvsc_netdev_notifier );
21382244 return 0 ;
21392245}
21402246
0 commit comments