iprule: Add option to suppress unspecific routing lookups
authorStefan Tomanek <stefan.tomanek@wertarbyte.de>
Wed, 7 Jun 2017 10:47:04 +0000 (12:47 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Sun, 11 Jun 2017 13:07:18 +0000 (15:07 +0200)
After applying this patch, policy routing rules can be employed that ignore
parts of a routing table. The following config snippet ignores routing lookups
from the specified main routing table yielding the default route, passing the
lookup process on to the next rule (that might provide a special default route
for marked packets):

config rule
option priority 10
# check main routing table first, but ignore default route result
option lookup main
option suppress_prefixlength 0

config rule
option priority 11
# use special routing table for marked packets
# (unless already consumed by previous rule)
option mark 0xFF
option lookup 100

The result is a ruleset like this (only visible using the full 'ip' binary):

 # ip rule
 0: from all lookup local
 10: from all lookup main suppress_prefixlength 0
 11: from all fwmark 0xff lookup 100
 32766: from all lookup main
 32767: from all lookup default
 #

Signed-off-by: Stefan Tomanek <stefan.tomanek@wertarbyte.de>
iprule.c
iprule.h
system-linux.c

index 81bb77a60c0743b7c76eb84c60b9941145c334bc..7cf7422f4168d8c33fdb051865f7fe4846d62487 100644 (file)
--- a/iprule.c
+++ b/iprule.c
@@ -42,6 +42,7 @@ enum {
        RULE_LOOKUP,
        RULE_ACTION,
        RULE_GOTO,
+       RULE_SUP_PREFIXLEN,
        __RULE_MAX
 };
 
@@ -55,6 +56,7 @@ static const struct blobmsg_policy rule_attr[__RULE_MAX] = {
        [RULE_TOS] = { .name = "tos", .type = BLOBMSG_TYPE_INT32 },
        [RULE_FWMARK] = { .name = "mark", .type = BLOBMSG_TYPE_STRING },
        [RULE_LOOKUP] = { .name = "lookup", .type = BLOBMSG_TYPE_STRING },
+       [RULE_SUP_PREFIXLEN] = { .name = "suppress_prefixlength", .type = BLOBMSG_TYPE_INT32 },
        [RULE_ACTION] = { .name = "action", .type = BLOBMSG_TYPE_STRING },
        [RULE_GOTO]   = { .name = "goto", .type = BLOBMSG_TYPE_INT32 },
 };
@@ -185,6 +187,11 @@ iprule_add(struct blob_attr *attr, bool v6)
                rule->flags |= IPRULE_LOOKUP;
        }
 
+       if ((cur = tb[RULE_SUP_PREFIXLEN]) != NULL) {
+               rule->sup_prefixlen = blobmsg_get_u32(cur);
+               rule->flags |= IPRULE_SUP_PREFIXLEN;
+       }
+
        if ((cur = tb[RULE_ACTION]) != NULL) {
                if (!system_resolve_iprule_action(blobmsg_data(cur), &rule->action)) {
                        DPRINTF("Failed to parse rule action: %s\n", (char *) blobmsg_data(cur));
index e8a25558ef76fc79f5f0f569ca923c92e849bdbc..7617c7600985cf2f7edb03bbd29ecd81342200c2 100644 (file)
--- a/iprule.h
+++ b/iprule.h
@@ -60,6 +60,9 @@ enum iprule_flags {
 
        /* rule is a goto */
        IPRULE_GOTO                     = (1 << 12),
+
+       /* rule suppresses results by prefix length */
+       IPRULE_SUP_PREFIXLEN    = (1 << 13),
 };
 
 struct iprule {
@@ -87,6 +90,7 @@ struct iprule {
        unsigned int fwmask;
 
        unsigned int lookup;
+       unsigned int sup_prefixlen;
        unsigned int action;
        unsigned int gotoid;
 };
index 3605d9bff6bbe1de158e663f836d1b9fab5b8d69..06c6abddda8477e30781b61bf5ae0bceca6649e4 100644 (file)
@@ -2171,6 +2171,9 @@ static int system_iprule(struct iprule *rule, int cmd)
                        nla_put_u32(msg, FRA_TABLE, rule->lookup);
        }
 
+       if (rule->flags & IPRULE_SUP_PREFIXLEN)
+               nla_put_u32(msg, FRA_SUPPRESS_PREFIXLEN, rule->sup_prefixlen);
+
        if (rule->flags & IPRULE_GOTO)
                nla_put_u32(msg, FRA_GOTO, rule->gotoid);