aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@redhat.com>2014-12-31 13:56:18 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-31 18:25:54 -0500
commit98293e8d2f51976d5f790400859a517c0f7cb598 (patch)
treea2ed6ec3f6be7d4721808474c4a62b3c1c5b6771 /net/ipv4
parente9b44019d41a5cf41de43e895a5ed38b19a59b5b (diff)
fib_trie: Use unsigned long for anything dealing with a shift by bits
This change makes it so that anything that can be shifted by, or compared to a value shifted by bits is updated to be an unsigned long. This is mostly a precaution against an insanely huge address space that somehow starts coming close to the 2^32 root node size which would require something like 1.5 billion addresses. I chose unsigned long instead of unsigned long long since I do not believe it is possible to allocate a 32 bit tnode on a 32 bit system as the memory consumed would be 16GB + 28B which exceeds the addressible space for any one process. Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_trie.c53
1 files changed, 26 insertions, 27 deletions
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 9d675486b38c..28a3065470bc 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -146,8 +146,8 @@ struct trie {
146#endif 146#endif
147}; 147};
148 148
149static void tnode_put_child_reorg(struct tnode *tn, int i, struct tnode *n, 149static void tnode_put_child_reorg(struct tnode *tn, unsigned long i,
150 int wasfull); 150 struct tnode *n, int wasfull);
151static struct tnode *resize(struct trie *t, struct tnode *tn); 151static struct tnode *resize(struct trie *t, struct tnode *tn);
152static struct tnode *inflate(struct trie *t, struct tnode *tn); 152static struct tnode *inflate(struct trie *t, struct tnode *tn);
153static struct tnode *halve(struct trie *t, struct tnode *tn); 153static struct tnode *halve(struct trie *t, struct tnode *tn);
@@ -183,25 +183,23 @@ static inline void node_set_parent(struct tnode *n, struct tnode *tp)
183/* This provides us with the number of children in this node, in the case of a 183/* This provides us with the number of children in this node, in the case of a
184 * leaf this will return 0 meaning none of the children are accessible. 184 * leaf this will return 0 meaning none of the children are accessible.
185 */ 185 */
186static inline int tnode_child_length(const struct tnode *tn) 186static inline unsigned long tnode_child_length(const struct tnode *tn)
187{ 187{
188 return (1ul << tn->bits) & ~(1ul); 188 return (1ul << tn->bits) & ~(1ul);
189} 189}
190 190
191/* 191/* caller must hold RTNL */
192 * caller must hold RTNL 192static inline struct tnode *tnode_get_child(const struct tnode *tn,
193 */ 193 unsigned long i)
194static inline struct tnode *tnode_get_child(const struct tnode *tn, unsigned int i)
195{ 194{
196 BUG_ON(i >= tnode_child_length(tn)); 195 BUG_ON(i >= tnode_child_length(tn));
197 196
198 return rtnl_dereference(tn->child[i]); 197 return rtnl_dereference(tn->child[i]);
199} 198}
200 199
201/* 200/* caller must hold RCU read lock or RTNL */
202 * caller must hold RCU read lock or RTNL 201static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn,
203 */ 202 unsigned long i)
204static inline struct tnode *tnode_get_child_rcu(const struct tnode *tn, unsigned int i)
205{ 203{
206 BUG_ON(i >= tnode_child_length(tn)); 204 BUG_ON(i >= tnode_child_length(tn));
207 205
@@ -400,7 +398,7 @@ static inline int tnode_full(const struct tnode *tn, const struct tnode *n)
400 return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n); 398 return n && ((n->pos + n->bits) == tn->pos) && IS_TNODE(n);
401} 399}
402 400
403static inline void put_child(struct tnode *tn, int i, 401static inline void put_child(struct tnode *tn, unsigned long i,
404 struct tnode *n) 402 struct tnode *n)
405{ 403{
406 tnode_put_child_reorg(tn, i, n, -1); 404 tnode_put_child_reorg(tn, i, n, -1);
@@ -411,13 +409,13 @@ static inline void put_child(struct tnode *tn, int i,
411 * Update the value of full_children and empty_children. 409 * Update the value of full_children and empty_children.
412 */ 410 */
413 411
414static void tnode_put_child_reorg(struct tnode *tn, int i, struct tnode *n, 412static void tnode_put_child_reorg(struct tnode *tn, unsigned long i,
415 int wasfull) 413 struct tnode *n, int wasfull)
416{ 414{
417 struct tnode *chi = rtnl_dereference(tn->child[i]); 415 struct tnode *chi = rtnl_dereference(tn->child[i]);
418 int isfull; 416 int isfull;
419 417
420 BUG_ON(i >= 1<<tn->bits); 418 BUG_ON(i >= tnode_child_length(tn));
421 419
422 /* update emptyChildren */ 420 /* update emptyChildren */
423 if (n == NULL && chi != NULL) 421 if (n == NULL && chi != NULL)
@@ -607,10 +605,10 @@ no_children:
607static void tnode_clean_free(struct tnode *tn) 605static void tnode_clean_free(struct tnode *tn)
608{ 606{
609 struct tnode *tofree; 607 struct tnode *tofree;
610 int i; 608 unsigned long i;
611 609
612 for (i = 0; i < tnode_child_length(tn); i++) { 610 for (i = 0; i < tnode_child_length(tn); i++) {
613 tofree = rtnl_dereference(tn->child[i]); 611 tofree = tnode_get_child(tn, i);
614 if (tofree) 612 if (tofree)
615 node_free(tofree); 613 node_free(tofree);
616 } 614 }
@@ -619,10 +617,10 @@ static void tnode_clean_free(struct tnode *tn)
619 617
620static struct tnode *inflate(struct trie *t, struct tnode *oldtnode) 618static struct tnode *inflate(struct trie *t, struct tnode *oldtnode)
621{ 619{
622 int olen = tnode_child_length(oldtnode); 620 unsigned long olen = tnode_child_length(oldtnode);
623 struct tnode *tn; 621 struct tnode *tn;
622 unsigned long i;
624 t_key m; 623 t_key m;
625 int i;
626 624
627 pr_debug("In inflate\n"); 625 pr_debug("In inflate\n");
628 626
@@ -664,7 +662,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *oldtnode)
664 for (i = 0; i < olen; i++) { 662 for (i = 0; i < olen; i++) {
665 struct tnode *inode = tnode_get_child(oldtnode, i); 663 struct tnode *inode = tnode_get_child(oldtnode, i);
666 struct tnode *left, *right; 664 struct tnode *left, *right;
667 int size, j; 665 unsigned long size, j;
668 666
669 /* An empty child */ 667 /* An empty child */
670 if (inode == NULL) 668 if (inode == NULL)
@@ -737,7 +735,7 @@ nomem:
737 735
738static struct tnode *halve(struct trie *t, struct tnode *oldtnode) 736static struct tnode *halve(struct trie *t, struct tnode *oldtnode)
739{ 737{
740 int olen = tnode_child_length(oldtnode); 738 unsigned long olen = tnode_child_length(oldtnode);
741 struct tnode *tn, *left, *right; 739 struct tnode *tn, *left, *right;
742 int i; 740 int i;
743 741
@@ -1532,9 +1530,9 @@ static int trie_flush_leaf(struct tnode *l)
1532static struct tnode *leaf_walk_rcu(struct tnode *p, struct tnode *c) 1530static struct tnode *leaf_walk_rcu(struct tnode *p, struct tnode *c)
1533{ 1531{
1534 do { 1532 do {
1535 t_key idx = c ? idx = get_index(c->key, p) + 1 : 0; 1533 unsigned long idx = c ? idx = get_index(c->key, p) + 1 : 0;
1536 1534
1537 while (idx < 1u << p->bits) { 1535 while (idx < tnode_child_length(p)) {
1538 c = tnode_get_child_rcu(p, idx++); 1536 c = tnode_get_child_rcu(p, idx++);
1539 if (!c) 1537 if (!c)
1540 continue; 1538 continue;
@@ -1786,8 +1784,8 @@ struct fib_trie_iter {
1786 1784
1787static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter) 1785static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter)
1788{ 1786{
1787 unsigned long cindex = iter->index;
1789 struct tnode *tn = iter->tnode; 1788 struct tnode *tn = iter->tnode;
1790 unsigned int cindex = iter->index;
1791 struct tnode *p; 1789 struct tnode *p;
1792 1790
1793 /* A single entry routing table */ 1791 /* A single entry routing table */
@@ -1797,7 +1795,7 @@ static struct tnode *fib_trie_get_next(struct fib_trie_iter *iter)
1797 pr_debug("get_next iter={node=%p index=%d depth=%d}\n", 1795 pr_debug("get_next iter={node=%p index=%d depth=%d}\n",
1798 iter->tnode, iter->index, iter->depth); 1796 iter->tnode, iter->index, iter->depth);
1799rescan: 1797rescan:
1800 while (cindex < (1<<tn->bits)) { 1798 while (cindex < tnode_child_length(tn)) {
1801 struct tnode *n = tnode_get_child_rcu(tn, cindex); 1799 struct tnode *n = tnode_get_child_rcu(tn, cindex);
1802 1800
1803 if (n) { 1801 if (n) {
@@ -1874,15 +1872,16 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s)
1874 hlist_for_each_entry_rcu(li, &n->list, hlist) 1872 hlist_for_each_entry_rcu(li, &n->list, hlist)
1875 ++s->prefixes; 1873 ++s->prefixes;
1876 } else { 1874 } else {
1877 int i; 1875 unsigned long i;
1878 1876
1879 s->tnodes++; 1877 s->tnodes++;
1880 if (n->bits < MAX_STAT_DEPTH) 1878 if (n->bits < MAX_STAT_DEPTH)
1881 s->nodesizes[n->bits]++; 1879 s->nodesizes[n->bits]++;
1882 1880
1883 for (i = 0; i < tnode_child_length(n); i++) 1881 for (i = 0; i < tnode_child_length(n); i++) {
1884 if (!rcu_access_pointer(n->child[i])) 1882 if (!rcu_access_pointer(n->child[i]))
1885 s->nullpointers++; 1883 s->nullpointers++;
1884 }
1886 } 1885 }
1887 } 1886 }
1888 rcu_read_unlock(); 1887 rcu_read_unlock();