aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_rules.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_rules.c')
-rw-r--r--net/ipv4/fib_rules.c39
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 50int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
51u32 fib_rules_tclass(const struct fib_result *res)
52{
53 return res->r ? ((struct fib4_rule *) res->r)->tclassid : 0;
54}
55#endif
56
57int 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}
70EXPORT_SYMBOL_GPL(fib_lookup); 67EXPORT_SYMBOL_GPL(__fib_lookup);
71 68
72static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, 69static 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;
183errout: 184errout:
184 return err; 185 return err;
185} 186}
186 187
188static 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
187static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, 200static 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
300fail: 315fail: