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) -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEE1ilQI7G+y+fdhnrfoSvjmEKSnqEFAmC/izUWHHN3QHNpbW9u d3VuZGVybGljaC5kZQAKCRChK+OYQpKeofECEADS3YF/XZw/CpLPETGLFfEg+hlE jYKPTq0enAgaEbiJuiHAI4hvdPAxD3bOGUhOU/QIMyfzJ5NVRkX1hc7A04v7HAZk fxsKI6OUQShL0ld3pFH3lNE+gnsDsHnAF8eIL/dJRVCLekxWO3jSI0VlPasGn0zG /kXugSrWV7z/fGDGmDAVE47LvTq0sCsiqDVwNZH869biYpIRh7D03EAvPkBx2UY/ StdgBC5jUED0DgJgtlmxil8Kei8gHIme1iRXnBR951vKAboyRo3bR72QkRQPoIZk l9lvFnaSAMcL9B/pcCZElmFVkkQY7h3nVw4vsyc7MbR5CKAnLMDJHyqXnnXAmStG gxR2pa54uD4hwcxax6CaTR1xhmSSFnAz8vZCaEpAyPjeU2Lt05Et1Ikv+y0Vlp3m te0M+aHu1leMjRtNye1nNDem7ubZ4kjhOFJM8YGfsQgcK0pZz0GayWiafheIguSW CNDCe52FvNzIOyjB6CeXS3iAWHckjIpBRXaBMg0uGWb7LFNXRfhg5HX02827usrS GOZ0+wq09RIc3vbgQ6c2JXSNGJ6ICa2NdNxosukzOQRquqEkGO8y+SlSKSSHZMbB mbkPJ/BnhEiTH9fkDMnPkNYYKy/6TuiFejxsmNrwBAd+MHYHJ8fBaGgNoWGRCfLY ygrNafDNE+Visz3wCw== =+IDL -----END PGP SIGNATURE----- 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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
303597e49b
@ -1849,6 +1849,8 @@ batadv_iv_ogm_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
|
||||
orig_node->orig) ||
|
||||
nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
|
||||
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,
|
||||
neigh_node->if_incoming->net_dev->ifindex) ||
|
||||
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,
|
||||
|
||||
if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
|
||||
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,
|
||||
hardif_neigh->if_incoming->net_dev->ifindex) ||
|
||||
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,
|
||||
router->addr) ||
|
||||
nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
|
||||
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,
|
||||
gw_node->bandwidth_down) ||
|
||||
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,
|
||||
|
||||
if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
|
||||
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,
|
||||
hardif_neigh->if_incoming->net_dev->ifindex) ||
|
||||
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,
|
||||
if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, orig_node->orig) ||
|
||||
nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
|
||||
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,
|
||||
neigh_node->if_incoming->net_dev->ifindex) ||
|
||||
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,
|
||||
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,
|
||||
gw_node->bandwidth_down)) {
|
||||
genlmsg_cancel(msg, hdr);
|
||||
|
@ -395,7 +395,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac,
|
||||
break;
|
||||
case BATADV_CLAIM_TYPE_ANNOUNCE:
|
||||
/* 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);
|
||||
batadv_dbg(BATADV_DBG_BLA, 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 */
|
||||
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.
|
||||
*/
|
||||
if (!orig_node)
|
||||
|
@ -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);
|
||||
int batadv_bla_init(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
|
||||
bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
|
||||
unsigned short vid);
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_arp.h>
|
||||
@ -403,7 +402,7 @@ int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* >1 neighbors -> (re)brodcast */
|
||||
/* >1 neighbors -> (re)broadcast */
|
||||
if (rcu_dereference(hlist_next_rcu(first)))
|
||||
goto out;
|
||||
|
||||
@ -677,44 +676,17 @@ batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_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
|
||||
* @hard_iface: hard interface to add to soft interface
|
||||
* @net: the applicable net namespace
|
||||
* @iface_name: name of the soft interface
|
||||
* @soft_iface: netdev struct of the mesh interface
|
||||
*
|
||||
* Return: 0 on success or negative error number in case of failure
|
||||
*/
|
||||
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 net_device *soft_iface, *master;
|
||||
__be16 ethertype = htons(ETH_P_BATMAN);
|
||||
int max_header_len = batadv_max_header_len();
|
||||
int ret;
|
||||
@ -724,35 +696,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
dev_hold(soft_iface);
|
||||
hard_iface->soft_iface = soft_iface;
|
||||
bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||
|
||||
@ -810,7 +754,6 @@ err_upper:
|
||||
err_dev:
|
||||
hard_iface->soft_iface = NULL;
|
||||
dev_put(soft_iface);
|
||||
err:
|
||||
batadv_hardif_put(hard_iface);
|
||||
return ret;
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
/**
|
||||
* 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);
|
||||
struct batadv_hard_iface*
|
||||
batadv_hardif_get_by_netdev(const struct net_device *net_dev);
|
||||
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);
|
||||
int batadv_hardif_min_mtu(struct net_device *soft_iface);
|
||||
void batadv_update_min_mtu(struct net_device *soft_iface);
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <linux/stddef.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
|
||||
*
|
||||
* Return: true if same and false if not same
|
||||
|
@ -13,7 +13,7 @@
|
||||
#define BATADV_DRIVER_DEVICE "batman-adv"
|
||||
|
||||
#ifndef BATADV_SOURCE_VERSION
|
||||
#define BATADV_SOURCE_VERSION "2021.1"
|
||||
#define BATADV_SOURCE_VERSION "2021.2"
|
||||
#endif
|
||||
|
||||
/* B.A.T.M.A.N. parameters */
|
||||
@ -88,7 +88,6 @@
|
||||
/* number of packets to send for broadcasts on different interface types */
|
||||
#define BATADV_NUM_BCASTS_DEFAULT 1
|
||||
#define BATADV_NUM_BCASTS_WIRELESS 3
|
||||
#define BATADV_NUM_BCASTS_MAX 3
|
||||
|
||||
/* length of the single packet used by the TP meter */
|
||||
#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,
|
||||
* BATADV_MCAST_WANT_NO_RTR6: No IPv6 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,
|
||||
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 br_ip_list *br_ip_entry, *tmp;
|
||||
u8 flags = BATADV_MCAST_WANT_NO_RTR6;
|
||||
int ret;
|
||||
u8 flags = BATADV_NO_FLAGS;
|
||||
|
||||
if (!bridge)
|
||||
return BATADV_MCAST_WANT_NO_RTR4 | BATADV_MCAST_WANT_NO_RTR6;
|
||||
|
||||
/* TODO: ask the bridge if a multicast router is present (the bridge
|
||||
* is capable of performing proper RFC4286 multicast router
|
||||
* discovery) instead of searching for a ff02::2 listener here
|
||||
*/
|
||||
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);
|
||||
}
|
||||
if (!br_multicast_has_router_adjacent(dev, ETH_P_IP))
|
||||
flags |= BATADV_MCAST_WANT_NO_RTR4;
|
||||
if (!br_multicast_has_router_adjacent(dev, ETH_P_IPV6))
|
||||
flags |= BATADV_MCAST_WANT_NO_RTR6;
|
||||
|
||||
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
|
||||
|
@ -814,6 +814,10 @@ static int batadv_netlink_hardif_fill(struct sk_buff *msg,
|
||||
bat_priv->soft_iface->ifindex))
|
||||
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,
|
||||
net_dev->ifindex) ||
|
||||
nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
|
||||
@ -1045,6 +1049,10 @@ static int batadv_netlink_vlan_fill(struct sk_buff *msg,
|
||||
bat_priv->soft_iface->ifindex))
|
||||
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))
|
||||
goto nla_put_failure;
|
||||
|
||||
|
@ -1182,9 +1182,9 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
|
||||
struct batadv_bcast_packet *bcast_packet;
|
||||
struct ethhdr *ethhdr;
|
||||
int hdr_size = sizeof(*bcast_packet);
|
||||
int ret = NET_RX_DROP;
|
||||
s32 seq_diff;
|
||||
u32 seqno;
|
||||
int ret;
|
||||
|
||||
/* drop packet if it has not necessary minimum size */
|
||||
if (unlikely(!pskb_may_pull(skb, hdr_size)))
|
||||
@ -1210,7 +1210,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
|
||||
if (batadv_is_my_mac(bat_priv, bcast_packet->orig))
|
||||
goto free_skb;
|
||||
|
||||
if (bcast_packet->ttl < 2)
|
||||
if (bcast_packet->ttl-- < 2)
|
||||
goto free_skb;
|
||||
|
||||
orig_node = batadv_orig_hash_find(bat_priv, bcast_packet->orig);
|
||||
@ -1249,7 +1249,9 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
|
||||
batadv_skb_set_priority(skb, sizeof(struct batadv_bcast_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
|
||||
* from the same backbone.
|
||||
@ -1275,6 +1277,7 @@ spin_unlock:
|
||||
spin_unlock_bh(&orig_node->bcast_seqno_lock);
|
||||
free_skb:
|
||||
kfree_skb(skb);
|
||||
ret = NET_RX_DROP;
|
||||
out:
|
||||
if (orig_node)
|
||||
batadv_orig_node_put(orig_node);
|
||||
|
@ -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
|
||||
* @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 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
|
||||
const struct sk_buff *skb,
|
||||
unsigned long delay,
|
||||
bool own_packet)
|
||||
static int batadv_forw_bcast_packet_to_list(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)
|
||||
{
|
||||
struct batadv_hard_iface *primary_if;
|
||||
struct batadv_forw_packet *forw_packet;
|
||||
struct batadv_bcast_packet *bcast_packet;
|
||||
unsigned long send_time = jiffies;
|
||||
struct sk_buff *newskb;
|
||||
|
||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||
if (!primary_if)
|
||||
goto err;
|
||||
|
||||
newskb = skb_copy(skb, GFP_ATOMIC);
|
||||
if (!newskb) {
|
||||
batadv_hardif_put(primary_if);
|
||||
if (!newskb)
|
||||
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, newskb);
|
||||
batadv_hardif_put(primary_if);
|
||||
if (!forw_packet)
|
||||
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;
|
||||
|
||||
INIT_DELAYED_WORK(&forw_packet->delayed_work,
|
||||
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;
|
||||
|
||||
err_packet_free:
|
||||
@ -796,10 +787,220 @@ err:
|
||||
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
|
||||
* @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
|
||||
* interface.
|
||||
@ -811,28 +1012,20 @@ err:
|
||||
* Return: True if (re)transmissions are left, false otherwise.
|
||||
*/
|
||||
static bool
|
||||
batadv_forw_packet_bcasts_left(struct batadv_forw_packet *forw_packet,
|
||||
struct batadv_hard_iface *hard_iface)
|
||||
batadv_forw_packet_bcasts_left(struct batadv_forw_packet *forw_packet)
|
||||
{
|
||||
unsigned int max;
|
||||
|
||||
if (hard_iface)
|
||||
max = hard_iface->num_bcasts;
|
||||
else
|
||||
max = BATADV_NUM_BCASTS_MAX;
|
||||
|
||||
return BATADV_SKB_CB(forw_packet->skb)->num_bcasts < max;
|
||||
return BATADV_SKB_CB(forw_packet->skb)->num_bcasts;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_forw_packet_bcasts_inc() - increment retransmission counter of a
|
||||
* batadv_forw_packet_bcasts_dec() - decrement retransmission counter of a
|
||||
* packet
|
||||
* @forw_packet: the packet to increase the counter for
|
||||
* @forw_packet: the packet to decrease the counter for
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
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)
|
||||
{
|
||||
struct batadv_hard_iface *hard_iface;
|
||||
struct batadv_hardif_neigh_node *neigh_node;
|
||||
struct delayed_work *delayed_work;
|
||||
struct batadv_forw_packet *forw_packet;
|
||||
struct batadv_bcast_packet *bcast_packet;
|
||||
struct sk_buff *skb1;
|
||||
struct net_device *soft_iface;
|
||||
struct batadv_priv *bat_priv;
|
||||
unsigned long send_time = jiffies + msecs_to_jiffies(5);
|
||||
struct batadv_forw_packet *forw_packet;
|
||||
struct delayed_work *delayed_work;
|
||||
struct batadv_priv *bat_priv;
|
||||
struct sk_buff *skb1;
|
||||
bool dropped = false;
|
||||
u8 *neigh_addr;
|
||||
u8 *orig_neigh;
|
||||
int ret = 0;
|
||||
|
||||
delayed_work = to_delayed_work(work);
|
||||
forw_packet = container_of(delayed_work, struct batadv_forw_packet,
|
||||
delayed_work);
|
||||
soft_iface = forw_packet->if_incoming->soft_iface;
|
||||
bat_priv = netdev_priv(soft_iface);
|
||||
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
|
||||
|
||||
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
|
||||
dropped = true;
|
||||
@ -878,76 +1071,15 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
|
||||
goto out;
|
||||
}
|
||||
|
||||
bcast_packet = (struct batadv_bcast_packet *)forw_packet->skb->data;
|
||||
/* send a copy of the saved skb */
|
||||
skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
|
||||
if (!skb1)
|
||||
goto out;
|
||||
|
||||
/* rebroadcast packet */
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
|
||||
if (hard_iface->soft_iface != soft_iface)
|
||||
continue;
|
||||
batadv_send_broadcast_skb(skb1, forw_packet->if_outgoing);
|
||||
batadv_forw_packet_bcasts_dec(forw_packet);
|
||||
|
||||
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 */
|
||||
skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
|
||||
if (skb1)
|
||||
batadv_send_broadcast_skb(skb1, hard_iface);
|
||||
|
||||
batadv_hardif_put(hard_iface);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
batadv_forw_packet_bcasts_inc(forw_packet);
|
||||
|
||||
/* if we still have some more bcasts to send */
|
||||
if (batadv_forw_packet_bcasts_left(forw_packet, NULL)) {
|
||||
if (batadv_forw_packet_bcasts_left(forw_packet)) {
|
||||
batadv_forw_packet_bcast_queue(bat_priv, forw_packet,
|
||||
send_time);
|
||||
return;
|
||||
|
@ -39,10 +39,14 @@ int batadv_send_broadcast_skb(struct sk_buff *skb,
|
||||
struct batadv_hard_iface *hard_iface);
|
||||
int batadv_send_unicast_skb(struct sk_buff *skb,
|
||||
struct batadv_neigh_node *neigh_node);
|
||||
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
|
||||
const struct sk_buff *skb,
|
||||
unsigned long delay,
|
||||
bool own_packet);
|
||||
int batadv_forw_bcast_packet(struct batadv_priv *bat_priv,
|
||||
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,
|
||||
bool own_packet);
|
||||
void
|
||||
batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
|
||||
const struct batadv_hard_iface *hard_iface);
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/rcupdate.h>
|
||||
@ -37,6 +36,7 @@
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netlink.h>
|
||||
#include <uapi/linux/batadv_packet.h>
|
||||
#include <uapi/linux/batman_adv.h>
|
||||
@ -191,7 +191,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
|
||||
struct vlan_ethhdr *vhdr;
|
||||
unsigned int header_len = 0;
|
||||
int data_len = skb->len, ret;
|
||||
unsigned long brd_delay = 1;
|
||||
unsigned long brd_delay = 0;
|
||||
bool do_bcast = false, client_added;
|
||||
unsigned short vid;
|
||||
u32 seqno;
|
||||
@ -330,7 +330,7 @@ send:
|
||||
|
||||
bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||
bcast_packet->version = BATADV_COMPAT_VERSION;
|
||||
bcast_packet->ttl = BATADV_TTL;
|
||||
bcast_packet->ttl = BATADV_TTL - 1;
|
||||
|
||||
/* batman packet type: broadcast */
|
||||
bcast_packet->packet_type = BATADV_BCAST;
|
||||
@ -346,13 +346,7 @@ send:
|
||||
seqno = atomic_inc_return(&bat_priv->bcast_seqno);
|
||||
bcast_packet->seqno = htonl(seqno);
|
||||
|
||||
batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay, true);
|
||||
|
||||
/* a copy is stored in the bcast list, therefore removing
|
||||
* the original skb.
|
||||
*/
|
||||
consume_skb(skb);
|
||||
|
||||
batadv_send_bcast_packet(bat_priv, skb, brd_delay, true);
|
||||
/* unicast packet */
|
||||
} else {
|
||||
/* 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,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct batadv_hard_iface *hard_iface;
|
||||
struct net *net = dev_net(dev);
|
||||
int ret = -EINVAL;
|
||||
|
||||
hard_iface = batadv_hardif_get_by_netdev(slave_dev);
|
||||
if (!hard_iface || hard_iface->soft_iface)
|
||||
goto out;
|
||||
|
||||
ret = batadv_hardif_enable_interface(hard_iface, net, dev->name);
|
||||
ret = batadv_hardif_enable_interface(hard_iface, dev);
|
||||
|
||||
out:
|
||||
if (hard_iface)
|
||||
@ -1092,38 +1085,6 @@ static int batadv_softif_newlink(struct net *src_net, struct net_device *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
|
||||
* netlink
|
||||
|
@ -12,14 +12,12 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/rtnetlink.h>
|
||||
|
||||
int batadv_skb_head_push(struct sk_buff *skb, unsigned int len);
|
||||
void batadv_interface_rx(struct net_device *soft_iface,
|
||||
struct sk_buff *skb, int hdr_size,
|
||||
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);
|
||||
extern struct rtnl_link_ops batadv_link_ops;
|
||||
int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user