Lines Matching refs:mrt
58 struct mr_table *mrt;
61 /* Big lock, protecting vif table, mrt cache and mroute socket state.
83 static void ip6mr_free_table(struct mr_table *mrt);
85 static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
88 static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
90 static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
92 static void mrt6msg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt);
95 static void mroute_clean_tables(struct mr_table *mrt, int flags);
99 #define ip6mr_for_each_table(mrt, net) \
100 list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list, \
105 struct mr_table *mrt)
109 if (!mrt)
113 ret = list_entry_rcu(mrt->list.next,
123 struct mr_table *mrt;
125 ip6mr_for_each_table(mrt, net) {
126 if (mrt->id == id)
127 return mrt;
133 struct mr_table **mrt)
149 *mrt = res.mrt;
157 struct mr_table *mrt;
173 mrt = ip6mr_get_table(rule->fr_net, arg->table);
174 if (!mrt)
176 res->mrt = mrt;
228 struct mr_table *mrt;
237 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
238 if (IS_ERR(mrt)) {
239 err = PTR_ERR(mrt);
252 ip6mr_free_table(mrt);
261 struct mr_table *mrt, *next;
264 list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) {
265 list_del(&mrt->list);
266 ip6mr_free_table(mrt);
290 #define ip6mr_for_each_table(mrt, net) \
291 for (mrt = net->ipv6.mrt6; mrt; mrt = NULL)
294 struct mr_table *mrt)
296 if (!mrt)
307 struct mr_table **mrt)
309 *mrt = net->ipv6.mrt6;
315 struct mr_table *mrt;
317 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
318 if (IS_ERR(mrt))
319 return PTR_ERR(mrt);
320 net->ipv6.mrt6 = mrt;
363 static void ip6mr_new_table_set(struct mr_table *mrt,
367 list_add_tail_rcu(&mrt->list, &net->ipv6.mr6_tables);
383 struct mr_table *mrt;
385 mrt = ip6mr_get_table(net, id);
386 if (mrt)
387 return mrt;
393 static void ip6mr_free_table(struct mr_table *mrt)
395 del_timer_sync(&mrt->ipmr_expire_timer);
396 mroute_clean_tables(mrt, MRT6_FLUSH_MIFS | MRT6_FLUSH_MIFS_STATIC |
398 rhltable_destroy(&mrt->mfc_hash);
399 kfree(mrt);
412 struct mr_table *mrt;
414 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
415 if (!mrt)
418 iter->mrt = mrt;
433 struct mr_table *mrt = iter->mrt;
444 vif - mrt->vif_table,
462 struct mr_table *mrt;
464 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
465 if (!mrt)
468 return mr_mfc_seq_start(seq, pos, mrt, &mfc_unres_lock);
483 struct mr_table *mrt = it->mrt;
489 if (it->cache != &mrt->mfc_unres_queue) {
496 if (VIF_EXISTS(mrt, n) &&
529 struct mr_table *mrt;
557 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
559 reg_vif_num = mrt->mroute_reg_vif_num;
563 reg_dev = mrt->vif_table[reg_vif_num].dev;
598 struct mr_table *mrt;
608 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
614 ip6mr_cache_report(mrt, skb, mrt->mroute_reg_vif_num, MRT6MSG_WHOLEPKT);
645 static struct net_device *ip6mr_reg_vif(struct net *net, struct mr_table *mrt)
650 if (mrt->id == RT6_TABLE_DFLT)
653 sprintf(name, "pim6reg%u", mrt->id);
697 static int mif6_delete(struct mr_table *mrt, int vifi, int notify,
704 if (vifi < 0 || vifi >= mrt->maxvif)
707 v = &mrt->vif_table[vifi];
709 if (VIF_EXISTS(mrt, vifi))
710 call_ip6mr_vif_entry_notifiers(read_pnet(&mrt->net),
712 mrt->id);
724 if (vifi == mrt->mroute_reg_vif_num)
725 mrt->mroute_reg_vif_num = -1;
728 if (vifi + 1 == mrt->maxvif) {
731 if (VIF_EXISTS(mrt, tmp))
734 mrt->maxvif = tmp + 1;
772 static void ip6mr_destroy_unres(struct mr_table *mrt, struct mfc6_cache *c)
774 struct net *net = read_pnet(&mrt->net);
777 atomic_dec(&mrt->cache_resolve_queue_len);
798 static void ipmr_do_expire_process(struct mr_table *mrt)
804 list_for_each_entry_safe(c, next, &mrt->mfc_unres_queue, list) {
814 mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
815 ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
818 if (!list_empty(&mrt->mfc_unres_queue))
819 mod_timer(&mrt->ipmr_expire_timer, jiffies + expires);
824 struct mr_table *mrt = from_timer(mrt, t, ipmr_expire_timer);
827 mod_timer(&mrt->ipmr_expire_timer, jiffies + 1);
831 if (!list_empty(&mrt->mfc_unres_queue))
832 ipmr_do_expire_process(mrt);
839 static void ip6mr_update_thresholds(struct mr_table *mrt,
849 for (vifi = 0; vifi < mrt->maxvif; vifi++) {
850 if (VIF_EXISTS(mrt, vifi) &&
862 static int mif6_add(struct net *net, struct mr_table *mrt,
866 struct vif_device *v = &mrt->vif_table[vifi];
872 if (VIF_EXISTS(mrt, vifi))
882 if (mrt->mroute_reg_vif_num >= 0)
884 dev = ip6mr_reg_vif(net, mrt);
927 mrt->mroute_reg_vif_num = vifi;
929 if (vifi + 1 > mrt->maxvif)
930 mrt->maxvif = vifi + 1;
933 v, vifi, mrt->id);
937 static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt,
946 return mr_mfc_find(mrt, &arg);
950 static struct mfc6_cache *ip6mr_cache_find_any(struct mr_table *mrt,
960 return mr_mfc_find_any_parent(mrt, mifi);
961 return mr_mfc_find_any(mrt, mifi, &arg);
966 ip6mr_cache_find_parent(struct mr_table *mrt,
976 return mr_mfc_find_parent(mrt, &arg, parent);
1006 static void ip6mr_cache_resolve(struct net *net, struct mr_table *mrt,
1020 if (mr_fill_mroute(mrt, skb, &c->_c,
1031 ip6_mr_forward(net, mrt, skb->dev, skb, c);
1041 static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
1079 msg->im6_mif = mrt->mroute_reg_vif_num;
1115 mroute6_sk = rcu_dereference(mrt->mroute_sk);
1122 mrt6msg_netlink_event(mrt, skb);
1136 static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
1144 list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) {
1173 err = ip6mr_cache_report(mrt, skb, mifi, MRT6MSG_NOCACHE);
1185 atomic_inc(&mrt->cache_resolve_queue_len);
1186 list_add(&c->_c.list, &mrt->mfc_unres_queue);
1187 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
1189 ipmr_do_expire_process(mrt);
1213 static int ip6mr_mfc_delete(struct mr_table *mrt, struct mf6cctl *mfc,
1220 c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
1225 rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params);
1228 call_ip6mr_mfc_entry_notifiers(read_pnet(&mrt->net),
1229 FIB_EVENT_ENTRY_DEL, c, mrt->id);
1230 mr6_netlink_event(mrt, c, RTM_DELROUTE);
1240 struct mr_table *mrt;
1247 ip6mr_for_each_table(mrt, net) {
1248 v = &mrt->vif_table[0];
1249 for (ct = 0; ct < mrt->maxvif; ct++, v++) {
1251 mif6_delete(mrt, ct, 1, NULL);
1408 static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
1428 c = ip6mr_cache_find_parent(mrt, &mfc->mf6cc_origin.sin6_addr,
1434 ip6mr_update_thresholds(mrt, &c->_c, ttls);
1439 c, mrt->id);
1440 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
1455 ip6mr_update_thresholds(mrt, &c->_c, ttls);
1459 err = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->_c.mnode,
1466 list_add_tail_rcu(&c->_c.list, &mrt->mfc_cache_list);
1473 list_for_each_entry(_uc, &mrt->mfc_unres_queue, list) {
1478 atomic_dec(&mrt->cache_resolve_queue_len);
1483 if (list_empty(&mrt->mfc_unres_queue))
1484 del_timer(&mrt->ipmr_expire_timer);
1488 ip6mr_cache_resolve(net, mrt, uc, c);
1492 c, mrt->id);
1493 mr6_netlink_event(mrt, c, RTM_NEWROUTE);
1501 static void mroute_clean_tables(struct mr_table *mrt, int flags)
1509 for (i = 0; i < mrt->maxvif; i++) {
1510 if (((mrt->vif_table[i].flags & VIFF_STATIC) &&
1512 (!(mrt->vif_table[i].flags & VIFF_STATIC) && !(flags & MRT6_FLUSH_MIFS)))
1514 mif6_delete(mrt, i, 0, &list);
1521 list_for_each_entry_safe(c, tmp, &mrt->mfc_cache_list, list) {
1525 rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params);
1527 call_ip6mr_mfc_entry_notifiers(read_pnet(&mrt->net),
1529 (struct mfc6_cache *)c, mrt->id);
1530 mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
1536 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
1538 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
1540 mr6_netlink_event(mrt, (struct mfc6_cache *)c,
1542 ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
1549 static int ip6mr_sk_init(struct mr_table *mrt, struct sock *sk)
1556 if (rtnl_dereference(mrt->mroute_sk)) {
1559 rcu_assign_pointer(mrt->mroute_sk, sk);
1579 struct mr_table *mrt;
1586 ip6mr_for_each_table(mrt, net) {
1587 if (sk == rtnl_dereference(mrt->mroute_sk)) {
1589 RCU_INIT_POINTER(mrt->mroute_sk, NULL);
1601 mroute_clean_tables(mrt, MRT6_FLUSH_MIFS | MRT6_FLUSH_MFC);
1613 struct mr_table *mrt;
1620 if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
1623 return rcu_access_pointer(mrt->mroute_sk);
1642 struct mr_table *mrt;
1648 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1649 if (!mrt)
1653 if (sk != rcu_access_pointer(mrt->mroute_sk) &&
1663 return ip6mr_sk_init(mrt, sk);
1676 ret = mif6_add(net, mrt, &vif,
1677 sk == rtnl_dereference(mrt->mroute_sk));
1687 ret = mif6_delete(mrt, mifi, 0, NULL);
1709 ret = ip6mr_mfc_delete(mrt, &mfc, parent);
1711 ret = ip6mr_mfc_add(net, mrt, &mfc,
1713 rtnl_dereference(mrt->mroute_sk),
1727 mroute_clean_tables(mrt, flags);
1743 mrt->mroute_do_assert = v;
1759 if (v != mrt->mroute_do_pim) {
1760 mrt->mroute_do_pim = v;
1761 mrt->mroute_do_assert = v;
1780 if (sk == rcu_access_pointer(mrt->mroute_sk))
1785 mrt = ip6mr_new_table(net, v);
1786 if (IS_ERR(mrt))
1787 ret = PTR_ERR(mrt);
1813 struct mr_table *mrt;
1819 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1820 if (!mrt)
1829 val = mrt->mroute_do_pim;
1833 val = mrt->mroute_do_assert;
1864 struct mr_table *mrt;
1866 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1867 if (!mrt)
1874 if (vr.mifi >= mrt->maxvif)
1876 vr.mifi = array_index_nospec(vr.mifi, mrt->maxvif);
1878 vif = &mrt->vif_table[vr.mifi];
1879 if (VIF_EXISTS(mrt, vr.mifi)) {
1897 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
1939 struct mr_table *mrt;
1941 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1942 if (!mrt)
1949 if (vr.mifi >= mrt->maxvif)
1951 vr.mifi = array_index_nospec(vr.mifi, mrt->maxvif);
1953 vif = &mrt->vif_table[vr.mifi];
1954 if (VIF_EXISTS(mrt, vr.mifi)) {
1972 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
2004 static int ip6mr_forward2(struct net *net, struct mr_table *mrt,
2008 struct vif_device *vif = &mrt->vif_table[vifi];
2022 ip6mr_cache_report(mrt, skb, vifi, MRT6MSG_WHOLEPKT);
2078 static int ip6mr_find_vif(struct mr_table *mrt, struct net_device *dev)
2082 for (ct = mrt->maxvif - 1; ct >= 0; ct--) {
2083 if (mrt->vif_table[ct].dev == dev)
2089 static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
2095 int true_vifi = ip6mr_find_vif(mrt, dev);
2109 cache_proxy = mr_mfc_find_any_parent(mrt, vif);
2121 if (mrt->vif_table[vif].dev != dev) {
2124 if (true_vifi >= 0 && mrt->mroute_do_assert &&
2130 (mrt->mroute_do_pim ||
2136 ip6mr_cache_report(mrt, skb, true_vifi, MRT6MSG_WRONGMIF);
2142 mrt->vif_table[vif].pkt_in++;
2143 mrt->vif_table[vif].bytes_in += skb->len;
2171 ip6mr_forward2(net, mrt, skb2, psend);
2178 ip6mr_forward2(net, mrt, skb, psend);
2195 struct mr_table *mrt;
2215 err = ip6mr_fib_lookup(net, &fl6, &mrt);
2222 cache = ip6mr_cache_find(mrt,
2225 int vif = ip6mr_find_vif(mrt, dev);
2228 cache = ip6mr_cache_find_any(mrt,
2239 vif = ip6mr_find_vif(mrt, dev);
2241 int err = ip6mr_cache_unresolved(mrt, vif, skb, dev);
2251 ip6_mr_forward(net, mrt, dev, skb, cache);
2262 struct mr_table *mrt;
2266 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
2267 if (!mrt)
2271 cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
2273 int vif = ip6mr_find_vif(mrt, skb->dev);
2276 cache = ip6mr_cache_find_any(mrt, &rt->rt6i_dst.addr,
2287 if (!dev || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
2317 err = ip6mr_cache_unresolved(mrt, vif, skb2, dev);
2323 err = mr_fill_mroute(mrt, skb, &cache->_c, rtm);
2328 static int ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2345 rtm->rtm_table = mrt->id;
2346 if (nla_put_u32(skb, RTA_TABLE, mrt->id))
2359 err = mr_fill_mroute(mrt, skb, &c->_c, rtm);
2372 static int _ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2376 return ip6mr_fill_mroute(mrt, skb, portid, seq, (struct mfc6_cache *)c,
2401 static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
2404 struct net *net = read_pnet(&mrt->net);
2408 skb = nlmsg_new(mr6_msgsize(mfc->_c.mfc_parent >= MAXMIFS, mrt->maxvif),
2413 err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0);
2443 static void mrt6msg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt)
2445 struct net *net = read_pnet(&mrt->net);
2505 struct mr_table *mrt;
2507 mrt = ip6mr_get_table(sock_net(skb->sk), filter.table_id);
2508 if (!mrt) {
2515 err = mr_table_dump(mrt, skb, cb, _ip6mr_fill_mroute,