summaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_rules.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-06-29 10:32:45 +0200
committerDavid S. Miller <davem@davemloft.net>2012-06-29 10:36:36 +0200
commit7a9bc9b81a5bc6e44ebc80ef781332e4385083f2 (patch)
tree1342c672823d47bfb112fee63951af9f6a3eb590 /net/ipv4/fib_rules.c
parentnet: l2tp_eth: provide tx_dropped counter (diff)
downloadlinux-7a9bc9b81a5bc6e44ebc80ef781332e4385083f2.tar.xz
linux-7a9bc9b81a5bc6e44ebc80ef781332e4385083f2.zip
ipv4: Elide fib_validate_source() completely when possible.
If rpfilter is off (or the SKB has an IPSEC path) and there are not tclassid users, we don't have to do anything at all when fib_validate_source() is invoked besides setting the itag to zero. We monitor tclassid uses with a counter (modified only under RTNL and marked __read_mostly) and we protect the fib_validate_source() real work with a test against this counter and whether rpfilter is to be done. Having a way to know whether we need no tclassid processing or not also opens the door for future optimized rpfilter algorithms that do not perform full FIB lookups. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_rules.c')
-rw-r--r--net/ipv4/fib_rules.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 2d043f71ef70..b23fd952c84f 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -169,8 +169,11 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
rule4->dst = nla_get_be32(tb[FRA_DST]);
#ifdef CONFIG_IP_ROUTE_CLASSID
- if (tb[FRA_FLOW])
+ if (tb[FRA_FLOW]) {
rule4->tclassid = nla_get_u32(tb[FRA_FLOW]);
+ if (rule4->tclassid)
+ fib_num_tclassid_users++;
+ }
#endif
rule4->src_len = frh->src_len;
@@ -184,6 +187,16 @@ errout:
return err;
}
+static void fib4_rule_delete(struct fib_rule *rule)
+{
+#ifdef CONFIG_IP_ROUTE_CLASSID
+ struct fib4_rule *rule4 = (struct fib4_rule *) rule;
+
+ if (rule4->tclassid)
+ fib_num_tclassid_users--;
+#endif
+}
+
static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
struct nlattr **tb)
{
@@ -256,6 +269,7 @@ static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = {
.action = fib4_rule_action,
.match = fib4_rule_match,
.configure = fib4_rule_configure,
+ .delete = fib4_rule_delete,
.compare = fib4_rule_compare,
.fill = fib4_rule_fill,
.default_pref = fib_default_rule_pref,