mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-12 08:56:47 +07:00
Included changes:
- change my email in MAINTAINERS and Doc files - create and export list of single hop neighs per interface - protect CRC in the BLA code by means of its own lock - minor fixes and code cleanups -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJWcRAcAAoJENpFlCjNi1MRxPQP/A8wAuHYUyMDu6ov5VRUR+24 TYKgCVI1evuYlkOdgHkTQfTlOILgV2NHvORzKwQRNToyvtsd4VIeXZfFJ0UXB0Wo sMz9vrmmcndGkcYPWs+6IoVUbxMPZXjRGhme3Ig7nNTOQ4GvcSaQANbYWAMBfg61 h6pxez67el9jzso2acHEgvOyaldOLDcbbdwt4vY7bPRgD9VXpE3nazBymaZXLLxs 1ByXiCgJw32gXSWv8RQ/j13btjrbWCdmcEz9Ag1xO5i5u9BI1VJ8nmbLuNu63S0G Ftgvk5QBeMAxs3xDiTmtQD3bmiS87Jy+1d5rFb581/arM5SnYq6GZIrb81tdVTU6 PMkMZ6/EUV2HSogq9PJ1ZDk/0oPYT5tqfLtJWcaAZplmWYt3ZUrQsPo4z5CtbBhU 6Ar29G5slkgLslcBqn6YB00LxwOmj7elyVdPtL+wMCojtut+Ds4O+FzPdvd/145F hCtIe55b2ciBsfp1dDXP5P15HeEMjLiN2xWJKAPLhDCmGruJ6Pnly+ElzgV+zdKL 7Qe1mOXwticMy3pH+ST7CP47tp5uyT0ak27eo+oOn4LI/ppM2qW1P9bNUZ6RrVwf dRRh0dzQruaLQauHK2Z6BWtA2Q36wY2anwmBONK34NH6VfRMB1GJMi3JF8gDgTds SWwU5FGWTn/cnCejtsbh =/Z+R -----END PGP SIGNATURE----- Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge Antonio Quartulli says: ==================== Included changes: - change my email in MAINTAINERS and Doc files - create and export list of single hop neighs per interface - protect CRC in the BLA code by means of its own lock - minor fixes and code cleanups ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
04ad37836c
@ -8,7 +8,7 @@ Description:
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/<vlan_subdir>/ap_isolation
|
||||
Date: May 2011
|
||||
Contact: Antonio Quartulli <antonio@meshcoding.com>
|
||||
Contact: Antonio Quartulli <a@unstable.cc>
|
||||
Description:
|
||||
Indicates whether the data traffic going from a
|
||||
wireless client to another wireless client will be
|
||||
@ -70,7 +70,7 @@ Description:
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/isolation_mark
|
||||
Date: Nov 2013
|
||||
Contact: Antonio Quartulli <antonio@meshcoding.com>
|
||||
Contact: Antonio Quartulli <a@unstable.cc>
|
||||
Description:
|
||||
Defines the isolation mark (and its bitmask) which
|
||||
is used to classify clients as "isolated" by the
|
||||
|
@ -2111,7 +2111,7 @@ F: include/linux/backlight.h
|
||||
BATMAN ADVANCED
|
||||
M: Marek Lindner <mareklindner@neomailbox.ch>
|
||||
M: Simon Wunderlich <sw@simonwunderlich.de>
|
||||
M: Antonio Quartulli <antonio@meshcoding.com>
|
||||
M: Antonio Quartulli <a@unstable.cc>
|
||||
L: b.a.t.m.a.n@lists.open-mesh.org
|
||||
W: http://www.open-mesh.org/
|
||||
S: Maintained
|
||||
|
@ -1379,6 +1379,7 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
|
||||
struct batadv_hard_iface *if_outgoing)
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
|
||||
struct batadv_hardif_neigh_node *hardif_neigh = NULL;
|
||||
struct batadv_neigh_node *router = NULL;
|
||||
struct batadv_neigh_node *router_router = NULL;
|
||||
struct batadv_orig_node *orig_neigh_node;
|
||||
@ -1423,6 +1424,13 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (is_single_hop_neigh) {
|
||||
hardif_neigh = batadv_hardif_neigh_get(if_incoming,
|
||||
ethhdr->h_source);
|
||||
if (hardif_neigh)
|
||||
hardif_neigh->last_seen = jiffies;
|
||||
}
|
||||
|
||||
router = batadv_orig_router_get(orig_node, if_outgoing);
|
||||
if (router) {
|
||||
router_router = batadv_orig_router_get(router->orig_node,
|
||||
@ -1557,6 +1565,8 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
|
||||
batadv_neigh_node_free_ref(router_router);
|
||||
if (orig_neigh_router)
|
||||
batadv_neigh_node_free_ref(orig_neigh_router);
|
||||
if (hardif_neigh)
|
||||
batadv_hardif_neigh_free_ref(hardif_neigh);
|
||||
|
||||
kfree_skb(skb_priv);
|
||||
}
|
||||
@ -1861,6 +1871,58 @@ static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
|
||||
seq_puts(seq, "No batman nodes in range ...\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_iv_hardif_neigh_print - print a single hop neighbour node
|
||||
* @seq: neighbour table seq_file struct
|
||||
* @hardif_neigh: hardif neighbour information
|
||||
*/
|
||||
static void
|
||||
batadv_iv_hardif_neigh_print(struct seq_file *seq,
|
||||
struct batadv_hardif_neigh_node *hardif_neigh)
|
||||
{
|
||||
int last_secs, last_msecs;
|
||||
|
||||
last_secs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) / 1000;
|
||||
last_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) % 1000;
|
||||
|
||||
seq_printf(seq, " %10s %pM %4i.%03is\n",
|
||||
hardif_neigh->if_incoming->net_dev->name,
|
||||
hardif_neigh->addr, last_secs, last_msecs);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_iv_ogm_neigh_print - print the single hop neighbour list
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @seq: neighbour table seq_file struct
|
||||
*/
|
||||
static void batadv_iv_neigh_print(struct batadv_priv *bat_priv,
|
||||
struct seq_file *seq)
|
||||
{
|
||||
struct net_device *net_dev = (struct net_device *)seq->private;
|
||||
struct batadv_hardif_neigh_node *hardif_neigh;
|
||||
struct batadv_hard_iface *hard_iface;
|
||||
int batman_count = 0;
|
||||
|
||||
seq_printf(seq, " %10s %-13s %s\n",
|
||||
"IF", "Neighbor", "last-seen");
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
|
||||
if (hard_iface->soft_iface != net_dev)
|
||||
continue;
|
||||
|
||||
hlist_for_each_entry_rcu(hardif_neigh,
|
||||
&hard_iface->neigh_list, list) {
|
||||
batadv_iv_hardif_neigh_print(seq, hardif_neigh);
|
||||
batman_count++;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (batman_count == 0)
|
||||
seq_puts(seq, "No batman nodes in range ...\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_iv_ogm_neigh_cmp - compare the metrics of two neighbors
|
||||
* @neigh1: the first neighbor object of the comparison
|
||||
@ -1902,8 +1964,8 @@ static int batadv_iv_ogm_neigh_cmp(struct batadv_neigh_node *neigh1,
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_iv_ogm_neigh_is_eob - check if neigh1 is equally good or better than
|
||||
* neigh2 from the metric prospective
|
||||
* batadv_iv_ogm_neigh_is_sob - check if neigh1 is similarly good or better
|
||||
* than neigh2 from the metric prospective
|
||||
* @neigh1: the first neighbor object of the comparison
|
||||
* @if_outgoing1: outgoing interface for the first neighbor
|
||||
* @neigh2: the second neighbor object of the comparison
|
||||
@ -1913,7 +1975,7 @@ static int batadv_iv_ogm_neigh_cmp(struct batadv_neigh_node *neigh1,
|
||||
* the metric via neigh2, false otherwise.
|
||||
*/
|
||||
static bool
|
||||
batadv_iv_ogm_neigh_is_eob(struct batadv_neigh_node *neigh1,
|
||||
batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
|
||||
struct batadv_hard_iface *if_outgoing1,
|
||||
struct batadv_neigh_node *neigh2,
|
||||
struct batadv_hard_iface *if_outgoing2)
|
||||
@ -1953,7 +2015,8 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
|
||||
.bat_ogm_schedule = batadv_iv_ogm_schedule,
|
||||
.bat_ogm_emit = batadv_iv_ogm_emit,
|
||||
.bat_neigh_cmp = batadv_iv_ogm_neigh_cmp,
|
||||
.bat_neigh_is_equiv_or_better = batadv_iv_ogm_neigh_is_eob,
|
||||
.bat_neigh_is_similar_or_better = batadv_iv_ogm_neigh_is_sob,
|
||||
.bat_neigh_print = batadv_iv_neigh_print,
|
||||
.bat_orig_print = batadv_iv_ogm_orig_print,
|
||||
.bat_orig_free = batadv_iv_ogm_orig_free,
|
||||
.bat_orig_add_if = batadv_iv_ogm_orig_add_if,
|
||||
|
@ -260,7 +260,9 @@ batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
|
||||
}
|
||||
|
||||
/* all claims gone, initialize CRC */
|
||||
spin_lock_bh(&backbone_gw->crc_lock);
|
||||
backbone_gw->crc = BATADV_BLA_CRC_INIT;
|
||||
spin_unlock_bh(&backbone_gw->crc_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -408,6 +410,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, u8 *orig,
|
||||
entry->lasttime = jiffies;
|
||||
entry->crc = BATADV_BLA_CRC_INIT;
|
||||
entry->bat_priv = bat_priv;
|
||||
spin_lock_init(&entry->crc_lock);
|
||||
atomic_set(&entry->request_sent, 0);
|
||||
atomic_set(&entry->wait_periods, 0);
|
||||
ether_addr_copy(entry->orig, orig);
|
||||
@ -557,7 +560,9 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
|
||||
__be16 crc;
|
||||
|
||||
memcpy(mac, batadv_announce_mac, 4);
|
||||
spin_lock_bh(&backbone_gw->crc_lock);
|
||||
crc = htons(backbone_gw->crc);
|
||||
spin_unlock_bh(&backbone_gw->crc_lock);
|
||||
memcpy(&mac[4], &crc, 2);
|
||||
|
||||
batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
|
||||
@ -618,14 +623,18 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
|
||||
"bla_add_claim(): changing ownership for %pM, vid %d\n",
|
||||
mac, BATADV_PRINT_VID(vid));
|
||||
|
||||
spin_lock_bh(&claim->backbone_gw->crc_lock);
|
||||
claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
|
||||
spin_unlock_bh(&claim->backbone_gw->crc_lock);
|
||||
batadv_backbone_gw_free_ref(claim->backbone_gw);
|
||||
}
|
||||
/* set (new) backbone gw */
|
||||
atomic_inc(&backbone_gw->refcount);
|
||||
claim->backbone_gw = backbone_gw;
|
||||
|
||||
spin_lock_bh(&backbone_gw->crc_lock);
|
||||
backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
|
||||
spin_unlock_bh(&backbone_gw->crc_lock);
|
||||
backbone_gw->lasttime = jiffies;
|
||||
|
||||
claim_free_ref:
|
||||
@ -653,7 +662,9 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
|
||||
batadv_choose_claim, claim);
|
||||
batadv_claim_free_ref(claim); /* reference from the hash is gone */
|
||||
|
||||
spin_lock_bh(&claim->backbone_gw->crc_lock);
|
||||
claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
|
||||
spin_unlock_bh(&claim->backbone_gw->crc_lock);
|
||||
|
||||
/* don't need the reference from hash_find() anymore */
|
||||
batadv_claim_free_ref(claim);
|
||||
@ -664,7 +675,7 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,
|
||||
u8 *backbone_addr, unsigned short vid)
|
||||
{
|
||||
struct batadv_bla_backbone_gw *backbone_gw;
|
||||
u16 crc;
|
||||
u16 backbone_crc, crc;
|
||||
|
||||
if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
|
||||
return 0;
|
||||
@ -683,12 +694,16 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,
|
||||
"handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
|
||||
BATADV_PRINT_VID(vid), backbone_gw->orig, crc);
|
||||
|
||||
if (backbone_gw->crc != crc) {
|
||||
spin_lock_bh(&backbone_gw->crc_lock);
|
||||
backbone_crc = backbone_gw->crc;
|
||||
spin_unlock_bh(&backbone_gw->crc_lock);
|
||||
|
||||
if (backbone_crc != crc) {
|
||||
batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
|
||||
"handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
|
||||
backbone_gw->orig,
|
||||
BATADV_PRINT_VID(backbone_gw->vid),
|
||||
backbone_gw->crc, crc);
|
||||
backbone_crc, crc);
|
||||
|
||||
batadv_bla_send_request(backbone_gw);
|
||||
} else {
|
||||
@ -1647,6 +1662,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||
struct batadv_bla_claim *claim;
|
||||
struct batadv_hard_iface *primary_if;
|
||||
struct hlist_head *head;
|
||||
u16 backbone_crc;
|
||||
u32 i;
|
||||
bool is_own;
|
||||
u8 *primary_addr;
|
||||
@ -1669,11 +1685,15 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||
hlist_for_each_entry_rcu(claim, head, hash_entry) {
|
||||
is_own = batadv_compare_eth(claim->backbone_gw->orig,
|
||||
primary_addr);
|
||||
|
||||
spin_lock_bh(&claim->backbone_gw->crc_lock);
|
||||
backbone_crc = claim->backbone_gw->crc;
|
||||
spin_unlock_bh(&claim->backbone_gw->crc_lock);
|
||||
seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)\n",
|
||||
claim->addr, BATADV_PRINT_VID(claim->vid),
|
||||
claim->backbone_gw->orig,
|
||||
(is_own ? 'x' : ' '),
|
||||
claim->backbone_gw->crc);
|
||||
backbone_crc);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
@ -1692,6 +1712,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||
struct batadv_hard_iface *primary_if;
|
||||
struct hlist_head *head;
|
||||
int secs, msecs;
|
||||
u16 backbone_crc;
|
||||
u32 i;
|
||||
bool is_own;
|
||||
u8 *primary_addr;
|
||||
@ -1722,10 +1743,14 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||
if (is_own)
|
||||
continue;
|
||||
|
||||
spin_lock_bh(&backbone_gw->crc_lock);
|
||||
backbone_crc = backbone_gw->crc;
|
||||
spin_unlock_bh(&backbone_gw->crc_lock);
|
||||
|
||||
seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)\n",
|
||||
backbone_gw->orig,
|
||||
BATADV_PRINT_VID(backbone_gw->vid), secs,
|
||||
msecs, backbone_gw->crc);
|
||||
msecs, backbone_crc);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -262,6 +262,13 @@ static int batadv_algorithms_open(struct inode *inode, struct file *file)
|
||||
return single_open(file, batadv_algo_seq_print_text, NULL);
|
||||
}
|
||||
|
||||
static int neighbors_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
||||
|
||||
return single_open(file, batadv_hardif_neigh_seq_print_text, net_dev);
|
||||
}
|
||||
|
||||
static int batadv_originators_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
||||
@ -375,6 +382,7 @@ static struct batadv_debuginfo *batadv_general_debuginfos[] = {
|
||||
};
|
||||
|
||||
/* The following attributes are per soft interface */
|
||||
static BATADV_DEBUGINFO(neighbors, S_IRUGO, neighbors_open);
|
||||
static BATADV_DEBUGINFO(originators, S_IRUGO, batadv_originators_open);
|
||||
static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open);
|
||||
static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
|
||||
@ -394,6 +402,7 @@ static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open);
|
||||
#endif
|
||||
|
||||
static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
|
||||
&batadv_debuginfo_neighbors,
|
||||
&batadv_debuginfo_originators,
|
||||
&batadv_debuginfo_gateways,
|
||||
&batadv_debuginfo_transtable_global,
|
||||
|
@ -71,14 +71,14 @@ void batadv_frag_purge_orig(struct batadv_orig_node *orig_node,
|
||||
|
||||
for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
|
||||
chain = &orig_node->fragments[i];
|
||||
spin_lock_bh(&orig_node->fragments[i].lock);
|
||||
spin_lock_bh(&chain->lock);
|
||||
|
||||
if (!check_cb || check_cb(chain)) {
|
||||
batadv_frag_clear_chain(&orig_node->fragments[i].head);
|
||||
orig_node->fragments[i].size = 0;
|
||||
batadv_frag_clear_chain(&chain->head);
|
||||
chain->size = 0;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&orig_node->fragments[i].lock);
|
||||
spin_unlock_bh(&chain->lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
@ -639,9 +640,12 @@ batadv_hardif_add_interface(struct net_device *net_dev)
|
||||
goto free_sysfs;
|
||||
|
||||
INIT_LIST_HEAD(&hard_iface->list);
|
||||
INIT_HLIST_HEAD(&hard_iface->neigh_list);
|
||||
INIT_WORK(&hard_iface->cleanup_work,
|
||||
batadv_hardif_remove_interface_finish);
|
||||
|
||||
spin_lock_init(&hard_iface->neigh_list_lock);
|
||||
|
||||
hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
|
||||
if (batadv_is_wifi_netdev(net_dev))
|
||||
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
|
||||
|
@ -552,7 +552,7 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops)
|
||||
!bat_algo_ops->bat_ogm_schedule ||
|
||||
!bat_algo_ops->bat_ogm_emit ||
|
||||
!bat_algo_ops->bat_neigh_cmp ||
|
||||
!bat_algo_ops->bat_neigh_is_equiv_or_better) {
|
||||
!bat_algo_ops->bat_neigh_is_similar_or_better) {
|
||||
pr_info("Routing algo '%s' does not implement required ops\n",
|
||||
bat_algo_ops->name);
|
||||
return -EINVAL;
|
||||
@ -908,7 +908,7 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
|
||||
* appropriate handlers
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @tvlv_handler: tvlv callback function handling the tvlv content
|
||||
* @ogm_source: flag indicating wether the tvlv is an ogm or a unicast packet
|
||||
* @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet
|
||||
* @orig_node: orig node emitting the ogm packet
|
||||
* @src: source mac address of the unicast packet
|
||||
* @dst: destination mac address of the unicast packet
|
||||
@ -961,7 +961,7 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
|
||||
* batadv_tvlv_containers_process - parse the given tvlv buffer to call the
|
||||
* appropriate handlers
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @ogm_source: flag indicating wether the tvlv is an ogm or a unicast packet
|
||||
* @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet
|
||||
* @orig_node: orig node emitting the ogm packet
|
||||
* @src: source mac address of the unicast packet
|
||||
* @dst: destination mac address of the unicast packet
|
||||
|
@ -201,6 +201,47 @@ void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo)
|
||||
call_rcu(&neigh_ifinfo->rcu, batadv_neigh_ifinfo_free_rcu);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hardif_neigh_free_rcu - free the hardif neigh_node
|
||||
* @rcu: rcu pointer of the neigh_node
|
||||
*/
|
||||
static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu)
|
||||
{
|
||||
struct batadv_hardif_neigh_node *hardif_neigh;
|
||||
|
||||
hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu);
|
||||
|
||||
spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
|
||||
hlist_del_init_rcu(&hardif_neigh->list);
|
||||
spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
|
||||
|
||||
batadv_hardif_free_ref_now(hardif_neigh->if_incoming);
|
||||
kfree(hardif_neigh);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hardif_neigh_free_now - decrement the hardif neighbors refcounter
|
||||
* and possibly free it (without rcu callback)
|
||||
* @hardif_neigh: hardif neigh neighbor to free
|
||||
*/
|
||||
static void
|
||||
batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh)
|
||||
{
|
||||
if (atomic_dec_and_test(&hardif_neigh->refcount))
|
||||
batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hardif_neigh_free_ref - decrement the hardif neighbors refcounter
|
||||
* and possibly free it
|
||||
* @hardif_neigh: hardif neigh neighbor to free
|
||||
*/
|
||||
void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh)
|
||||
{
|
||||
if (atomic_dec_and_test(&hardif_neigh->refcount))
|
||||
call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_neigh_node_free_rcu - free the neigh_node
|
||||
* @rcu: rcu pointer of the neigh_node
|
||||
@ -209,6 +250,7 @@ static void batadv_neigh_node_free_rcu(struct rcu_head *rcu)
|
||||
{
|
||||
struct hlist_node *node_tmp;
|
||||
struct batadv_neigh_node *neigh_node;
|
||||
struct batadv_hardif_neigh_node *hardif_neigh;
|
||||
struct batadv_neigh_ifinfo *neigh_ifinfo;
|
||||
struct batadv_algo_ops *bao;
|
||||
|
||||
@ -220,6 +262,14 @@ static void batadv_neigh_node_free_rcu(struct rcu_head *rcu)
|
||||
batadv_neigh_ifinfo_free_ref_now(neigh_ifinfo);
|
||||
}
|
||||
|
||||
hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming,
|
||||
neigh_node->addr);
|
||||
if (hardif_neigh) {
|
||||
/* batadv_hardif_neigh_get() increases refcount too */
|
||||
batadv_hardif_neigh_free_now(hardif_neigh);
|
||||
batadv_hardif_neigh_free_now(hardif_neigh);
|
||||
}
|
||||
|
||||
if (bao->bat_neigh_free)
|
||||
bao->bat_neigh_free(neigh_node);
|
||||
|
||||
@ -478,6 +528,106 @@ batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hardif_neigh_create - create a hardif neighbour node
|
||||
* @hard_iface: the interface this neighbour is connected to
|
||||
* @neigh_addr: the interface address of the neighbour to retrieve
|
||||
*
|
||||
* Returns the hardif neighbour node if found or created or NULL otherwise.
|
||||
*/
|
||||
static struct batadv_hardif_neigh_node *
|
||||
batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface,
|
||||
const u8 *neigh_addr)
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||
struct batadv_hardif_neigh_node *hardif_neigh = NULL;
|
||||
|
||||
spin_lock_bh(&hard_iface->neigh_list_lock);
|
||||
|
||||
/* check if neighbor hasn't been added in the meantime */
|
||||
hardif_neigh = batadv_hardif_neigh_get(hard_iface, neigh_addr);
|
||||
if (hardif_neigh)
|
||||
goto out;
|
||||
|
||||
if (!atomic_inc_not_zero(&hard_iface->refcount))
|
||||
goto out;
|
||||
|
||||
hardif_neigh = kzalloc(sizeof(*hardif_neigh), GFP_ATOMIC);
|
||||
if (!hardif_neigh) {
|
||||
batadv_hardif_free_ref(hard_iface);
|
||||
goto out;
|
||||
}
|
||||
|
||||
INIT_HLIST_NODE(&hardif_neigh->list);
|
||||
ether_addr_copy(hardif_neigh->addr, neigh_addr);
|
||||
hardif_neigh->if_incoming = hard_iface;
|
||||
hardif_neigh->last_seen = jiffies;
|
||||
|
||||
atomic_set(&hardif_neigh->refcount, 1);
|
||||
|
||||
if (bat_priv->bat_algo_ops->bat_hardif_neigh_init)
|
||||
bat_priv->bat_algo_ops->bat_hardif_neigh_init(hardif_neigh);
|
||||
|
||||
hlist_add_head(&hardif_neigh->list, &hard_iface->neigh_list);
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&hard_iface->neigh_list_lock);
|
||||
return hardif_neigh;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hardif_neigh_get_or_create - retrieve or create a hardif neighbour
|
||||
* node
|
||||
* @hard_iface: the interface this neighbour is connected to
|
||||
* @neigh_addr: the interface address of the neighbour to retrieve
|
||||
*
|
||||
* Returns the hardif neighbour node if found or created or NULL otherwise.
|
||||
*/
|
||||
static struct batadv_hardif_neigh_node *
|
||||
batadv_hardif_neigh_get_or_create(struct batadv_hard_iface *hard_iface,
|
||||
const u8 *neigh_addr)
|
||||
{
|
||||
struct batadv_hardif_neigh_node *hardif_neigh = NULL;
|
||||
|
||||
/* first check without locking to avoid the overhead */
|
||||
hardif_neigh = batadv_hardif_neigh_get(hard_iface, neigh_addr);
|
||||
if (hardif_neigh)
|
||||
return hardif_neigh;
|
||||
|
||||
return batadv_hardif_neigh_create(hard_iface, neigh_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hardif_neigh_get - retrieve a hardif neighbour from the list
|
||||
* @hard_iface: the interface where this neighbour is connected to
|
||||
* @neigh_addr: the address of the neighbour
|
||||
*
|
||||
* Looks for and possibly returns a neighbour belonging to this hard interface.
|
||||
* Returns NULL if the neighbour is not found.
|
||||
*/
|
||||
struct batadv_hardif_neigh_node *
|
||||
batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
|
||||
const u8 *neigh_addr)
|
||||
{
|
||||
struct batadv_hardif_neigh_node *tmp_hardif_neigh, *hardif_neigh = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(tmp_hardif_neigh,
|
||||
&hard_iface->neigh_list, list) {
|
||||
if (!batadv_compare_eth(tmp_hardif_neigh->addr, neigh_addr))
|
||||
continue;
|
||||
|
||||
if (!atomic_inc_not_zero(&tmp_hardif_neigh->refcount))
|
||||
continue;
|
||||
|
||||
hardif_neigh = tmp_hardif_neigh;
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return hardif_neigh;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_neigh_node_new - create and init a new neigh_node object
|
||||
* @orig_node: originator object representing the neighbour
|
||||
@ -493,11 +643,17 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node,
|
||||
const u8 *neigh_addr)
|
||||
{
|
||||
struct batadv_neigh_node *neigh_node;
|
||||
struct batadv_hardif_neigh_node *hardif_neigh = NULL;
|
||||
|
||||
neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
|
||||
if (neigh_node)
|
||||
goto out;
|
||||
|
||||
hardif_neigh = batadv_hardif_neigh_get_or_create(hard_iface,
|
||||
neigh_addr);
|
||||
if (!hardif_neigh)
|
||||
goto out;
|
||||
|
||||
neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC);
|
||||
if (!neigh_node)
|
||||
goto out;
|
||||
@ -523,14 +679,53 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node,
|
||||
hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
|
||||
spin_unlock_bh(&orig_node->neigh_list_lock);
|
||||
|
||||
/* increment unique neighbor refcount */
|
||||
atomic_inc(&hardif_neigh->refcount);
|
||||
|
||||
batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv,
|
||||
"Creating new neighbor %pM for orig_node %pM on interface %s\n",
|
||||
neigh_addr, orig_node->orig, hard_iface->net_dev->name);
|
||||
|
||||
out:
|
||||
if (hardif_neigh)
|
||||
batadv_hardif_neigh_free_ref(hardif_neigh);
|
||||
return neigh_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hardif_neigh_seq_print_text - print the single hop neighbour list
|
||||
* @seq: neighbour table seq_file struct
|
||||
* @offset: not used
|
||||
*
|
||||
* Always returns 0.
|
||||
*/
|
||||
int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct net_device *net_dev = (struct net_device *)seq->private;
|
||||
struct batadv_priv *bat_priv = netdev_priv(net_dev);
|
||||
struct batadv_hard_iface *primary_if;
|
||||
|
||||
primary_if = batadv_seq_print_text_primary_if_get(seq);
|
||||
if (!primary_if)
|
||||
return 0;
|
||||
|
||||
seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s %s)]\n",
|
||||
BATADV_SOURCE_VERSION, primary_if->net_dev->name,
|
||||
primary_if->net_dev->dev_addr, net_dev->name,
|
||||
bat_priv->bat_algo_ops->name);
|
||||
|
||||
batadv_hardif_free_ref(primary_if);
|
||||
|
||||
if (!bat_priv->bat_algo_ops->bat_neigh_print) {
|
||||
seq_puts(seq,
|
||||
"No printing function for this routing protocol\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bat_priv->bat_algo_ops->bat_neigh_print(bat_priv, seq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_orig_ifinfo_free_rcu - free the orig_ifinfo object
|
||||
* @rcu: rcu pointer of the orig_ifinfo object
|
||||
|
@ -41,6 +41,11 @@ void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node);
|
||||
void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node);
|
||||
struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
|
||||
const u8 *addr);
|
||||
struct batadv_hardif_neigh_node *
|
||||
batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
|
||||
const u8 *neigh_addr);
|
||||
void
|
||||
batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh);
|
||||
struct batadv_neigh_node *
|
||||
batadv_neigh_node_new(struct batadv_orig_node *orig_node,
|
||||
struct batadv_hard_iface *hard_iface,
|
||||
@ -57,6 +62,8 @@ batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
|
||||
struct batadv_hard_iface *if_outgoing);
|
||||
void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo);
|
||||
|
||||
int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset);
|
||||
|
||||
struct batadv_orig_ifinfo *
|
||||
batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
|
||||
struct batadv_hard_iface *if_outgoing);
|
||||
|
@ -497,9 +497,9 @@ batadv_find_router(struct batadv_priv *bat_priv,
|
||||
/* alternative candidate should be good enough to be
|
||||
* considered
|
||||
*/
|
||||
if (!bao->bat_neigh_is_equiv_or_better(cand_router,
|
||||
cand->if_outgoing,
|
||||
router, recv_if))
|
||||
if (!bao->bat_neigh_is_similar_or_better(cand_router,
|
||||
cand->if_outgoing,
|
||||
router, recv_if))
|
||||
goto next;
|
||||
|
||||
/* don't use the same router twice */
|
||||
|
@ -1435,7 +1435,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
|
||||
* TT_CLIENT_WIFI, therefore they have to be copied in the
|
||||
* client entry
|
||||
*/
|
||||
tt_global_entry->common.flags |= flags;
|
||||
common->flags |= flags;
|
||||
|
||||
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
|
||||
* one originator left in the list and we previously received a
|
||||
@ -2411,8 +2411,8 @@ static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node,
|
||||
{
|
||||
struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp;
|
||||
struct batadv_orig_node_vlan *vlan;
|
||||
int i, orig_num_vlan;
|
||||
u32 crc;
|
||||
int i;
|
||||
|
||||
/* check if each received CRC matches the locally stored one */
|
||||
for (i = 0; i < num_vlan; i++) {
|
||||
@ -2438,6 +2438,18 @@ static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check if any excess VLANs exist locally for the originator
|
||||
* which are not mentioned in the TVLV from the originator.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
orig_num_vlan = 0;
|
||||
hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list)
|
||||
orig_num_vlan++;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (orig_num_vlan > num_vlan)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,8 @@ struct batadv_hard_iface_bat_iv {
|
||||
* @bat_iv: BATMAN IV specific per hard interface data
|
||||
* @cleanup_work: work queue callback item for hard interface deinit
|
||||
* @debug_dir: dentry for nc subdir in batman-adv directory in debugfs
|
||||
* @neigh_list: list of unique single hop neighbors via this interface
|
||||
* @neigh_list_lock: lock protecting neigh_list
|
||||
*/
|
||||
struct batadv_hard_iface {
|
||||
struct list_head list;
|
||||
@ -115,6 +117,9 @@ struct batadv_hard_iface {
|
||||
struct batadv_hard_iface_bat_iv bat_iv;
|
||||
struct work_struct cleanup_work;
|
||||
struct dentry *debug_dir;
|
||||
struct hlist_head neigh_list;
|
||||
/* neigh_list_lock protects: neigh_list */
|
||||
spinlock_t neigh_list_lock;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -340,6 +345,23 @@ struct batadv_gw_node {
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
/**
|
||||
* batadv_hardif_neigh_node - unique neighbor per hard interface
|
||||
* @list: list node for batadv_hard_iface::neigh_list
|
||||
* @addr: the MAC address of the neighboring interface
|
||||
* @if_incoming: pointer to incoming hard interface
|
||||
* @refcount: number of contexts the object is used
|
||||
* @rcu: struct used for freeing in a RCU-safe manner
|
||||
*/
|
||||
struct batadv_hardif_neigh_node {
|
||||
struct hlist_node list;
|
||||
u8 addr[ETH_ALEN];
|
||||
struct batadv_hard_iface *if_incoming;
|
||||
unsigned long last_seen;
|
||||
atomic_t refcount;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct batadv_neigh_node - structure for single hops neighbors
|
||||
* @list: list node for batadv_orig_node::neigh_list
|
||||
@ -884,6 +906,7 @@ struct batadv_socket_packet {
|
||||
* backbone gateway - no bcast traffic is formwared until the situation was
|
||||
* resolved
|
||||
* @crc: crc16 checksum over all claims
|
||||
* @crc_lock: lock protecting crc
|
||||
* @refcount: number of contexts the object is used
|
||||
* @rcu: struct used for freeing in an RCU-safe manner
|
||||
*/
|
||||
@ -897,6 +920,7 @@ struct batadv_bla_backbone_gw {
|
||||
atomic_t wait_periods;
|
||||
atomic_t request_sent;
|
||||
u16 crc;
|
||||
spinlock_t crc_lock; /* protects crc */
|
||||
atomic_t refcount;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
@ -1131,11 +1155,13 @@ struct batadv_forw_packet {
|
||||
* @bat_primary_iface_set: called when primary interface is selected / changed
|
||||
* @bat_ogm_schedule: prepare a new outgoing OGM for the send queue
|
||||
* @bat_ogm_emit: send scheduled OGM
|
||||
* @bat_hardif_neigh_init: called on creation of single hop entry
|
||||
* @bat_neigh_cmp: compare the metrics of two neighbors for their respective
|
||||
* outgoing interfaces
|
||||
* @bat_neigh_is_equiv_or_better: check if neigh1 is equally good or better
|
||||
* than neigh2 for their respective outgoing interface from the metric
|
||||
* @bat_neigh_is_similar_or_better: check if neigh1 is equally similar or
|
||||
* better than neigh2 for their respective outgoing interface from the metric
|
||||
* prospective
|
||||
* @bat_neigh_print: print the single hop neighbor list (optional)
|
||||
* @bat_neigh_free: free the resources allocated by the routing algorithm for a
|
||||
* neigh_node object
|
||||
* @bat_orig_print: print the originator table (optional)
|
||||
@ -1156,15 +1182,17 @@ struct batadv_algo_ops {
|
||||
void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface);
|
||||
void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
|
||||
/* neigh_node handling API */
|
||||
void (*bat_hardif_neigh_init)(struct batadv_hardif_neigh_node *neigh);
|
||||
int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1,
|
||||
struct batadv_hard_iface *if_outgoing1,
|
||||
struct batadv_neigh_node *neigh2,
|
||||
struct batadv_hard_iface *if_outgoing2);
|
||||
bool (*bat_neigh_is_equiv_or_better)
|
||||
bool (*bat_neigh_is_similar_or_better)
|
||||
(struct batadv_neigh_node *neigh1,
|
||||
struct batadv_hard_iface *if_outgoing1,
|
||||
struct batadv_neigh_node *neigh2,
|
||||
struct batadv_hard_iface *if_outgoing2);
|
||||
void (*bat_neigh_print)(struct batadv_priv *priv, struct seq_file *seq);
|
||||
void (*bat_neigh_free)(struct batadv_neigh_node *neigh);
|
||||
/* orig_node handling API */
|
||||
void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq,
|
||||
|
Loading…
Reference in New Issue
Block a user