summaryrefslogtreecommitdiff
path: root/net/core/fib_rules.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2006-11-10 02:23:20 +0300
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 08:21:42 +0300
commit3dfbcc411e461db51a1ac1aa1c6ebe2c5a0275a0 (patch)
tree14637fc46cade241f7156f208c12d9978d948b8f /net/core/fib_rules.c
parent1f6c9557e8206757c91b5737bb8dbd5b1ae3a773 (diff)
downloadlinux-3dfbcc411e461db51a1ac1aa1c6ebe2c5a0275a0.tar.xz
[NET] rules: Add support to invert selectors
Introduces a new flag FIB_RULE_INVERT causing rules to apply if the specified selector doesn't match. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/fib_rules.c')
-rw-r--r--net/core/fib_rules.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index da91bf2e6151..4148e274a204 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -107,6 +107,22 @@ out:
EXPORT_SYMBOL_GPL(fib_rules_unregister);
+static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
+ struct flowi *fl, int flags)
+{
+ int ret = 0;
+
+ if (rule->ifindex && (rule->ifindex != fl->iif))
+ goto out;
+
+ if ((rule->mark ^ fl->mark) & rule->mark_mask)
+ goto out;
+
+ ret = ops->match(rule, fl, flags);
+out:
+ return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
+}
+
int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
int flags, struct fib_lookup_arg *arg)
{
@@ -116,13 +132,7 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
rcu_read_lock();
list_for_each_entry_rcu(rule, ops->rules_list, list) {
- if (rule->ifindex && (rule->ifindex != fl->iif))
- continue;
-
- if ((rule->mark ^ fl->mark) & rule->mark_mask)
- continue;
-
- if (!ops->match(rule, fl, flags))
+ if (!fib_rule_match(rule, ops, fl, flags))
continue;
err = ops->action(rule, fl, flags, arg);