diff options
author | Benjamin Thery <benjamin.thery@bull.net> | 2009-01-21 23:56:18 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-22 16:57:38 -0500 |
commit | 2bb8b26c3ea8bde1943dc5cd4dda2dc9f48fb281 (patch) | |
tree | dacd8256827d6539ff79162cbf8fad2873835126 /net | |
parent | 5c0a66f5f3c9c59e2c341400048e2cff768e67a9 (diff) |
netns: ipmr: dynamically allocate mfc_cache_array
Preliminary work to make IPv4 multicast routing netns-aware.
Dynamically allocate IPv4 multicast forwarding cache, mfc_cache_array,
and move it to struct netns_ipv4.
At the moment, mfc_cache_array is only referenced in init_net.
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ipmr.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8428a0fb5c10..35b868dd3bfd 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -82,8 +82,6 @@ static DEFINE_RWLOCK(mrt_lock); | |||
82 | static int mroute_do_assert; /* Set in PIM assert */ | 82 | static int mroute_do_assert; /* Set in PIM assert */ |
83 | static int mroute_do_pim; | 83 | static int mroute_do_pim; |
84 | 84 | ||
85 | static struct mfc_cache *mfc_cache_array[MFC_LINES]; /* Forwarding cache */ | ||
86 | |||
87 | static struct mfc_cache *mfc_unres_queue; /* Queue of unresolved entries */ | 85 | static struct mfc_cache *mfc_unres_queue; /* Queue of unresolved entries */ |
88 | static atomic_t cache_resolve_queue_len; /* Size of unresolved */ | 86 | static atomic_t cache_resolve_queue_len; /* Size of unresolved */ |
89 | 87 | ||
@@ -524,7 +522,7 @@ static struct mfc_cache *ipmr_cache_find(__be32 origin, __be32 mcastgrp) | |||
524 | int line = MFC_HASH(mcastgrp, origin); | 522 | int line = MFC_HASH(mcastgrp, origin); |
525 | struct mfc_cache *c; | 523 | struct mfc_cache *c; |
526 | 524 | ||
527 | for (c=mfc_cache_array[line]; c; c = c->next) { | 525 | for (c = init_net.ipv4.mfc_cache_array[line]; c; c = c->next) { |
528 | if (c->mfc_origin==origin && c->mfc_mcastgrp==mcastgrp) | 526 | if (c->mfc_origin==origin && c->mfc_mcastgrp==mcastgrp) |
529 | break; | 527 | break; |
530 | } | 528 | } |
@@ -764,7 +762,8 @@ static int ipmr_mfc_delete(struct mfcctl *mfc) | |||
764 | 762 | ||
765 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); | 763 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); |
766 | 764 | ||
767 | for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) { | 765 | for (cp = &init_net.ipv4.mfc_cache_array[line]; |
766 | (c = *cp) != NULL; cp = &c->next) { | ||
768 | if (c->mfc_origin == mfc->mfcc_origin.s_addr && | 767 | if (c->mfc_origin == mfc->mfcc_origin.s_addr && |
769 | c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { | 768 | c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { |
770 | write_lock_bh(&mrt_lock); | 769 | write_lock_bh(&mrt_lock); |
@@ -785,7 +784,8 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock) | |||
785 | 784 | ||
786 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); | 785 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); |
787 | 786 | ||
788 | for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) { | 787 | for (cp = &init_net.ipv4.mfc_cache_array[line]; |
788 | (c = *cp) != NULL; cp = &c->next) { | ||
789 | if (c->mfc_origin == mfc->mfcc_origin.s_addr && | 789 | if (c->mfc_origin == mfc->mfcc_origin.s_addr && |
790 | c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) | 790 | c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) |
791 | break; | 791 | break; |
@@ -816,8 +816,8 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock) | |||
816 | c->mfc_flags |= MFC_STATIC; | 816 | c->mfc_flags |= MFC_STATIC; |
817 | 817 | ||
818 | write_lock_bh(&mrt_lock); | 818 | write_lock_bh(&mrt_lock); |
819 | c->next = mfc_cache_array[line]; | 819 | c->next = init_net.ipv4.mfc_cache_array[line]; |
820 | mfc_cache_array[line] = c; | 820 | init_net.ipv4.mfc_cache_array[line] = c; |
821 | write_unlock_bh(&mrt_lock); | 821 | write_unlock_bh(&mrt_lock); |
822 | 822 | ||
823 | /* | 823 | /* |
@@ -866,7 +866,7 @@ static void mroute_clean_tables(struct sock *sk) | |||
866 | for (i=0; i<MFC_LINES; i++) { | 866 | for (i=0; i<MFC_LINES; i++) { |
867 | struct mfc_cache *c, **cp; | 867 | struct mfc_cache *c, **cp; |
868 | 868 | ||
869 | cp = &mfc_cache_array[i]; | 869 | cp = &init_net.ipv4.mfc_cache_array[i]; |
870 | while ((c = *cp) != NULL) { | 870 | while ((c = *cp) != NULL) { |
871 | if (c->mfc_flags&MFC_STATIC) { | 871 | if (c->mfc_flags&MFC_STATIC) { |
872 | cp = &c->next; | 872 | cp = &c->next; |
@@ -1767,10 +1767,11 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos) | |||
1767 | { | 1767 | { |
1768 | struct mfc_cache *mfc; | 1768 | struct mfc_cache *mfc; |
1769 | 1769 | ||
1770 | it->cache = mfc_cache_array; | 1770 | it->cache = init_net.ipv4.mfc_cache_array; |
1771 | read_lock(&mrt_lock); | 1771 | read_lock(&mrt_lock); |
1772 | for (it->ct = 0; it->ct < MFC_LINES; it->ct++) | 1772 | for (it->ct = 0; it->ct < MFC_LINES; it->ct++) |
1773 | for (mfc = mfc_cache_array[it->ct]; mfc; mfc = mfc->next) | 1773 | for (mfc = init_net.ipv4.mfc_cache_array[it->ct]; |
1774 | mfc; mfc = mfc->next) | ||
1774 | if (pos-- == 0) | 1775 | if (pos-- == 0) |
1775 | return mfc; | 1776 | return mfc; |
1776 | read_unlock(&mrt_lock); | 1777 | read_unlock(&mrt_lock); |
@@ -1812,10 +1813,10 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1812 | if (it->cache == &mfc_unres_queue) | 1813 | if (it->cache == &mfc_unres_queue) |
1813 | goto end_of_list; | 1814 | goto end_of_list; |
1814 | 1815 | ||
1815 | BUG_ON(it->cache != mfc_cache_array); | 1816 | BUG_ON(it->cache != init_net.ipv4.mfc_cache_array); |
1816 | 1817 | ||
1817 | while (++it->ct < MFC_LINES) { | 1818 | while (++it->ct < MFC_LINES) { |
1818 | mfc = mfc_cache_array[it->ct]; | 1819 | mfc = init_net.ipv4.mfc_cache_array[it->ct]; |
1819 | if (mfc) | 1820 | if (mfc) |
1820 | return mfc; | 1821 | return mfc; |
1821 | } | 1822 | } |
@@ -1843,7 +1844,7 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) | |||
1843 | 1844 | ||
1844 | if (it->cache == &mfc_unres_queue) | 1845 | if (it->cache == &mfc_unres_queue) |
1845 | spin_unlock_bh(&mfc_unres_lock); | 1846 | spin_unlock_bh(&mfc_unres_lock); |
1846 | else if (it->cache == mfc_cache_array) | 1847 | else if (it->cache == init_net.ipv4.mfc_cache_array) |
1847 | read_unlock(&mrt_lock); | 1848 | read_unlock(&mrt_lock); |
1848 | } | 1849 | } |
1849 | 1850 | ||
@@ -1929,12 +1930,26 @@ static int __net_init ipmr_net_init(struct net *net) | |||
1929 | err = -ENOMEM; | 1930 | err = -ENOMEM; |
1930 | goto fail; | 1931 | goto fail; |
1931 | } | 1932 | } |
1933 | |||
1934 | /* Forwarding cache */ | ||
1935 | net->ipv4.mfc_cache_array = kcalloc(MFC_LINES, | ||
1936 | sizeof(struct mfc_cache *), | ||
1937 | GFP_KERNEL); | ||
1938 | if (!net->ipv4.mfc_cache_array) { | ||
1939 | err = -ENOMEM; | ||
1940 | goto fail_mfc_cache; | ||
1941 | } | ||
1942 | return 0; | ||
1943 | |||
1944 | fail_mfc_cache: | ||
1945 | kfree(net->ipv4.vif_table); | ||
1932 | fail: | 1946 | fail: |
1933 | return err; | 1947 | return err; |
1934 | } | 1948 | } |
1935 | 1949 | ||
1936 | static void __net_exit ipmr_net_exit(struct net *net) | 1950 | static void __net_exit ipmr_net_exit(struct net *net) |
1937 | { | 1951 | { |
1952 | kfree(net->ipv4.mfc_cache_array); | ||
1938 | kfree(net->ipv4.vif_table); | 1953 | kfree(net->ipv4.vif_table); |
1939 | } | 1954 | } |
1940 | 1955 | ||