aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/batman-adv/hard-interface.c3
-rw-r--r--net/batman-adv/main.c1
-rw-r--r--net/batman-adv/main.h1
-rw-r--r--net/batman-adv/netlink.c24
4 files changed, 19 insertions, 10 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 781c5b6e6e8e..508f4416dfc9 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -951,6 +951,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
951 batadv_check_known_mac_addr(hard_iface->net_dev); 951 batadv_check_known_mac_addr(hard_iface->net_dev);
952 kref_get(&hard_iface->refcount); 952 kref_get(&hard_iface->refcount);
953 list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); 953 list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
954 batadv_hardif_generation++;
954 955
955 return hard_iface; 956 return hard_iface;
956 957
@@ -993,6 +994,7 @@ void batadv_hardif_remove_interfaces(void)
993 list_for_each_entry_safe(hard_iface, hard_iface_tmp, 994 list_for_each_entry_safe(hard_iface, hard_iface_tmp,
994 &batadv_hardif_list, list) { 995 &batadv_hardif_list, list) {
995 list_del_rcu(&hard_iface->list); 996 list_del_rcu(&hard_iface->list);
997 batadv_hardif_generation++;
996 batadv_hardif_remove_interface(hard_iface); 998 batadv_hardif_remove_interface(hard_iface);
997 } 999 }
998 rtnl_unlock(); 1000 rtnl_unlock();
@@ -1054,6 +1056,7 @@ static int batadv_hard_if_event(struct notifier_block *this,
1054 case NETDEV_UNREGISTER: 1056 case NETDEV_UNREGISTER:
1055 case NETDEV_PRE_TYPE_CHANGE: 1057 case NETDEV_PRE_TYPE_CHANGE:
1056 list_del_rcu(&hard_iface->list); 1058 list_del_rcu(&hard_iface->list);
1059 batadv_hardif_generation++;
1057 1060
1058 batadv_hardif_remove_interface(hard_iface); 1061 batadv_hardif_remove_interface(hard_iface);
1059 break; 1062 break;
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index c75e47826949..d1ed839fd32b 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -74,6 +74,7 @@
74 * list traversals just rcu-locked 74 * list traversals just rcu-locked
75 */ 75 */
76struct list_head batadv_hardif_list; 76struct list_head batadv_hardif_list;
77unsigned int batadv_hardif_generation;
77static int (*batadv_rx_handler[256])(struct sk_buff *skb, 78static int (*batadv_rx_handler[256])(struct sk_buff *skb,
78 struct batadv_hard_iface *recv_if); 79 struct batadv_hard_iface *recv_if);
79 80
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index b68a41190eb0..b572066325e4 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -247,6 +247,7 @@ static inline int batadv_print_vid(unsigned short vid)
247} 247}
248 248
249extern struct list_head batadv_hardif_list; 249extern struct list_head batadv_hardif_list;
250extern unsigned int batadv_hardif_generation;
250 251
251extern unsigned char batadv_broadcast_addr[]; 252extern unsigned char batadv_broadcast_addr[];
252extern struct workqueue_struct *batadv_event_workqueue; 253extern struct workqueue_struct *batadv_event_workqueue;
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 0d9459b69bdb..2dc3304cee54 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -29,11 +29,11 @@
29#include <linux/if_ether.h> 29#include <linux/if_ether.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/list.h>
32#include <linux/netdevice.h> 33#include <linux/netdevice.h>
33#include <linux/netlink.h> 34#include <linux/netlink.h>
34#include <linux/printk.h> 35#include <linux/printk.h>
35#include <linux/rculist.h> 36#include <linux/rtnetlink.h>
36#include <linux/rcupdate.h>
37#include <linux/skbuff.h> 37#include <linux/skbuff.h>
38#include <linux/stddef.h> 38#include <linux/stddef.h>
39#include <linux/types.h> 39#include <linux/types.h>
@@ -445,23 +445,27 @@ out:
445 * batadv_netlink_dump_hardif_entry() - Dump one hard interface into a message 445 * batadv_netlink_dump_hardif_entry() - Dump one hard interface into a message
446 * @msg: Netlink message to dump into 446 * @msg: Netlink message to dump into
447 * @portid: Port making netlink request 447 * @portid: Port making netlink request
448 * @seq: Sequence number of netlink message 448 * @cb: Control block containing additional options
449 * @hard_iface: Hard interface to dump 449 * @hard_iface: Hard interface to dump
450 * 450 *
451 * Return: error code, or 0 on success 451 * Return: error code, or 0 on success
452 */ 452 */
453static int 453static int
454batadv_netlink_dump_hardif_entry(struct sk_buff *msg, u32 portid, u32 seq, 454batadv_netlink_dump_hardif_entry(struct sk_buff *msg, u32 portid,
455 struct netlink_callback *cb,
455 struct batadv_hard_iface *hard_iface) 456 struct batadv_hard_iface *hard_iface)
456{ 457{
457 struct net_device *net_dev = hard_iface->net_dev; 458 struct net_device *net_dev = hard_iface->net_dev;
458 void *hdr; 459 void *hdr;
459 460
460 hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, NLM_F_MULTI, 461 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
462 &batadv_netlink_family, NLM_F_MULTI,
461 BATADV_CMD_GET_HARDIFS); 463 BATADV_CMD_GET_HARDIFS);
462 if (!hdr) 464 if (!hdr)
463 return -EMSGSIZE; 465 return -EMSGSIZE;
464 466
467 genl_dump_check_consistent(cb, hdr);
468
465 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, 469 if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
466 net_dev->ifindex) || 470 net_dev->ifindex) ||
467 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME, 471 nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
@@ -498,7 +502,6 @@ batadv_netlink_dump_hardifs(struct sk_buff *msg, struct netlink_callback *cb)
498 struct batadv_hard_iface *hard_iface; 502 struct batadv_hard_iface *hard_iface;
499 int ifindex; 503 int ifindex;
500 int portid = NETLINK_CB(cb->skb).portid; 504 int portid = NETLINK_CB(cb->skb).portid;
501 int seq = cb->nlh->nlmsg_seq;
502 int skip = cb->args[0]; 505 int skip = cb->args[0];
503 int i = 0; 506 int i = 0;
504 507
@@ -516,23 +519,24 @@ batadv_netlink_dump_hardifs(struct sk_buff *msg, struct netlink_callback *cb)
516 return -ENODEV; 519 return -ENODEV;
517 } 520 }
518 521
519 rcu_read_lock(); 522 rtnl_lock();
523 cb->seq = batadv_hardif_generation << 1 | 1;
520 524
521 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 525 list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
522 if (hard_iface->soft_iface != soft_iface) 526 if (hard_iface->soft_iface != soft_iface)
523 continue; 527 continue;
524 528
525 if (i++ < skip) 529 if (i++ < skip)
526 continue; 530 continue;
527 531
528 if (batadv_netlink_dump_hardif_entry(msg, portid, seq, 532 if (batadv_netlink_dump_hardif_entry(msg, portid, cb,
529 hard_iface)) { 533 hard_iface)) {
530 i--; 534 i--;
531 break; 535 break;
532 } 536 }
533 } 537 }
534 538
535 rcu_read_unlock(); 539 rtnl_unlock();
536 540
537 dev_put(soft_iface); 541 dev_put(soft_iface);
538 542