From: Patrick McHardy Date: Thu, 14 Dec 2006 00:58:32 +0000 (-0800) Subject: [IPROUTE]: Add support for routing rule fwmark masks X-Git-Tag: v2.6.19-061214~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be7f286e8353cc947c6d2a74b21989af23988812;p=thirdparty%2Fiproute2.git [IPROUTE]: Add support for routing rule fwmark masks Needs kernel >= 2.6.19. Signed-off-by: Patrick McHardy --- diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 1ec494ff1..477270c67 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -263,6 +263,7 @@ enum rtattr_type_t RTA_SESSION, RTA_MP_ALGO, RTA_TABLE, + RTA_FWMASK, __RTA_MAX }; diff --git a/ip/iprule.c b/ip/iprule.c index 591112ec4..cb45f02ed 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -37,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 := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]\n"); + fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n"); fprintf(stderr, " [ dev STRING ] [ pref NUMBER ]\n"); fprintf(stderr, "ACTION := [ table TABLE_ID ]\n"); fprintf(stderr, " [ prohibit | reject | unreachable ]\n"); @@ -129,8 +129,17 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) SPRINT_BUF(b1); fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1))); } - if (tb[RTA_PROTOINFO]) { - fprintf(fp, "fwmark %#x ", *(__u32*)RTA_DATA(tb[RTA_PROTOINFO])); + if (tb[RTA_PROTOINFO] || tb[RTA_FWMASK]) { + __u32 mark = 0, mask = 0; + + if (tb[RTA_PROTOINFO]) + mark = *(__u32*)RTA_DATA(tb[RTA_PROTOINFO]); + + if (tb[RTA_FWMASK] && + (mask = *(__u32*)RTA_DATA(tb[RTA_FWMASK])) != 0xFFFFFFFF) + fprintf(fp, "fwmark 0x%x/0x%x ", mark, mask); + else + fprintf(fp, "fwmark 0x%x ", mark); } if (tb[RTA_IIF]) { @@ -252,11 +261,19 @@ static int iprule_modify(int cmd, int argc, char **argv) invarg("TOS value is invalid\n", *argv); req.r.rtm_tos = tos; } else if (strcmp(*argv, "fwmark") == 0) { - __u32 fwmark; + char *slash; + __u32 fwmark, fwmask; NEXT_ARG(); + if ((slash = strchr(*argv, '/')) != NULL) + *slash = '\0'; if (get_u32(&fwmark, *argv, 0)) invarg("fwmark value is invalid\n", *argv); addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); + if (slash) { + if (get_u32(&fwmask, slash+1, 0)) + invarg("fwmask value is invalid\n", slash+1); + addattr32(&req.n, sizeof(req), RTA_FWMASK, fwmask); + } } else if (matches(*argv, "realms") == 0) { __u32 realm; NEXT_ARG(); diff --git a/man/man8/ip.8 b/man/man8/ip.8 index 12da6d598..a9132da2c 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -223,7 +223,7 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" .B tos .IR TOS " ] [ " .B fwmark -.IR FWMARK " ] [ " +.IR FWMARK[/MASK] " ] [ " .B dev .IR STRING " ] [ " .B pref