[NET] rules: Add support to invert selectors
authorThomas Graf <tgraf@suug.ch>
Thu, 9 Nov 2006 23:23:20 +0000 (15:23 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Sun, 3 Dec 2006 05:21:42 +0000 (21:21 -0800)
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>
include/linux/fib_rules.h
net/core/fib_rules.c

index adcdfbdd14d5371d49994b67f060157299c0469a..8270aac2aa5d95a9ada6f9ff1b5234362ca1d285 100644 (file)
@@ -6,6 +6,7 @@
 
 /* rule is permanent, and cannot be deleted */
 #define FIB_RULE_PERMANENT     1
+#define FIB_RULE_INVERT                2
 
 struct fib_rule_hdr
 {
index da91bf2e6151bcea2a6bf1d7afac04308a07f896..4148e274a2049b2ef0bcd87d158d6b4b9d9082c3 100644 (file)
@@ -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);