diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h index 87b606b..9ea9868 100644 --- a/include/linux/fib_rules.h +++ b/include/linux/fib_rules.h @@ -47,6 +47,8 @@ enum FRA_UNUSED8, FRA_TABLE, /* Extended table id */ FRA_FWMASK, /* mask for netfilter mark */ + FRA_IPSET_N, /* ipset name */ + FRA_IPSET_M, /* ipset match: src or dst */ __FRA_MAX }; diff --git a/ip/iprule.c b/ip/iprule.c index e1a943a..c3d6207 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[/MASK] ]\n"); + fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ] [ ipset IPSET src|dst ]\n"); fprintf(stderr, " [ dev STRING ] [ pref NUMBER ]\n"); fprintf(stderr, "ACTION := [ table TABLE_ID ]\n"); fprintf(stderr, " [ prohibit | reject | unreachable ]\n"); @@ -150,6 +150,26 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "[detached] "); } + if (tb[FRA_IPSET_N]) { + char *str; + __u32 m=*(__u32*)RTA_DATA(tb[FRA_IPSET_M]); + + switch(m) { + case 1: + str="src"; + break; + + case 2: + str="dst"; + break; + + default: + str="unkn"; + break; + } + fprintf(fp, "ipset %s %s ", (char*)RTA_DATA(tb[FRA_IPSET_N]),str); + } + table = rtm_get_table(r, tb); if (table) fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1))); @@ -311,6 +331,21 @@ static int iprule_modify(int cmd, int argc, char **argv) strcmp(*argv, "iif") == 0) { NEXT_ARG(); addattr_l(&req.n, sizeof(req), FRA_IFNAME, *argv, strlen(*argv)+1); + } else if (strcmp(*argv, "ipset") == 0) { + char *n; + __u32 m=0; + + NEXT_ARG(); + n=*argv; + NEXT_ARG(); + if(!strcmp(*argv,"src")) + m=1; + if(!strcmp(*argv,"dst")) + m=2; + if(!m) + invarg("ipset match is invalid\n",*argv); + addattr_l(&req.n, sizeof(req), FRA_IPSET_N, n, strlen(n)+1); + addattr32(&req.n, sizeof(req), FRA_IPSET_M, m); } else if (strcmp(*argv, "nat") == 0 || matches(*argv, "map-to") == 0) { NEXT_ARG();