[linux-next] LinuxNextTracking branch, master, updated. next-20161122

batman at open-mesh.org batman at open-mesh.org
Wed Nov 23 00:16:00 CET 2016


The following commit has been merged in the master branch:
commit f463c99b208718b4fd25ec3501e0bd9d2e30f522
Merge: 5a2138812604c32b7617b3b2e53e336617121d3b 9b4aec647a92a2464337db10507348aecf0f0fd7
Author: David S. Miller <davem at davemloft.net>
Date:   Sat Nov 19 11:13:05 2016 -0500

    Merge tag 'batadv-next-for-davem-20161119' of git://git.open-mesh.org/linux-merge
    
    Simon Wunderlich says:
    
    ====================
    This feature patchset includes the following changes:
    
     - 6 patches adding functionality to detect a WiFi interface under
       other virtual interfaces, like VLANs. They introduce a cache for
       the detected the WiFi configuration to avoid RTNL locking in
       critical sections. Patches have been prepared by Marek Lindner
       and Sven Eckelmann
    
     - Enable automatic module loading for genl requests, by Sven Eckelmann
    
     - Fix a potential race condition on interface removal. This is not
       happening very often in practice, but requires bigger changes to fix,
       so we are sending this to net-next. By Linus Luessing
    ====================
    
    Signed-off-by: David S. Miller <davem at davemloft.net>

diff --combined net/batman-adv/hard-interface.c
index dc1816e,61a431a..672150b4
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@@ -92,8 -92,8 +92,8 @@@ out
   *
   * Return: result of rtnl_link_ops->get_link_net or @fallback_net
   */
- static const struct net *batadv_getlink_net(const struct net_device *netdev,
- 					    const struct net *fallback_net)
+ static struct net *batadv_getlink_net(const struct net_device *netdev,
+ 				      struct net *fallback_net)
  {
  	if (!netdev->rtnl_link_ops)
  		return fallback_net;
@@@ -116,9 -116,9 +116,9 @@@
   * Return: true if the devices are each others parent, otherwise false
   */
  static bool batadv_mutual_parents(const struct net_device *dev1,
- 				  const struct net *net1,
+ 				  struct net *net1,
  				  const struct net_device *dev2,
- 				  const struct net *net2)
+ 				  struct net *net2)
  {
  	int dev1_parent_iflink = dev_get_iflink(dev1);
  	int dev2_parent_iflink = dev_get_iflink(dev2);
@@@ -154,7 -154,7 +154,7 @@@ static bool batadv_is_on_batman_iface(c
  {
  	struct net *net = dev_net(net_dev);
  	struct net_device *parent_dev;
- 	const struct net *parent_net;
+ 	struct net *parent_net;
  	bool ret;
  
  	/* check if this is a batman-adv mesh interface */
@@@ -202,13 -202,77 +202,77 @@@ static bool batadv_is_valid_iface(cons
  }
  
  /**
-  * batadv_is_wifi_netdev - check if the given net_device struct is a wifi
-  *  interface
+  * batadv_get_real_netdevice - check if the given netdev struct is a virtual
+  *  interface on top of another 'real' interface
+  * @netdev: the device to check
+  *
+  * Callers must hold the rtnl semaphore. You may want batadv_get_real_netdev()
+  * instead of this.
+  *
+  * Return: the 'real' net device or the original net device and NULL in case
+  *  of an error.
+  */
+ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
+ {
+ 	struct batadv_hard_iface *hard_iface = NULL;
+ 	struct net_device *real_netdev = NULL;
+ 	struct net *real_net;
+ 	struct net *net;
+ 	int ifindex;
+ 
+ 	ASSERT_RTNL();
+ 
+ 	if (!netdev)
+ 		return NULL;
+ 
+ 	if (netdev->ifindex == dev_get_iflink(netdev)) {
+ 		dev_hold(netdev);
+ 		return netdev;
+ 	}
+ 
+ 	hard_iface = batadv_hardif_get_by_netdev(netdev);
+ 	if (!hard_iface || !hard_iface->soft_iface)
+ 		goto out;
+ 
+ 	net = dev_net(hard_iface->soft_iface);
+ 	ifindex = dev_get_iflink(netdev);
+ 	real_net = batadv_getlink_net(netdev, net);
+ 	real_netdev = dev_get_by_index(real_net, ifindex);
+ 
+ out:
+ 	if (hard_iface)
+ 		batadv_hardif_put(hard_iface);
+ 	return real_netdev;
+ }
+ 
+ /**
+  * batadv_get_real_netdev - check if the given net_device struct is a virtual
+  *  interface on top of another 'real' interface
   * @net_device: the device to check
   *
-  * Return: true if the net device is a 802.11 wireless device, false otherwise.
+  * Return: the 'real' net device or the original net device and NULL in case
+  *  of an error.
   */
- bool batadv_is_wifi_netdev(struct net_device *net_device)
+ struct net_device *batadv_get_real_netdev(struct net_device *net_device)
+ {
+ 	struct net_device *real_netdev;
+ 
+ 	rtnl_lock();
+ 	real_netdev = batadv_get_real_netdevice(net_device);
+ 	rtnl_unlock();
+ 
+ 	return real_netdev;
+ }
+ 
+ /**
+  * batadv_is_wext_netdev - check if the given net_device struct is a
+  *  wext wifi interface
+  * @net_device: the device to check
+  *
+  * Return: true if the net device is a wext wireless device, false
+  *  otherwise.
+  */
+ static bool batadv_is_wext_netdev(struct net_device *net_device)
  {
  	if (!net_device)
  		return false;
@@@ -221,6 -285,22 +285,22 @@@
  		return true;
  #endif
  
+ 	return false;
+ }
+ 
+ /**
+  * batadv_is_cfg80211_netdev - check if the given net_device struct is a
+  *  cfg80211 wifi interface
+  * @net_device: the device to check
+  *
+  * Return: true if the net device is a cfg80211 wireless device, false
+  *  otherwise.
+  */
+ static bool batadv_is_cfg80211_netdev(struct net_device *net_device)
+ {
+ 	if (!net_device)
+ 		return false;
+ 
  	/* cfg80211 drivers have to set ieee80211_ptr */
  	if (net_device->ieee80211_ptr)
  		return true;
@@@ -229,6 -309,73 +309,73 @@@
  }
  
  /**
+  * batadv_wifi_flags_evaluate - calculate wifi flags for net_device
+  * @net_device: the device to check
+  *
+  * Return: batadv_hard_iface_wifi_flags flags of the device
+  */
+ static u32 batadv_wifi_flags_evaluate(struct net_device *net_device)
+ {
+ 	u32 wifi_flags = 0;
+ 	struct net_device *real_netdev;
+ 
+ 	if (batadv_is_wext_netdev(net_device))
+ 		wifi_flags |= BATADV_HARDIF_WIFI_WEXT_DIRECT;
+ 
+ 	if (batadv_is_cfg80211_netdev(net_device))
+ 		wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
+ 
+ 	real_netdev = batadv_get_real_netdevice(net_device);
+ 	if (!real_netdev)
+ 		return wifi_flags;
+ 
+ 	if (real_netdev == net_device)
+ 		goto out;
+ 
+ 	if (batadv_is_wext_netdev(real_netdev))
+ 		wifi_flags |= BATADV_HARDIF_WIFI_WEXT_INDIRECT;
+ 
+ 	if (batadv_is_cfg80211_netdev(real_netdev))
+ 		wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
+ 
+ out:
+ 	dev_put(real_netdev);
+ 	return wifi_flags;
+ }
+ 
+ /**
+  * batadv_is_cfg80211_hardif - check if the given hardif is a cfg80211 wifi
+  *  interface
+  * @hard_iface: the device to check
+  *
+  * Return: true if the net device is a cfg80211 wireless device, false
+  *  otherwise.
+  */
+ bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface)
+ {
+ 	u32 allowed_flags = 0;
+ 
+ 	allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
+ 	allowed_flags |= BATADV_HARDIF_WIFI_CFG80211_INDIRECT;
+ 
+ 	return !!(hard_iface->wifi_flags & allowed_flags);
+ }
+ 
+ /**
+  * batadv_is_wifi_hardif - check if the given hardif is a wifi interface
+  * @hard_iface: the device to check
+  *
+  * Return: true if the net device is a 802.11 wireless device, false otherwise.
+  */
+ bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface)
+ {
+ 	if (!hard_iface)
+ 		return false;
+ 
+ 	return hard_iface->wifi_flags != 0;
+ }
+ 
+ /**
   * batadv_hardif_no_broadcast - check whether (re)broadcast is necessary
   * @if_outgoing: the outgoing interface checked and considered for (re)broadcast
   * @orig_addr: the originator of this packet
@@@ -704,6 -851,7 +851,6 @@@ void batadv_hardif_disable_interface(st
  			batadv_softif_destroy_sysfs(hard_iface->soft_iface);
  	}
  
 -	hard_iface->soft_iface = NULL;
  	batadv_hardif_put(hard_iface);
  
  out:
@@@ -748,7 -896,8 +895,8 @@@ batadv_hardif_add_interface(struct net_
  	kref_init(&hard_iface->refcount);
  
  	hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
- 	if (batadv_is_wifi_netdev(net_dev))
+ 	hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
+ 	if (batadv_is_wifi_hardif(hard_iface))
  		hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
  
  	batadv_v_hardif_init(hard_iface);
@@@ -857,6 -1006,11 +1005,11 @@@ static int batadv_hard_if_event(struct 
  		if (hard_iface == primary_if)
  			batadv_primary_if_update_addr(bat_priv, NULL);
  		break;
+ 	case NETDEV_CHANGEUPPER:
+ 		hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
+ 		if (batadv_is_wifi_hardif(hard_iface))
+ 			hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
+ 		break;
  	default:
  		break;
  	}

-- 
LinuxNextTracking


More information about the linux-merge mailing list