Skip to content

Commit 04f3f5b

Browse files
lunnsimonwunderlich
authored andcommitted
batman-adv: add B.A.T.M.A.N. Dump BLA claims via netlink
Dump the list of bridge loop avoidance claims via the netlink socket. Signed-off-by: Andrew Lunn <[email protected]> [[email protected]: add policy for attributes, fix includes, fix soft_iface reference leak] Signed-off-by: Sven Eckelmann <[email protected]> [[email protected]: fix kerneldoc, fix error reporting] Signed-off-by: Simon Wunderlich <[email protected]> Signed-off-by: Marek Lindner <[email protected]>
1 parent b71bb6f commit 04f3f5b

File tree

4 files changed

+202
-1
lines changed

4 files changed

+202
-1
lines changed

include/uapi/linux/batman_adv.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ enum batadv_tt_client_flags {
9191
* @BATADV_ATTR_BANDWIDTH_UP: Reported uplink bandwidth
9292
* @BATADV_ATTR_BANDWIDTH_DOWN: Reported downlink bandwidth
9393
* @BATADV_ATTR_ROUTER: Gateway router MAC address
94+
* @BATADV_ATTR_BLA_OWN: Flag indicating own originator
95+
* @BATADV_ATTR_BLA_ADDRESS: Bridge loop avoidance claim MAC address
96+
* @BATADV_ATTR_BLA_VID: BLA VLAN ID
97+
* @BATADV_ATTR_BLA_BACKBONE: BLA gateway originator MAC address
98+
* @BATADV_ATTR_BLA_CRC: BLA CRC
9499
* @__BATADV_ATTR_AFTER_LAST: internal use
95100
* @NUM_BATADV_ATTR: total number of batadv_nl_attrs available
96101
* @BATADV_ATTR_MAX: highest attribute number currently defined
@@ -126,6 +131,11 @@ enum batadv_nl_attrs {
126131
BATADV_ATTR_BANDWIDTH_UP,
127132
BATADV_ATTR_BANDWIDTH_DOWN,
128133
BATADV_ATTR_ROUTER,
134+
BATADV_ATTR_BLA_OWN,
135+
BATADV_ATTR_BLA_ADDRESS,
136+
BATADV_ATTR_BLA_VID,
137+
BATADV_ATTR_BLA_BACKBONE,
138+
BATADV_ATTR_BLA_CRC,
129139
/* add attributes above here, update the policy in netlink.c */
130140
__BATADV_ATTR_AFTER_LAST,
131141
NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST,
@@ -146,6 +156,7 @@ enum batadv_nl_attrs {
146156
* @BATADV_CMD_GET_ORIGINATORS: Query list of originators
147157
* @BATADV_CMD_GET_NEIGHBORS: Query list of neighbours
148158
* @BATADV_CMD_GET_GATEWAYS: Query list of gateways
159+
* @BATADV_CMD_GET_BLA_CLAIM: Query list of bridge loop avoidance claims
149160
* @__BATADV_CMD_AFTER_LAST: internal use
150161
* @BATADV_CMD_MAX: highest used command number
151162
*/
@@ -161,6 +172,7 @@ enum batadv_nl_commands {
161172
BATADV_CMD_GET_ORIGINATORS,
162173
BATADV_CMD_GET_NEIGHBORS,
163174
BATADV_CMD_GET_GATEWAYS,
175+
BATADV_CMD_GET_BLA_CLAIM,
164176
/* add new commands above here */
165177
__BATADV_CMD_AFTER_LAST,
166178
BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1

net/batman-adv/bridge_loop_avoidance.c

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <linux/list.h>
3636
#include <linux/lockdep.h>
3737
#include <linux/netdevice.h>
38+
#include <linux/netlink.h>
3839
#include <linux/rculist.h>
3940
#include <linux/rcupdate.h>
4041
#include <linux/seq_file.h>
@@ -45,12 +46,18 @@
4546
#include <linux/string.h>
4647
#include <linux/workqueue.h>
4748
#include <net/arp.h>
49+
#include <net/genetlink.h>
50+
#include <net/netlink.h>
51+
#include <net/sock.h>
52+
#include <uapi/linux/batman_adv.h>
4853

4954
#include "hard-interface.h"
5055
#include "hash.h"
5156
#include "log.h"
57+
#include "netlink.h"
5258
#include "originator.h"
5359
#include "packet.h"
60+
#include "soft-interface.h"
5461
#include "sysfs.h"
5562
#include "translation-table.h"
5663

@@ -2051,6 +2058,168 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
20512058
return 0;
20522059
}
20532060

2061+
/**
2062+
* batadv_bla_claim_dump_entry - dump one entry of the claim table
2063+
* to a netlink socket
2064+
* @msg: buffer for the message
2065+
* @portid: netlink port
2066+
* @seq: Sequence number of netlink message
2067+
* @primary_if: primary interface
2068+
* @claim: entry to dump
2069+
*
2070+
* Return: 0 or error code.
2071+
*/
2072+
static int
2073+
batadv_bla_claim_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
2074+
struct batadv_hard_iface *primary_if,
2075+
struct batadv_bla_claim *claim)
2076+
{
2077+
u8 *primary_addr = primary_if->net_dev->dev_addr;
2078+
u16 backbone_crc;
2079+
bool is_own;
2080+
void *hdr;
2081+
int ret = -EINVAL;
2082+
2083+
hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
2084+
NLM_F_MULTI, BATADV_CMD_GET_BLA_CLAIM);
2085+
if (!hdr) {
2086+
ret = -ENOBUFS;
2087+
goto out;
2088+
}
2089+
2090+
is_own = batadv_compare_eth(claim->backbone_gw->orig,
2091+
primary_addr);
2092+
2093+
spin_lock_bh(&claim->backbone_gw->crc_lock);
2094+
backbone_crc = claim->backbone_gw->crc;
2095+
spin_unlock_bh(&claim->backbone_gw->crc_lock);
2096+
2097+
if (is_own)
2098+
if (nla_put_flag(msg, BATADV_ATTR_BLA_OWN)) {
2099+
genlmsg_cancel(msg, hdr);
2100+
goto out;
2101+
}
2102+
2103+
if (nla_put(msg, BATADV_ATTR_BLA_ADDRESS, ETH_ALEN, claim->addr) ||
2104+
nla_put_u16(msg, BATADV_ATTR_BLA_VID, claim->vid) ||
2105+
nla_put(msg, BATADV_ATTR_BLA_BACKBONE, ETH_ALEN,
2106+
claim->backbone_gw->orig) ||
2107+
nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
2108+
backbone_crc)) {
2109+
genlmsg_cancel(msg, hdr);
2110+
goto out;
2111+
}
2112+
2113+
genlmsg_end(msg, hdr);
2114+
ret = 0;
2115+
2116+
out:
2117+
return ret;
2118+
}
2119+
2120+
/**
2121+
* batadv_bla_claim_dump_bucket - dump one bucket of the claim table
2122+
* to a netlink socket
2123+
* @msg: buffer for the message
2124+
* @portid: netlink port
2125+
* @seq: Sequence number of netlink message
2126+
* @primary_if: primary interface
2127+
* @head: bucket to dump
2128+
* @idx_skip: How many entries to skip
2129+
*
2130+
* Return: always 0.
2131+
*/
2132+
static int
2133+
batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
2134+
struct batadv_hard_iface *primary_if,
2135+
struct hlist_head *head, int *idx_skip)
2136+
{
2137+
struct batadv_bla_claim *claim;
2138+
int idx = 0;
2139+
2140+
rcu_read_lock();
2141+
hlist_for_each_entry_rcu(claim, head, hash_entry) {
2142+
if (idx++ < *idx_skip)
2143+
continue;
2144+
if (batadv_bla_claim_dump_entry(msg, portid, seq,
2145+
primary_if, claim)) {
2146+
*idx_skip = idx - 1;
2147+
goto unlock;
2148+
}
2149+
}
2150+
2151+
*idx_skip = idx;
2152+
unlock:
2153+
rcu_read_unlock();
2154+
return 0;
2155+
}
2156+
2157+
/**
2158+
* batadv_bla_claim_dump - dump claim table to a netlink socket
2159+
* @msg: buffer for the message
2160+
* @cb: callback structure containing arguments
2161+
*
2162+
* Return: message length.
2163+
*/
2164+
int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb)
2165+
{
2166+
struct batadv_hard_iface *primary_if = NULL;
2167+
int portid = NETLINK_CB(cb->skb).portid;
2168+
struct net *net = sock_net(cb->skb->sk);
2169+
struct net_device *soft_iface;
2170+
struct batadv_hashtable *hash;
2171+
struct batadv_priv *bat_priv;
2172+
int bucket = cb->args[0];
2173+
struct hlist_head *head;
2174+
int idx = cb->args[1];
2175+
int ifindex;
2176+
int ret = 0;
2177+
2178+
ifindex = batadv_netlink_get_ifindex(cb->nlh,
2179+
BATADV_ATTR_MESH_IFINDEX);
2180+
if (!ifindex)
2181+
return -EINVAL;
2182+
2183+
soft_iface = dev_get_by_index(net, ifindex);
2184+
if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
2185+
ret = -ENODEV;
2186+
goto out;
2187+
}
2188+
2189+
bat_priv = netdev_priv(soft_iface);
2190+
hash = bat_priv->bla.claim_hash;
2191+
2192+
primary_if = batadv_primary_if_get_selected(bat_priv);
2193+
if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
2194+
ret = -ENOENT;
2195+
goto out;
2196+
}
2197+
2198+
while (bucket < hash->size) {
2199+
head = &hash->table[bucket];
2200+
2201+
if (batadv_bla_claim_dump_bucket(msg, portid,
2202+
cb->nlh->nlmsg_seq,
2203+
primary_if, head, &idx))
2204+
break;
2205+
bucket++;
2206+
}
2207+
2208+
cb->args[0] = bucket;
2209+
cb->args[1] = idx;
2210+
2211+
ret = msg->len;
2212+
2213+
out:
2214+
if (primary_if)
2215+
batadv_hardif_put(primary_if);
2216+
2217+
if (soft_iface)
2218+
dev_put(soft_iface);
2219+
2220+
return ret;
2221+
}
2222+
20542223
/**
20552224
* batadv_bla_backbone_table_seq_print_text - print the backbone table in a seq
20562225
* file

net/batman-adv/bridge_loop_avoidance.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/types.h>
2424

2525
struct net_device;
26+
struct netlink_callback;
2627
struct seq_file;
2728
struct sk_buff;
2829

@@ -35,6 +36,7 @@ bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
3536
struct batadv_orig_node *orig_node,
3637
int hdr_size);
3738
int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
39+
int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb);
3840
int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
3941
void *offset);
4042
bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig,
@@ -47,7 +49,7 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
4749
void batadv_bla_status_update(struct net_device *net_dev);
4850
int batadv_bla_init(struct batadv_priv *bat_priv);
4951
void batadv_bla_free(struct batadv_priv *bat_priv);
50-
52+
int batadv_bla_claim_dump(struct sk_buff *msg, struct netlink_callback *cb);
5153
#define BATADV_BLA_CRC_INIT 0
5254
#else /* ifdef CONFIG_BATMAN_ADV_BLA */
5355

@@ -112,6 +114,12 @@ static inline void batadv_bla_free(struct batadv_priv *bat_priv)
112114
{
113115
}
114116

117+
static inline int batadv_bla_claim_dump(struct sk_buff *msg,
118+
struct netlink_callback *cb)
119+
{
120+
return -EOPNOTSUPP;
121+
}
122+
115123
#endif /* ifdef CONFIG_BATMAN_ADV_BLA */
116124

117125
#endif /* ifndef _NET_BATMAN_ADV_BLA_H_ */

net/batman-adv/netlink.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <uapi/linux/batman_adv.h>
3939

4040
#include "bat_algo.h"
41+
#include "bridge_loop_avoidance.h"
4142
#include "gateway_client.h"
4243
#include "hard-interface.h"
4344
#include "originator.h"
@@ -91,6 +92,11 @@ static struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
9192
[BATADV_ATTR_BANDWIDTH_UP] = { .type = NLA_U32 },
9293
[BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NLA_U32 },
9394
[BATADV_ATTR_ROUTER] = { .len = ETH_ALEN },
95+
[BATADV_ATTR_BLA_OWN] = { .type = NLA_FLAG },
96+
[BATADV_ATTR_BLA_ADDRESS] = { .len = ETH_ALEN },
97+
[BATADV_ATTR_BLA_VID] = { .type = NLA_U16 },
98+
[BATADV_ATTR_BLA_BACKBONE] = { .len = ETH_ALEN },
99+
[BATADV_ATTR_BLA_CRC] = { .type = NLA_U16 },
94100
};
95101

96102
/**
@@ -580,6 +586,12 @@ static struct genl_ops batadv_netlink_ops[] = {
580586
.policy = batadv_netlink_policy,
581587
.dumpit = batadv_gw_dump,
582588
},
589+
{
590+
.cmd = BATADV_CMD_GET_BLA_CLAIM,
591+
.flags = GENL_ADMIN_PERM,
592+
.policy = batadv_netlink_policy,
593+
.dumpit = batadv_bla_claim_dump,
594+
},
583595
};
584596

585597
/**

0 commit comments

Comments
 (0)