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 98460a07..d5440269 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; @@ -732,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; @@ -746,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++; @@ -806,6 +822,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); diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index 3e20d6ed..85d959cc 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -1081,6 +1081,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", @@ -1117,6 +1118,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++; 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)); }