From 20e4840a0a209006ac16cfd5cd1e6a28b346ce67 Mon Sep 17 00:00:00 2001 From: Thomas Egerer Date: Mon, 30 Oct 2017 19:11:44 +0100 Subject: [PATCH 1/4] xfrm_policy: Add filter option for socket policies Listing policies on systems with a lot of socket policies can be confusing due to the number of returned polices. Even if socket polices are not of interest, they cannot be filtered. This patch adds an option to filter all socket policies from the output. Signed-off-by: Thomas Egerer --- ip/xfrm.h | 1 + ip/xfrm_policy.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ip/xfrm.h b/ip/xfrm.h index 54d80ce5..8566d639 100644 --- a/ip/xfrm.h +++ b/ip/xfrm.h @@ -90,6 +90,7 @@ struct xfrm_filter { __u8 action_mask; __u32 priority_mask; __u8 policy_flags_mask; + __u8 filter_socket; __u8 ptype; __u8 ptype_mask; diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index de689c4d..0c86a52a 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -58,7 +58,7 @@ static void usage(void) fprintf(stderr, " [ LIMIT-LIST ] [ TMPL-LIST ]\n"); fprintf(stderr, "Usage: ip xfrm policy { delete | get } { SELECTOR | index INDEX } dir DIR\n"); fprintf(stderr, " [ ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]\n"); - fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ SELECTOR ] [ dir DIR ]\n"); + fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ nosock ] [ SELECTOR ] [ dir DIR ]\n"); fprintf(stderr, " [ index INDEX ] [ ptype PTYPE ] [ action ACTION ] [ priority PRIORITY ]\n"); fprintf(stderr, " [ flag FLAG-LIST ]\n"); fprintf(stderr, "Usage: ip xfrm policy flush [ ptype PTYPE ]\n"); @@ -403,6 +403,9 @@ static int xfrm_policy_filter_match(struct xfrm_userpolicy_info *xpinfo, if ((xpinfo->dir^filter.xpinfo.dir)&filter.dir_mask) return 0; + if (filter.filter_socket && (xpinfo->dir >= XFRM_POLICY_MAX)) + return 0; + if ((ptype^filter.ptype)&filter.ptype_mask) return 0; @@ -806,6 +809,9 @@ static int xfrm_policy_list_or_deleteall(int argc, char **argv, int deleteall) filter.policy_flags_mask = XFRM_FILTER_MASK_FULL; + } else if (strcmp(*argv, "nosock") == 0) { + /* filter all socket-based policies */ + filter.filter_socket = 1; } else { if (selp) invarg("unknown", *argv); From 5474d440b8a26b30104329d699217c87d34652ad Mon Sep 17 00:00:00 2001 From: Thomas Egerer Date: Mon, 30 Oct 2017 19:11:45 +0100 Subject: [PATCH 2/4] xfrm_policy: Do not attempt to deleteall a socket policy Socket polices are added to a socket using setsockopt(2). They cannot be deleted by iproute2. The attempt to delete them causes an error (EINVAL). To avoid this unnecessary error message all socket policies are skipped in xfrm_policy_keep. Signed-off-by: Thomas Egerer --- ip/xfrm_policy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index 0c86a52a..e716a7d0 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -735,6 +735,10 @@ static int xfrm_policy_keep(const struct sockaddr_nl *who, if (!xfrm_policy_filter_match(xpinfo, ptype)) return 0; + /* can't delete socket policies */ + if (xpinfo->dir >= XFRM_POLICY_MAX) + return 0; + if (xb->offset + NLMSG_LENGTH(sizeof(*xpid)) > xb->size) return 0; From 0c7d651b38d6ad5a2538aef21560cad6fe90f683 Mon Sep 17 00:00:00 2001 From: Thomas Egerer Date: Mon, 30 Oct 2017 19:11:46 +0100 Subject: [PATCH 3/4] xfrm_{state, policy}: Allow to deleteall polices/states with marks Using 'ip deleteall' with policies that have marks, fails unless you eplicitely specify the mark values. This is very uncomfortable when bulk-deleting policies and states. With this patch all relevant states and policies are wiped by 'ip deleteall' regardless of their mark values. Signed-off-by: Thomas Egerer --- ip/xfrm_policy.c | 9 +++++++++ ip/xfrm_state.c | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index e716a7d0..09f96dbb 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -753,6 +753,15 @@ static int xfrm_policy_keep(const struct sockaddr_nl *who, xpid->dir = xpinfo->dir; xpid->index = xpinfo->index; + if (tb[XFRMA_MARK]) { + int r = addattr_l(new_n, xb->size, XFRMA_MARK, + (void *)RTA_DATA(tb[XFRMA_MARK]), tb[XFRMA_MARK]->rta_len); + if (r < 0) { + fprintf(stderr, "%s: XFRMA_MARK failed\n", __func__); + exit(1); + } + } + xb->offset += new_n->nlmsg_len; xb->nlmsg_count++; diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index 99fdec23..ba5d6639 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -1080,6 +1080,7 @@ static int xfrm_state_keep(const struct sockaddr_nl *who, int len = n->nlmsg_len; struct nlmsghdr *new_n; struct xfrm_usersa_id *xsid; + struct rtattr *tb[XFRMA_MAX+1]; if (n->nlmsg_type != XFRM_MSG_NEWSA) { fprintf(stderr, "Not a state: %08x %08x %08x\n", @@ -1116,6 +1117,17 @@ static int xfrm_state_keep(const struct sockaddr_nl *who, addattr_l(new_n, xb->size, XFRMA_SRCADDR, &xsinfo->saddr, sizeof(xsid->daddr)); + parse_rtattr(tb, XFRMA_MAX, XFRMS_RTA(xsinfo), len); + + if (tb[XFRMA_MARK]) { + int r = addattr_l(new_n, xb->size, XFRMA_MARK, + (void *)RTA_DATA(tb[XFRMA_MARK]), tb[XFRMA_MARK]->rta_len); + if (r < 0) { + fprintf(stderr, "%s: XFRMA_MARK failed\n", __func__); + exit(1); + } + } + xb->offset += new_n->nlmsg_len; xb->nlmsg_count++; From e4beb5278728125999d2d90c0edbb178217ff582 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 7 Nov 2017 11:15:34 +0900 Subject: [PATCH 4/4] netem: use fixed rather than floating point for scaling Don't need to do floating point math to compute scaled random. Signed-off-by: Stephen Hemminger --- tc/q_netem.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tc/q_netem.c b/tc/q_netem.c index cdaddce9..b97c351e 100644 --- a/tc/q_netem.c +++ b/tc/q_netem.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -53,15 +54,12 @@ static void explain1(const char *arg) */ #define MAX_DIST (16*1024) -static const double max_percent_value = 0xffffffff; - /* scaled value used to percent of maximum. */ static void set_percent(__u32 *percent, double per) { - *percent = (unsigned int) rint(per * max_percent_value); + *percent = rint(per * UINT32_MAX); } - /* Parse either a fraction '.3' or percent '30% * return: 0 = ok, -1 = error, 1 = out of range */ @@ -89,7 +87,7 @@ static int get_percent(__u32 *percent, const char *str) static void print_percent(char *buf, int len, __u32 per) { - snprintf(buf, len, "%g%%", 100. * (double) per / max_percent_value); + snprintf(buf, len, "%g%%", (100. * per) / UINT32_MAX); } static char *sprint_percent(__u32 per, char *buf) @@ -323,7 +321,7 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv, /* netem option is "1-h" but kernel * expects "h". */ - gemodel.h = max_percent_value - gemodel.h; + gemodel.h = UINT32_MAX - gemodel.h; if (!NEXT_IS_NUMBER()) continue; @@ -630,7 +628,7 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) fprintf(f, " loss gemodel p %s", sprint_percent(gemodel->p, b1)); fprintf(f, " r %s", sprint_percent(gemodel->r, b1)); - fprintf(f, " 1-h %s", sprint_percent(max_percent_value - + fprintf(f, " 1-h %s", sprint_percent(UINT32_MAX - gemodel->h, b1)); fprintf(f, " 1-k %s", sprint_percent(gemodel->k1, b1)); }