diff options
Diffstat (limited to 'net/ipv4/fib_rules.c')
| -rw-r--r-- | net/ipv4/fib_rules.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 2d043f71ef70..a83d74e498d2 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
| @@ -47,14 +47,7 @@ struct fib4_rule { | |||
| 47 | #endif | 47 | #endif |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | #ifdef CONFIG_IP_ROUTE_CLASSID | 50 | int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) |
| 51 | u32 fib_rules_tclass(const struct fib_result *res) | ||
| 52 | { | ||
| 53 | return res->r ? ((struct fib4_rule *) res->r)->tclassid : 0; | ||
| 54 | } | ||
| 55 | #endif | ||
| 56 | |||
| 57 | int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) | ||
| 58 | { | 51 | { |
| 59 | struct fib_lookup_arg arg = { | 52 | struct fib_lookup_arg arg = { |
| 60 | .result = res, | 53 | .result = res, |
| @@ -63,11 +56,15 @@ int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) | |||
| 63 | int err; | 56 | int err; |
| 64 | 57 | ||
| 65 | err = fib_rules_lookup(net->ipv4.rules_ops, flowi4_to_flowi(flp), 0, &arg); | 58 | err = fib_rules_lookup(net->ipv4.rules_ops, flowi4_to_flowi(flp), 0, &arg); |
| 66 | res->r = arg.rule; | 59 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 67 | 60 | if (arg.rule) | |
| 61 | res->tclassid = ((struct fib4_rule *)arg.rule)->tclassid; | ||
| 62 | else | ||
| 63 | res->tclassid = 0; | ||
| 64 | #endif | ||
| 68 | return err; | 65 | return err; |
| 69 | } | 66 | } |
| 70 | EXPORT_SYMBOL_GPL(fib_lookup); | 67 | EXPORT_SYMBOL_GPL(__fib_lookup); |
| 71 | 68 | ||
| 72 | static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, | 69 | static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, |
| 73 | int flags, struct fib_lookup_arg *arg) | 70 | int flags, struct fib_lookup_arg *arg) |
| @@ -169,8 +166,11 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
| 169 | rule4->dst = nla_get_be32(tb[FRA_DST]); | 166 | rule4->dst = nla_get_be32(tb[FRA_DST]); |
| 170 | 167 | ||
| 171 | #ifdef CONFIG_IP_ROUTE_CLASSID | 168 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 172 | if (tb[FRA_FLOW]) | 169 | if (tb[FRA_FLOW]) { |
| 173 | rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); | 170 | rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); |
| 171 | if (rule4->tclassid) | ||
| 172 | net->ipv4.fib_num_tclassid_users++; | ||
| 173 | } | ||
| 174 | #endif | 174 | #endif |
| 175 | 175 | ||
| 176 | rule4->src_len = frh->src_len; | 176 | rule4->src_len = frh->src_len; |
| @@ -179,11 +179,24 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
| 179 | rule4->dstmask = inet_make_mask(rule4->dst_len); | 179 | rule4->dstmask = inet_make_mask(rule4->dst_len); |
| 180 | rule4->tos = frh->tos; | 180 | rule4->tos = frh->tos; |
| 181 | 181 | ||
| 182 | net->ipv4.fib_has_custom_rules = true; | ||
| 182 | err = 0; | 183 | err = 0; |
| 183 | errout: | 184 | errout: |
| 184 | return err; | 185 | return err; |
| 185 | } | 186 | } |
| 186 | 187 | ||
| 188 | static void fib4_rule_delete(struct fib_rule *rule) | ||
| 189 | { | ||
| 190 | struct net *net = rule->fr_net; | ||
| 191 | #ifdef CONFIG_IP_ROUTE_CLASSID | ||
| 192 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; | ||
| 193 | |||
| 194 | if (rule4->tclassid) | ||
| 195 | net->ipv4.fib_num_tclassid_users--; | ||
| 196 | #endif | ||
| 197 | net->ipv4.fib_has_custom_rules = true; | ||
| 198 | } | ||
| 199 | |||
| 187 | static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | 200 | static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, |
| 188 | struct nlattr **tb) | 201 | struct nlattr **tb) |
| 189 | { | 202 | { |
| @@ -256,6 +269,7 @@ static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = { | |||
| 256 | .action = fib4_rule_action, | 269 | .action = fib4_rule_action, |
| 257 | .match = fib4_rule_match, | 270 | .match = fib4_rule_match, |
| 258 | .configure = fib4_rule_configure, | 271 | .configure = fib4_rule_configure, |
| 272 | .delete = fib4_rule_delete, | ||
| 259 | .compare = fib4_rule_compare, | 273 | .compare = fib4_rule_compare, |
| 260 | .fill = fib4_rule_fill, | 274 | .fill = fib4_rule_fill, |
| 261 | .default_pref = fib_default_rule_pref, | 275 | .default_pref = fib_default_rule_pref, |
| @@ -295,6 +309,7 @@ int __net_init fib4_rules_init(struct net *net) | |||
| 295 | if (err < 0) | 309 | if (err < 0) |
| 296 | goto fail; | 310 | goto fail; |
| 297 | net->ipv4.rules_ops = ops; | 311 | net->ipv4.rules_ops = ops; |
| 312 | net->ipv4.fib_has_custom_rules = false; | ||
| 298 | return 0; | 313 | return 0; |
| 299 | 314 | ||
| 300 | fail: | 315 | fail: |
