Lines Matching refs:mrt
80 struct mr6_table *mrt;
83 /* Big lock, protecting vif table, mrt cache and mroute socket state.
109 static void ip6mr_free_table(struct mr6_table *mrt);
111 static int ip6_mr_forward(struct net *net, struct mr6_table *mrt,
113 static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt,
115 static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
119 static void mroute_clean_tables(struct mr6_table *mrt);
123 #define ip6mr_for_each_table(mrt, net) \
124 list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list)
128 struct mr6_table *mrt;
130 ip6mr_for_each_table(mrt, net) {
131 if (mrt->id == id)
132 return mrt;
138 struct mr6_table **mrt)
147 *mrt = res.mrt;
155 struct mr6_table *mrt;
169 mrt = ip6mr_get_table(rule->fr_net, rule->table);
170 if (mrt == NULL)
172 res->mrt = mrt;
224 struct mr6_table *mrt;
233 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
234 if (mrt == NULL) {
247 kfree(mrt);
255 struct mr6_table *mrt, *next;
257 list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) {
258 list_del(&mrt->list);
259 ip6mr_free_table(mrt);
264 #define ip6mr_for_each_table(mrt, net) \
265 for (mrt = net->ipv6.mrt6; mrt; mrt = NULL)
273 struct mr6_table **mrt)
275 *mrt = net->ipv6.mrt6;
293 struct mr6_table *mrt;
296 mrt = ip6mr_get_table(net, id);
297 if (mrt != NULL)
298 return mrt;
300 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
301 if (mrt == NULL)
303 mrt->id = id;
304 write_pnet(&mrt->net, net);
308 INIT_LIST_HEAD(&mrt->mfc6_cache_array[i]);
310 INIT_LIST_HEAD(&mrt->mfc6_unres_queue);
312 setup_timer(&mrt->ipmr_expire_timer, ipmr_expire_process,
313 (unsigned long)mrt);
316 mrt->mroute_reg_vif_num = -1;
319 list_add_tail_rcu(&mrt->list, &net->ipv6.mr6_tables);
321 return mrt;
324 static void ip6mr_free_table(struct mr6_table *mrt)
326 del_timer(&mrt->ipmr_expire_timer);
327 mroute_clean_tables(mrt);
328 kfree(mrt);
335 struct mr6_table *mrt;
344 struct mr6_table *mrt = it->mrt;
349 it->cache = &mrt->mfc6_cache_array[it->ct];
357 it->cache = &mrt->mfc6_unres_queue;
373 struct mr6_table *mrt;
381 struct mr6_table *mrt = iter->mrt;
383 for (iter->ct = 0; iter->ct < mrt->maxvif; ++iter->ct) {
384 if (!MIF_EXISTS(mrt, iter->ct))
387 return &mrt->vif6_table[iter->ct];
397 struct mr6_table *mrt;
399 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
400 if (mrt == NULL)
403 iter->mrt = mrt;
414 struct mr6_table *mrt = iter->mrt;
420 while (++iter->ct < mrt->maxvif) {
421 if (!MIF_EXISTS(mrt, iter->ct))
423 return &mrt->vif6_table[iter->ct];
437 struct mr6_table *mrt = iter->mrt;
448 vif - mrt->vif6_table,
481 struct mr6_table *mrt;
483 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
484 if (mrt == NULL)
487 it->mrt = mrt;
497 struct mr6_table *mrt = it->mrt;
507 if (it->cache == &mrt->mfc6_unres_queue)
510 BUG_ON(it->cache != &mrt->mfc6_cache_array[it->ct]);
513 it->cache = &mrt->mfc6_cache_array[it->ct];
521 it->cache = &mrt->mfc6_unres_queue;
538 struct mr6_table *mrt = it->mrt;
540 if (it->cache == &mrt->mfc6_unres_queue)
542 else if (it->cache == mrt->mfc6_cache_array)
558 struct mr6_table *mrt = it->mrt;
564 if (it->cache != &mrt->mfc6_unres_queue) {
571 if (MIF_EXISTS(mrt, n) &&
618 struct mr6_table *mrt;
646 if (ip6mr_fib_lookup(net, &fl, &mrt) < 0)
648 reg_vif_num = mrt->mroute_reg_vif_num;
652 reg_dev = mrt->vif6_table[reg_vif_num].dev;
687 struct mr6_table *mrt;
695 err = ip6mr_fib_lookup(net, &fl, &mrt);
702 ip6mr_cache_report(mrt, skb, mrt->mroute_reg_vif_num, MRT6MSG_WHOLEPKT);
722 static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt)
727 if (mrt->id == RT6_TABLE_DFLT)
730 sprintf(name, "pim6reg%u", mrt->id);
764 static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
770 if (vifi < 0 || vifi >= mrt->maxvif)
773 v = &mrt->vif6_table[vifi];
785 if (vifi == mrt->mroute_reg_vif_num)
786 mrt->mroute_reg_vif_num = -1;
789 if (vifi + 1 == mrt->maxvif) {
792 if (MIF_EXISTS(mrt, tmp))
795 mrt->maxvif = tmp + 1;
822 static void ip6mr_destroy_unres(struct mr6_table *mrt, struct mfc6_cache *c)
824 struct net *net = read_pnet(&mrt->net);
827 atomic_dec(&mrt->cache_resolve_queue_len);
847 static void ipmr_do_expire_process(struct mr6_table *mrt)
853 list_for_each_entry_safe(c, next, &mrt->mfc6_unres_queue, list) {
863 ip6mr_destroy_unres(mrt, c);
866 if (!list_empty(&mrt->mfc6_unres_queue))
867 mod_timer(&mrt->ipmr_expire_timer, jiffies + expires);
872 struct mr6_table *mrt = (struct mr6_table *)arg;
875 mod_timer(&mrt->ipmr_expire_timer, jiffies + 1);
879 if (!list_empty(&mrt->mfc6_unres_queue))
880 ipmr_do_expire_process(mrt);
887 static void ip6mr_update_thresholds(struct mr6_table *mrt, struct mfc6_cache *cache,
896 for (vifi = 0; vifi < mrt->maxvif; vifi++) {
897 if (MIF_EXISTS(mrt, vifi) &&
908 static int mif6_add(struct net *net, struct mr6_table *mrt,
912 struct mif_device *v = &mrt->vif6_table[vifi];
918 if (MIF_EXISTS(mrt, vifi))
928 if (mrt->mroute_reg_vif_num >= 0)
930 dev = ip6mr_reg_vif(net, mrt);
980 mrt->mroute_reg_vif_num = vifi;
982 if (vifi + 1 > mrt->maxvif)
983 mrt->maxvif = vifi + 1;
988 static struct mfc6_cache *ip6mr_cache_find(struct mr6_table *mrt,
1014 list_for_each_entry(c, &mrt->mfc6_cache_array[line], list)
1067 static void ip6mr_cache_resolve(struct net *net, struct mr6_table *mrt,
1081 if (__ip6mr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) {
1091 ip6_mr_forward(net, mrt, skb, c);
1102 static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt,
1139 msg->im6_mif = mrt->mroute_reg_vif_num;
1174 if (mrt->mroute6_sk == NULL) {
1182 ret = sock_queue_rcv_skb(mrt->mroute6_sk, skb);
1197 ip6mr_cache_unresolved(struct mr6_table *mrt, mifi_t mifi, struct sk_buff *skb)
1204 list_for_each_entry(c, &mrt->mfc6_unres_queue, list) {
1217 if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 ||
1235 err = ip6mr_cache_report(mrt, skb, mifi, MRT6MSG_NOCACHE);
1247 atomic_inc(&mrt->cache_resolve_queue_len);
1248 list_add(&c->list, &mrt->mfc6_unres_queue);
1250 ipmr_do_expire_process(mrt);
1272 static int ip6mr_mfc_delete(struct mr6_table *mrt, struct mf6cctl *mfc)
1279 list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[line], list) {
1298 struct mr6_table *mrt;
1306 ip6mr_for_each_table(mrt, net) {
1307 v = &mrt->vif6_table[0];
1308 for (ct = 0; ct < mrt->maxvif; ct++, v++) {
1310 mif6_delete(mrt, ct, &list);
1413 static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
1434 list_for_each_entry(c, &mrt->mfc6_cache_array[line], list) {
1445 ip6mr_update_thresholds(mrt, c, ttls);
1462 ip6mr_update_thresholds(mrt, c, ttls);
1467 list_add(&c->list, &mrt->mfc6_cache_array[line]);
1476 list_for_each_entry(uc, &mrt->mfc6_unres_queue, list) {
1480 atomic_dec(&mrt->cache_resolve_queue_len);
1485 if (list_empty(&mrt->mfc6_unres_queue))
1486 del_timer(&mrt->ipmr_expire_timer);
1490 ip6mr_cache_resolve(net, mrt, uc, c);
1500 static void mroute_clean_tables(struct mr6_table *mrt)
1509 for (i = 0; i < mrt->maxvif; i++) {
1510 if (!(mrt->vif6_table[i].flags & VIFF_STATIC))
1511 mif6_delete(mrt, i, &list);
1519 list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
1530 if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
1532 list_for_each_entry_safe(c, next, &mrt->mfc6_unres_queue, list) {
1534 ip6mr_destroy_unres(mrt, c);
1540 static int ip6mr_sk_init(struct mr6_table *mrt, struct sock *sk)
1547 if (likely(mrt->mroute6_sk == NULL)) {
1548 mrt->mroute6_sk = sk;
1564 struct mr6_table *mrt;
1567 ip6mr_for_each_table(mrt, net) {
1568 if (sk == mrt->mroute6_sk) {
1570 mrt->mroute6_sk = NULL;
1574 mroute_clean_tables(mrt);
1586 struct mr6_table *mrt;
1593 if (ip6mr_fib_lookup(net, &fl, &mrt) < 0)
1596 return mrt->mroute6_sk;
1613 struct mr6_table *mrt;
1615 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1616 if (mrt == NULL)
1620 if (sk != mrt->mroute6_sk && !capable(CAP_NET_ADMIN))
1632 return ip6mr_sk_init(mrt, sk);
1645 ret = mif6_add(net, mrt, &vif, sk == mrt->mroute6_sk);
1655 ret = mif6_delete(mrt, mifi, NULL);
1671 ret = ip6mr_mfc_delete(mrt, &mfc);
1673 ret = ip6mr_mfc_add(net, mrt, &mfc, sk == mrt->mroute6_sk);
1685 mrt->mroute_do_assert = !!v;
1698 if (v != mrt->mroute_do_pim) {
1699 mrt->mroute_do_pim = v;
1700 mrt->mroute_do_assert = v;
1716 if (sk == mrt->mroute6_sk)
1747 struct mr6_table *mrt;
1749 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1750 if (mrt == NULL)
1759 val = mrt->mroute_do_pim;
1763 val = mrt->mroute_do_assert;
1794 struct mr6_table *mrt;
1796 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1797 if (mrt == NULL)
1804 if (vr.mifi >= mrt->maxvif)
1807 vif = &mrt->vif6_table[vr.mifi];
1808 if (MIF_EXISTS(mrt, vr.mifi)) {
1826 c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
1856 static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
1860 struct mif_device *vif = &mrt->vif6_table[vifi];
1874 ip6mr_cache_report(mrt, skb, vifi, MRT6MSG_WHOLEPKT);
1928 static int ip6mr_find_vif(struct mr6_table *mrt, struct net_device *dev)
1932 for (ct = mrt->maxvif - 1; ct >= 0; ct--) {
1933 if (mrt->vif6_table[ct].dev == dev)
1939 static int ip6_mr_forward(struct net *net, struct mr6_table *mrt,
1977 if (mrt->vif6_table[vif].dev != skb->dev) {
1981 true_vifi = ip6mr_find_vif(mrt, skb->dev);
1983 if (true_vifi >= 0 && mrt->mroute_do_assert &&
1989 (mrt->mroute_do_pim ||
1994 ip6mr_cache_report(mrt, skb, true_vifi, MRT6MSG_WRONGMIF);
1999 mrt->vif6_table[vif].pkt_in++;
2000 mrt->vif6_table[vif].bytes_in += skb->len;
2010 ip6mr_forward2(net, mrt, skb2, cache, psend);
2016 ip6mr_forward2(net, mrt, skb, cache, psend);
2034 struct mr6_table *mrt;
2041 err = ip6mr_fib_lookup(net, &fl, &mrt);
2046 cache = ip6mr_cache_find(mrt,
2055 vif = ip6mr_find_vif(mrt, skb->dev);
2057 int err = ip6mr_cache_unresolved(mrt, vif, skb);
2067 ip6_mr_forward(net, mrt, skb, cache);
2075 static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2087 if (MIF_EXISTS(mrt, c->mf6c_parent))
2088 RTA_PUT(skb, RTA_IIF, 4, &mrt->vif6_table[c->mf6c_parent].dev->ifindex);
2093 if (MIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
2099 nhp->rtnh_ifindex = mrt->vif6_table[ct].dev->ifindex;
2117 struct mr6_table *mrt;
2121 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
2122 if (mrt == NULL)
2126 cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
2140 if (dev == NULL || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
2169 err = ip6mr_cache_unresolved(mrt, vif, skb2);
2178 err = __ip6mr_fill_mroute(mrt, skb, cache, rtm);
2183 static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
2198 rtm->rtm_table = mrt->id;
2199 NLA_PUT_U32(skb, RTA_TABLE, mrt->id);
2207 if (__ip6mr_fill_mroute(mrt, skb, c, rtm) < 0)
2220 struct mr6_table *mrt;
2231 ip6mr_for_each_table(mrt, net) {
2237 list_for_each_entry(mfc, &mrt->mfc6_cache_array[h], list) {
2240 if (ip6mr_fill_mroute(mrt, skb,