aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/ipv6.h1
-rw-r--r--net/ipv6/ip6mr.c47
2 files changed, 32 insertions, 16 deletions
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 4ab0cb01a7a5..14c1bbe68a85 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -57,6 +57,7 @@ struct netns_ipv6 {
57 struct sock *igmp_sk; 57 struct sock *igmp_sk;
58#ifdef CONFIG_IPV6_MROUTE 58#ifdef CONFIG_IPV6_MROUTE
59 struct sock *mroute6_sk; 59 struct sock *mroute6_sk;
60 struct mfc6_cache **mfc6_cache_array;
60 struct mif_device *vif6_table; 61 struct mif_device *vif6_table;
61 int maxvif; 62 int maxvif;
62#endif 63#endif
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index fab5aba28a20..287e526ba036 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -68,8 +68,6 @@ static int mroute_do_pim;
68#define mroute_do_pim 0 68#define mroute_do_pim 0
69#endif 69#endif
70 70
71static struct mfc6_cache *mfc6_cache_array[MFC6_LINES]; /* Forwarding cache */
72
73static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */ 71static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */
74static atomic_t cache_resolve_queue_len; /* Size of unresolved */ 72static atomic_t cache_resolve_queue_len; /* Size of unresolved */
75 73
@@ -109,10 +107,11 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos)
109{ 107{
110 struct mfc6_cache *mfc; 108 struct mfc6_cache *mfc;
111 109
112 it->cache = mfc6_cache_array; 110 it->cache = init_net.ipv6.mfc6_cache_array;
113 read_lock(&mrt_lock); 111 read_lock(&mrt_lock);
114 for (it->ct = 0; it->ct < ARRAY_SIZE(mfc6_cache_array); it->ct++) 112 for (it->ct = 0; it->ct < MFC6_LINES; it->ct++)
115 for (mfc = mfc6_cache_array[it->ct]; mfc; mfc = mfc->next) 113 for (mfc = init_net.ipv6.mfc6_cache_array[it->ct];
114 mfc; mfc = mfc->next)
116 if (pos-- == 0) 115 if (pos-- == 0)
117 return mfc; 116 return mfc;
118 read_unlock(&mrt_lock); 117 read_unlock(&mrt_lock);
@@ -243,10 +242,10 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
243 if (it->cache == &mfc_unres_queue) 242 if (it->cache == &mfc_unres_queue)
244 goto end_of_list; 243 goto end_of_list;
245 244
246 BUG_ON(it->cache != mfc6_cache_array); 245 BUG_ON(it->cache != init_net.ipv6.mfc6_cache_array);
247 246
248 while (++it->ct < ARRAY_SIZE(mfc6_cache_array)) { 247 while (++it->ct < MFC6_LINES) {
249 mfc = mfc6_cache_array[it->ct]; 248 mfc = init_net.ipv6.mfc6_cache_array[it->ct];
250 if (mfc) 249 if (mfc)
251 return mfc; 250 return mfc;
252 } 251 }
@@ -274,7 +273,7 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
274 273
275 if (it->cache == &mfc_unres_queue) 274 if (it->cache == &mfc_unres_queue)
276 spin_unlock_bh(&mfc_unres_lock); 275 spin_unlock_bh(&mfc_unres_lock);
277 else if (it->cache == mfc6_cache_array) 276 else if (it->cache == init_net.ipv6.mfc6_cache_array)
278 read_unlock(&mrt_lock); 277 read_unlock(&mrt_lock);
279} 278}
280 279
@@ -680,7 +679,7 @@ static struct mfc6_cache *ip6mr_cache_find(struct in6_addr *origin, struct in6_a
680 int line = MFC6_HASH(mcastgrp, origin); 679 int line = MFC6_HASH(mcastgrp, origin);
681 struct mfc6_cache *c; 680 struct mfc6_cache *c;
682 681
683 for (c = mfc6_cache_array[line]; c; c = c->next) { 682 for (c = init_net.ipv6.mfc6_cache_array[line]; c; c = c->next) {
684 if (ipv6_addr_equal(&c->mf6c_origin, origin) && 683 if (ipv6_addr_equal(&c->mf6c_origin, origin) &&
685 ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp)) 684 ipv6_addr_equal(&c->mf6c_mcastgrp, mcastgrp))
686 break; 685 break;
@@ -925,7 +924,8 @@ static int ip6mr_mfc_delete(struct mf6cctl *mfc)
925 924
926 line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); 925 line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);
927 926
928 for (cp = &mfc6_cache_array[line]; (c = *cp) != NULL; cp = &c->next) { 927 for (cp = &init_net.ipv6.mfc6_cache_array[line];
928 (c = *cp) != NULL; cp = &c->next) {
929 if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && 929 if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
930 ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) { 930 ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) {
931 write_lock_bh(&mrt_lock); 931 write_lock_bh(&mrt_lock);
@@ -978,12 +978,26 @@ static int __net_init ip6mr_net_init(struct net *net)
978 err = -ENOMEM; 978 err = -ENOMEM;
979 goto fail; 979 goto fail;
980 } 980 }
981
982 /* Forwarding cache */
983 net->ipv6.mfc6_cache_array = kcalloc(MFC6_LINES,
984 sizeof(struct mfc6_cache *),
985 GFP_KERNEL);
986 if (!net->ipv6.mfc6_cache_array) {
987 err = -ENOMEM;
988 goto fail_mfc6_cache;
989 }
990 return 0;
991
992fail_mfc6_cache:
993 kfree(net->ipv6.vif6_table);
981fail: 994fail:
982 return err; 995 return err;
983} 996}
984 997
985static void __net_exit ip6mr_net_exit(struct net *net) 998static void __net_exit ip6mr_net_exit(struct net *net)
986{ 999{
1000 kfree(net->ipv6.mfc6_cache_array);
987 kfree(net->ipv6.vif6_table); 1001 kfree(net->ipv6.vif6_table);
988} 1002}
989 1003
@@ -1062,7 +1076,8 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
1062 1076
1063 line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr); 1077 line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);
1064 1078
1065 for (cp = &mfc6_cache_array[line]; (c = *cp) != NULL; cp = &c->next) { 1079 for (cp = &init_net.ipv6.mfc6_cache_array[line];
1080 (c = *cp) != NULL; cp = &c->next) {
1066 if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) && 1081 if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
1067 ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) 1082 ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr))
1068 break; 1083 break;
@@ -1093,8 +1108,8 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
1093 c->mfc_flags |= MFC_STATIC; 1108 c->mfc_flags |= MFC_STATIC;
1094 1109
1095 write_lock_bh(&mrt_lock); 1110 write_lock_bh(&mrt_lock);
1096 c->next = mfc6_cache_array[line]; 1111 c->next = init_net.ipv6.mfc6_cache_array[line];
1097 mfc6_cache_array[line] = c; 1112 init_net.ipv6.mfc6_cache_array[line] = c;
1098 write_unlock_bh(&mrt_lock); 1113 write_unlock_bh(&mrt_lock);
1099 1114
1100 /* 1115 /*
@@ -1140,10 +1155,10 @@ static void mroute_clean_tables(struct sock *sk)
1140 /* 1155 /*
1141 * Wipe the cache 1156 * Wipe the cache
1142 */ 1157 */
1143 for (i = 0; i < ARRAY_SIZE(mfc6_cache_array); i++) { 1158 for (i = 0; i < MFC6_LINES; i++) {
1144 struct mfc6_cache *c, **cp; 1159 struct mfc6_cache *c, **cp;
1145 1160
1146 cp = &mfc6_cache_array[i]; 1161 cp = &init_net.ipv6.mfc6_cache_array[i];
1147 while ((c = *cp) != NULL) { 1162 while ((c = *cp) != NULL) {
1148 if (c->mfc_flags & MFC_STATIC) { 1163 if (c->mfc_flags & MFC_STATIC) {
1149 cp = &c->next; 1164 cp = &c->next;