aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r--net/ipv4/fib_semantics.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index d71bfbdc0bf4..1e09852df512 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -140,6 +140,27 @@ const struct fib_prop fib_props[RTN_MAX + 1] = {
140 }, 140 },
141}; 141};
142 142
143static void free_nh_exceptions(struct fib_nh *nh)
144{
145 struct fnhe_hash_bucket *hash = nh->nh_exceptions;
146 int i;
147
148 for (i = 0; i < FNHE_HASH_SIZE; i++) {
149 struct fib_nh_exception *fnhe;
150
151 fnhe = rcu_dereference(hash[i].chain);
152 while (fnhe) {
153 struct fib_nh_exception *next;
154
155 next = rcu_dereference(fnhe->fnhe_next);
156 kfree(fnhe);
157
158 fnhe = next;
159 }
160 }
161 kfree(hash);
162}
163
143/* Release a nexthop info record */ 164/* Release a nexthop info record */
144static void free_fib_info_rcu(struct rcu_head *head) 165static void free_fib_info_rcu(struct rcu_head *head)
145{ 166{
@@ -148,6 +169,8 @@ static void free_fib_info_rcu(struct rcu_head *head)
148 change_nexthops(fi) { 169 change_nexthops(fi) {
149 if (nexthop_nh->nh_dev) 170 if (nexthop_nh->nh_dev)
150 dev_put(nexthop_nh->nh_dev); 171 dev_put(nexthop_nh->nh_dev);
172 if (nexthop_nh->nh_exceptions)
173 free_nh_exceptions(nexthop_nh);
151 } endfor_nexthops(fi); 174 } endfor_nexthops(fi);
152 175
153 release_net(fi->fib_net); 176 release_net(fi->fib_net);