Commit f463c99b authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 5a213881 9b4aec64
...@@ -717,17 +717,10 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, ...@@ -717,17 +717,10 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
if (direct_link) if (direct_link)
forw_packet_aggr->direct_link_flags |= 1; forw_packet_aggr->direct_link_flags |= 1;
/* add new packet to packet list */
spin_lock_bh(&bat_priv->forw_bat_list_lock);
hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
/* start timer for this packet */
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
batadv_iv_send_outstanding_bat_ogm_packet); batadv_iv_send_outstanding_bat_ogm_packet);
queue_delayed_work(batadv_event_workqueue,
&forw_packet_aggr->delayed_work, batadv_forw_packet_ogmv1_queue(bat_priv, forw_packet_aggr, send_time);
send_time - jiffies);
} }
/* aggregate a new packet into the existing ogm packet */ /* aggregate a new packet into the existing ogm packet */
...@@ -1272,7 +1265,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, ...@@ -1272,7 +1265,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
*/ */
tq_iface_penalty = BATADV_TQ_MAX_VALUE; tq_iface_penalty = BATADV_TQ_MAX_VALUE;
if (if_outgoing && (if_incoming == if_outgoing) && if (if_outgoing && (if_incoming == if_outgoing) &&
batadv_is_wifi_netdev(if_outgoing->net_dev)) batadv_is_wifi_hardif(if_outgoing))
tq_iface_penalty = batadv_hop_penalty(BATADV_TQ_MAX_VALUE, tq_iface_penalty = batadv_hop_penalty(BATADV_TQ_MAX_VALUE,
bat_priv); bat_priv);
...@@ -1789,9 +1782,6 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) ...@@ -1789,9 +1782,6 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
forw_packet = container_of(delayed_work, struct batadv_forw_packet, forw_packet = container_of(delayed_work, struct batadv_forw_packet,
delayed_work); delayed_work);
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
spin_lock_bh(&bat_priv->forw_bat_list_lock);
hlist_del(&forw_packet->list);
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
dropped = true; dropped = true;
...@@ -1813,7 +1803,10 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) ...@@ -1813,7 +1803,10 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
batadv_iv_ogm_schedule(forw_packet->if_incoming); batadv_iv_ogm_schedule(forw_packet->if_incoming);
out: out:
batadv_forw_packet_free(forw_packet, dropped); /* do we get something for free()? */
if (batadv_forw_packet_steal(forw_packet,
&bat_priv->forw_bat_list_lock))
batadv_forw_packet_free(forw_packet, dropped);
} }
static int batadv_iv_ogm_receive(struct sk_buff *skb, static int batadv_iv_ogm_receive(struct sk_buff *skb,
......
...@@ -75,6 +75,7 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ...@@ -75,6 +75,7 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
{ {
struct batadv_hard_iface *hard_iface = neigh->if_incoming; struct batadv_hard_iface *hard_iface = neigh->if_incoming;
struct ethtool_link_ksettings link_settings; struct ethtool_link_ksettings link_settings;
struct net_device *real_netdev;
struct station_info sinfo; struct station_info sinfo;
u32 throughput; u32 throughput;
int ret; int ret;
...@@ -89,23 +90,27 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ...@@ -89,23 +90,27 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
/* if this is a wireless device, then ask its throughput through /* if this is a wireless device, then ask its throughput through
* cfg80211 API * cfg80211 API
*/ */
if (batadv_is_wifi_netdev(hard_iface->net_dev)) { if (batadv_is_wifi_hardif(hard_iface)) {
if (hard_iface->net_dev->ieee80211_ptr) { if (!batadv_is_cfg80211_hardif(hard_iface))
ret = cfg80211_get_station(hard_iface->net_dev, /* unsupported WiFi driver version */
neigh->addr, &sinfo); goto default_throughput;
if (ret == -ENOENT) {
/* Node is not associated anymore! It would be real_netdev = batadv_get_real_netdev(hard_iface->net_dev);
* possible to delete this neighbor. For now set if (!real_netdev)
* the throughput metric to 0. goto default_throughput;
*/
return 0; ret = cfg80211_get_station(real_netdev, neigh->addr, &sinfo);
}
if (!ret) dev_put(real_netdev);
return sinfo.expected_throughput / 100; if (ret == -ENOENT) {
/* Node is not associated anymore! It would be
* possible to delete this neighbor. For now set
* the throughput metric to 0.
*/
return 0;
} }
if (!ret)
/* unsupported WiFi driver version */ return sinfo.expected_throughput / 100;
goto default_throughput;
} }
/* if not a wifi interface, check if this device provides data via /* if not a wifi interface, check if this device provides data via
...@@ -187,7 +192,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh) ...@@ -187,7 +192,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
int elp_skb_len; int elp_skb_len;
/* this probing routine is for Wifi neighbours only */ /* this probing routine is for Wifi neighbours only */
if (!batadv_is_wifi_netdev(hard_iface->net_dev)) if (!batadv_is_wifi_hardif(hard_iface))
return true; return true;
/* probe the neighbor only if no unicast packets have been sent /* probe the neighbor only if no unicast packets have been sent
...@@ -352,7 +357,7 @@ int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface) ...@@ -352,7 +357,7 @@ int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
/* warn the user (again) if there is no throughput data is available */ /* warn the user (again) if there is no throughput data is available */
hard_iface->bat_v.flags &= ~BATADV_WARNING_DEFAULT; hard_iface->bat_v.flags &= ~BATADV_WARNING_DEFAULT;
if (batadv_is_wifi_netdev(hard_iface->net_dev)) if (batadv_is_wifi_hardif(hard_iface))
hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX; hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
INIT_DELAYED_WORK(&hard_iface->bat_v.elp_wq, INIT_DELAYED_WORK(&hard_iface->bat_v.elp_wq,
......
...@@ -92,8 +92,8 @@ batadv_hardif_get_by_netdev(const struct net_device *net_dev) ...@@ -92,8 +92,8 @@ batadv_hardif_get_by_netdev(const struct net_device *net_dev)
* *
* Return: result of rtnl_link_ops->get_link_net or @fallback_net * Return: result of rtnl_link_ops->get_link_net or @fallback_net
*/ */
static const struct net *batadv_getlink_net(const struct net_device *netdev, static struct net *batadv_getlink_net(const struct net_device *netdev,
const struct net *fallback_net) struct net *fallback_net)
{ {
if (!netdev->rtnl_link_ops) if (!netdev->rtnl_link_ops)
return fallback_net; return fallback_net;
...@@ -116,9 +116,9 @@ static const struct net *batadv_getlink_net(const struct net_device *netdev, ...@@ -116,9 +116,9 @@ static const struct net *batadv_getlink_net(const struct net_device *netdev,
* Return: true if the devices are each others parent, otherwise false * Return: true if the devices are each others parent, otherwise false
*/ */
static bool batadv_mutual_parents(const struct net_device *dev1, 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_device *dev2,
const struct net *net2) struct net *net2)
{ {
int dev1_parent_iflink = dev_get_iflink(dev1); int dev1_parent_iflink = dev_get_iflink(dev1);
int dev2_parent_iflink = dev_get_iflink(dev2); int dev2_parent_iflink = dev_get_iflink(dev2);
...@@ -154,7 +154,7 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev) ...@@ -154,7 +154,7 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
{ {
struct net *net = dev_net(net_dev); struct net *net = dev_net(net_dev);
struct net_device *parent_dev; struct net_device *parent_dev;
const struct net *parent_net; struct net *parent_net;
bool ret; bool ret;
/* check if this is a batman-adv mesh interface */ /* check if this is a batman-adv mesh interface */
...@@ -202,13 +202,77 @@ static bool batadv_is_valid_iface(const struct net_device *net_dev) ...@@ -202,13 +202,77 @@ static bool batadv_is_valid_iface(const struct net_device *net_dev)
} }
/** /**
* batadv_is_wifi_netdev - check if the given net_device struct is a wifi * batadv_get_real_netdevice - check if the given netdev struct is a virtual
* interface * 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 * @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) if (!net_device)
return false; return false;
...@@ -221,6 +285,22 @@ bool batadv_is_wifi_netdev(struct net_device *net_device) ...@@ -221,6 +285,22 @@ bool batadv_is_wifi_netdev(struct net_device *net_device)
return true; return true;
#endif #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 */ /* cfg80211 drivers have to set ieee80211_ptr */
if (net_device->ieee80211_ptr) if (net_device->ieee80211_ptr)
return true; return true;
...@@ -228,6 +308,73 @@ bool batadv_is_wifi_netdev(struct net_device *net_device) ...@@ -228,6 +308,73 @@ bool batadv_is_wifi_netdev(struct net_device *net_device)
return false; return false;
} }
/**
* 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 * batadv_hardif_no_broadcast - check whether (re)broadcast is necessary
* @if_outgoing: the outgoing interface checked and considered for (re)broadcast * @if_outgoing: the outgoing interface checked and considered for (re)broadcast
...@@ -748,7 +895,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) ...@@ -748,7 +895,8 @@ batadv_hardif_add_interface(struct net_device *net_dev)
kref_init(&hard_iface->refcount); kref_init(&hard_iface->refcount);
hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT; 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; hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
batadv_v_hardif_init(hard_iface); batadv_v_hardif_init(hard_iface);
...@@ -857,6 +1005,11 @@ static int batadv_hard_if_event(struct notifier_block *this, ...@@ -857,6 +1005,11 @@ static int batadv_hard_if_event(struct notifier_block *this,
if (hard_iface == primary_if) if (hard_iface == primary_if)
batadv_primary_if_update_addr(bat_priv, NULL); batadv_primary_if_update_addr(bat_priv, NULL);
break; 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: default:
break; break;
} }
......
...@@ -65,8 +65,9 @@ enum batadv_hard_if_cleanup { ...@@ -65,8 +65,9 @@ enum batadv_hard_if_cleanup {
extern struct notifier_block batadv_hard_if_notifier; extern struct notifier_block batadv_hard_if_notifier;
bool batadv_is_wifi_netdev(struct net_device *net_device); struct net_device *batadv_get_real_netdev(struct net_device *net_device);
bool batadv_is_wifi_iface(int ifindex); bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface);
bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface);
struct batadv_hard_iface* struct batadv_hard_iface*
batadv_hardif_get_by_netdev(const struct net_device *net_dev); batadv_hardif_get_by_netdev(const struct net_device *net_dev);
int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/crc32c.h> #include <linux/crc32c.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/genetlink.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -44,6 +45,7 @@ ...@@ -44,6 +45,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <net/dsfield.h> #include <net/dsfield.h>
#include <net/rtnetlink.h> #include <net/rtnetlink.h>
#include <uapi/linux/batman_adv.h>
#include "bat_algo.h" #include "bat_algo.h"
#include "bat_iv_ogm.h" #include "bat_iv_ogm.h"
...@@ -648,3 +650,4 @@ MODULE_DESCRIPTION(BATADV_DRIVER_DESC); ...@@ -648,3 +650,4 @@ MODULE_DESCRIPTION(BATADV_DRIVER_DESC);
MODULE_SUPPORTED_DEVICE(BATADV_DRIVER_DEVICE); MODULE_SUPPORTED_DEVICE(BATADV_DRIVER_DEVICE);
MODULE_VERSION(BATADV_SOURCE_VERSION); MODULE_VERSION(BATADV_SOURCE_VERSION);
MODULE_ALIAS_RTNL_LINK("batadv"); MODULE_ALIAS_RTNL_LINK("batadv");
MODULE_ALIAS_GENL_FAMILY(BATADV_NL_NAME);
This diff is collapsed.
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "main.h" #include "main.h"
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/spinlock.h>
#include <linux/types.h> #include <linux/types.h>
#include "packet.h" #include "packet.h"
...@@ -34,6 +35,10 @@ batadv_forw_packet_alloc(struct batadv_hard_iface *if_incoming, ...@@ -34,6 +35,10 @@ batadv_forw_packet_alloc(struct batadv_hard_iface *if_incoming,
struct batadv_hard_iface *if_outgoing, struct batadv_hard_iface *if_outgoing,
atomic_t *queue_left, atomic_t *queue_left,
struct batadv_priv *bat_priv); struct batadv_priv *bat_priv);
bool batadv_forw_packet_steal(struct batadv_forw_packet *packet, spinlock_t *l);
void batadv_forw_packet_ogmv1_queue(struct batadv_priv *bat_priv,
struct batadv_forw_packet *forw_packet,
unsigned long send_time);
int batadv_send_skb_to_orig(struct sk_buff *skb, int batadv_send_skb_to_orig(struct sk_buff *skb,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
......
...@@ -646,6 +646,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, ...@@ -646,6 +646,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
struct net *net = dev_net(soft_iface); struct net *net = dev_net(soft_iface);
struct batadv_softif_vlan *vlan; struct batadv_softif_vlan *vlan;
struct net_device *in_dev = NULL; struct net_device *in_dev = NULL;
struct batadv_hard_iface *in_hardif = NULL;
struct hlist_head *head; struct hlist_head *head;
struct batadv_tt_orig_list_entry *orig_entry; struct batadv_tt_orig_list_entry *orig_entry;
int hash_added, table_size, packet_size_max; int hash_added, table_size, packet_size_max;
...@@ -657,6 +658,9 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, ...@@ -657,6 +658,9 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
if (ifindex != BATADV_NULL_IFINDEX) if (ifindex != BATADV_NULL_IFINDEX)
in_dev = dev_get_by_index(net, ifindex); in_dev = dev_get_by_index(net, ifindex);
if (in_dev)
in_hardif = batadv_hardif_get_by_netdev(in_dev);
tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid); tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
if (!is_multicast_ether_addr(addr)) if (!is_multicast_ether_addr(addr))
...@@ -730,7 +734,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, ...@@ -730,7 +734,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
*/ */
tt_local->common.flags = BATADV_TT_CLIENT_NEW; tt_local->common.flags = BATADV_TT_CLIENT_NEW;
tt_local->common.vid = vid; tt_local->common.vid = vid;
if (batadv_is_wifi_netdev(in_dev)) if (batadv_is_wifi_hardif(in_hardif))
tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
kref_init(&tt_local->common.refcount); kref_init(&tt_local->common.refcount);
tt_local->last_seen = jiffies; tt_local->last_seen = jiffies;
...@@ -790,7 +794,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, ...@@ -790,7 +794,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
*/ */
remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK; remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK;
if (batadv_is_wifi_netdev(in_dev)) if (batadv_is_wifi_hardif(in_hardif))
tt_local->common.flags |= BATADV_TT_CLIENT_WIFI; tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
else else
tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI; tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI;
...@@ -814,6 +818,8 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, ...@@ -814,6 +818,8 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
ret = true; ret = true;
out: out:
if (in_hardif)
batadv_hardif_put(in_hardif);
if (in_dev) if (in_dev)
dev_put(in_dev); dev_put(in_dev);
if (tt_local) if (tt_local)
......
...@@ -118,12 +118,28 @@ struct batadv_hard_iface_bat_v { ...@@ -118,12 +118,28 @@ struct batadv_hard_iface_bat_v {
u8 flags; u8 flags;
}; };
/**
* enum batadv_hard_iface_wifi_flags - Flags describing the wifi configuration
* 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),
};
/** /**
* struct batadv_hard_iface - network device known to batman-adv * struct batadv_hard_iface - network device known to batman-adv
* @list: list node for batadv_hardif_list * @list: list node for batadv_hardif_list
* @if_num: identificator of the interface * @if_num: identificator of the interface
* @if_status: status of the interface for batman-adv * @if_status: status of the interface for batman-adv
* @num_bcasts: number of payload re-broadcasts on this interface (ARQ) * @num_bcasts: number of payload re-broadcasts on this interface (ARQ)
* @wifi_flags: flags whether this is (directly or indirectly) a wifi interface
* @net_dev: pointer to the net_device * @net_dev: pointer to the net_device
* @hardif_obj: kobject of the per interface sysfs "mesh" directory * @hardif_obj: kobject of the per interface sysfs "mesh" directory
* @refcount: number of contexts the object is used * @refcount: number of contexts the object is used
...@@ -142,6 +158,7 @@ struct batadv_hard_iface { ...@@ -142,6 +158,7 @@ struct batadv_hard_iface {
s16 if_num; s16 if_num;
char if_status; char if_status;
u8 num_bcasts; u8 num_bcasts;
u32 wifi_flags;
struct net_device *net_dev; struct net_device *net_dev;
struct kobject *hardif_obj; struct kobject *hardif_obj;
struct kref refcount; struct kref refcount;
...@@ -1368,6 +1385,7 @@ struct batadv_skb_cb { ...@@ -1368,6 +1385,7 @@ struct batadv_skb_cb {
/** /**
* struct batadv_forw_packet - structure for bcast packets to be sent/forwarded * struct batadv_forw_packet - structure for bcast packets to be sent/forwarded
* @list: list node for batadv_priv::forw_{bat,bcast}_list * @list: list node for batadv_priv::forw_{bat,bcast}_list
* @cleanup_list: list node for purging functions
* @send_time: execution time for delayed_work (packet sending) * @send_time: execution time for delayed_work (packet sending)
* @own: bool for locally generated packets (local OGMs are re-scheduled after * @own: bool for locally generated packets (local OGMs are re-scheduled after
* sending) * sending)
...@@ -1384,6 +1402,7 @@ struct batadv_skb_cb { ...@@ -1384,6 +1402,7 @@ struct batadv_skb_cb {
*/ */
struct batadv_forw_packet { struct batadv_forw_packet {
struct hlist_node list; struct hlist_node list;
struct hlist_node cleanup_list;
unsigned long send_time; unsigned long send_time;
u8 own; u8 own;
struct sk_buff *skb; struct sk_buff *skb;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment