2019-01-30 02:27:32

by Callum Sinclair

[permalink] [raw]
Subject: [PATCH] ipmr: ip6mr: Create new sockopt to clear mfc cache only

Created a way to clear the multicast forwarding cache on a socket
without having to either remove the entries manually using the delete
entry socket option or destroy and recreate the multicast socket.

Callum Sinclair (1):
ipmr: ip6mr: Create new sockopt to clear mfc cache only

include/uapi/linux/mroute.h | 3 ++-
include/uapi/linux/mroute6.h | 3 ++-
net/ipv4/ipmr.c | 41 +++++++++++++++++++++-----------
net/ipv6/ip6mr.c | 45 +++++++++++++++++++++++-------------
4 files changed, 60 insertions(+), 32 deletions(-)

--
2.20.1



2019-01-30 02:25:47

by Callum Sinclair

[permalink] [raw]
Subject: [PATCH] ipmr: ip6mr: Create new sockopt to clear mfc cache only

Currently the only way to clear the mfc cache was to delete the entries
one by one using the MRT_DEL_MFC socket option or to destroy and
recreate the socket.

Create a new socket option which will clear the multicast forwarding
cache on the socket without destroying the socket.

Signed-off-by: Callum Sinclair <[email protected]>
---
include/uapi/linux/mroute.h | 3 ++-
include/uapi/linux/mroute6.h | 3 ++-
net/ipv4/ipmr.c | 41 +++++++++++++++++++++-----------
net/ipv6/ip6mr.c | 45 +++++++++++++++++++++++-------------
4 files changed, 60 insertions(+), 32 deletions(-)

diff --git a/include/uapi/linux/mroute.h b/include/uapi/linux/mroute.h
index 5d37a9ccce63..8a0beb885cd9 100644
--- a/include/uapi/linux/mroute.h
+++ b/include/uapi/linux/mroute.h
@@ -28,7 +28,8 @@
#define MRT_TABLE (MRT_BASE+9) /* Specify mroute table ID */
#define MRT_ADD_MFC_PROXY (MRT_BASE+10) /* Add a (*,*|G) mfc entry */
#define MRT_DEL_MFC_PROXY (MRT_BASE+11) /* Del a (*,*|G) mfc entry */
-#define MRT_MAX (MRT_BASE+11)
+#define MRT_DEL_MFC_ALL (MRT_BASE+12) /* Del all multicast entries */
+#define MRT_MAX (MRT_BASE+12)

#define SIOCGETVIFCNT SIOCPROTOPRIVATE /* IP protocol privates */
#define SIOCGETSGCNT (SIOCPROTOPRIVATE+1)
diff --git a/include/uapi/linux/mroute6.h b/include/uapi/linux/mroute6.h
index 9999cc006390..7def70cdf571 100644
--- a/include/uapi/linux/mroute6.h
+++ b/include/uapi/linux/mroute6.h
@@ -31,7 +31,8 @@
#define MRT6_TABLE (MRT6_BASE+9) /* Specify mroute table ID */
#define MRT6_ADD_MFC_PROXY (MRT6_BASE+10) /* Add a (*,*|G) mfc entry */
#define MRT6_DEL_MFC_PROXY (MRT6_BASE+11) /* Del a (*,*|G) mfc entry */
-#define MRT6_MAX (MRT6_BASE+11)
+#define MRT6_DEL_MFC_ALL (MRT6_BASE+12) /* Del all multicast entries */
+#define MRT6_MAX (MRT6_BASE+12)

#define SIOCGETMIFCNT_IN6 SIOCPROTOPRIVATE /* IP protocol privates */
#define SIOCGETSGCNT_IN6 (SIOCPROTOPRIVATE+1)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index ddbf8c9a1abb..bbbce5ec8a0c 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1298,22 +1298,10 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
return 0;
}

-/* Close the multicast socket, and clear the vif tables etc */
-static void mroute_clean_tables(struct mr_table *mrt, bool all)
+/* Clear the vif tables */
+static void mroute_clean_cache(struct mr_table *mrt, bool all)
{
- struct net *net = read_pnet(&mrt->net);
struct mr_mfc *c, *tmp;
- struct mfc_cache *cache;
- LIST_HEAD(list);
- int i;
-
- /* Shut down all active vif entries */
- for (i = 0; i < mrt->maxvif; i++) {
- if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
- continue;
- vif_delete(mrt, i, 0, &list);
- }
- unregister_netdevice_many(&list);

/* Wipe the cache */
list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
@@ -1340,6 +1328,24 @@ static void mroute_clean_tables(struct mr_table *mrt, bool all)
}
}

+/* Close the multicast socket, and clear the vif tables etc */
+static void mroute_clean_tables(struct mr_table *mrt, bool all)
+{
+ struct net *net = read_pnet(&mrt->net);
+ LIST_HEAD(list);
+ int i;
+
+ /* Shut down all active vif entries */
+ for (i = 0; i < mrt->maxvif; i++) {
+ if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
+ continue;
+ vif_delete(mrt, i, 0, &list);
+ }
+ unregister_netdevice_many(&list);
+
+ mroute_clean_cache (mrt, all);
+}
+
/* called from ip_ra_control(), before an RCU grace period,
* we dont need to call synchronize_rcu() here
*/
@@ -1482,6 +1488,13 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval,
sk == rtnl_dereference(mrt->mroute_sk),
parent);
break;
+ case MRT_DEL_MFC_ALL:
+ rtnl_lock();
+ ipmr_for_each_table(mrt, net) {
+ mroute_clean_cache(mrt, true);
+ }
+ rtnl_unlock();
+ break;
/* Control PIM assert. */
case MRT_ASSERT:
if (optlen != sizeof(val)) {
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 30337b38274b..64631f85dcf4 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1492,25 +1492,11 @@ static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
return 0;
}

-/*
- * Close the multicast socket, and clear the vif tables etc
- */
-
-static void mroute_clean_tables(struct mr_table *mrt, bool all)
+/* Clear the vif tables */
+static void mroute_clean_cache(struct mr_table *mrt, bool all)
{
struct mr_mfc *c, *tmp;
- LIST_HEAD(list);
- int i;
-
- /* Shut down all active vif entries */
- for (i = 0; i < mrt->maxvif; i++) {
- if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
- continue;
- mif6_delete(mrt, i, 0, &list);
- }
- unregister_netdevice_many(&list);

- /* Wipe the cache */
list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
if (!all && (c->mfc_flags & MFC_STATIC))
continue;
@@ -1535,6 +1521,26 @@ static void mroute_clean_tables(struct mr_table *mrt, bool all)
spin_unlock_bh(&mfc_unres_lock);
}
}
+/*
+ * Close the multicast socket, and clear the vif tables etc
+ */
+
+static void mroute_clean_tables(struct mr_table *mrt, bool all)
+{
+ LIST_HEAD(list);
+ int i;
+
+ /* Shut down all active vif entries */
+ for (i = 0; i < mrt->maxvif; i++) {
+ if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
+ continue;
+ mif6_delete(mrt, i, 0, &list);
+ }
+ unregister_netdevice_many(&list);
+
+ /* Wipe the cache */
+ mroute_clean_cache(mrt, all);
+}

static int ip6mr_sk_init(struct mr_table *mrt, struct sock *sk)
{
@@ -1703,6 +1709,13 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
parent);
rtnl_unlock();
return ret;
+ case MRT6_DEL_MFC_ALL:
+ rtnl_lock();
+ ip6mr_for_each_table(mrt, net) {
+ mroute_clean_cache(mrt, true);
+ }
+ rtnl_unlock();
+ return 0;

/*
* Control PIM assert (to activate pim will activate assert)
--
2.20.1


2019-01-30 05:43:10

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] ipmr: ip6mr: Create new sockopt to clear mfc cache only

Hi Callum,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net/master]
[also build test ERROR on v5.0-rc4 next-20190129]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Callum-Sinclair/ipmr-ip6mr-Create-new-sockopt-to-clear-mfc-cache-only/20190130-104146
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 8.2.0-11) 8.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.2.0 make.cross ARCH=arm

All errors (new ones prefixed by >>):

net/ipv4/ipmr.c: In function 'mroute_clean_cache':
>> net/ipv4/ipmr.c:1312:3: error: 'cache' undeclared (first use in this function); did you mean 'cacheid'?
cache = (struct mfc_cache *)c;
^~~~~
cacheid
net/ipv4/ipmr.c:1312:3: note: each undeclared identifier is reported only once for each function it appears in
net/ipv4/ipmr.c:1313:33: error: 'net' undeclared (first use in this function)
call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache,
^~~
net/ipv4/ipmr.c: In function 'mroute_clean_tables':
net/ipv4/ipmr.c:1334:14: warning: unused variable 'net' [-Wunused-variable]
struct net *net = read_pnet(&mrt->net);
^~~

vim +1312 net/ipv4/ipmr.c

^1da177e4 Linus Torvalds 2005-04-16 1300
7ba7b80d1 Callum Sinclair 2019-01-30 1301 /* Clear the vif tables */
7ba7b80d1 Callum Sinclair 2019-01-30 1302 static void mroute_clean_cache(struct mr_table *mrt, bool all)
^1da177e4 Linus Torvalds 2005-04-16 1303 {
494fff563 Yuval Mintz 2018-02-28 1304 struct mr_mfc *c, *tmp;
^1da177e4 Linus Torvalds 2005-04-16 1305
a8cb16dd9 Eric Dumazet 2010-10-01 1306 /* Wipe the cache */
8fb472c09 Nikolay Aleksandrov 2017-01-12 1307 list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
0e615e960 Nikolay Aleksandrov 2015-11-20 1308 if (!all && (c->mfc_flags & MFC_STATIC))
^1da177e4 Linus Torvalds 2005-04-16 1309 continue;
8fb472c09 Nikolay Aleksandrov 2017-01-12 1310 rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params);
a8c9486b8 Eric Dumazet 2010-10-01 1311 list_del_rcu(&c->list);
494fff563 Yuval Mintz 2018-02-28 @1312 cache = (struct mfc_cache *)c;
494fff563 Yuval Mintz 2018-02-28 1313 call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache,
b362053a7 Yotam Gigi 2017-09-27 1314 mrt->id);
494fff563 Yuval Mintz 2018-02-28 1315 mroute_netlink_event(mrt, cache, RTM_DELROUTE);
8c13af2a2 Yuval Mintz 2018-03-26 1316 mr_cache_put(c);
^1da177e4 Linus Torvalds 2005-04-16 1317 }
^1da177e4 Linus Torvalds 2005-04-16 1318
0c12295a7 Patrick McHardy 2010-04-13 1319 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
^1da177e4 Linus Torvalds 2005-04-16 1320 spin_lock_bh(&mfc_unres_lock);
8fb472c09 Nikolay Aleksandrov 2017-01-12 1321 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
862465f2e Patrick McHardy 2010-04-13 1322 list_del(&c->list);
494fff563 Yuval Mintz 2018-02-28 1323 cache = (struct mfc_cache *)c;
494fff563 Yuval Mintz 2018-02-28 1324 mroute_netlink_event(mrt, cache, RTM_DELROUTE);
494fff563 Yuval Mintz 2018-02-28 1325 ipmr_destroy_unres(mrt, cache);
^1da177e4 Linus Torvalds 2005-04-16 1326 }
^1da177e4 Linus Torvalds 2005-04-16 1327 spin_unlock_bh(&mfc_unres_lock);
^1da177e4 Linus Torvalds 2005-04-16 1328 }
^1da177e4 Linus Torvalds 2005-04-16 1329 }
^1da177e4 Linus Torvalds 2005-04-16 1330

:::::: The code at line 1312 was first introduced by commit
:::::: 494fff56379c4ad5b8fe36a5b7ffede4044ca7bb ipmr, ip6mr: Make mfc_cache a common structure

:::::: TO: Yuval Mintz <[email protected]>
:::::: CC: David S. Miller <[email protected]>

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (4.30 kB)
.config.gz (66.81 kB)
Download all attachments

2019-01-30 07:14:39

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] ipmr: ip6mr: Create new sockopt to clear mfc cache only

Hi Callum,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net/master]
[also build test ERROR on v5.0-rc4 next-20190129]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Callum-Sinclair/ipmr-ip6mr-Create-new-sockopt-to-clear-mfc-cache-only/20190130-104146
config: i386-defconfig (attached as .config)
compiler: gcc-8 (Debian 8.2.0-14) 8.2.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386

All errors (new ones prefixed by >>):

net/ipv4/ipmr.c: In function 'mroute_clean_cache':
>> net/ipv4/ipmr.c:1312:3: error: 'cache' undeclared (first use in this function); did you mean 'hh_cache'?
cache = (struct mfc_cache *)c;
^~~~~
hh_cache
net/ipv4/ipmr.c:1312:3: note: each undeclared identifier is reported only once for each function it appears in
>> net/ipv4/ipmr.c:1313:33: error: 'net' undeclared (first use in this function)
call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache,
^~~
net/ipv4/ipmr.c: In function 'mroute_clean_tables':
net/ipv4/ipmr.c:1334:14: warning: unused variable 'net' [-Wunused-variable]
struct net *net = read_pnet(&mrt->net);
^~~

vim +1312 net/ipv4/ipmr.c

^1da177e4 Linus Torvalds 2005-04-16 1300
7ba7b80d1 Callum Sinclair 2019-01-30 1301 /* Clear the vif tables */
7ba7b80d1 Callum Sinclair 2019-01-30 1302 static void mroute_clean_cache(struct mr_table *mrt, bool all)
^1da177e4 Linus Torvalds 2005-04-16 1303 {
494fff563 Yuval Mintz 2018-02-28 1304 struct mr_mfc *c, *tmp;
^1da177e4 Linus Torvalds 2005-04-16 1305
a8cb16dd9 Eric Dumazet 2010-10-01 1306 /* Wipe the cache */
8fb472c09 Nikolay Aleksandrov 2017-01-12 1307 list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
0e615e960 Nikolay Aleksandrov 2015-11-20 1308 if (!all && (c->mfc_flags & MFC_STATIC))
^1da177e4 Linus Torvalds 2005-04-16 1309 continue;
8fb472c09 Nikolay Aleksandrov 2017-01-12 1310 rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params);
a8c9486b8 Eric Dumazet 2010-10-01 1311 list_del_rcu(&c->list);
494fff563 Yuval Mintz 2018-02-28 @1312 cache = (struct mfc_cache *)c;
494fff563 Yuval Mintz 2018-02-28 @1313 call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache,
b362053a7 Yotam Gigi 2017-09-27 1314 mrt->id);
494fff563 Yuval Mintz 2018-02-28 1315 mroute_netlink_event(mrt, cache, RTM_DELROUTE);
8c13af2a2 Yuval Mintz 2018-03-26 1316 mr_cache_put(c);
^1da177e4 Linus Torvalds 2005-04-16 1317 }
^1da177e4 Linus Torvalds 2005-04-16 1318
0c12295a7 Patrick McHardy 2010-04-13 1319 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
^1da177e4 Linus Torvalds 2005-04-16 1320 spin_lock_bh(&mfc_unres_lock);
8fb472c09 Nikolay Aleksandrov 2017-01-12 1321 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
862465f2e Patrick McHardy 2010-04-13 1322 list_del(&c->list);
494fff563 Yuval Mintz 2018-02-28 1323 cache = (struct mfc_cache *)c;
494fff563 Yuval Mintz 2018-02-28 1324 mroute_netlink_event(mrt, cache, RTM_DELROUTE);
494fff563 Yuval Mintz 2018-02-28 1325 ipmr_destroy_unres(mrt, cache);
^1da177e4 Linus Torvalds 2005-04-16 1326 }
^1da177e4 Linus Torvalds 2005-04-16 1327 spin_unlock_bh(&mfc_unres_lock);
^1da177e4 Linus Torvalds 2005-04-16 1328 }
^1da177e4 Linus Torvalds 2005-04-16 1329 }
^1da177e4 Linus Torvalds 2005-04-16 1330

:::::: The code at line 1312 was first introduced by commit
:::::: 494fff56379c4ad5b8fe36a5b7ffede4044ca7bb ipmr, ip6mr: Make mfc_cache a common structure

:::::: TO: Yuval Mintz <[email protected]>
:::::: CC: David S. Miller <[email protected]>

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (4.12 kB)
.config.gz (26.31 kB)
Download all attachments