]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
Add support for inverted selectors
authorThomas Graf <tgraf@suug.ch>
Thu, 9 Nov 2006 11:38:02 +0000 (12:38 +0100)
committerStephen Hemminger <shemminger@osdl.org>
Thu, 9 Nov 2006 16:51:29 +0000 (08:51 -0800)
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
include/linux/fib_rules.h [new file with mode: 0644]
ip/iprule.c

diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
new file mode 100644 (file)
index 0000000..8270aac
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef __LINUX_FIB_RULES_H
+#define __LINUX_FIB_RULES_H
+
+#include <linux/types.h>
+#include <linux/rtnetlink.h>
+
+/* rule is permanent, and cannot be deleted */
+#define FIB_RULE_PERMANENT     1
+#define FIB_RULE_INVERT                2
+
+struct fib_rule_hdr
+{
+       __u8            family;
+       __u8            dst_len;
+       __u8            src_len;
+       __u8            tos;
+
+       __u8            table;
+       __u8            res1;   /* reserved */
+       __u8            res2;   /* reserved */
+       __u8            action;
+
+       __u32           flags;
+};
+
+enum
+{
+       FRA_UNSPEC,
+       FRA_DST,        /* destination address */
+       FRA_SRC,        /* source address */
+       FRA_IFNAME,     /* interface name */
+       FRA_UNUSED1,
+       FRA_UNUSED2,
+       FRA_PRIORITY,   /* priority/preference */
+       FRA_UNUSED3,
+       FRA_UNUSED4,
+       FRA_UNUSED5,
+       FRA_FWMARK,     /* mark */
+       FRA_FLOW,       /* flow/class id */
+       FRA_UNUSED6,
+       FRA_UNUSED7,
+       FRA_UNUSED8,
+       FRA_TABLE,      /* Extended table id */
+       FRA_FWMASK,     /* mask for netfilter mark */
+       __FRA_MAX
+};
+
+#define FRA_MAX (__FRA_MAX - 1)
+
+enum
+{
+       FR_ACT_UNSPEC,
+       FR_ACT_TO_TBL,          /* Pass to fixed table */
+       FR_ACT_RES1,
+       FR_ACT_RES2,
+       FR_ACT_RES3,
+       FR_ACT_RES4,
+       FR_ACT_BLACKHOLE,       /* Drop without notification */
+       FR_ACT_UNREACHABLE,     /* Drop with ENETUNREACH */
+       FR_ACT_PROHIBIT,        /* Drop with EACCES */
+       __FR_ACT_MAX,
+};
+
+#define FR_ACT_MAX (__FR_ACT_MAX - 1)
+
+#endif
index 6caf573cef365e2c0522649502523d0362a998f2..af014bad85f541f55ac9f564a482955b27004277 100644 (file)
@@ -24,6 +24,7 @@
 #include <netinet/ip.h>
 #include <arpa/inet.h>
 #include <string.h>
+#include <linux/fib_rules.h>
 
 #include "rt_names.h"
 #include "utils.h"
@@ -36,7 +37,7 @@ static void usage(void) __attribute__((noreturn));
 static void usage(void)
 {
        fprintf(stderr, "Usage: ip rule [ list | add | del | flush ] SELECTOR ACTION\n");
-       fprintf(stderr, "SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]\n");
+       fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]\n");
        fprintf(stderr, "            [ dev STRING ] [ pref NUMBER ]\n");
        fprintf(stderr, "ACTION := [ table TABLE_ID ]\n");
        fprintf(stderr, "          [ prohibit | reject | unreachable ]\n");
@@ -80,6 +81,9 @@ static int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n,
        else
                fprintf(fp, "0:\t");
 
+       if (r->rtm_flags & FIB_RULE_INVERT)
+               fprintf(fp, "not ");
+
        if (tb[RTA_SRC]) {
                if (r->rtm_src_len != host_len) {
                        fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family,
@@ -209,6 +213,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
        req.r.rtm_scope = RT_SCOPE_UNIVERSE;
        req.r.rtm_table = 0;
        req.r.rtm_type = RTN_UNSPEC;
+       req.r.rtm_flags = 0;
 
        if (cmd == RTM_NEWRULE) {
                req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
@@ -216,7 +221,9 @@ static int iprule_modify(int cmd, int argc, char **argv)
        }
 
        while (argc > 0) {
-               if (strcmp(*argv, "from") == 0) {
+               if (strcmp(*argv, "not") == 0) {
+                       req.r.rtm_flags |= FIB_RULE_INVERT;
+               } else if (strcmp(*argv, "from") == 0) {
                        inet_prefix dst;
                        NEXT_ARG();
                        get_prefix(&dst, *argv, req.r.rtm_family);