diff options
Diffstat (limited to 'net/ipv4/fib_rules.c')
-rw-r--r-- | net/ipv4/fib_rules.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 2d043f71ef7..c06da93b0b7 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -54,7 +54,7 @@ u32 fib_rules_tclass(const struct fib_result *res) | |||
54 | } | 54 | } |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) | 57 | int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) |
58 | { | 58 | { |
59 | struct fib_lookup_arg arg = { | 59 | struct fib_lookup_arg arg = { |
60 | .result = res, | 60 | .result = res, |
@@ -67,7 +67,7 @@ int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) | |||
67 | 67 | ||
68 | return err; | 68 | return err; |
69 | } | 69 | } |
70 | EXPORT_SYMBOL_GPL(fib_lookup); | 70 | EXPORT_SYMBOL_GPL(__fib_lookup); |
71 | 71 | ||
72 | static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, | 72 | static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, |
73 | int flags, struct fib_lookup_arg *arg) | 73 | int flags, struct fib_lookup_arg *arg) |
@@ -169,8 +169,11 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
169 | rule4->dst = nla_get_be32(tb[FRA_DST]); | 169 | rule4->dst = nla_get_be32(tb[FRA_DST]); |
170 | 170 | ||
171 | #ifdef CONFIG_IP_ROUTE_CLASSID | 171 | #ifdef CONFIG_IP_ROUTE_CLASSID |
172 | if (tb[FRA_FLOW]) | 172 | if (tb[FRA_FLOW]) { |
173 | rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); | 173 | rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); |
174 | if (rule4->tclassid) | ||
175 | net->ipv4.fib_num_tclassid_users++; | ||
176 | } | ||
174 | #endif | 177 | #endif |
175 | 178 | ||
176 | rule4->src_len = frh->src_len; | 179 | rule4->src_len = frh->src_len; |
@@ -179,11 +182,24 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
179 | rule4->dstmask = inet_make_mask(rule4->dst_len); | 182 | rule4->dstmask = inet_make_mask(rule4->dst_len); |
180 | rule4->tos = frh->tos; | 183 | rule4->tos = frh->tos; |
181 | 184 | ||
185 | net->ipv4.fib_has_custom_rules = true; | ||
182 | err = 0; | 186 | err = 0; |
183 | errout: | 187 | errout: |
184 | return err; | 188 | return err; |
185 | } | 189 | } |
186 | 190 | ||
191 | static void fib4_rule_delete(struct fib_rule *rule) | ||
192 | { | ||
193 | struct net *net = rule->fr_net; | ||
194 | #ifdef CONFIG_IP_ROUTE_CLASSID | ||
195 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; | ||
196 | |||
197 | if (rule4->tclassid) | ||
198 | net->ipv4.fib_num_tclassid_users--; | ||
199 | #endif | ||
200 | net->ipv4.fib_has_custom_rules = true; | ||
201 | } | ||
202 | |||
187 | static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | 203 | static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, |
188 | struct nlattr **tb) | 204 | struct nlattr **tb) |
189 | { | 205 | { |
@@ -256,6 +272,7 @@ static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = { | |||
256 | .action = fib4_rule_action, | 272 | .action = fib4_rule_action, |
257 | .match = fib4_rule_match, | 273 | .match = fib4_rule_match, |
258 | .configure = fib4_rule_configure, | 274 | .configure = fib4_rule_configure, |
275 | .delete = fib4_rule_delete, | ||
259 | .compare = fib4_rule_compare, | 276 | .compare = fib4_rule_compare, |
260 | .fill = fib4_rule_fill, | 277 | .fill = fib4_rule_fill, |
261 | .default_pref = fib_default_rule_pref, | 278 | .default_pref = fib_default_rule_pref, |
@@ -295,6 +312,7 @@ int __net_init fib4_rules_init(struct net *net) | |||
295 | if (err < 0) | 312 | if (err < 0) |
296 | goto fail; | 313 | goto fail; |
297 | net->ipv4.rules_ops = ops; | 314 | net->ipv4.rules_ops = ops; |
315 | net->ipv4.fib_has_custom_rules = false; | ||
298 | return 0; | 316 | return 0; |
299 | 317 | ||
300 | fail: | 318 | fail: |