diff options
author | David S. Miller <davem@davemloft.net> | 2012-06-29 04:32:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-29 04:36:36 -0400 |
commit | 7a9bc9b81a5bc6e44ebc80ef781332e4385083f2 (patch) | |
tree | 1342c672823d47bfb112fee63951af9f6a3eb590 /net/ipv4/fib_semantics.c | |
parent | b8c8430726e5bd552e01dacc5a44f3f83f7446ca (diff) |
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_semantics.c')
-rw-r--r-- | net/ipv4/fib_semantics.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 415f8230fc88..c46c20b6b0b6 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -163,6 +163,12 @@ void free_fib_info(struct fib_info *fi) | |||
163 | return; | 163 | return; |
164 | } | 164 | } |
165 | fib_info_cnt--; | 165 | fib_info_cnt--; |
166 | #ifdef CONFIG_IP_ROUTE_CLASSID | ||
167 | change_nexthops(fi) { | ||
168 | if (nexthop_nh->nh_tclassid) | ||
169 | fib_num_tclassid_users--; | ||
170 | } endfor_nexthops(fi); | ||
171 | #endif | ||
166 | call_rcu(&fi->rcu, free_fib_info_rcu); | 172 | call_rcu(&fi->rcu, free_fib_info_rcu); |
167 | } | 173 | } |
168 | 174 | ||
@@ -421,6 +427,8 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh, | |||
421 | #ifdef CONFIG_IP_ROUTE_CLASSID | 427 | #ifdef CONFIG_IP_ROUTE_CLASSID |
422 | nla = nla_find(attrs, attrlen, RTA_FLOW); | 428 | nla = nla_find(attrs, attrlen, RTA_FLOW); |
423 | nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0; | 429 | nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0; |
430 | if (nexthop_nh->nh_tclassid) | ||
431 | fib_num_tclassid_users++; | ||
424 | #endif | 432 | #endif |
425 | } | 433 | } |
426 | 434 | ||
@@ -815,6 +823,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
815 | nh->nh_flags = cfg->fc_flags; | 823 | nh->nh_flags = cfg->fc_flags; |
816 | #ifdef CONFIG_IP_ROUTE_CLASSID | 824 | #ifdef CONFIG_IP_ROUTE_CLASSID |
817 | nh->nh_tclassid = cfg->fc_flow; | 825 | nh->nh_tclassid = cfg->fc_flow; |
826 | if (nh->nh_tclassid) | ||
827 | fib_num_tclassid_users++; | ||
818 | #endif | 828 | #endif |
819 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 829 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
820 | nh->nh_weight = 1; | 830 | nh->nh_weight = 1; |