diff options
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r-- | net/ipv4/fib_semantics.c | 23 |
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 | ||
143 | static 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 */ |
144 | static void free_fib_info_rcu(struct rcu_head *head) | 165 | static 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); |