hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/batman-adv/bridge_loop_avoidance.c
....@@ -1,19 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-/* Copyright (C) 2011-2018 B.A.T.M.A.N. contributors:
2
+/* Copyright (C) 2011-2020 B.A.T.M.A.N. contributors:
33 *
44 * Simon Wunderlich
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of version 2 of the GNU General Public
8
- * License as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful, but
11
- * WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- * General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
175 */
186
197 #include "bridge_loop_avoidance.h"
....@@ -60,7 +48,6 @@
6048 #include "netlink.h"
6149 #include "originator.h"
6250 #include "soft-interface.h"
63
-#include "sysfs.h"
6451 #include "translation-table.h"
6552
6653 static const u8 batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05};
....@@ -177,6 +164,9 @@
177164 */
178165 static void batadv_backbone_gw_put(struct batadv_bla_backbone_gw *backbone_gw)
179166 {
167
+ if (!backbone_gw)
168
+ return;
169
+
180170 kref_put(&backbone_gw->refcount, batadv_backbone_gw_release);
181171 }
182172
....@@ -212,6 +202,9 @@
212202 */
213203 static void batadv_claim_put(struct batadv_bla_claim *claim)
214204 {
205
+ if (!claim)
206
+ return;
207
+
215208 kref_put(&claim->refcount, batadv_claim_release);
216209 }
217210
....@@ -862,7 +855,7 @@
862855
863856 /* handle as ANNOUNCE frame */
864857 backbone_gw->lasttime = jiffies;
865
- crc = ntohs(*((__be16 *)(&an_addr[4])));
858
+ crc = ntohs(*((__force __be16 *)(&an_addr[4])));
866859
867860 batadv_dbg(BATADV_DBG_BLA, bat_priv,
868861 "%s(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
....@@ -1010,7 +1003,7 @@
10101003 * @hw_dst: the Hardware destination in the ARP Header
10111004 * @ethhdr: pointer to the Ethernet header of the claim frame
10121005 *
1013
- * checks if it is a claim packet and if its on the same group.
1006
+ * checks if it is a claim packet and if it's on the same group.
10141007 * This function also applies the group ID of the sender
10151008 * if it is in the same mesh.
10161009 *
....@@ -1842,7 +1835,7 @@
18421835 * @vid: the VLAN ID of the frame
18431836 *
18441837 * Checks if this packet is a loop detect frame which has been sent by us,
1845
- * throw an uevent and log the event if that is the case.
1838
+ * throws an uevent and logs the event if that is the case.
18461839 *
18471840 * Return: true if it is a loop detect frame which is to be dropped, false
18481841 * otherwise.
....@@ -1880,7 +1873,7 @@
18801873
18811874 ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
18821875
1883
- /* backbone_gw is unreferenced in the report work function function
1876
+ /* backbone_gw is unreferenced in the report work function
18841877 * if queue_work() call was successful
18851878 */
18861879 if (!ret)
....@@ -1900,7 +1893,7 @@
19001893 * * we have to race for a claim
19011894 * * if the frame is allowed on the LAN
19021895 *
1903
- * in these cases, the skb is further handled by this function
1896
+ * In these cases, the skb is further handled by this function
19041897 *
19051898 * Return: true if handled, otherwise it returns false and the caller shall
19061899 * further process the skb.
....@@ -2200,14 +2193,15 @@
22002193 * to a netlink socket
22012194 * @msg: buffer for the message
22022195 * @portid: netlink port
2203
- * @seq: Sequence number of netlink message
2196
+ * @cb: Control block containing additional options
22042197 * @primary_if: primary interface
22052198 * @claim: entry to dump
22062199 *
22072200 * Return: 0 or error code.
22082201 */
22092202 static int
2210
-batadv_bla_claim_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
2203
+batadv_bla_claim_dump_entry(struct sk_buff *msg, u32 portid,
2204
+ struct netlink_callback *cb,
22112205 struct batadv_hard_iface *primary_if,
22122206 struct batadv_bla_claim *claim)
22132207 {
....@@ -2217,12 +2211,15 @@
22172211 void *hdr;
22182212 int ret = -EINVAL;
22192213
2220
- hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
2221
- NLM_F_MULTI, BATADV_CMD_GET_BLA_CLAIM);
2214
+ hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2215
+ &batadv_netlink_family, NLM_F_MULTI,
2216
+ BATADV_CMD_GET_BLA_CLAIM);
22222217 if (!hdr) {
22232218 ret = -ENOBUFS;
22242219 goto out;
22252220 }
2221
+
2222
+ genl_dump_check_consistent(cb, hdr);
22262223
22272224 is_own = batadv_compare_eth(claim->backbone_gw->orig,
22282225 primary_addr);
....@@ -2259,28 +2256,33 @@
22592256 * to a netlink socket
22602257 * @msg: buffer for the message
22612258 * @portid: netlink port
2262
- * @seq: Sequence number of netlink message
2259
+ * @cb: Control block containing additional options
22632260 * @primary_if: primary interface
2264
- * @head: bucket to dump
2261
+ * @hash: hash to dump
2262
+ * @bucket: bucket index to dump
22652263 * @idx_skip: How many entries to skip
22662264 *
22672265 * Return: always 0.
22682266 */
22692267 static int
2270
-batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
2268
+batadv_bla_claim_dump_bucket(struct sk_buff *msg, u32 portid,
2269
+ struct netlink_callback *cb,
22712270 struct batadv_hard_iface *primary_if,
2272
- struct hlist_head *head, int *idx_skip)
2271
+ struct batadv_hashtable *hash, unsigned int bucket,
2272
+ int *idx_skip)
22732273 {
22742274 struct batadv_bla_claim *claim;
22752275 int idx = 0;
22762276 int ret = 0;
22772277
2278
- rcu_read_lock();
2279
- hlist_for_each_entry_rcu(claim, head, hash_entry) {
2278
+ spin_lock_bh(&hash->list_locks[bucket]);
2279
+ cb->seq = atomic_read(&hash->generation) << 1 | 1;
2280
+
2281
+ hlist_for_each_entry(claim, &hash->table[bucket], hash_entry) {
22802282 if (idx++ < *idx_skip)
22812283 continue;
22822284
2283
- ret = batadv_bla_claim_dump_entry(msg, portid, seq,
2285
+ ret = batadv_bla_claim_dump_entry(msg, portid, cb,
22842286 primary_if, claim);
22852287 if (ret) {
22862288 *idx_skip = idx - 1;
....@@ -2290,7 +2292,7 @@
22902292
22912293 *idx_skip = 0;
22922294 unlock:
2293
- rcu_read_unlock();
2295
+ spin_unlock_bh(&hash->list_locks[bucket]);
22942296 return ret;
22952297 }
22962298
....@@ -2310,7 +2312,6 @@
23102312 struct batadv_hashtable *hash;
23112313 struct batadv_priv *bat_priv;
23122314 int bucket = cb->args[0];
2313
- struct hlist_head *head;
23142315 int idx = cb->args[1];
23152316 int ifindex;
23162317 int ret = 0;
....@@ -2336,11 +2337,8 @@
23362337 }
23372338
23382339 while (bucket < hash->size) {
2339
- head = &hash->table[bucket];
2340
-
2341
- if (batadv_bla_claim_dump_bucket(msg, portid,
2342
- cb->nlh->nlmsg_seq,
2343
- primary_if, head, &idx))
2340
+ if (batadv_bla_claim_dump_bucket(msg, portid, cb, primary_if,
2341
+ hash, bucket, &idx))
23442342 break;
23452343 bucket++;
23462344 }
....@@ -2431,14 +2429,15 @@
24312429 * netlink socket
24322430 * @msg: buffer for the message
24332431 * @portid: netlink port
2434
- * @seq: Sequence number of netlink message
2432
+ * @cb: Control block containing additional options
24352433 * @primary_if: primary interface
24362434 * @backbone_gw: entry to dump
24372435 *
24382436 * Return: 0 or error code.
24392437 */
24402438 static int
2441
-batadv_bla_backbone_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
2439
+batadv_bla_backbone_dump_entry(struct sk_buff *msg, u32 portid,
2440
+ struct netlink_callback *cb,
24422441 struct batadv_hard_iface *primary_if,
24432442 struct batadv_bla_backbone_gw *backbone_gw)
24442443 {
....@@ -2449,12 +2448,15 @@
24492448 void *hdr;
24502449 int ret = -EINVAL;
24512450
2452
- hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family,
2453
- NLM_F_MULTI, BATADV_CMD_GET_BLA_BACKBONE);
2451
+ hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
2452
+ &batadv_netlink_family, NLM_F_MULTI,
2453
+ BATADV_CMD_GET_BLA_BACKBONE);
24542454 if (!hdr) {
24552455 ret = -ENOBUFS;
24562456 goto out;
24572457 }
2458
+
2459
+ genl_dump_check_consistent(cb, hdr);
24582460
24592461 is_own = batadv_compare_eth(backbone_gw->orig, primary_addr);
24602462
....@@ -2492,28 +2494,33 @@
24922494 * a netlink socket
24932495 * @msg: buffer for the message
24942496 * @portid: netlink port
2495
- * @seq: Sequence number of netlink message
2497
+ * @cb: Control block containing additional options
24962498 * @primary_if: primary interface
2497
- * @head: bucket to dump
2499
+ * @hash: hash to dump
2500
+ * @bucket: bucket index to dump
24982501 * @idx_skip: How many entries to skip
24992502 *
25002503 * Return: always 0.
25012504 */
25022505 static int
2503
-batadv_bla_backbone_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
2506
+batadv_bla_backbone_dump_bucket(struct sk_buff *msg, u32 portid,
2507
+ struct netlink_callback *cb,
25042508 struct batadv_hard_iface *primary_if,
2505
- struct hlist_head *head, int *idx_skip)
2509
+ struct batadv_hashtable *hash,
2510
+ unsigned int bucket, int *idx_skip)
25062511 {
25072512 struct batadv_bla_backbone_gw *backbone_gw;
25082513 int idx = 0;
25092514 int ret = 0;
25102515
2511
- rcu_read_lock();
2512
- hlist_for_each_entry_rcu(backbone_gw, head, hash_entry) {
2516
+ spin_lock_bh(&hash->list_locks[bucket]);
2517
+ cb->seq = atomic_read(&hash->generation) << 1 | 1;
2518
+
2519
+ hlist_for_each_entry(backbone_gw, &hash->table[bucket], hash_entry) {
25132520 if (idx++ < *idx_skip)
25142521 continue;
25152522
2516
- ret = batadv_bla_backbone_dump_entry(msg, portid, seq,
2523
+ ret = batadv_bla_backbone_dump_entry(msg, portid, cb,
25172524 primary_if, backbone_gw);
25182525 if (ret) {
25192526 *idx_skip = idx - 1;
....@@ -2523,7 +2530,7 @@
25232530
25242531 *idx_skip = 0;
25252532 unlock:
2526
- rcu_read_unlock();
2533
+ spin_unlock_bh(&hash->list_locks[bucket]);
25272534 return ret;
25282535 }
25292536
....@@ -2543,7 +2550,6 @@
25432550 struct batadv_hashtable *hash;
25442551 struct batadv_priv *bat_priv;
25452552 int bucket = cb->args[0];
2546
- struct hlist_head *head;
25472553 int idx = cb->args[1];
25482554 int ifindex;
25492555 int ret = 0;
....@@ -2569,11 +2575,8 @@
25692575 }
25702576
25712577 while (bucket < hash->size) {
2572
- head = &hash->table[bucket];
2573
-
2574
- if (batadv_bla_backbone_dump_bucket(msg, portid,
2575
- cb->nlh->nlmsg_seq,
2576
- primary_if, head, &idx))
2578
+ if (batadv_bla_backbone_dump_bucket(msg, portid, cb, primary_if,
2579
+ hash, bucket, &idx))
25772580 break;
25782581 bucket++;
25792582 }