summaryrefslogtreecommitdiff
path: root/net/ipv6/ip6mr.c
diff options
context:
space:
mode:
authorYuval Mintz <yuvalm@mellanox.com>2018-02-28 23:29:35 +0200
committerDavid S. Miller <davem@davemloft.net>2018-03-01 13:13:23 -0500
commit845c9a7ae7f5342ba42280c3a2f2aa92bce641d7 (patch)
tree7fea1a929b16c9a216b7d0ccd78e389a01db1a39 /net/ipv6/ip6mr.c
parent494fff56379c4ad5b8fe36a5b7ffede4044ca7bb (diff)
downloadlwn-845c9a7ae7f5342ba42280c3a2f2aa92bce641d7.tar.gz
lwn-845c9a7ae7f5342ba42280c3a2f2aa92bce641d7.zip
ipmr, ip6mr: Unite logic for searching in MFC cache
ipmr and ip6mr utilize the exact same methods for searching the hashed resolved connections, difference being only in the construction of the hash comparison key. In order to unite the flow, introduce an mr_table operation set that would contain the protocol specific information required for common flows, in this case - the hash parameters and a comparison key representing a (*,*) route. Signed-off-by: Yuval Mintz <yuvalm@mellanox.com> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6mr.c')
-rw-r--r--net/ipv6/ip6mr.c74
1 files changed, 17 insertions, 57 deletions
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 3fe254f9f9b7..ea902a952fb6 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -302,6 +302,16 @@ static void ip6mr_new_table_set(struct mr_table *mrt,
#endif
}
+static struct mfc6_cache_cmp_arg ip6mr_mr_table_ops_cmparg_any = {
+ .mf6c_origin = IN6ADDR_ANY_INIT,
+ .mf6c_mcastgrp = IN6ADDR_ANY_INIT,
+};
+
+static struct mr_table_ops ip6mr_mr_table_ops = {
+ .rht_params = &ip6mr_rht_params,
+ .cmparg_any = &ip6mr_mr_table_ops_cmparg_any,
+};
+
static struct mr_table *ip6mr_new_table(struct net *net, u32 id)
{
struct mr_table *mrt;
@@ -310,7 +320,7 @@ static struct mr_table *ip6mr_new_table(struct net *net, u32 id)
if (mrt)
return mrt;
- return mr_table_alloc(net, id, &ip6mr_rht_params,
+ return mr_table_alloc(net, id, &ip6mr_mr_table_ops,
ipmr_expire_process, ip6mr_new_table_set);
}
@@ -988,33 +998,8 @@ static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt,
.mf6c_origin = *origin,
.mf6c_mcastgrp = *mcastgrp,
};
- struct rhlist_head *tmp, *list;
- struct mr_mfc *c;
-
- list = rhltable_lookup(&mrt->mfc_hash, &arg, ip6mr_rht_params);
- rhl_for_each_entry_rcu(c, tmp, list, mnode)
- return (struct mfc6_cache *)c;
- return NULL;
-}
-
-/* Look for a (*,*,oif) entry */
-static struct mfc6_cache *ip6mr_cache_find_any_parent(struct mr_table *mrt,
- mifi_t mifi)
-{
- struct mfc6_cache_cmp_arg arg = {
- .mf6c_origin = in6addr_any,
- .mf6c_mcastgrp = in6addr_any,
- };
- struct rhlist_head *tmp, *list;
- struct mr_mfc *c;
-
- list = rhltable_lookup(&mrt->mfc_hash, &arg, ip6mr_rht_params);
- rhl_for_each_entry_rcu(c, tmp, list, mnode)
- if (c->mfc_un.res.ttls[mifi] < 255)
- return (struct mfc6_cache *)c;
-
- return NULL;
+ return mr_mfc_find(mrt, &arg);
}
/* Look for a (*,G) entry */
@@ -1026,26 +1011,10 @@ static struct mfc6_cache *ip6mr_cache_find_any(struct mr_table *mrt,
.mf6c_origin = in6addr_any,
.mf6c_mcastgrp = *mcastgrp,
};
- struct rhlist_head *tmp, *list;
- struct mr_mfc *c;
- struct mfc6_cache *proxy;
if (ipv6_addr_any(mcastgrp))
- goto skip;
-
- list = rhltable_lookup(&mrt->mfc_hash, &arg, ip6mr_rht_params);
- rhl_for_each_entry_rcu(c, tmp, list, mnode) {
- if (c->mfc_un.res.ttls[mifi] < 255)
- return (struct mfc6_cache *)c;
-
- /* It's ok if the mifi is part of the static tree */
- proxy = ip6mr_cache_find_any_parent(mrt, c->mfc_parent);
- if (proxy && proxy->_c.mfc_un.res.ttls[mifi] < 255)
- return (struct mfc6_cache *)c;
- }
-
-skip:
- return ip6mr_cache_find_any_parent(mrt, mifi);
+ return mr_mfc_find_any_parent(mrt, mifi);
+ return mr_mfc_find_any(mrt, mifi, &arg);
}
/* Look for a (S,G,iif) entry if parent != -1 */
@@ -1059,20 +1028,11 @@ ip6mr_cache_find_parent(struct mr_table *mrt,
.mf6c_origin = *origin,
.mf6c_mcastgrp = *mcastgrp,
};
- struct rhlist_head *tmp, *list;
- struct mr_mfc *c;
-
- list = rhltable_lookup(&mrt->mfc_hash, &arg, ip6mr_rht_params);
- rhl_for_each_entry_rcu(c, tmp, list, mnode)
- if (parent == -1 || parent == c->mfc_parent)
- return (struct mfc6_cache *)c;
- return NULL;
+ return mr_mfc_find_parent(mrt, &arg, parent);
}
-/*
- * Allocate a multicast cache entry
- */
+/* Allocate a multicast cache entry */
static struct mfc6_cache *ip6mr_cache_alloc(void)
{
struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
@@ -2107,7 +2067,7 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
* interface is part of the static tree.
*/
rcu_read_lock();
- cache_proxy = ip6mr_cache_find_any_parent(mrt, vif);
+ cache_proxy = mr_mfc_find_any_parent(mrt, vif);
if (cache_proxy &&
cache_proxy->_c.mfc_un.res.ttls[true_vifi] < 255) {
rcu_read_unlock();