Skip to content

Commit

Permalink
batman-adv: additional checks for virtual interfaces on top of WiFi
Browse files Browse the repository at this point in the history
In a few situations batman-adv tries to determine whether a given interface
is a WiFi interface to enable specific WiFi optimizations. If the interface
batman-adv has been configured with is a virtual interface (e.g. VLAN) it
would not be properly detected as WiFi interface and thus not benefit from
the special WiFi treatment.
This patch changes that by peeking under the hood whenever a virtual
interface is in play.

Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
[sven.eckelmann@open-mesh.com: integrate in wifi_flags caching, retrieve
 namespace of link interface]
Signed-off-by: Sven Eckelmann <sven.eckelmann@open-mesh.com>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
  • Loading branch information
lindnermarek authored and simonwunderlich committed Nov 8, 2016
1 parent 10b1bbb commit 5ed4a46
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
58 changes: 58 additions & 0 deletions net/batman-adv/hard-interface.c
Expand Up @@ -201,6 +201,47 @@ static bool batadv_is_valid_iface(const struct net_device *net_dev)
return true;
}

/**
* 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
*
* 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_is_wext_netdev - check if the given net_device struct is a
* wext wifi interface
Expand Down Expand Up @@ -254,13 +295,29 @@ static bool batadv_is_cfg80211_netdev(struct net_device *net_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;
}

Expand All @@ -277,6 +334,7 @@ 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);
}
Expand Down
4 changes: 4 additions & 0 deletions net/batman-adv/types.h
Expand Up @@ -123,10 +123,14 @@ struct batadv_hard_iface_bat_v {
* of a batadv_hard_iface
* @BATADV_HARDIF_WIFI_WEXT_DIRECT: it is a wext wifi device
* @BATADV_HARDIF_WIFI_CFG80211_DIRECT: it is a cfg80211 wifi device
* @BATADV_HARDIF_WIFI_WEXT_INDIRECT: link device is a wext wifi device
* @BATADV_HARDIF_WIFI_CFG80211_INDIRECT: link device is a cfg80211 wifi device
*/
enum batadv_hard_iface_wifi_flags {
BATADV_HARDIF_WIFI_WEXT_DIRECT = BIT(0),
BATADV_HARDIF_WIFI_CFG80211_DIRECT = BIT(1),
BATADV_HARDIF_WIFI_WEXT_INDIRECT = BIT(2),
BATADV_HARDIF_WIFI_CFG80211_INDIRECT = BIT(3),
};

/**
Expand Down

0 comments on commit 5ed4a46

Please sign in to comment.