mirror of https://gitee.com/openkylin/linux.git
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
|
What: /sys/class/net/<mesh_iface>/mesh/<vlan_subdir>/ap_isolation
|
||||||
Date: May 2011
|
Date: May 2011
|
||||||
Contact: Antonio Quartulli <antonio@meshcoding.com>
|
Contact: Antonio Quartulli <a@unstable.cc>
|
||||||
Description:
|
Description:
|
||||||
Indicates whether the data traffic going from a
|
Indicates whether the data traffic going from a
|
||||||
wireless client to another wireless client will be
|
wireless client to another wireless client will be
|
||||||
|
@ -70,7 +70,7 @@ Description:
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/isolation_mark
|
What: /sys/class/net/<mesh_iface>/mesh/isolation_mark
|
||||||
Date: Nov 2013
|
Date: Nov 2013
|
||||||
Contact: Antonio Quartulli <antonio@meshcoding.com>
|
Contact: Antonio Quartulli <a@unstable.cc>
|
||||||
Description:
|
Description:
|
||||||
Defines the isolation mark (and its bitmask) which
|
Defines the isolation mark (and its bitmask) which
|
||||||
is used to classify clients as "isolated" by the
|
is used to classify clients as "isolated" by the
|
||||||
|
|
|
@ -2111,7 +2111,7 @@ F: include/linux/backlight.h
|
||||||
BATMAN ADVANCED
|
BATMAN ADVANCED
|
||||||
M: Marek Lindner <mareklindner@neomailbox.ch>
|
M: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
M: Simon Wunderlich <sw@simonwunderlich.de>
|
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
|
L: b.a.t.m.a.n@lists.open-mesh.org
|
||||||
W: http://www.open-mesh.org/
|
W: http://www.open-mesh.org/
|
||||||
S: Maintained
|
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_hard_iface *if_outgoing)
|
||||||
{
|
{
|
||||||
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
|
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 = NULL;
|
||||||
struct batadv_neigh_node *router_router = NULL;
|
struct batadv_neigh_node *router_router = NULL;
|
||||||
struct batadv_orig_node *orig_neigh_node;
|
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;
|
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);
|
router = batadv_orig_router_get(orig_node, if_outgoing);
|
||||||
if (router) {
|
if (router) {
|
||||||
router_router = batadv_orig_router_get(router->orig_node,
|
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);
|
batadv_neigh_node_free_ref(router_router);
|
||||||
if (orig_neigh_router)
|
if (orig_neigh_router)
|
||||||
batadv_neigh_node_free_ref(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);
|
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");
|
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
|
* batadv_iv_ogm_neigh_cmp - compare the metrics of two neighbors
|
||||||
* @neigh1: the first neighbor object of the comparison
|
* @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
|
* batadv_iv_ogm_neigh_is_sob - check if neigh1 is similarly good or better
|
||||||
* neigh2 from the metric prospective
|
* than neigh2 from the metric prospective
|
||||||
* @neigh1: the first neighbor object of the comparison
|
* @neigh1: the first neighbor object of the comparison
|
||||||
* @if_outgoing1: outgoing interface for the first neighbor
|
* @if_outgoing1: outgoing interface for the first neighbor
|
||||||
* @neigh2: the second neighbor object of the comparison
|
* @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.
|
* the metric via neigh2, false otherwise.
|
||||||
*/
|
*/
|
||||||
static bool
|
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_hard_iface *if_outgoing1,
|
||||||
struct batadv_neigh_node *neigh2,
|
struct batadv_neigh_node *neigh2,
|
||||||
struct batadv_hard_iface *if_outgoing2)
|
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_schedule = batadv_iv_ogm_schedule,
|
||||||
.bat_ogm_emit = batadv_iv_ogm_emit,
|
.bat_ogm_emit = batadv_iv_ogm_emit,
|
||||||
.bat_neigh_cmp = batadv_iv_ogm_neigh_cmp,
|
.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_print = batadv_iv_ogm_orig_print,
|
||||||
.bat_orig_free = batadv_iv_ogm_orig_free,
|
.bat_orig_free = batadv_iv_ogm_orig_free,
|
||||||
.bat_orig_add_if = batadv_iv_ogm_orig_add_if,
|
.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 */
|
/* all claims gone, initialize CRC */
|
||||||
|
spin_lock_bh(&backbone_gw->crc_lock);
|
||||||
backbone_gw->crc = BATADV_BLA_CRC_INIT;
|
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->lasttime = jiffies;
|
||||||
entry->crc = BATADV_BLA_CRC_INIT;
|
entry->crc = BATADV_BLA_CRC_INIT;
|
||||||
entry->bat_priv = bat_priv;
|
entry->bat_priv = bat_priv;
|
||||||
|
spin_lock_init(&entry->crc_lock);
|
||||||
atomic_set(&entry->request_sent, 0);
|
atomic_set(&entry->request_sent, 0);
|
||||||
atomic_set(&entry->wait_periods, 0);
|
atomic_set(&entry->wait_periods, 0);
|
||||||
ether_addr_copy(entry->orig, orig);
|
ether_addr_copy(entry->orig, orig);
|
||||||
|
@ -557,7 +560,9 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
|
||||||
__be16 crc;
|
__be16 crc;
|
||||||
|
|
||||||
memcpy(mac, batadv_announce_mac, 4);
|
memcpy(mac, batadv_announce_mac, 4);
|
||||||
|
spin_lock_bh(&backbone_gw->crc_lock);
|
||||||
crc = htons(backbone_gw->crc);
|
crc = htons(backbone_gw->crc);
|
||||||
|
spin_unlock_bh(&backbone_gw->crc_lock);
|
||||||
memcpy(&mac[4], &crc, 2);
|
memcpy(&mac[4], &crc, 2);
|
||||||
|
|
||||||
batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
|
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",
|
"bla_add_claim(): changing ownership for %pM, vid %d\n",
|
||||||
mac, BATADV_PRINT_VID(vid));
|
mac, BATADV_PRINT_VID(vid));
|
||||||
|
|
||||||
|
spin_lock_bh(&claim->backbone_gw->crc_lock);
|
||||||
claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
|
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);
|
batadv_backbone_gw_free_ref(claim->backbone_gw);
|
||||||
}
|
}
|
||||||
/* set (new) backbone gw */
|
/* set (new) backbone gw */
|
||||||
atomic_inc(&backbone_gw->refcount);
|
atomic_inc(&backbone_gw->refcount);
|
||||||
claim->backbone_gw = backbone_gw;
|
claim->backbone_gw = backbone_gw;
|
||||||
|
|
||||||
|
spin_lock_bh(&backbone_gw->crc_lock);
|
||||||
backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
|
backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
|
||||||
|
spin_unlock_bh(&backbone_gw->crc_lock);
|
||||||
backbone_gw->lasttime = jiffies;
|
backbone_gw->lasttime = jiffies;
|
||||||
|
|
||||||
claim_free_ref:
|
claim_free_ref:
|
||||||
|
@ -653,7 +662,9 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
|
||||||
batadv_choose_claim, claim);
|
batadv_choose_claim, claim);
|
||||||
batadv_claim_free_ref(claim); /* reference from the hash is gone */
|
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);
|
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 */
|
/* don't need the reference from hash_find() anymore */
|
||||||
batadv_claim_free_ref(claim);
|
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)
|
u8 *backbone_addr, unsigned short vid)
|
||||||
{
|
{
|
||||||
struct batadv_bla_backbone_gw *backbone_gw;
|
struct batadv_bla_backbone_gw *backbone_gw;
|
||||||
u16 crc;
|
u16 backbone_crc, crc;
|
||||||
|
|
||||||
if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
|
if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
|
||||||
return 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",
|
"handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
|
||||||
BATADV_PRINT_VID(vid), backbone_gw->orig, crc);
|
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,
|
batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
|
||||||
"handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
|
"handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
|
||||||
backbone_gw->orig,
|
backbone_gw->orig,
|
||||||
BATADV_PRINT_VID(backbone_gw->vid),
|
BATADV_PRINT_VID(backbone_gw->vid),
|
||||||
backbone_gw->crc, crc);
|
backbone_crc, crc);
|
||||||
|
|
||||||
batadv_bla_send_request(backbone_gw);
|
batadv_bla_send_request(backbone_gw);
|
||||||
} else {
|
} 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_bla_claim *claim;
|
||||||
struct batadv_hard_iface *primary_if;
|
struct batadv_hard_iface *primary_if;
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
|
u16 backbone_crc;
|
||||||
u32 i;
|
u32 i;
|
||||||
bool is_own;
|
bool is_own;
|
||||||
u8 *primary_addr;
|
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) {
|
hlist_for_each_entry_rcu(claim, head, hash_entry) {
|
||||||
is_own = batadv_compare_eth(claim->backbone_gw->orig,
|
is_own = batadv_compare_eth(claim->backbone_gw->orig,
|
||||||
primary_addr);
|
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",
|
seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)\n",
|
||||||
claim->addr, BATADV_PRINT_VID(claim->vid),
|
claim->addr, BATADV_PRINT_VID(claim->vid),
|
||||||
claim->backbone_gw->orig,
|
claim->backbone_gw->orig,
|
||||||
(is_own ? 'x' : ' '),
|
(is_own ? 'x' : ' '),
|
||||||
claim->backbone_gw->crc);
|
backbone_crc);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
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 batadv_hard_iface *primary_if;
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
int secs, msecs;
|
int secs, msecs;
|
||||||
|
u16 backbone_crc;
|
||||||
u32 i;
|
u32 i;
|
||||||
bool is_own;
|
bool is_own;
|
||||||
u8 *primary_addr;
|
u8 *primary_addr;
|
||||||
|
@ -1722,10 +1743,14 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
if (is_own)
|
if (is_own)
|
||||||
continue;
|
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",
|
seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)\n",
|
||||||
backbone_gw->orig,
|
backbone_gw->orig,
|
||||||
BATADV_PRINT_VID(backbone_gw->vid), secs,
|
BATADV_PRINT_VID(backbone_gw->vid), secs,
|
||||||
msecs, backbone_gw->crc);
|
msecs, backbone_crc);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
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);
|
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)
|
static int batadv_originators_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
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 */
|
/* 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(originators, S_IRUGO, batadv_originators_open);
|
||||||
static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open);
|
static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open);
|
||||||
static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
|
static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
|
||||||
|
@ -394,6 +402,7 @@ static BATADV_DEBUGINFO(nc_nodes, S_IRUGO, batadv_nc_nodes_open);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
|
static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
|
||||||
|
&batadv_debuginfo_neighbors,
|
||||||
&batadv_debuginfo_originators,
|
&batadv_debuginfo_originators,
|
||||||
&batadv_debuginfo_gateways,
|
&batadv_debuginfo_gateways,
|
||||||
&batadv_debuginfo_transtable_global,
|
&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++) {
|
for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
|
||||||
chain = &orig_node->fragments[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)) {
|
if (!check_cb || check_cb(chain)) {
|
||||||
batadv_frag_clear_chain(&orig_node->fragments[i].head);
|
batadv_frag_clear_chain(&chain->head);
|
||||||
orig_node->fragments[i].size = 0;
|
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/rculist.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
|
|
||||||
|
@ -639,9 +640,12 @@ batadv_hardif_add_interface(struct net_device *net_dev)
|
||||||
goto free_sysfs;
|
goto free_sysfs;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&hard_iface->list);
|
INIT_LIST_HEAD(&hard_iface->list);
|
||||||
|
INIT_HLIST_HEAD(&hard_iface->neigh_list);
|
||||||
INIT_WORK(&hard_iface->cleanup_work,
|
INIT_WORK(&hard_iface->cleanup_work,
|
||||||
batadv_hardif_remove_interface_finish);
|
batadv_hardif_remove_interface_finish);
|
||||||
|
|
||||||
|
spin_lock_init(&hard_iface->neigh_list_lock);
|
||||||
|
|
||||||
hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
|
hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
|
||||||
if (batadv_is_wifi_netdev(net_dev))
|
if (batadv_is_wifi_netdev(net_dev))
|
||||||
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
|
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_schedule ||
|
||||||
!bat_algo_ops->bat_ogm_emit ||
|
!bat_algo_ops->bat_ogm_emit ||
|
||||||
!bat_algo_ops->bat_neigh_cmp ||
|
!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",
|
pr_info("Routing algo '%s' does not implement required ops\n",
|
||||||
bat_algo_ops->name);
|
bat_algo_ops->name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -908,7 +908,7 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
|
||||||
* appropriate handlers
|
* appropriate handlers
|
||||||
* @bat_priv: the bat priv with all the soft interface information
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
* @tvlv_handler: tvlv callback function handling the tvlv content
|
* @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
|
* @orig_node: orig node emitting the ogm packet
|
||||||
* @src: source mac address of the unicast packet
|
* @src: source mac address of the unicast packet
|
||||||
* @dst: destination 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
|
* batadv_tvlv_containers_process - parse the given tvlv buffer to call the
|
||||||
* appropriate handlers
|
* appropriate handlers
|
||||||
* @bat_priv: the bat priv with all the soft interface information
|
* @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
|
* @orig_node: orig node emitting the ogm packet
|
||||||
* @src: source mac address of the unicast packet
|
* @src: source mac address of the unicast packet
|
||||||
* @dst: destination 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);
|
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
|
* batadv_neigh_node_free_rcu - free the neigh_node
|
||||||
* @rcu: rcu pointer of 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 hlist_node *node_tmp;
|
||||||
struct batadv_neigh_node *neigh_node;
|
struct batadv_neigh_node *neigh_node;
|
||||||
|
struct batadv_hardif_neigh_node *hardif_neigh;
|
||||||
struct batadv_neigh_ifinfo *neigh_ifinfo;
|
struct batadv_neigh_ifinfo *neigh_ifinfo;
|
||||||
struct batadv_algo_ops *bao;
|
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);
|
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)
|
if (bao->bat_neigh_free)
|
||||||
bao->bat_neigh_free(neigh_node);
|
bao->bat_neigh_free(neigh_node);
|
||||||
|
|
||||||
|
@ -478,6 +528,106 @@ batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
|
||||||
return res;
|
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
|
* batadv_neigh_node_new - create and init a new neigh_node object
|
||||||
* @orig_node: originator object representing the neighbour
|
* @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)
|
const u8 *neigh_addr)
|
||||||
{
|
{
|
||||||
struct batadv_neigh_node *neigh_node;
|
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);
|
neigh_node = batadv_neigh_node_get(orig_node, hard_iface, neigh_addr);
|
||||||
if (neigh_node)
|
if (neigh_node)
|
||||||
goto out;
|
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);
|
neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC);
|
||||||
if (!neigh_node)
|
if (!neigh_node)
|
||||||
goto out;
|
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);
|
hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
|
||||||
spin_unlock_bh(&orig_node->neigh_list_lock);
|
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,
|
batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv,
|
||||||
"Creating new neighbor %pM for orig_node %pM on interface %s\n",
|
"Creating new neighbor %pM for orig_node %pM on interface %s\n",
|
||||||
neigh_addr, orig_node->orig, hard_iface->net_dev->name);
|
neigh_addr, orig_node->orig, hard_iface->net_dev->name);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (hardif_neigh)
|
||||||
|
batadv_hardif_neigh_free_ref(hardif_neigh);
|
||||||
return neigh_node;
|
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
|
* batadv_orig_ifinfo_free_rcu - free the orig_ifinfo object
|
||||||
* @rcu: rcu pointer of 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);
|
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,
|
struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
|
||||||
const u8 *addr);
|
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 *
|
struct batadv_neigh_node *
|
||||||
batadv_neigh_node_new(struct batadv_orig_node *orig_node,
|
batadv_neigh_node_new(struct batadv_orig_node *orig_node,
|
||||||
struct batadv_hard_iface *hard_iface,
|
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);
|
struct batadv_hard_iface *if_outgoing);
|
||||||
void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo);
|
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 *
|
struct batadv_orig_ifinfo *
|
||||||
batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
|
batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
|
||||||
struct batadv_hard_iface *if_outgoing);
|
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
|
/* alternative candidate should be good enough to be
|
||||||
* considered
|
* considered
|
||||||
*/
|
*/
|
||||||
if (!bao->bat_neigh_is_equiv_or_better(cand_router,
|
if (!bao->bat_neigh_is_similar_or_better(cand_router,
|
||||||
cand->if_outgoing,
|
cand->if_outgoing,
|
||||||
router, recv_if))
|
router, recv_if))
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
/* don't use the same router twice */
|
/* 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
|
* TT_CLIENT_WIFI, therefore they have to be copied in the
|
||||||
* client entry
|
* client entry
|
||||||
*/
|
*/
|
||||||
tt_global_entry->common.flags |= flags;
|
common->flags |= flags;
|
||||||
|
|
||||||
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
|
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
|
||||||
* one originator left in the list and we previously received a
|
* 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_tvlv_tt_vlan_data *tt_vlan_tmp;
|
||||||
struct batadv_orig_node_vlan *vlan;
|
struct batadv_orig_node_vlan *vlan;
|
||||||
|
int i, orig_num_vlan;
|
||||||
u32 crc;
|
u32 crc;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* check if each received CRC matches the locally stored one */
|
/* check if each received CRC matches the locally stored one */
|
||||||
for (i = 0; i < num_vlan; i++) {
|
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;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,8 @@ struct batadv_hard_iface_bat_iv {
|
||||||
* @bat_iv: BATMAN IV specific per hard interface data
|
* @bat_iv: BATMAN IV specific per hard interface data
|
||||||
* @cleanup_work: work queue callback item for hard interface deinit
|
* @cleanup_work: work queue callback item for hard interface deinit
|
||||||
* @debug_dir: dentry for nc subdir in batman-adv directory in debugfs
|
* @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 batadv_hard_iface {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
@ -115,6 +117,9 @@ struct batadv_hard_iface {
|
||||||
struct batadv_hard_iface_bat_iv bat_iv;
|
struct batadv_hard_iface_bat_iv bat_iv;
|
||||||
struct work_struct cleanup_work;
|
struct work_struct cleanup_work;
|
||||||
struct dentry *debug_dir;
|
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;
|
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
|
* struct batadv_neigh_node - structure for single hops neighbors
|
||||||
* @list: list node for batadv_orig_node::neigh_list
|
* @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
|
* backbone gateway - no bcast traffic is formwared until the situation was
|
||||||
* resolved
|
* resolved
|
||||||
* @crc: crc16 checksum over all claims
|
* @crc: crc16 checksum over all claims
|
||||||
|
* @crc_lock: lock protecting crc
|
||||||
* @refcount: number of contexts the object is used
|
* @refcount: number of contexts the object is used
|
||||||
* @rcu: struct used for freeing in an RCU-safe manner
|
* @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 wait_periods;
|
||||||
atomic_t request_sent;
|
atomic_t request_sent;
|
||||||
u16 crc;
|
u16 crc;
|
||||||
|
spinlock_t crc_lock; /* protects crc */
|
||||||
atomic_t refcount;
|
atomic_t refcount;
|
||||||
struct rcu_head rcu;
|
struct rcu_head rcu;
|
||||||
};
|
};
|
||||||
|
@ -1131,11 +1155,13 @@ struct batadv_forw_packet {
|
||||||
* @bat_primary_iface_set: called when primary interface is selected / changed
|
* @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_schedule: prepare a new outgoing OGM for the send queue
|
||||||
* @bat_ogm_emit: send scheduled OGM
|
* @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
|
* @bat_neigh_cmp: compare the metrics of two neighbors for their respective
|
||||||
* outgoing interfaces
|
* outgoing interfaces
|
||||||
* @bat_neigh_is_equiv_or_better: check if neigh1 is equally good or better
|
* @bat_neigh_is_similar_or_better: check if neigh1 is equally similar or
|
||||||
* than neigh2 for their respective outgoing interface from the metric
|
* better than neigh2 for their respective outgoing interface from the metric
|
||||||
* prospective
|
* prospective
|
||||||
|
* @bat_neigh_print: print the single hop neighbor list (optional)
|
||||||
* @bat_neigh_free: free the resources allocated by the routing algorithm for a
|
* @bat_neigh_free: free the resources allocated by the routing algorithm for a
|
||||||
* neigh_node object
|
* neigh_node object
|
||||||
* @bat_orig_print: print the originator table (optional)
|
* @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_schedule)(struct batadv_hard_iface *hard_iface);
|
||||||
void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
|
void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet);
|
||||||
/* neigh_node handling API */
|
/* neigh_node handling API */
|
||||||
|
void (*bat_hardif_neigh_init)(struct batadv_hardif_neigh_node *neigh);
|
||||||
int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1,
|
int (*bat_neigh_cmp)(struct batadv_neigh_node *neigh1,
|
||||||
struct batadv_hard_iface *if_outgoing1,
|
struct batadv_hard_iface *if_outgoing1,
|
||||||
struct batadv_neigh_node *neigh2,
|
struct batadv_neigh_node *neigh2,
|
||||||
struct batadv_hard_iface *if_outgoing2);
|
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_neigh_node *neigh1,
|
||||||
struct batadv_hard_iface *if_outgoing1,
|
struct batadv_hard_iface *if_outgoing1,
|
||||||
struct batadv_neigh_node *neigh2,
|
struct batadv_neigh_node *neigh2,
|
||||||
struct batadv_hard_iface *if_outgoing2);
|
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);
|
void (*bat_neigh_free)(struct batadv_neigh_node *neigh);
|
||||||
/* orig_node handling API */
|
/* orig_node handling API */
|
||||||
void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq,
|
void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq,
|
||||||
|
|
Loading…
Reference in New Issue