diff options
Diffstat (limited to 'net/ipv6/ip6_fib.c')
-rw-r--r-- | net/ipv6/ip6_fib.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index b6a585909d35..4076a0b14b20 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -134,9 +134,9 @@ static __inline__ u32 fib6_new_sernum(void) | |||
134 | # define BITOP_BE32_SWIZZLE 0 | 134 | # define BITOP_BE32_SWIZZLE 0 |
135 | #endif | 135 | #endif |
136 | 136 | ||
137 | static __inline__ __be32 addr_bit_set(void *token, int fn_bit) | 137 | static __inline__ __be32 addr_bit_set(const void *token, int fn_bit) |
138 | { | 138 | { |
139 | __be32 *addr = token; | 139 | const __be32 *addr = token; |
140 | /* | 140 | /* |
141 | * Here, | 141 | * Here, |
142 | * 1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f) | 142 | * 1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f) |
@@ -260,10 +260,10 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id) | |||
260 | return net->ipv6.fib6_main_tbl; | 260 | return net->ipv6.fib6_main_tbl; |
261 | } | 261 | } |
262 | 262 | ||
263 | struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, | 263 | struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, |
264 | int flags, pol_lookup_t lookup) | 264 | int flags, pol_lookup_t lookup) |
265 | { | 265 | { |
266 | return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl, flags); | 266 | return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl6, flags); |
267 | } | 267 | } |
268 | 268 | ||
269 | static void __net_init fib6_tables_init(struct net *net) | 269 | static void __net_init fib6_tables_init(struct net *net) |
@@ -394,10 +394,11 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) | |||
394 | arg.net = net; | 394 | arg.net = net; |
395 | w->args = &arg; | 395 | w->args = &arg; |
396 | 396 | ||
397 | rcu_read_lock(); | ||
397 | for (h = s_h; h < FIB6_TABLE_HASHSZ; h++, s_e = 0) { | 398 | for (h = s_h; h < FIB6_TABLE_HASHSZ; h++, s_e = 0) { |
398 | e = 0; | 399 | e = 0; |
399 | head = &net->ipv6.fib_table_hash[h]; | 400 | head = &net->ipv6.fib_table_hash[h]; |
400 | hlist_for_each_entry(tb, node, head, tb6_hlist) { | 401 | hlist_for_each_entry_rcu(tb, node, head, tb6_hlist) { |
401 | if (e < s_e) | 402 | if (e < s_e) |
402 | goto next; | 403 | goto next; |
403 | res = fib6_dump_table(tb, skb, cb); | 404 | res = fib6_dump_table(tb, skb, cb); |
@@ -408,6 +409,7 @@ next: | |||
408 | } | 409 | } |
409 | } | 410 | } |
410 | out: | 411 | out: |
412 | rcu_read_unlock(); | ||
411 | cb->args[1] = e; | 413 | cb->args[1] = e; |
412 | cb->args[0] = h; | 414 | cb->args[0] = h; |
413 | 415 | ||
@@ -822,7 +824,7 @@ st_failure: | |||
822 | 824 | ||
823 | struct lookup_args { | 825 | struct lookup_args { |
824 | int offset; /* key offset on rt6_info */ | 826 | int offset; /* key offset on rt6_info */ |
825 | struct in6_addr *addr; /* search key */ | 827 | const struct in6_addr *addr; /* search key */ |
826 | }; | 828 | }; |
827 | 829 | ||
828 | static struct fib6_node * fib6_lookup_1(struct fib6_node *root, | 830 | static struct fib6_node * fib6_lookup_1(struct fib6_node *root, |
@@ -881,8 +883,8 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root, | |||
881 | return NULL; | 883 | return NULL; |
882 | } | 884 | } |
883 | 885 | ||
884 | struct fib6_node * fib6_lookup(struct fib6_node *root, struct in6_addr *daddr, | 886 | struct fib6_node * fib6_lookup(struct fib6_node *root, const struct in6_addr *daddr, |
885 | struct in6_addr *saddr) | 887 | const struct in6_addr *saddr) |
886 | { | 888 | { |
887 | struct fib6_node *fn; | 889 | struct fib6_node *fn; |
888 | struct lookup_args args[] = { | 890 | struct lookup_args args[] = { |
@@ -916,7 +918,7 @@ struct fib6_node * fib6_lookup(struct fib6_node *root, struct in6_addr *daddr, | |||
916 | 918 | ||
917 | 919 | ||
918 | static struct fib6_node * fib6_locate_1(struct fib6_node *root, | 920 | static struct fib6_node * fib6_locate_1(struct fib6_node *root, |
919 | struct in6_addr *addr, | 921 | const struct in6_addr *addr, |
920 | int plen, int offset) | 922 | int plen, int offset) |
921 | { | 923 | { |
922 | struct fib6_node *fn; | 924 | struct fib6_node *fn; |
@@ -946,8 +948,8 @@ static struct fib6_node * fib6_locate_1(struct fib6_node *root, | |||
946 | } | 948 | } |
947 | 949 | ||
948 | struct fib6_node * fib6_locate(struct fib6_node *root, | 950 | struct fib6_node * fib6_locate(struct fib6_node *root, |
949 | struct in6_addr *daddr, int dst_len, | 951 | const struct in6_addr *daddr, int dst_len, |
950 | struct in6_addr *saddr, int src_len) | 952 | const struct in6_addr *saddr, int src_len) |
951 | { | 953 | { |
952 | struct fib6_node *fn; | 954 | struct fib6_node *fn; |
953 | 955 | ||
@@ -1500,15 +1502,18 @@ static void fib6_gc_timer_cb(unsigned long arg) | |||
1500 | 1502 | ||
1501 | static int __net_init fib6_net_init(struct net *net) | 1503 | static int __net_init fib6_net_init(struct net *net) |
1502 | { | 1504 | { |
1505 | size_t size = sizeof(struct hlist_head) * FIB6_TABLE_HASHSZ; | ||
1506 | |||
1503 | setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); | 1507 | setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); |
1504 | 1508 | ||
1505 | net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); | 1509 | net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); |
1506 | if (!net->ipv6.rt6_stats) | 1510 | if (!net->ipv6.rt6_stats) |
1507 | goto out_timer; | 1511 | goto out_timer; |
1508 | 1512 | ||
1509 | net->ipv6.fib_table_hash = kcalloc(FIB6_TABLE_HASHSZ, | 1513 | /* Avoid false sharing : Use at least a full cache line */ |
1510 | sizeof(*net->ipv6.fib_table_hash), | 1514 | size = max_t(size_t, size, L1_CACHE_BYTES); |
1511 | GFP_KERNEL); | 1515 | |
1516 | net->ipv6.fib_table_hash = kzalloc(size, GFP_KERNEL); | ||
1512 | if (!net->ipv6.fib_table_hash) | 1517 | if (!net->ipv6.fib_table_hash) |
1513 | goto out_rt6_stats; | 1518 | goto out_rt6_stats; |
1514 | 1519 | ||