hc
2024-05-10 748e4f3d702def1a4bff191e0cf93b6a05340f01
kernel/net/ipv6/ip6mr.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Linux IPv6 multicast routing support for BSD pim6sd
34 * Based on net/ipv4/ipmr.c.
....@@ -8,12 +9,6 @@
89 * 6WIND, Paris, France
910 * Copyright (C)2007,2008 USAGI/WIDE Project
1011 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
11
- *
12
- * This program is free software; you can redistribute it and/or
13
- * modify it under the terms of the GNU General Public License
14
- * as published by the Free Software Foundation; either version
15
- * 2 of the License, or (at your option) any later version.
16
- *
1712 */
1813
1914 #include <linux/uaccess.h>
....@@ -88,7 +83,8 @@
8883 static void ip6mr_free_table(struct mr_table *mrt);
8984
9085 static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
91
- struct sk_buff *skb, struct mfc6_cache *cache);
86
+ struct net_device *dev, struct sk_buff *skb,
87
+ struct mfc6_cache *cache);
9288 static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
9389 mifi_t mifi, int assert);
9490 static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
....@@ -96,12 +92,14 @@
9692 static void mrt6msg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt);
9793 static int ip6mr_rtm_dumproute(struct sk_buff *skb,
9894 struct netlink_callback *cb);
99
-static void mroute_clean_tables(struct mr_table *mrt, bool all);
95
+static void mroute_clean_tables(struct mr_table *mrt, int flags);
10096 static void ipmr_expire_process(struct timer_list *t);
10197
10298 #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
10399 #define ip6mr_for_each_table(mrt, net) \
104
- list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list)
100
+ list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list, \
101
+ lockdep_rtnl_is_held() || \
102
+ list_empty(&net->ipv6.mr6_tables))
105103
106104 static struct mr_table *ip6mr_mr_table_iter(struct net *net,
107105 struct mr_table *mrt)
....@@ -141,6 +139,9 @@
141139 .flags = FIB_LOOKUP_NOREF,
142140 };
143141
142
+ /* update flow if oif or iif point to device enslaved to l3mdev */
143
+ l3mdev_update_flow(net, flowi6_to_flowi(flp6));
144
+
144145 err = fib_rules_lookup(net->ipv6.mr6_rules_ops,
145146 flowi6_to_flowi(flp6), 0, &arg);
146147 if (err < 0)
....@@ -167,7 +168,9 @@
167168 return -EINVAL;
168169 }
169170
170
- mrt = ip6mr_get_table(rule->fr_net, rule->table);
171
+ arg->table = fib_rule_get_table(rule, arg);
172
+
173
+ mrt = ip6mr_get_table(rule->fr_net, arg->table);
171174 if (!mrt)
172175 return -EAGAIN;
173176 res->mrt = mrt;
....@@ -266,9 +269,10 @@
266269 rtnl_unlock();
267270 }
268271
269
-static int ip6mr_rules_dump(struct net *net, struct notifier_block *nb)
272
+static int ip6mr_rules_dump(struct net *net, struct notifier_block *nb,
273
+ struct netlink_ext_ack *extack)
270274 {
271
- return fib_rules_dump(net, nb, RTNL_FAMILY_IP6MR);
275
+ return fib_rules_dump(net, nb, RTNL_FAMILY_IP6MR, extack);
272276 }
273277
274278 static unsigned int ip6mr_rules_seq_read(struct net *net)
....@@ -325,7 +329,8 @@
325329 rtnl_unlock();
326330 }
327331
328
-static int ip6mr_rules_dump(struct net *net, struct notifier_block *nb)
332
+static int ip6mr_rules_dump(struct net *net, struct notifier_block *nb,
333
+ struct netlink_ext_ack *extack)
329334 {
330335 return 0;
331336 }
....@@ -351,7 +356,6 @@
351356 .key_offset = offsetof(struct mfc6_cache, cmparg),
352357 .key_len = sizeof(struct mfc6_cache_cmp_arg),
353358 .nelem_hint = 3,
354
- .locks_mul = 1,
355359 .obj_cmpfn = ip6mr_hash_cmp,
356360 .automatic_shrinking = true,
357361 };
....@@ -389,7 +393,8 @@
389393 static void ip6mr_free_table(struct mr_table *mrt)
390394 {
391395 del_timer_sync(&mrt->ipmr_expire_timer);
392
- mroute_clean_tables(mrt, true);
396
+ mroute_clean_tables(mrt, MRT6_FLUSH_MIFS | MRT6_FLUSH_MIFS_STATIC |
397
+ MRT6_FLUSH_MFC | MRT6_FLUSH_MFC_STATIC);
393398 rhltable_destroy(&mrt->mfc_hash);
394399 kfree(mrt);
395400 }
....@@ -658,7 +663,7 @@
658663 return NULL;
659664 }
660665
661
- if (dev_open(dev))
666
+ if (dev_open(dev, NULL))
662667 goto failure;
663668
664669 dev_hold(dev);
....@@ -735,7 +740,7 @@
735740
736741 in6_dev = __in6_dev_get(dev);
737742 if (in6_dev) {
738
- in6_dev->cnf.mc_forwarding--;
743
+ atomic_dec(&in6_dev->cnf.mc_forwarding);
739744 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
740745 NETCONFA_MC_FORWARDING,
741746 dev->ifindex, &in6_dev->cnf);
....@@ -903,7 +908,7 @@
903908
904909 in6_dev = __in6_dev_get(dev);
905910 if (in6_dev) {
906
- in6_dev->cnf.mc_forwarding++;
911
+ atomic_inc(&in6_dev->cnf.mc_forwarding);
907912 inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF,
908913 NETCONFA_MC_FORWARDING,
909914 dev->ifindex, &in6_dev->cnf);
....@@ -1023,7 +1028,7 @@
10231028 }
10241029 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
10251030 } else
1026
- ip6_mr_forward(net, mrt, skb, c);
1031
+ ip6_mr_forward(net, mrt, skb->dev, skb, c);
10271032 }
10281033 }
10291034
....@@ -1064,7 +1069,7 @@
10641069 And all this only to mangle msg->im6_msgtype and
10651070 to set msg->im6_mbz to "mbz" :-)
10661071 */
1067
- skb_push(skb, -skb_network_offset(pkt));
1072
+ __skb_pull(skb, skb_network_offset(pkt));
10681073
10691074 skb_push(skb, sizeof(*msg));
10701075 skb_reset_transport_header(skb);
....@@ -1129,7 +1134,7 @@
11291134
11301135 /* Queue a packet for resolution. It gets locked cache entry! */
11311136 static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
1132
- struct sk_buff *skb)
1137
+ struct sk_buff *skb, struct net_device *dev)
11331138 {
11341139 struct mfc6_cache *c;
11351140 bool found = false;
....@@ -1149,8 +1154,8 @@
11491154 * Create a new entry if allowable
11501155 */
11511156
1152
- if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 ||
1153
- (c = ip6mr_cache_alloc_unres()) == NULL) {
1157
+ c = ip6mr_cache_alloc_unres();
1158
+ if (!c) {
11541159 spin_unlock_bh(&mfc_unres_lock);
11551160
11561161 kfree_skb(skb);
....@@ -1189,6 +1194,10 @@
11891194 kfree_skb(skb);
11901195 err = -ENOBUFS;
11911196 } else {
1197
+ if (dev) {
1198
+ skb->dev = dev;
1199
+ skb->skb_iif = dev->ifindex;
1200
+ }
11921201 skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb);
11931202 err = 0;
11941203 }
....@@ -1253,10 +1262,11 @@
12531262 return net->ipv6.ipmr_seq + ip6mr_rules_seq_read(net);
12541263 }
12551264
1256
-static int ip6mr_dump(struct net *net, struct notifier_block *nb)
1265
+static int ip6mr_dump(struct net *net, struct notifier_block *nb,
1266
+ struct netlink_ext_ack *extack)
12571267 {
12581268 return mr_dump(net, nb, RTNL_FAMILY_IP6MR, ip6mr_rules_dump,
1259
- ip6mr_mr_table_iter, &mrt_lock);
1269
+ ip6mr_mr_table_iter, &mrt_lock, extack);
12601270 }
12611271
12621272 static struct notifier_block ip6_mr_notifier = {
....@@ -1488,42 +1498,51 @@
14881498 * Close the multicast socket, and clear the vif tables etc
14891499 */
14901500
1491
-static void mroute_clean_tables(struct mr_table *mrt, bool all)
1501
+static void mroute_clean_tables(struct mr_table *mrt, int flags)
14921502 {
14931503 struct mr_mfc *c, *tmp;
14941504 LIST_HEAD(list);
14951505 int i;
14961506
14971507 /* Shut down all active vif entries */
1498
- for (i = 0; i < mrt->maxvif; i++) {
1499
- if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
1500
- continue;
1501
- mif6_delete(mrt, i, 0, &list);
1508
+ if (flags & (MRT6_FLUSH_MIFS | MRT6_FLUSH_MIFS_STATIC)) {
1509
+ for (i = 0; i < mrt->maxvif; i++) {
1510
+ if (((mrt->vif_table[i].flags & VIFF_STATIC) &&
1511
+ !(flags & MRT6_FLUSH_MIFS_STATIC)) ||
1512
+ (!(mrt->vif_table[i].flags & VIFF_STATIC) && !(flags & MRT6_FLUSH_MIFS)))
1513
+ continue;
1514
+ mif6_delete(mrt, i, 0, &list);
1515
+ }
1516
+ unregister_netdevice_many(&list);
15021517 }
1503
- unregister_netdevice_many(&list);
15041518
15051519 /* Wipe the cache */
1506
- list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
1507
- if (!all && (c->mfc_flags & MFC_STATIC))
1508
- continue;
1509
- rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params);
1510
- list_del_rcu(&c->list);
1511
- call_ip6mr_mfc_entry_notifiers(read_pnet(&mrt->net),
1512
- FIB_EVENT_ENTRY_DEL,
1513
- (struct mfc6_cache *)c, mrt->id);
1514
- mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
1515
- mr_cache_put(c);
1520
+ if (flags & (MRT6_FLUSH_MFC | MRT6_FLUSH_MFC_STATIC)) {
1521
+ list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
1522
+ if (((c->mfc_flags & MFC_STATIC) && !(flags & MRT6_FLUSH_MFC_STATIC)) ||
1523
+ (!(c->mfc_flags & MFC_STATIC) && !(flags & MRT6_FLUSH_MFC)))
1524
+ continue;
1525
+ rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params);
1526
+ list_del_rcu(&c->list);
1527
+ call_ip6mr_mfc_entry_notifiers(read_pnet(&mrt->net),
1528
+ FIB_EVENT_ENTRY_DEL,
1529
+ (struct mfc6_cache *)c, mrt->id);
1530
+ mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
1531
+ mr_cache_put(c);
1532
+ }
15161533 }
15171534
1518
- if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
1519
- spin_lock_bh(&mfc_unres_lock);
1520
- list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
1521
- list_del(&c->list);
1522
- mr6_netlink_event(mrt, (struct mfc6_cache *)c,
1523
- RTM_DELROUTE);
1524
- ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
1535
+ if (flags & MRT6_FLUSH_MFC) {
1536
+ if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
1537
+ spin_lock_bh(&mfc_unres_lock);
1538
+ list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
1539
+ list_del(&c->list);
1540
+ mr6_netlink_event(mrt, (struct mfc6_cache *)c,
1541
+ RTM_DELROUTE);
1542
+ ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
1543
+ }
1544
+ spin_unlock_bh(&mfc_unres_lock);
15251545 }
1526
- spin_unlock_bh(&mfc_unres_lock);
15271546 }
15281547 }
15291548
....@@ -1539,7 +1558,7 @@
15391558 } else {
15401559 rcu_assign_pointer(mrt->mroute_sk, sk);
15411560 sock_set_flag(sk, SOCK_RCU_FREE);
1542
- net->ipv6.devconf_all->mc_forwarding++;
1561
+ atomic_inc(&net->ipv6.devconf_all->mc_forwarding);
15431562 }
15441563 write_unlock_bh(&mrt_lock);
15451564
....@@ -1572,14 +1591,14 @@
15721591 * so the RCU grace period before sk freeing
15731592 * is guaranteed by sk_destruct()
15741593 */
1575
- net->ipv6.devconf_all->mc_forwarding--;
1594
+ atomic_dec(&net->ipv6.devconf_all->mc_forwarding);
15761595 write_unlock_bh(&mrt_lock);
15771596 inet6_netconf_notify_devconf(net, RTM_NEWNETCONF,
15781597 NETCONFA_MC_FORWARDING,
15791598 NETCONFA_IFINDEX_ALL,
15801599 net->ipv6.devconf_all);
15811600
1582
- mroute_clean_tables(mrt, false);
1601
+ mroute_clean_tables(mrt, MRT6_FLUSH_MIFS | MRT6_FLUSH_MFC);
15831602 err = 0;
15841603 break;
15851604 }
....@@ -1612,7 +1631,8 @@
16121631 * MOSPF/PIM router set up we can clean this up.
16131632 */
16141633
1615
-int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
1634
+int ip6_mroute_setsockopt(struct sock *sk, int optname, sockptr_t optval,
1635
+ unsigned int optlen)
16161636 {
16171637 int ret, parent = 0;
16181638 struct mif6ctl vif;
....@@ -1648,7 +1668,7 @@
16481668 case MRT6_ADD_MIF:
16491669 if (optlen < sizeof(vif))
16501670 return -EINVAL;
1651
- if (copy_from_user(&vif, optval, sizeof(vif)))
1671
+ if (copy_from_sockptr(&vif, optval, sizeof(vif)))
16521672 return -EFAULT;
16531673 if (vif.mif6c_mifi >= MAXMIFS)
16541674 return -ENFILE;
....@@ -1661,7 +1681,7 @@
16611681 case MRT6_DEL_MIF:
16621682 if (optlen < sizeof(mifi_t))
16631683 return -EINVAL;
1664
- if (copy_from_user(&mifi, optval, sizeof(mifi_t)))
1684
+ if (copy_from_sockptr(&mifi, optval, sizeof(mifi_t)))
16651685 return -EFAULT;
16661686 rtnl_lock();
16671687 ret = mif6_delete(mrt, mifi, 0, NULL);
....@@ -1675,12 +1695,12 @@
16751695 case MRT6_ADD_MFC:
16761696 case MRT6_DEL_MFC:
16771697 parent = -1;
1678
- /* fall through */
1698
+ fallthrough;
16791699 case MRT6_ADD_MFC_PROXY:
16801700 case MRT6_DEL_MFC_PROXY:
16811701 if (optlen < sizeof(mfc))
16821702 return -EINVAL;
1683
- if (copy_from_user(&mfc, optval, sizeof(mfc)))
1703
+ if (copy_from_sockptr(&mfc, optval, sizeof(mfc)))
16841704 return -EFAULT;
16851705 if (parent == 0)
16861706 parent = mfc.mf6cc_parent;
....@@ -1695,6 +1715,20 @@
16951715 rtnl_unlock();
16961716 return ret;
16971717
1718
+ case MRT6_FLUSH:
1719
+ {
1720
+ int flags;
1721
+
1722
+ if (optlen != sizeof(flags))
1723
+ return -EINVAL;
1724
+ if (copy_from_sockptr(&flags, optval, sizeof(flags)))
1725
+ return -EFAULT;
1726
+ rtnl_lock();
1727
+ mroute_clean_tables(mrt, flags);
1728
+ rtnl_unlock();
1729
+ return 0;
1730
+ }
1731
+
16981732 /*
16991733 * Control PIM assert (to activate pim will activate assert)
17001734 */
....@@ -1704,7 +1738,7 @@
17041738
17051739 if (optlen != sizeof(v))
17061740 return -EINVAL;
1707
- if (get_user(v, (int __user *)optval))
1741
+ if (copy_from_sockptr(&v, optval, sizeof(v)))
17081742 return -EFAULT;
17091743 mrt->mroute_do_assert = v;
17101744 return 0;
....@@ -1717,7 +1751,7 @@
17171751
17181752 if (optlen != sizeof(v))
17191753 return -EINVAL;
1720
- if (get_user(v, (int __user *)optval))
1754
+ if (copy_from_sockptr(&v, optval, sizeof(v)))
17211755 return -EFAULT;
17221756 v = !!v;
17231757 rtnl_lock();
....@@ -1738,7 +1772,7 @@
17381772
17391773 if (optlen != sizeof(u32))
17401774 return -EINVAL;
1741
- if (get_user(v, (u32 __user *)optval))
1775
+ if (copy_from_sockptr(&v, optval, sizeof(v)))
17421776 return -EFAULT;
17431777 /* "pim6reg%u" should not exceed 16 bytes (IFNAMSIZ) */
17441778 if (v != RT_TABLE_DEFAULT && v >= 100000000)
....@@ -1968,7 +2002,7 @@
19682002 */
19692003
19702004 static int ip6mr_forward2(struct net *net, struct mr_table *mrt,
1971
- struct sk_buff *skb, struct mfc6_cache *c, int vifi)
2005
+ struct sk_buff *skb, int vifi)
19722006 {
19732007 struct ipv6hdr *ipv6h;
19742008 struct vif_device *vif = &mrt->vif_table[vifi];
....@@ -2053,11 +2087,12 @@
20532087 }
20542088
20552089 static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
2056
- struct sk_buff *skb, struct mfc6_cache *c)
2090
+ struct net_device *dev, struct sk_buff *skb,
2091
+ struct mfc6_cache *c)
20572092 {
20582093 int psend = -1;
20592094 int vif, ct;
2060
- int true_vifi = ip6mr_find_vif(mrt, skb->dev);
2095
+ int true_vifi = ip6mr_find_vif(mrt, dev);
20612096
20622097 vif = c->_c.mfc_parent;
20632098 c->_c.mfc_un.res.pkt++;
....@@ -2083,7 +2118,7 @@
20832118 /*
20842119 * Wrong interface: drop packet and (maybe) send PIM assert.
20852120 */
2086
- if (mrt->vif_table[vif].dev != skb->dev) {
2121
+ if (mrt->vif_table[vif].dev != dev) {
20872122 c->_c.mfc_un.res.wrong_if++;
20882123
20892124 if (true_vifi >= 0 && mrt->mroute_do_assert &&
....@@ -2133,15 +2168,14 @@
21332168 if (psend != -1) {
21342169 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
21352170 if (skb2)
2136
- ip6mr_forward2(net, mrt, skb2,
2137
- c, psend);
2171
+ ip6mr_forward2(net, mrt, skb2, psend);
21382172 }
21392173 psend = ct;
21402174 }
21412175 }
21422176 last_forward:
21432177 if (psend != -1) {
2144
- ip6mr_forward2(net, mrt, skb, c, psend);
2178
+ ip6mr_forward2(net, mrt, skb, psend);
21452179 return;
21462180 }
21472181
....@@ -2164,6 +2198,19 @@
21642198 .flowi6_mark = skb->mark,
21652199 };
21662200 int err;
2201
+ struct net_device *dev;
2202
+
2203
+ /* skb->dev passed in is the master dev for vrfs.
2204
+ * Get the proper interface that does have a vif associated with it.
2205
+ */
2206
+ dev = skb->dev;
2207
+ if (netif_is_l3_master(skb->dev)) {
2208
+ dev = dev_get_by_index_rcu(net, IPCB(skb)->iif);
2209
+ if (!dev) {
2210
+ kfree_skb(skb);
2211
+ return -ENODEV;
2212
+ }
2213
+ }
21672214
21682215 err = ip6mr_fib_lookup(net, &fl6, &mrt);
21692216 if (err < 0) {
....@@ -2175,7 +2222,7 @@
21752222 cache = ip6mr_cache_find(mrt,
21762223 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr);
21772224 if (!cache) {
2178
- int vif = ip6mr_find_vif(mrt, skb->dev);
2225
+ int vif = ip6mr_find_vif(mrt, dev);
21792226
21802227 if (vif >= 0)
21812228 cache = ip6mr_cache_find_any(mrt,
....@@ -2189,9 +2236,9 @@
21892236 if (!cache) {
21902237 int vif;
21912238
2192
- vif = ip6mr_find_vif(mrt, skb->dev);
2239
+ vif = ip6mr_find_vif(mrt, dev);
21932240 if (vif >= 0) {
2194
- int err = ip6mr_cache_unresolved(mrt, vif, skb);
2241
+ int err = ip6mr_cache_unresolved(mrt, vif, skb, dev);
21952242 read_unlock(&mrt_lock);
21962243
21972244 return err;
....@@ -2201,7 +2248,7 @@
22012248 return -ENODEV;
22022249 }
22032250
2204
- ip6_mr_forward(net, mrt, skb, cache);
2251
+ ip6_mr_forward(net, mrt, dev, skb, cache);
22052252
22062253 read_unlock(&mrt_lock);
22072254
....@@ -2267,7 +2314,7 @@
22672314 iph->saddr = rt->rt6i_src.addr;
22682315 iph->daddr = rt->rt6i_dst.addr;
22692316
2270
- err = ip6mr_cache_unresolved(mrt, vif, skb2);
2317
+ err = ip6mr_cache_unresolved(mrt, vif, skb2, dev);
22712318 read_unlock(&mrt_lock);
22722319
22732320 return err;
....@@ -2443,6 +2490,33 @@
24432490
24442491 static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
24452492 {
2493
+ const struct nlmsghdr *nlh = cb->nlh;
2494
+ struct fib_dump_filter filter = {};
2495
+ int err;
2496
+
2497
+ if (cb->strict_check) {
2498
+ err = ip_valid_fib_dump_req(sock_net(skb->sk), nlh,
2499
+ &filter, cb);
2500
+ if (err < 0)
2501
+ return err;
2502
+ }
2503
+
2504
+ if (filter.table_id) {
2505
+ struct mr_table *mrt;
2506
+
2507
+ mrt = ip6mr_get_table(sock_net(skb->sk), filter.table_id);
2508
+ if (!mrt) {
2509
+ if (rtnl_msg_family(cb->nlh) != RTNL_FAMILY_IP6MR)
2510
+ return skb->len;
2511
+
2512
+ NL_SET_ERR_MSG_MOD(cb->extack, "MR table does not exist");
2513
+ return -ENOENT;
2514
+ }
2515
+ err = mr_table_dump(mrt, skb, cb, _ip6mr_fill_mroute,
2516
+ &mfc_unres_lock, &filter);
2517
+ return skb->len ? : err;
2518
+ }
2519
+
24462520 return mr_rtm_dumproute(skb, cb, ip6mr_mr_table_iter,
2447
- _ip6mr_fill_mroute, &mfc_unres_lock);
2521
+ _ip6mr_fill_mroute, &mfc_unres_lock, &filter);
24482522 }