Lines Matching refs:mrt

58 	struct mr_table	*mrt;
61 /* Big lock, protecting vif table, mrt cache and mroute socket state.
88 static void ip6mr_free_table(struct mr_table *mrt);
90 static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
93 static int ip6mr_cache_report(const struct mr_table *mrt, struct sk_buff *pkt,
95 static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
97 static void mrt6msg_netlink_event(const struct mr_table *mrt, struct sk_buff *pkt);
102 static void mroute_clean_tables(struct mr_table *mrt, int flags);
106 #define ip6mr_for_each_table(mrt, net) \
107 list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list, \
112 struct mr_table *mrt)
116 if (!mrt)
120 ret = list_entry_rcu(mrt->list.next,
130 struct mr_table *mrt;
132 ip6mr_for_each_table(mrt, net) {
133 if (mrt->id == id)
134 return mrt;
141 struct mr_table *mrt;
144 mrt = __ip6mr_get_table(net, id);
146 return mrt;
150 struct mr_table **mrt)
166 *mrt = res.mrt;
174 struct mr_table *mrt;
190 mrt = __ip6mr_get_table(rule->fr_net, arg->table);
191 if (!mrt)
193 res->mrt = mrt;
240 struct mr_table *mrt;
249 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
250 if (IS_ERR(mrt)) {
251 err = PTR_ERR(mrt);
264 ip6mr_free_table(mrt);
273 struct mr_table *mrt, *next;
276 list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) {
277 list_del(&mrt->list);
278 ip6mr_free_table(mrt);
301 #define ip6mr_for_each_table(mrt, net) \
302 for (mrt = net->ipv6.mrt6; mrt; mrt = NULL)
305 struct mr_table *mrt)
307 if (!mrt)
320 struct mr_table **mrt)
322 *mrt = net->ipv6.mrt6;
328 struct mr_table *mrt;
330 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
331 if (IS_ERR(mrt))
332 return PTR_ERR(mrt);
333 net->ipv6.mrt6 = mrt;
375 static void ip6mr_new_table_set(struct mr_table *mrt,
379 list_add_tail_rcu(&mrt->list, &net->ipv6.mr6_tables);
395 struct mr_table *mrt;
397 mrt = __ip6mr_get_table(net, id);
398 if (mrt)
399 return mrt;
405 static void ip6mr_free_table(struct mr_table *mrt)
407 struct net *net = read_pnet(&mrt->net);
411 timer_shutdown_sync(&mrt->ipmr_expire_timer);
412 mroute_clean_tables(mrt, MRT6_FLUSH_MIFS | MRT6_FLUSH_MIFS_STATIC |
414 rhltable_destroy(&mrt->mfc_hash);
415 kfree(mrt);
428 struct mr_table *mrt;
431 mrt = __ip6mr_get_table(net, RT6_TABLE_DFLT);
432 if (!mrt) {
437 iter->mrt = mrt;
451 struct mr_table *mrt = iter->mrt;
466 vif - mrt->vif_table,
484 struct mr_table *mrt;
486 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
487 if (!mrt)
490 return mr_mfc_seq_start(seq, pos, mrt, &mfc_unres_lock);
505 struct mr_table *mrt = it->mrt;
511 if (it->cache != &mrt->mfc_unres_queue) {
518 if (VIF_EXISTS(mrt, n) &&
551 struct mr_table *mrt;
579 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
583 reg_vif_num = READ_ONCE(mrt->mroute_reg_vif_num);
585 reg_dev = vif_dev_read(&mrt->vif_table[reg_vif_num]);
616 struct mr_table *mrt;
626 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
632 ip6mr_cache_report(mrt, skb, READ_ONCE(mrt->mroute_reg_vif_num),
664 static struct net_device *ip6mr_reg_vif(struct net *net, struct mr_table *mrt)
669 if (mrt->id == RT6_TABLE_DFLT)
672 sprintf(name, "pim6reg%u", mrt->id);
717 static int mif6_delete(struct mr_table *mrt, int vifi, int notify,
724 if (vifi < 0 || vifi >= mrt->maxvif)
727 v = &mrt->vif_table[vifi];
733 call_ip6mr_vif_entry_notifiers(read_pnet(&mrt->net),
735 vifi, mrt->id);
740 if (vifi == mrt->mroute_reg_vif_num) {
742 WRITE_ONCE(mrt->mroute_reg_vif_num, -1);
746 if (vifi + 1 == mrt->maxvif) {
749 if (VIF_EXISTS(mrt, tmp))
752 WRITE_ONCE(mrt->maxvif, tmp + 1);
790 static void ip6mr_destroy_unres(struct mr_table *mrt, struct mfc6_cache *c)
792 struct net *net = read_pnet(&mrt->net);
795 atomic_dec(&mrt->cache_resolve_queue_len);
816 static void ipmr_do_expire_process(struct mr_table *mrt)
822 list_for_each_entry_safe(c, next, &mrt->mfc_unres_queue, list) {
832 mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
833 ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
836 if (!list_empty(&mrt->mfc_unres_queue))
837 mod_timer(&mrt->ipmr_expire_timer, jiffies + expires);
842 struct mr_table *mrt = timer_container_of(mrt, t, ipmr_expire_timer);
845 mod_timer(&mrt->ipmr_expire_timer, jiffies + 1);
849 if (!list_empty(&mrt->mfc_unres_queue))
850 ipmr_do_expire_process(mrt);
857 static void ip6mr_update_thresholds(struct mr_table *mrt,
867 for (vifi = 0; vifi < mrt->maxvif; vifi++) {
868 if (VIF_EXISTS(mrt, vifi) &&
880 static int mif6_add(struct net *net, struct mr_table *mrt,
884 struct vif_device *v = &mrt->vif_table[vifi];
890 if (VIF_EXISTS(mrt, vifi))
900 if (mrt->mroute_reg_vif_num >= 0)
902 dev = ip6mr_reg_vif(net, mrt);
946 WRITE_ONCE(mrt->mroute_reg_vif_num, vifi);
948 if (vifi + 1 > mrt->maxvif)
949 WRITE_ONCE(mrt->maxvif, vifi + 1);
952 v, dev, vifi, mrt->id);
956 static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt,
965 return mr_mfc_find(mrt, &arg);
969 static struct mfc6_cache *ip6mr_cache_find_any(struct mr_table *mrt,
979 return mr_mfc_find_any_parent(mrt, mifi);
980 return mr_mfc_find_any(mrt, mifi, &arg);
985 ip6mr_cache_find_parent(struct mr_table *mrt,
995 return mr_mfc_find_parent(mrt, &arg, parent);
1025 static void ip6mr_cache_resolve(struct net *net, struct mr_table *mrt,
1039 if (mr_fill_mroute(mrt, skb, &c->_c,
1051 ip6_mr_forward(net, mrt, skb->dev, skb, c);
1063 static int ip6mr_cache_report(const struct mr_table *mrt, struct sk_buff *pkt,
1104 msg->im6_mif = READ_ONCE(mrt->mroute_reg_vif_num);
1139 mroute6_sk = rcu_dereference(mrt->mroute_sk);
1145 mrt6msg_netlink_event(mrt, skb);
1159 static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
1167 list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) {
1196 err = ip6mr_cache_report(mrt, skb, mifi, MRT6MSG_NOCACHE);
1208 atomic_inc(&mrt->cache_resolve_queue_len);
1209 list_add(&c->_c.list, &mrt->mfc_unres_queue);
1210 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
1212 ipmr_do_expire_process(mrt);
1236 static int ip6mr_mfc_delete(struct mr_table *mrt, struct mf6cctl *mfc,
1243 c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
1248 rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params);
1251 call_ip6mr_mfc_entry_notifiers(read_pnet(&mrt->net),
1252 FIB_EVENT_ENTRY_DEL, c, mrt->id);
1253 mr6_netlink_event(mrt, c, RTM_DELROUTE);
1263 struct mr_table *mrt;
1270 ip6mr_for_each_table(mrt, net) {
1271 v = &mrt->vif_table[0];
1272 for (ct = 0; ct < mrt->maxvif; ct++, v++) {
1274 mif6_delete(mrt, ct, 1, NULL);
1443 static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
1463 c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
1469 ip6mr_update_thresholds(mrt, &c->_c, ttls);
1474 c, mrt->id);
1475 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
1490 ip6mr_update_thresholds(mrt, &c->_c, ttls);
1494 err = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->_c.mnode,
1501 list_add_tail_rcu(&c->_c.list, &mrt->mfc_cache_list);
1508 list_for_each_entry(_uc, &mrt->mfc_unres_queue, list) {
1513 atomic_dec(&mrt->cache_resolve_queue_len);
1518 if (list_empty(&mrt->mfc_unres_queue))
1519 timer_delete(&mrt->ipmr_expire_timer);
1523 ip6mr_cache_resolve(net, mrt, uc, c);
1527 c, mrt->id);
1528 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
1536 static void mroute_clean_tables(struct mr_table *mrt, int flags)
1544 for (i = 0; i < mrt->maxvif; i++) {
1545 if (((mrt->vif_table[i].flags & VIFF_STATIC) &&
1547 (!(mrt->vif_table[i].flags & VIFF_STATIC) && !(flags & MRT6_FLUSH_MIFS)))
1549 mif6_delete(mrt, i, 0, &list);
1556 list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
1560 rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params);
1562 call_ip6mr_mfc_entry_notifiers(read_pnet(&mrt->net),
1564 (struct mfc6_cache *)c, mrt->id);
1565 mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
1571 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
1573 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
1575 mr6_netlink_event(mrt, (struct mfc6_cache *)c,
1577 ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
1584 static int ip6mr_sk_init(struct mr_table *mrt, struct sock *sk)
1591 if (rtnl_dereference(mrt->mroute_sk)) {
1594 rcu_assign_pointer(mrt->mroute_sk, sk);
1614 struct mr_table *mrt;
1626 ip6mr_for_each_table(mrt, net) {
1627 if (sk == rtnl_dereference(mrt->mroute_sk)) {
1629 RCU_INIT_POINTER(mrt->mroute_sk, NULL);
1641 mroute_clean_tables(mrt, MRT6_FLUSH_MIFS | MRT6_FLUSH_MFC);
1653 struct mr_table *mrt;
1660 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
1663 return rcu_access_pointer(mrt->mroute_sk);
1682 struct mr_table *mrt;
1688 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1689 if (!mrt)
1693 if (sk != rcu_access_pointer(mrt->mroute_sk) &&
1703 return ip6mr_sk_init(mrt, sk);
1716 ret = mif6_add(net, mrt, &vif,
1717 sk == rtnl_dereference(mrt->mroute_sk));
1727 ret = mif6_delete(mrt, mifi, 0, NULL);
1749 ret = ip6mr_mfc_delete(mrt, &mfc, parent);
1751 ret = ip6mr_mfc_add(net, mrt, &mfc,
1753 rtnl_dereference(mrt->mroute_sk),
1767 mroute_clean_tables(mrt, flags);
1783 mrt->mroute_do_assert = v;
1802 if (v != mrt->mroute_do_pim) {
1803 mrt->mroute_do_pim = v;
1804 mrt->mroute_do_assert = v;
1805 mrt->mroute_do_wrvifwhole = do_wrmifwhole;
1824 if (sk == rcu_access_pointer(mrt->mroute_sk))
1829 mrt = ip6mr_new_table(net, v);
1830 if (IS_ERR(mrt))
1831 ret = PTR_ERR(mrt);
1857 struct mr_table *mrt;
1863 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1864 if (!mrt)
1873 val = mrt->mroute_do_pim;
1877 val = mrt->mroute_do_assert;
1907 struct mr_table *mrt;
1909 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1910 if (!mrt)
1916 if (vr->mifi >= mrt->maxvif)
1918 vr->mifi = array_index_nospec(vr->mifi, mrt->maxvif);
1920 vif = &mrt->vif_table[vr->mifi];
1921 if (VIF_EXISTS(mrt, vr->mifi)) {
1935 c = ip6mr_cache_find(mrt, &sr->src.sin6_addr,
1975 struct mr_table *mrt;
1977 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1978 if (!mrt)
1985 if (vr.mifi >= mrt->maxvif)
1987 vr.mifi = array_index_nospec(vr.mifi, mrt->maxvif);
1989 vif = &mrt->vif_table[vr.mifi];
1990 if (VIF_EXISTS(mrt, vr.mifi)) {
2008 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
2038 static int ip6mr_prepare_xmit(struct net *net, struct mr_table *mrt,
2041 struct vif_device *vif = &mrt->vif_table[vifi];
2057 ip6mr_cache_report(mrt, skb, vifi, MRT6MSG_WHOLEPKT);
2103 static void ip6mr_forward2(struct net *net, struct mr_table *mrt,
2108 if (ip6mr_prepare_xmit(net, mrt, skb, vifi))
2122 static void ip6mr_output2(struct net *net, struct mr_table *mrt,
2125 if (ip6mr_prepare_xmit(net, mrt, skb, vifi))
2136 static int ip6mr_find_vif(struct mr_table *mrt, struct net_device *dev)
2141 for (ct = READ_ONCE(mrt->maxvif) - 1; ct >= 0; ct--) {
2142 if (rcu_access_pointer(mrt->vif_table[ct].dev) == dev)
2149 static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
2155 int true_vifi = ip6mr_find_vif(mrt, dev);
2168 cache_proxy = mr_mfc_find_any_parent(mrt, vif);
2177 if (rcu_access_pointer(mrt->vif_table[vif].dev) != dev) {
2180 if (true_vifi >= 0 && mrt->mroute_do_assert &&
2186 (mrt->mroute_do_pim ||
2192 ip6mr_cache_report(mrt, skb, true_vifi, MRT6MSG_WRONGMIF);
2193 if (mrt->mroute_do_wrvifwhole)
2194 ip6mr_cache_report(mrt, skb, true_vifi,
2201 WRITE_ONCE(mrt->vif_table[vif].pkt_in,
2202 mrt->vif_table[vif].pkt_in + 1);
2203 WRITE_ONCE(mrt->vif_table[vif].bytes_in,
2204 mrt->vif_table[vif].bytes_in + skb->len);
2232 ip6mr_forward2(net, mrt, skb2, psend);
2239 ip6mr_forward2(net, mrt, skb, psend);
2248 static void ip6_mr_output_finish(struct net *net, struct mr_table *mrt,
2283 ip6mr_output2(net, mrt, skb2, psend);
2290 ip6mr_output2(net, mrt, skb, psend);
2307 struct mr_table *mrt;
2325 err = ip6mr_fib_lookup(net, &fl6, &mrt);
2331 cache = ip6mr_cache_find(mrt,
2334 int vif = ip6mr_find_vif(mrt, dev);
2337 cache = ip6mr_cache_find_any(mrt,
2348 vif = ip6mr_find_vif(mrt, dev);
2350 int err = ip6mr_cache_unresolved(mrt, vif, skb, dev);
2358 ip6_mr_forward(net, mrt, dev, skb, cache);
2371 struct mr_table *mrt;
2382 err = ip6mr_fib_lookup(net, &fl6, &mrt);
2388 cache = ip6mr_cache_find(mrt,
2391 vif = ip6mr_find_vif(mrt, dev);
2393 cache = ip6mr_cache_find_any(mrt,
2400 vif = ip6mr_find_vif(mrt, dev);
2402 return ip6mr_cache_unresolved(mrt, vif, skb, dev);
2408 if (rcu_access_pointer(mrt->vif_table[vif].dev) != dev)
2411 ip6_mr_output_finish(net, mrt, dev, skb, cache);
2422 struct mr_table *mrt;
2427 mrt = __ip6mr_get_table(net, RT6_TABLE_DFLT);
2428 if (!mrt) {
2433 cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
2435 int vif = ip6mr_find_vif(mrt, skb->dev);
2438 cache = ip6mr_cache_find_any(mrt, &rt->rt6i_dst.addr,
2449 if (!dev || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
2479 err = ip6mr_cache_unresolved(mrt, vif, skb2, dev);
2485 err = mr_fill_mroute(mrt, skb, &cache->_c, rtm);
2490 static int ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2507 rtm->rtm_table = mrt->id;
2508 if (nla_put_u32(skb, RTA_TABLE, mrt->id))
2521 err = mr_fill_mroute(mrt, skb, &c->_c, rtm);
2534 static int _ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2538 return ip6mr_fill_mroute(mrt, skb, portid, seq, (struct mfc6_cache *)c,
2563 static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
2566 struct net *net = read_pnet(&mrt->net);
2570 skb = nlmsg_new(mr6_msgsize(mfc->_c.mfc_parent >= MAXMIFS, mrt->maxvif),
2575 err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0);
2604 static void mrt6msg_netlink_event(const struct mr_table *mrt, struct sk_buff *pkt)
2606 struct net *net = read_pnet(&mrt->net);
2697 struct mr_table *mrt;
2712 mrt = __ip6mr_get_table(net, tableid ?: RT_TABLE_DEFAULT);
2713 if (!mrt) {
2720 cache = ip6mr_cache_find(mrt, &src, &grp);
2727 skb = nlmsg_new(mr6_msgsize(false, mrt->maxvif), GFP_KERNEL);
2731 err = ip6mr_fill_mroute(mrt, skb, NETLINK_CB(in_skb).portid,
2757 struct mr_table *mrt;
2759 mrt = __ip6mr_get_table(sock_net(skb->sk), filter.table_id);
2760 if (!mrt) {
2767 err = mr_table_dump(mrt, skb, cb, _ip6mr_fill_mroute,