Commit 303597e4 authored by David S. Miller's avatar David S. Miller

Merge tag 'batadv-next-pullrequest-20210608' of git://git.open-mesh.org/linux-merge

Simon Wunderlich says:

====================
pull request for net-next: batman-adv 2021-06-08

here is a feature/cleanup pull request of batman-adv to go into net-next.

Please pull or let me know of any problem!

This feature/cleanup patchset includes the following patches:

 - bump version strings, by Simon Wunderlich

 - consistently send iface index/name in genlmsg, by Sven Eckelmann

 - improve broadcast queueing, by Linus Lüssing (2 patches)

 - add support for routable IPv4 multicast with bridged setups,
   by Linus Lüssing

 - remove repeated declarations, by Shaokun Zhang

 - fix spelling mistakes, by Zheng Yongjun

 - clean up hard interface handling after dropping sysfs support,
   by Sven Eckelmann (4 patches)
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 76241154 020577f8
...@@ -1849,6 +1849,8 @@ batadv_iv_ogm_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq, ...@@ -1849,6 +1849,8 @@ batadv_iv_ogm_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
orig_node->orig) || orig_node->orig) ||
nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN, nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
neigh_node->addr) || neigh_node->addr) ||
nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
neigh_node->if_incoming->net_dev->name) ||
nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
neigh_node->if_incoming->net_dev->ifindex) || neigh_node->if_incoming->net_dev->ifindex) ||
nla_put_u8(msg, BATADV_ATTR_TQ, tq_avg) || nla_put_u8(msg, BATADV_ATTR_TQ, tq_avg) ||
...@@ -2078,6 +2080,8 @@ batadv_iv_ogm_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq, ...@@ -2078,6 +2080,8 @@ batadv_iv_ogm_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN, if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
hardif_neigh->addr) || hardif_neigh->addr) ||
nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
hardif_neigh->if_incoming->net_dev->name) ||
nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
hardif_neigh->if_incoming->net_dev->ifindex) || hardif_neigh->if_incoming->net_dev->ifindex) ||
nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
...@@ -2459,6 +2463,8 @@ static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid, ...@@ -2459,6 +2463,8 @@ static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid,
router->addr) || router->addr) ||
nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
router->if_incoming->net_dev->name) || router->if_incoming->net_dev->name) ||
nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
router->if_incoming->net_dev->ifindex) ||
nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN, nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN,
gw_node->bandwidth_down) || gw_node->bandwidth_down) ||
nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_UP, nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_UP,
......
...@@ -146,6 +146,8 @@ batadv_v_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq, ...@@ -146,6 +146,8 @@ batadv_v_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN, if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
hardif_neigh->addr) || hardif_neigh->addr) ||
nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
hardif_neigh->if_incoming->net_dev->name) ||
nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
hardif_neigh->if_incoming->net_dev->ifindex) || hardif_neigh->if_incoming->net_dev->ifindex) ||
nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
...@@ -298,6 +300,8 @@ batadv_v_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq, ...@@ -298,6 +300,8 @@ batadv_v_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, orig_node->orig) || if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, orig_node->orig) ||
nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN, nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
neigh_node->addr) || neigh_node->addr) ||
nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
neigh_node->if_incoming->net_dev->name) ||
nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
neigh_node->if_incoming->net_dev->ifindex) || neigh_node->if_incoming->net_dev->ifindex) ||
nla_put_u32(msg, BATADV_ATTR_THROUGHPUT, throughput) || nla_put_u32(msg, BATADV_ATTR_THROUGHPUT, throughput) ||
...@@ -739,6 +743,12 @@ static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid, ...@@ -739,6 +743,12 @@ static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid,
goto out; goto out;
} }
if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
router->if_incoming->net_dev->ifindex)) {
genlmsg_cancel(msg, hdr);
goto out;
}
if (nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN, if (nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN,
gw_node->bandwidth_down)) { gw_node->bandwidth_down)) {
genlmsg_cancel(msg, hdr); genlmsg_cancel(msg, hdr);
......
...@@ -395,7 +395,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac, ...@@ -395,7 +395,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac,
break; break;
case BATADV_CLAIM_TYPE_ANNOUNCE: case BATADV_CLAIM_TYPE_ANNOUNCE:
/* announcement frame /* announcement frame
* set HW SRC to the special mac containg the crc * set HW SRC to the special mac containing the crc
*/ */
ether_addr_copy(hw_src, mac); ether_addr_copy(hw_src, mac);
batadv_dbg(BATADV_DBG_BLA, bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv,
...@@ -1040,7 +1040,7 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv, ...@@ -1040,7 +1040,7 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv,
/* lets see if this originator is in our mesh */ /* lets see if this originator is in our mesh */
orig_node = batadv_orig_hash_find(bat_priv, backbone_addr); orig_node = batadv_orig_hash_find(bat_priv, backbone_addr);
/* dont accept claims from gateways which are not in /* don't accept claims from gateways which are not in
* the same mesh or group. * the same mesh or group.
*/ */
if (!orig_node) if (!orig_node)
......
...@@ -52,7 +52,6 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, ...@@ -52,7 +52,6 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
void batadv_bla_status_update(struct net_device *net_dev); void batadv_bla_status_update(struct net_device *net_dev);
int batadv_bla_init(struct batadv_priv *bat_priv); int batadv_bla_init(struct batadv_priv *bat_priv);
void batadv_bla_free(struct batadv_priv *bat_priv); void batadv_bla_free(struct batadv_priv *bat_priv);
int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb);
#ifdef CONFIG_BATMAN_ADV_DAT #ifdef CONFIG_BATMAN_ADV_DAT
bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr, bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
unsigned short vid); unsigned short vid);
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/byteorder/generic.h> #include <linux/byteorder/generic.h>
#include <linux/errno.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
...@@ -403,7 +402,7 @@ int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing, ...@@ -403,7 +402,7 @@ int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
goto out; goto out;
} }
/* >1 neighbors -> (re)brodcast */ /* >1 neighbors -> (re)broadcast */
if (rcu_dereference(hlist_next_rcu(first))) if (rcu_dereference(hlist_next_rcu(first)))
goto out; goto out;
...@@ -677,44 +676,17 @@ batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface) ...@@ -677,44 +676,17 @@ batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
batadv_update_min_mtu(hard_iface->soft_iface); batadv_update_min_mtu(hard_iface->soft_iface);
} }
/**
* batadv_master_del_slave() - remove hard_iface from the current master iface
* @slave: the interface enslaved in another master
* @master: the master from which slave has to be removed
*
* Invoke ndo_del_slave on master passing slave as argument. In this way the
* slave is free'd and the master can correctly change its internal state.
*
* Return: 0 on success, a negative value representing the error otherwise
*/
static int batadv_master_del_slave(struct batadv_hard_iface *slave,
struct net_device *master)
{
int ret;
if (!master)
return 0;
ret = -EBUSY;
if (master->netdev_ops->ndo_del_slave)
ret = master->netdev_ops->ndo_del_slave(master, slave->net_dev);
return ret;
}
/** /**
* batadv_hardif_enable_interface() - Enslave hard interface to soft interface * batadv_hardif_enable_interface() - Enslave hard interface to soft interface
* @hard_iface: hard interface to add to soft interface * @hard_iface: hard interface to add to soft interface
* @net: the applicable net namespace * @soft_iface: netdev struct of the mesh interface
* @iface_name: name of the soft interface
* *
* Return: 0 on success or negative error number in case of failure * Return: 0 on success or negative error number in case of failure
*/ */
int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
struct net *net, const char *iface_name) struct net_device *soft_iface)
{ {
struct batadv_priv *bat_priv; struct batadv_priv *bat_priv;
struct net_device *soft_iface, *master;
__be16 ethertype = htons(ETH_P_BATMAN); __be16 ethertype = htons(ETH_P_BATMAN);
int max_header_len = batadv_max_header_len(); int max_header_len = batadv_max_header_len();
int ret; int ret;
...@@ -724,35 +696,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, ...@@ -724,35 +696,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
kref_get(&hard_iface->refcount); kref_get(&hard_iface->refcount);
soft_iface = dev_get_by_name(net, iface_name);
if (!soft_iface) {
soft_iface = batadv_softif_create(net, iface_name);
if (!soft_iface) {
ret = -ENOMEM;
goto err;
}
/* dev_get_by_name() increases the reference counter for us */
dev_hold(soft_iface); dev_hold(soft_iface);
}
if (!batadv_softif_is_valid(soft_iface)) {
pr_err("Can't create batman mesh interface %s: already exists as regular interface\n",
soft_iface->name);
ret = -EINVAL;
goto err_dev;
}
/* check if the interface is enslaved in another virtual one and
* in that case unlink it first
*/
master = netdev_master_upper_dev_get(hard_iface->net_dev);
ret = batadv_master_del_slave(hard_iface, master);
if (ret)
goto err_dev;
hard_iface->soft_iface = soft_iface; hard_iface->soft_iface = soft_iface;
bat_priv = netdev_priv(hard_iface->soft_iface); bat_priv = netdev_priv(hard_iface->soft_iface);
...@@ -810,7 +754,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, ...@@ -810,7 +754,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
err_dev: err_dev:
hard_iface->soft_iface = NULL; hard_iface->soft_iface = NULL;
dev_put(soft_iface); dev_put(soft_iface);
err:
batadv_hardif_put(hard_iface); batadv_hardif_put(hard_iface);
return ret; return ret;
} }
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/types.h> #include <linux/types.h>
#include <net/net_namespace.h>
/** /**
* enum batadv_hard_if_state - State of a hard interface * enum batadv_hard_if_state - State of a hard interface
...@@ -75,7 +74,7 @@ bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface); ...@@ -75,7 +74,7 @@ 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,
struct net *net, const char *iface_name); struct net_device *soft_iface);
void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface); void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface);
int batadv_hardif_min_mtu(struct net_device *soft_iface); int batadv_hardif_min_mtu(struct net_device *soft_iface);
void batadv_update_min_mtu(struct net_device *soft_iface); void batadv_update_min_mtu(struct net_device *soft_iface);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/types.h> #include <linux/types.h>
/* callback to a compare function. should compare 2 element datas for their /* callback to a compare function. should compare 2 element data for their
* keys * keys
* *
* Return: true if same and false if not same * Return: true if same and false if not same
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv" #define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION #ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2021.1" #define BATADV_SOURCE_VERSION "2021.2"
#endif #endif
/* B.A.T.M.A.N. parameters */ /* B.A.T.M.A.N. parameters */
...@@ -88,7 +88,6 @@ ...@@ -88,7 +88,6 @@
/* number of packets to send for broadcasts on different interface types */ /* number of packets to send for broadcasts on different interface types */
#define BATADV_NUM_BCASTS_DEFAULT 1 #define BATADV_NUM_BCASTS_DEFAULT 1
#define BATADV_NUM_BCASTS_WIRELESS 3 #define BATADV_NUM_BCASTS_WIRELESS 3
#define BATADV_NUM_BCASTS_MAX 3
/* length of the single packet used by the TP meter */ /* length of the single packet used by the TP meter */
#define BATADV_TP_PACKET_LEN ETH_DATA_LEN #define BATADV_TP_PACKET_LEN ETH_DATA_LEN
......
...@@ -193,53 +193,22 @@ static u8 batadv_mcast_mla_rtr_flags_softif_get(struct batadv_priv *bat_priv, ...@@ -193,53 +193,22 @@ static u8 batadv_mcast_mla_rtr_flags_softif_get(struct batadv_priv *bat_priv,
* BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present * BATADV_MCAST_WANT_NO_RTR6: No IPv6 multicast router is present
* The former two OR'd: no multicast router is present * The former two OR'd: no multicast router is present
*/ */
#if IS_ENABLED(CONFIG_IPV6)
static u8 batadv_mcast_mla_rtr_flags_bridge_get(struct batadv_priv *bat_priv, static u8 batadv_mcast_mla_rtr_flags_bridge_get(struct batadv_priv *bat_priv,
struct net_device *bridge) struct net_device *bridge)
{ {
struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
struct net_device *dev = bat_priv->soft_iface; struct net_device *dev = bat_priv->soft_iface;
struct br_ip_list *br_ip_entry, *tmp; u8 flags = BATADV_NO_FLAGS;
u8 flags = BATADV_MCAST_WANT_NO_RTR6;
int ret;
if (!bridge) if (!bridge)
return BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6; return BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6;
/* TODO: ask the bridge if a multicast router is present (the bridge if (!br_multicast_has_router_adjacent(dev, ETH_P_IP))
* is capable of performing proper RFC4286 multicast router flags |= BATADV_MCAST_WANT_NO_RTR4;
* discovery) instead of searching for a ff02::2 listener here if (!br_multicast_has_router_adjacent(dev, ETH_P_IPV6))
*/ flags |= BATADV_MCAST_WANT_NO_RTR6;
ret = br_multicast_list_adjacent(dev, &bridge_mcast_list);
if (ret < 0)
return BATADV_NO_FLAGS;
list_for_each_entry_safe(br_ip_entry, tmp, &bridge_mcast_list, list) {
/* the bridge snooping does not maintain IPv4 link-local
* addresses - therefore we won't find any IPv4 multicast router
* address here, only IPv6 ones
*/
if (br_ip_entry->addr.proto == htons(ETH_P_IPV6) &&
ipv6_addr_is_ll_all_routers(&br_ip_entry->addr.dst.ip6))
flags &= ~BATADV_MCAST_WANT_NO_RTR6;
list_del(&br_ip_entry->list);
kfree(br_ip_entry);
}
return flags; return flags;
} }
#else
static inline u8
batadv_mcast_mla_rtr_flags_bridge_get(struct batadv_priv *bat_priv,
struct net_device *bridge)
{
if (bridge)
return BATADV_NO_FLAGS;
else
return BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6;
}
#endif
/** /**
* batadv_mcast_mla_rtr_flags_get() - get multicast router flags * batadv_mcast_mla_rtr_flags_get() - get multicast router flags
......
...@@ -814,6 +814,10 @@ static int batadv_netlink_hardif_fill(struct sk_buff *msg, ...@@ -814,6 +814,10 @@ static int batadv_netlink_hardif_fill(struct sk_buff *msg,
bat_priv->soft_iface->ifindex)) bat_priv->soft_iface->ifindex))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_string(msg, BATADV_ATTR_MESH_IFNAME,
bat_priv->soft_iface->name))
goto nla_put_failure;
if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
net_dev->ifindex) || net_dev->ifindex) ||
nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
...@@ -1045,6 +1049,10 @@ static int batadv_netlink_vlan_fill(struct sk_buff *msg, ...@@ -1045,6 +1049,10 @@ static int batadv_netlink_vlan_fill(struct sk_buff *msg,
bat_priv->soft_iface->ifindex)) bat_priv->soft_iface->ifindex))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_string(msg, BATADV_ATTR_MESH_IFNAME,
bat_priv->soft_iface->name))
goto nla_put_failure;
if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK)) if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK))
goto nla_put_failure; goto nla_put_failure;
......
...@@ -1182,9 +1182,9 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, ...@@ -1182,9 +1182,9 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
struct batadv_bcast_packet *bcast_packet; struct batadv_bcast_packet *bcast_packet;
struct ethhdr *ethhdr; struct ethhdr *ethhdr;
int hdr_size = sizeof(*bcast_packet); int hdr_size = sizeof(*bcast_packet);
int ret = NET_RX_DROP;
s32 seq_diff; s32 seq_diff;
u32 seqno; u32 seqno;
int ret;
/* drop packet if it has not necessary minimum size */ /* drop packet if it has not necessary minimum size */
if (unlikely(!pskb_may_pull(skb, hdr_size))) if (unlikely(!pskb_may_pull(skb, hdr_size)))
...@@ -1210,7 +1210,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, ...@@ -1210,7 +1210,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
if (batadv_is_my_mac(bat_priv, bcast_packet->orig)) if (batadv_is_my_mac(bat_priv, bcast_packet->orig))
goto free_skb; goto free_skb;
if (bcast_packet->ttl < 2) if (bcast_packet->ttl-- < 2)
goto free_skb; goto free_skb;
orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig); orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig);
...@@ -1249,7 +1249,9 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, ...@@ -1249,7 +1249,9 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_packet)); batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_packet));
/* rebroadcast packet */ /* rebroadcast packet */
batadv_add_bcast_packet_to_list(bat_priv, skb, 1, false); ret = batadv_forw_bcast_packet(bat_priv, skb, 0, false);
if (ret == NETDEV_TX_BUSY)
goto free_skb;
/* don't hand the broadcast up if it is from an originator /* don't hand the broadcast up if it is from an originator
* from the same backbone. * from the same backbone.
...@@ -1275,6 +1277,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, ...@@ -1275,6 +1277,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
spin_unlock_bh(&orig_node->bcast_seqno_lock); spin_unlock_bh(&orig_node->bcast_seqno_lock);
free_skb: free_skb:
kfree_skb(skb); kfree_skb(skb);
ret = NET_RX_DROP;
out: out:
if (orig_node) if (orig_node)
batadv_orig_node_put(orig_node); batadv_orig_node_put(orig_node);
......
...@@ -737,57 +737,48 @@ void batadv_forw_packet_ogmv1_queue(struct batadv_priv *bat_priv, ...@@ -737,57 +737,48 @@ void batadv_forw_packet_ogmv1_queue(struct batadv_priv *bat_priv,
} }
/** /**
* batadv_add_bcast_packet_to_list() - queue broadcast packet for multiple sends * batadv_forw_bcast_packet_to_list() - queue broadcast packet for transmissions
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @skb: broadcast packet to add * @skb: broadcast packet to add
* @delay: number of jiffies to wait before sending * @delay: number of jiffies to wait before sending
* @own_packet: true if it is a self-generated broadcast packet * @own_packet: true if it is a self-generated broadcast packet
* @if_in: the interface where the packet was received on
* @if_out: the outgoing interface to queue on
* *
* add a broadcast packet to the queue and setup timers. broadcast packets * Adds a broadcast packet to the queue and sets up timers. Broadcast packets
* are sent multiple times to increase probability for being received. * are sent multiple times to increase probability for being received.
* *
* The skb is not consumed, so the caller should make sure that the
* skb is freed.
*
* Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY on errors. * Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY on errors.
*/ */
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, static int batadv_forw_bcast_packet_to_list(struct batadv_priv *bat_priv,
const struct sk_buff *skb, struct sk_buff *skb,
unsigned long delay, unsigned long delay,
bool own_packet) bool own_packet,
struct batadv_hard_iface *if_in,
struct batadv_hard_iface *if_out)
{ {
struct batadv_hard_iface *primary_if;
struct batadv_forw_packet *forw_packet; struct batadv_forw_packet *forw_packet;
struct batadv_bcast_packet *bcast_packet; unsigned long send_time = jiffies;
struct sk_buff *newskb; struct sk_buff *newskb;
primary_if = batadv_primary_if_get_selected(bat_priv);
if (!primary_if)
goto err;
newskb = skb_copy(skb, GFP_ATOMIC); newskb = skb_copy(skb, GFP_ATOMIC);
if (!newskb) { if (!newskb)
batadv_hardif_put(primary_if);
goto err; goto err;
}
forw_packet = batadv_forw_packet_alloc(primary_if, NULL, forw_packet = batadv_forw_packet_alloc(if_in, if_out,
&bat_priv->bcast_queue_left, &bat_priv->bcast_queue_left,
bat_priv, newskb); bat_priv, newskb);
batadv_hardif_put(primary_if);
if (!forw_packet) if (!forw_packet)
goto err_packet_free; goto err_packet_free;
/* as we have a copy now, it is safe to decrease the TTL */
bcast_packet = (struct batadv_bcast_packet *)newskb->data;
bcast_packet->ttl--;
forw_packet->own = own_packet; forw_packet->own = own_packet;
INIT_DELAYED_WORK(&forw_packet->delayed_work, INIT_DELAYED_WORK(&forw_packet->delayed_work,
batadv_send_outstanding_bcast_packet); batadv_send_outstanding_bcast_packet);
batadv_forw_packet_bcast_queue(bat_priv, forw_packet, jiffies + delay); send_time += delay ? delay : msecs_to_jiffies(5);
batadv_forw_packet_bcast_queue(bat_priv, forw_packet, send_time);
return NETDEV_TX_OK; return NETDEV_TX_OK;
err_packet_free: err_packet_free:
...@@ -796,10 +787,220 @@ int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, ...@@ -796,10 +787,220 @@ int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
/**
* batadv_forw_bcast_packet_if() - forward and queue a broadcast packet
* @bat_priv: the bat priv with all the soft interface information
* @skb: broadcast packet to add
* @delay: number of jiffies to wait before sending
* @own_packet: true if it is a self-generated broadcast packet
* @if_in: the interface where the packet was received on
* @if_out: the outgoing interface to forward to
*
* Transmits a broadcast packet on the specified interface either immediately
* or if a delay is given after that. Furthermore, queues additional
* retransmissions if this interface is a wireless one.
*
* Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY on errors.
*/
static int batadv_forw_bcast_packet_if(struct batadv_priv *bat_priv,
struct sk_buff *skb,
unsigned long delay,
bool own_packet,
struct batadv_hard_iface *if_in,
struct batadv_hard_iface *if_out)
{
unsigned int num_bcasts = if_out->num_bcasts;
struct sk_buff *newskb;
int ret = NETDEV_TX_OK;
if (!delay) {
newskb = skb_copy(skb, GFP_ATOMIC);
if (!newskb)
return NETDEV_TX_BUSY;
batadv_send_broadcast_skb(newskb, if_out);
num_bcasts--;
}
/* delayed broadcast or rebroadcasts? */
if (num_bcasts >= 1) {
BATADV_SKB_CB(skb)->num_bcasts = num_bcasts;
ret = batadv_forw_bcast_packet_to_list(bat_priv, skb, delay,
own_packet, if_in,
if_out);
}
return ret;
}
/**
* batadv_send_no_broadcast() - check whether (re)broadcast is necessary
* @bat_priv: the bat priv with all the soft interface information
* @skb: broadcast packet to check
* @own_packet: true if it is a self-generated broadcast packet
* @if_out: the outgoing interface checked and considered for (re)broadcast
*
* Return: False if a packet needs to be (re)broadcasted on the given interface,
* true otherwise.
*/
static bool batadv_send_no_broadcast(struct batadv_priv *bat_priv,
struct sk_buff *skb, bool own_packet,
struct batadv_hard_iface *if_out)
{
struct batadv_hardif_neigh_node *neigh_node = NULL;
struct batadv_bcast_packet *bcast_packet;
u8 *orig_neigh;
u8 *neigh_addr;
char *type;
int ret;
if (!own_packet) {
neigh_addr = eth_hdr(skb)->h_source;
neigh_node = batadv_hardif_neigh_get(if_out,
neigh_addr);
}
bcast_packet = (struct batadv_bcast_packet *)skb->data;
orig_neigh = neigh_node ? neigh_node->orig : NULL;
ret = batadv_hardif_no_broadcast(if_out, bcast_packet->orig,
orig_neigh);
if (neigh_node)
batadv_hardif_neigh_put(neigh_node);
/* ok, may broadcast */
if (!ret)
return false;
/* no broadcast */
switch (ret) {
case BATADV_HARDIF_BCAST_NORECIPIENT:
type = "no neighbor";
break;
case BATADV_HARDIF_BCAST_DUPFWD:
type = "single neighbor is source";
break;
case BATADV_HARDIF_BCAST_DUPORIG:
type = "single neighbor is originator";
break;
default:
type = "unknown";
}
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"BCAST packet from orig %pM on %s suppressed: %s\n",
bcast_packet->orig,
if_out->net_dev->name, type);
return true;
}
/**
* __batadv_forw_bcast_packet() - forward and queue a broadcast packet
* @bat_priv: the bat priv with all the soft interface information
* @skb: broadcast packet to add
* @delay: number of jiffies to wait before sending
* @own_packet: true if it is a self-generated broadcast packet
*
* Transmits a broadcast packet either immediately or if a delay is given
* after that. Furthermore, queues additional retransmissions on wireless
* interfaces.
*
* This call clones the given skb, hence the caller needs to take into
* account that the data segment of the given skb might not be
* modifiable anymore.
*
* Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY on errors.
*/
static int __batadv_forw_bcast_packet(struct batadv_priv *bat_priv,
struct sk_buff *skb,
unsigned long delay,
bool own_packet)
{
struct batadv_hard_iface *hard_iface;
struct batadv_hard_iface *primary_if;
int ret = NETDEV_TX_OK;
primary_if = batadv_primary_if_get_selected(bat_priv);
if (!primary_if)
return NETDEV_TX_BUSY;
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
if (hard_iface->soft_iface != bat_priv->soft_iface)
continue;
if (!kref_get_unless_zero(&hard_iface->refcount))
continue;
if (batadv_send_no_broadcast(bat_priv, skb, own_packet,
hard_iface)) {
batadv_hardif_put(hard_iface);
continue;
}
ret = batadv_forw_bcast_packet_if(bat_priv, skb, delay,
own_packet, primary_if,
hard_iface);
batadv_hardif_put(hard_iface);
if (ret == NETDEV_TX_BUSY)
break;
}
rcu_read_unlock();
batadv_hardif_put(primary_if);
return ret;
}
/**
* batadv_forw_bcast_packet() - forward and queue a broadcast packet
* @bat_priv: the bat priv with all the soft interface information
* @skb: broadcast packet to add
* @delay: number of jiffies to wait before sending
* @own_packet: true if it is a self-generated broadcast packet
*
* Transmits a broadcast packet either immediately or if a delay is given
* after that. Furthermore, queues additional retransmissions on wireless
* interfaces.
*
* Return: NETDEV_TX_OK on success and NETDEV_TX_BUSY on errors.
*/
int batadv_forw_bcast_packet(struct batadv_priv *bat_priv,
struct sk_buff *skb,
unsigned long delay,
bool own_packet)
{
return __batadv_forw_bcast_packet(bat_priv, skb, delay, own_packet);
}
/**
* batadv_send_bcast_packet() - send and queue a broadcast packet
* @bat_priv: the bat priv with all the soft interface information
* @skb: broadcast packet to add
* @delay: number of jiffies to wait before sending
* @own_packet: true if it is a self-generated broadcast packet
*
* Transmits a broadcast packet either immediately or if a delay is given
* after that. Furthermore, queues additional retransmissions on wireless
* interfaces.
*
* Consumes the provided skb.
*/
void batadv_send_bcast_packet(struct batadv_priv *bat_priv,
struct sk_buff *skb,
unsigned long delay,
bool own_packet)
{
__batadv_forw_bcast_packet(bat_priv, skb, delay, own_packet);
consume_skb(skb);
}
/** /**
* batadv_forw_packet_bcasts_left() - check if a retransmission is necessary * batadv_forw_packet_bcasts_left() - check if a retransmission is necessary
* @forw_packet: the forwarding packet to check * @forw_packet: the forwarding packet to check
* @hard_iface: the interface to check on
* *
* Checks whether a given packet has any (re)transmissions left on the provided * Checks whether a given packet has any (re)transmissions left on the provided
* interface. * interface.
...@@ -811,28 +1012,20 @@ int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, ...@@ -811,28 +1012,20 @@ int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
* Return: True if (re)transmissions are left, false otherwise. * Return: True if (re)transmissions are left, false otherwise.
*/ */
static bool static bool
batadv_forw_packet_bcasts_left(struct batadv_forw_packet *forw_packet, batadv_forw_packet_bcasts_left(struct batadv_forw_packet *forw_packet)
struct batadv_hard_iface *hard_iface)
{ {
unsigned int max; return BATADV_SKB_CB(forw_packet->skb)->num_bcasts;
if (hard_iface)
max = hard_iface->num_bcasts;
else
max = BATADV_NUM_BCASTS_MAX;
return BATADV_SKB_CB(forw_packet->skb)->num_bcasts < max;
} }
/** /**
* batadv_forw_packet_bcasts_inc() - increment retransmission counter of a * batadv_forw_packet_bcasts_dec() - decrement retransmission counter of a
* packet * packet
* @forw_packet: the packet to increase the counter for * @forw_packet: the packet to decrease the counter for
*/ */
static void static void
batadv_forw_packet_bcasts_inc(struct batadv_forw_packet *forw_packet) batadv_forw_packet_bcasts_dec(struct batadv_forw_packet *forw_packet)
{ {
BATADV_SKB_CB(forw_packet->skb)->num_bcasts++; BATADV_SKB_CB(forw_packet->skb)->num_bcasts--;
} }
/** /**
...@@ -843,30 +1036,30 @@ batadv_forw_packet_bcasts_inc(struct batadv_forw_packet *forw_packet) ...@@ -843,30 +1036,30 @@ batadv_forw_packet_bcasts_inc(struct batadv_forw_packet *forw_packet)
*/ */
bool batadv_forw_packet_is_rebroadcast(struct batadv_forw_packet *forw_packet) bool batadv_forw_packet_is_rebroadcast(struct batadv_forw_packet *forw_packet)
{ {
return BATADV_SKB_CB(forw_packet->skb)->num_bcasts > 0; unsigned char num_bcasts = BATADV_SKB_CB(forw_packet->skb)->num_bcasts;
return num_bcasts != forw_packet->if_outgoing->num_bcasts;
} }
/**
* batadv_send_outstanding_bcast_packet() - transmit a queued broadcast packet
* @work: work queue item
*
* Transmits a queued broadcast packet and if necessary reschedules it.
*/
static void batadv_send_outstanding_bcast_packet(struct work_struct *work) static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
{ {
struct batadv_hard_iface *hard_iface; unsigned long send_time = jiffies + msecs_to_jiffies(5);
struct batadv_hardif_neigh_node *neigh_node;
struct delayed_work *delayed_work;
struct batadv_forw_packet *forw_packet; struct batadv_forw_packet *forw_packet;
struct batadv_bcast_packet *bcast_packet; struct delayed_work *delayed_work;
struct sk_buff *skb1;
struct net_device *soft_iface;
struct batadv_priv *bat_priv; struct batadv_priv *bat_priv;
unsigned long send_time = jiffies + msecs_to_jiffies(5); struct sk_buff *skb1;
bool dropped = false; bool dropped = false;
u8 *neigh_addr;
u8 *orig_neigh;
int ret = 0;
delayed_work = to_delayed_work(work); delayed_work = to_delayed_work(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);
soft_iface = forw_packet->if_incoming->soft_iface; bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
bat_priv = netdev_priv(soft_iface);
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
dropped = true; dropped = true;
...@@ -878,76 +1071,15 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) ...@@ -878,76 +1071,15 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
goto out; goto out;
} }
bcast_packet = (struct batadv_bcast_packet *)forw_packet->skb->data;
/* rebroadcast packet */
rcu_read_lock();
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
if (hard_iface->soft_iface != soft_iface)
continue;
if (!batadv_forw_packet_bcasts_left(forw_packet, hard_iface))
continue;
if (forw_packet->own) {
neigh_node = NULL;
} else {
neigh_addr = eth_hdr(forw_packet->skb)->h_source;
neigh_node = batadv_hardif_neigh_get(hard_iface,
neigh_addr);
}
orig_neigh = neigh_node ? neigh_node->orig : NULL;
ret = batadv_hardif_no_broadcast(hard_iface, bcast_packet->orig,
orig_neigh);
if (ret) {
char *type;
switch (ret) {
case BATADV_HARDIF_BCAST_NORECIPIENT:
type = "no neighbor";
break;
case BATADV_HARDIF_BCAST_DUPFWD:
type = "single neighbor is source";
break;
case BATADV_HARDIF_BCAST_DUPORIG:
type = "single neighbor is originator";
break;
default:
type = "unknown";
}
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "BCAST packet from orig %pM on %s suppressed: %s\n",
bcast_packet->orig,
hard_iface->net_dev->name, type);
if (neigh_node)
batadv_hardif_neigh_put(neigh_node);
continue;
}
if (neigh_node)
batadv_hardif_neigh_put(neigh_node);
if (!kref_get_unless_zero(&hard_iface->refcount))
continue;
/* send a copy of the saved skb */ /* send a copy of the saved skb */
skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
if (skb1) if (!skb1)
batadv_send_broadcast_skb(skb1, hard_iface); goto out;
batadv_hardif_put(hard_iface);
}
rcu_read_unlock();
batadv_forw_packet_bcasts_inc(forw_packet); batadv_send_broadcast_skb(skb1, forw_packet->if_outgoing);
batadv_forw_packet_bcasts_dec(forw_packet);
/* if we still have some more bcasts to send */ if (batadv_forw_packet_bcasts_left(forw_packet)) {
if (batadv_forw_packet_bcasts_left(forw_packet, NULL)) {
batadv_forw_packet_bcast_queue(bat_priv, forw_packet, batadv_forw_packet_bcast_queue(bat_priv, forw_packet,
send_time); send_time);
return; return;
......
...@@ -39,8 +39,12 @@ int batadv_send_broadcast_skb(struct sk_buff *skb, ...@@ -39,8 +39,12 @@ int batadv_send_broadcast_skb(struct sk_buff *skb,
struct batadv_hard_iface *hard_iface); struct batadv_hard_iface *hard_iface);
int batadv_send_unicast_skb(struct sk_buff *skb, int batadv_send_unicast_skb(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node); struct batadv_neigh_node *neigh_node);
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, int batadv_forw_bcast_packet(struct batadv_priv *bat_priv,
const struct sk_buff *skb, struct sk_buff *skb,
unsigned long delay,
bool own_packet);
void batadv_send_bcast_packet(struct batadv_priv *bat_priv,
struct sk_buff *skb,
unsigned long delay, unsigned long delay,
bool own_packet); bool own_packet);
void void
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/printk.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/rculist.h> #include <linux/rculist.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
...@@ -37,6 +36,7 @@ ...@@ -37,6 +36,7 @@
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include <net/net_namespace.h>
#include <net/netlink.h> #include <net/netlink.h>
#include <uapi/linux/batadv_packet.h> #include <uapi/linux/batadv_packet.h>
#include <uapi/linux/batman_adv.h> #include <uapi/linux/batman_adv.h>
...@@ -191,7 +191,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, ...@@ -191,7 +191,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
struct vlan_ethhdr *vhdr; struct vlan_ethhdr *vhdr;
unsigned int header_len = 0; unsigned int header_len = 0;
int data_len = skb->len, ret; int data_len = skb->len, ret;
unsigned long brd_delay = 1; unsigned long brd_delay = 0;
bool do_bcast = false, client_added; bool do_bcast = false, client_added;
unsigned short vid; unsigned short vid;
u32 seqno; u32 seqno;
...@@ -330,7 +330,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, ...@@ -330,7 +330,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
bcast_packet = (struct batadv_bcast_packet *)skb->data; bcast_packet = (struct batadv_bcast_packet *)skb->data;
bcast_packet->version = BATADV_COMPAT_VERSION; bcast_packet->version = BATADV_COMPAT_VERSION;
bcast_packet->ttl = BATADV_TTL; bcast_packet->ttl = BATADV_TTL - 1;
/* batman packet type: broadcast */ /* batman packet type: broadcast */
bcast_packet->packet_type = BATADV_BCAST; bcast_packet->packet_type = BATADV_BCAST;
...@@ -346,13 +346,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, ...@@ -346,13 +346,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
seqno = atomic_inc_return(&bat_priv->bcast_seqno); seqno = atomic_inc_return(&bat_priv->bcast_seqno);
bcast_packet->seqno = htonl(seqno); bcast_packet->seqno = htonl(seqno);
batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay, true); batadv_send_bcast_packet(bat_priv, skb, brd_delay, true);
/* a copy is stored in the bcast list, therefore removing
* the original skb.
*/
consume_skb(skb);
/* unicast packet */ /* unicast packet */
} else { } else {
/* DHCP packets going to a server will use the GW feature */ /* DHCP packets going to a server will use the GW feature */
...@@ -848,14 +842,13 @@ static int batadv_softif_slave_add(struct net_device *dev, ...@@ -848,14 +842,13 @@ static int batadv_softif_slave_add(struct net_device *dev,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct batadv_hard_iface *hard_iface; struct batadv_hard_iface *hard_iface;
struct net *net = dev_net(dev);
int ret = -EINVAL; int ret = -EINVAL;
hard_iface = batadv_hardif_get_by_netdev(slave_dev); hard_iface = batadv_hardif_get_by_netdev(slave_dev);
if (!hard_iface || hard_iface->soft_iface) if (!hard_iface || hard_iface->soft_iface)
goto out; goto out;
ret = batadv_hardif_enable_interface(hard_iface, net, dev->name); ret = batadv_hardif_enable_interface(hard_iface, dev);
out: out:
if (hard_iface) if (hard_iface)
...@@ -1092,38 +1085,6 @@ static int batadv_softif_newlink(struct net *src_net, struct net_device *dev, ...@@ -1092,38 +1085,6 @@ static int batadv_softif_newlink(struct net *src_net, struct net_device *dev,
return register_netdevice(dev); return register_netdevice(dev);
} }
/**
* batadv_softif_create() - Create and register soft interface
* @net: the applicable net namespace
* @name: name of the new soft interface
*
* Return: newly allocated soft_interface, NULL on errors
*/
struct net_device *batadv_softif_create(struct net *net, const char *name)
{
struct net_device *soft_iface;
int ret;
soft_iface = alloc_netdev(sizeof(struct batadv_priv), name,
NET_NAME_UNKNOWN, batadv_softif_init_early);
if (!soft_iface)
return NULL;
dev_net_set(soft_iface, net);
soft_iface->rtnl_link_ops = &batadv_link_ops;
ret = register_netdevice(soft_iface);
if (ret < 0) {
pr_err("Unable to register the batman interface '%s': %i\n",
name, ret);
free_netdev(soft_iface);
return NULL;
}
return soft_iface;
}
/** /**
* batadv_softif_destroy_netlink() - deletion of batadv_soft_interface via * batadv_softif_destroy_netlink() - deletion of batadv_soft_interface via
* netlink * netlink
......
...@@ -12,14 +12,12 @@ ...@@ -12,14 +12,12 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/types.h> #include <linux/types.h>
#include <net/net_namespace.h>
#include <net/rtnetlink.h> #include <net/rtnetlink.h>
int batadv_skb_head_push(struct sk_buff *skb, unsigned int len); int batadv_skb_head_push(struct sk_buff *skb, unsigned int len);
void batadv_interface_rx(struct net_device *soft_iface, void batadv_interface_rx(struct net_device *soft_iface,
struct sk_buff *skb, int hdr_size, struct sk_buff *skb, int hdr_size,
struct batadv_orig_node *orig_node); struct batadv_orig_node *orig_node);
struct net_device *batadv_softif_create(struct net *net, const char *name);
bool batadv_softif_is_valid(const struct net_device *net_dev); bool batadv_softif_is_valid(const struct net_device *net_dev);
extern struct rtnl_link_ops batadv_link_ops; extern struct rtnl_link_ops batadv_link_ops;
int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid); int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid);
......
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