diff --git a/ip/iprule.c b/ip/iprule.c index 6af71cab..2f58d8c2 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -71,6 +71,7 @@ static struct unsigned int tos, tosmask; unsigned int pref, prefmask; unsigned int fwmark, fwmask; + uint64_t tun_id; char iif[IFNAMSIZ]; char oif[IFNAMSIZ]; struct fib_rule_uid_range range; @@ -210,6 +211,18 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) return false; } + if (filter.tun_id) { + __u64 tun_id = 0; + + if (tb[FRA_TUN_ID]) { + tun_id = ntohll(rta_getattr_u64(tb[FRA_TUN_ID])); + if (filter.tun_id != tun_id) + return false; + } else { + return false; + } + } + table = frh_get_table(frh, tb); if (filter.tb > 0 && filter.tb ^ table) return false; @@ -376,6 +389,12 @@ int print_rule(struct nlmsghdr *n, void *arg) } } + if (tb[FRA_TUN_ID]) { + __u64 tun_id = ntohll(rta_getattr_u64(tb[FRA_TUN_ID])); + + print_u64(PRINT_ANY, "tun_id", "tun_id %llu ", tun_id); + } + table = frh_get_table(frh, tb); if (table) { print_string(PRINT_ANY, "table", @@ -619,6 +638,13 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action) &filter.range.end) != 2) invarg("invalid UID range\n", *argv); + } else if (matches(*argv, "tun_id") == 0) { + __u64 tun_id; + + NEXT_ARG(); + if (get_u64(&tun_id, *argv, 0)) + invarg("\"tun_id\" value is invalid\n", *argv); + filter.tun_id = tun_id; } else if (matches(*argv, "lookup") == 0 || matches(*argv, "table") == 0) { __u32 tid; @@ -845,6 +871,13 @@ static int iprule_modify(int cmd, int argc, char **argv) if (rtnl_rtprot_a2n(&proto, *argv)) invarg("\"protocol\" value is invalid\n", *argv); addattr8(&req.n, sizeof(req), FRA_PROTOCOL, proto); + } else if (matches(*argv, "tun_id") == 0) { + __u64 tun_id; + + NEXT_ARG(); + if (get_be64(&tun_id, *argv, 0)) + invarg("\"tun_id\" value is invalid\n", *argv); + addattr64(&req.n, sizeof(req), FRA_TUN_ID, tun_id); } else if (matches(*argv, "table") == 0 || strcmp(*argv, "lookup") == 0) { NEXT_ARG(); diff --git a/man/man8/ip-rule.8 b/man/man8/ip-rule.8 index 1455a49a..2c12bf64 100644 --- a/man/man8/ip-rule.8 +++ b/man/man8/ip-rule.8 @@ -54,7 +54,9 @@ ip-rule \- routing policy database management .IR NUMBER "-" NUMBER " ] ] [ " .BR dport " [ " .IR NUMBER " | " -.IR NUMBER "-" NUMBER " ] ]" +.IR NUMBER "-" NUMBER " ] ] [ " +.B tun_id +.IR TUN_ID " ]" .BR diff --git a/misc/nstat.c b/misc/nstat.c index 88f1c769..653580ea 100644 --- a/misc/nstat.c +++ b/misc/nstat.c @@ -177,11 +177,13 @@ static int count_spaces(const char *line) static void load_ugly_table(FILE *fp) { - char buf[2048]; + char *buf = NULL; + size_t buflen = 0; + ssize_t nread; struct nstat_ent *db = NULL; struct nstat_ent *n; - while (fgets(buf, sizeof(buf), fp) != NULL) { + while ((nread = getline(&buf, &buflen, fp)) != -1) { char idbuf[4096]; int off; char *p; @@ -218,7 +220,8 @@ static void load_ugly_table(FILE *fp) p = next; } n = db; - if (fgets(buf, sizeof(buf), fp) == NULL) + nread = getline(&buf, &buflen, fp); + if (nread == -1) abort(); count2 = count_spaces(buf); if (count2 > count1) @@ -237,6 +240,7 @@ static void load_ugly_table(FILE *fp) n = n->next; } while (p > buf + off + 2); } + free(buf); while (db) { n = db; diff --git a/rdma/utils.c b/rdma/utils.c index 61f4aeb1..069d44fe 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -425,8 +425,8 @@ int rd_attr_cb(const struct nlattr *attr, void *data) const struct nlattr **tb = data; int type; - if (mnl_attr_type_valid(attr, RDMA_NLDEV_ATTR_MAX) < 0) - /* We received uknown attribute */ + if (mnl_attr_type_valid(attr, RDMA_NLDEV_ATTR_MAX - 1) < 0) + /* We received unknown attribute */ return MNL_CB_OK; type = mnl_attr_get_type(attr); diff --git a/testsuite/Makefile b/testsuite/Makefile index 9b0f1c15..7f247bbc 100644 --- a/testsuite/Makefile +++ b/testsuite/Makefile @@ -85,11 +85,11 @@ endif TC="$$i/tc/tc" IP="$$i/ip/ip" SS=$$i/misc/ss DEV="$(DEV)" IPVER="$@" SNAME="$$i" \ ERRF="$(RESULTS_DIR)/$@.$$o.err" $(PREFIX) tests/$@ > $(RESULTS_DIR)/$@.$$o.out; \ if [ "$$?" = "127" ]; then \ - echo "\e[1;35mSKIPPED\e[0m"; \ + printf "\033[1;35mSKIPPED\033[0m\n"; \ elif [ -e "$(RESULTS_DIR)/$@.$$o.err" ]; then \ - echo "\e[0;31mFAILED\e[0m"; \ + printf "\033[0;31mFAILED\033[0m\n"; \ else \ - echo "\e[0;32mPASS\e[0m"; \ + printf "\033[0;32mPASS\033[0m\n"; \ fi; \ rm "$$TMP_ERR" "$$TMP_OUT"; \ sudo dmesg > $(RESULTS_DIR)/$@.$$o.dmesg; \