lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180228234400.14321-2-sharpd@cumulusnetworks.com>
Date:   Wed, 28 Feb 2018 18:43:58 -0500
From:   Donald Sharp <sharpd@...ulusnetworks.com>
To:     netdev@...r.kernel.org, dsahern@...il.com
Subject: [PATCH v4 iproute2-next 1/3] ip: Use the `struct fib_rule_hdr` for rules

The iprule.c code was using `struct rtmsg` as the data
type to pass into the kernel for the netlink message.
While 'struct rtmsg' and `struct fib_rule_hdr` are
the same size and mostly the same, we should use
the correct data structure.  This commit translates
the data structures to have iprule.c use the correct
one.

Additionally copy over the modified fib_rules.h file

Signed-off-by: Donald Sharp <sharpd@...ulusnetworks.com>
---
 include/uapi/linux/fib_rules.h |   1 +
 ip/iprule.c                    | 128 +++++++++++++++++++++--------------------
 2 files changed, 68 insertions(+), 61 deletions(-)

diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h
index 2b642bf9..9477c3af 100644
--- a/include/uapi/linux/fib_rules.h
+++ b/include/uapi/linux/fib_rules.h
@@ -58,6 +58,7 @@ enum {
 	FRA_PAD,
 	FRA_L3MDEV,	/* iif or oif is l3mdev goto its table */
 	FRA_UID_RANGE,	/* UID range */
+	FRA_PROTOCOL,
 	__FRA_MAX
 };
 
diff --git a/ip/iprule.c b/ip/iprule.c
index a3abf2f6..94356bf8 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -73,25 +73,33 @@ static struct
 	inet_prefix dst;
 } filter;
 
+static inline int frh_get_table(struct fib_rule_hdr *frh, struct rtattr **tb)
+{
+	__u32 table = frh->table;
+	if (tb[RTA_TABLE])
+		table = rta_getattr_u32(tb[RTA_TABLE]);
+	return table;
+}
+
 static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
 {
-	struct rtmsg *r = NLMSG_DATA(n);
+	struct fib_rule_hdr *frh = NLMSG_DATA(n);
 	__u32 table;
 
-	if (preferred_family != AF_UNSPEC && r->rtm_family != preferred_family)
+	if (preferred_family != AF_UNSPEC && frh->family != preferred_family)
 		return false;
 
 	if (filter.prefmask &&
 	    filter.pref ^ (tb[FRA_PRIORITY] ? rta_getattr_u32(tb[FRA_PRIORITY]) : 0))
 		return false;
-	if (filter.not && !(r->rtm_flags & FIB_RULE_INVERT))
+	if (filter.not && !(frh->flags & FIB_RULE_INVERT))
 		return false;
 
 	if (filter.src.family) {
 		inet_prefix *f_src = &filter.src;
 
-		if (f_src->family != r->rtm_family ||
-		    f_src->bitlen > r->rtm_src_len)
+		if (f_src->family != frh->family ||
+		    f_src->bitlen > frh->src_len)
 			return false;
 
 		if (inet_addr_match_rta(f_src, tb[FRA_SRC]))
@@ -101,15 +109,15 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
 	if (filter.dst.family) {
 		inet_prefix *f_dst = &filter.dst;
 
-		if (f_dst->family != r->rtm_family ||
-		    f_dst->bitlen > r->rtm_dst_len)
+		if (f_dst->family != frh->family ||
+		    f_dst->bitlen > frh->dst_len)
 			return false;
 
 		if (inet_addr_match_rta(f_dst, tb[FRA_DST]))
 			return false;
 	}
 
-	if (filter.tosmask && filter.tos ^ r->rtm_tos)
+	if (filter.tosmask && filter.tos ^ frh->tos)
 		return false;
 
 	if (filter.fwmark) {
@@ -159,7 +167,7 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
 			return false;
 	}
 
-	table = rtm_get_table(r, tb);
+	table = frh_get_table(frh, tb);
 	if (filter.tb > 0 && filter.tb ^ table)
 		return false;
 
@@ -169,7 +177,7 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
 int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE *)arg;
-	struct rtmsg *r = NLMSG_DATA(n);
+	struct fib_rule_hdr *frh = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	int host_len = -1;
 	__u32 table;
@@ -180,13 +188,13 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	if (n->nlmsg_type != RTM_NEWRULE && n->nlmsg_type != RTM_DELRULE)
 		return 0;
 
-	len -= NLMSG_LENGTH(sizeof(*r));
+	len -= NLMSG_LENGTH(sizeof(*frh));
 	if (len < 0)
 		return -1;
 
-	parse_rtattr(tb, FRA_MAX, RTM_RTA(r), len);
+	parse_rtattr(tb, FRA_MAX, RTM_RTA(frh), len);
 
-	host_len = af_bit_len(r->rtm_family);
+	host_len = af_bit_len(frh->family);
 
 	if (!filter_nlmsg(n, tb, host_len))
 		return 0;
@@ -200,41 +208,41 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 	else
 		fprintf(fp, "0:\t");
 
-	if (r->rtm_flags & FIB_RULE_INVERT)
+	if (frh->flags & FIB_RULE_INVERT)
 		fprintf(fp, "not ");
 
 	if (tb[FRA_SRC]) {
-		if (r->rtm_src_len != host_len) {
+		if (frh->src_len != host_len) {
 			fprintf(fp, "from %s/%u ",
-				rt_addr_n2a_rta(r->rtm_family, tb[FRA_SRC]),
-				r->rtm_src_len);
+				rt_addr_n2a_rta(frh->family, tb[FRA_SRC]),
+				frh->src_len);
 		} else {
 			fprintf(fp, "from %s ",
-				format_host_rta(r->rtm_family, tb[FRA_SRC]));
+				format_host_rta(frh->family, tb[FRA_SRC]));
 		}
-	} else if (r->rtm_src_len) {
-		fprintf(fp, "from 0/%d ", r->rtm_src_len);
+	} else if (frh->src_len) {
+		fprintf(fp, "from 0/%d ", frh->src_len);
 	} else {
 		fprintf(fp, "from all ");
 	}
 
 	if (tb[FRA_DST]) {
-		if (r->rtm_dst_len != host_len) {
+		if (frh->dst_len != host_len) {
 			fprintf(fp, "to %s/%u ",
-				rt_addr_n2a_rta(r->rtm_family, tb[FRA_DST]),
-				r->rtm_dst_len);
+				rt_addr_n2a_rta(frh->family, tb[FRA_DST]),
+				frh->dst_len);
 		} else {
 			fprintf(fp, "to %s ",
-				format_host_rta(r->rtm_family, tb[FRA_DST]));
+				format_host_rta(frh->family, tb[FRA_DST]));
 		}
-	} else if (r->rtm_dst_len) {
-		fprintf(fp, "to 0/%d ", r->rtm_dst_len);
+	} else if (frh->dst_len) {
+		fprintf(fp, "to 0/%d ", frh->dst_len);
 	}
 
-	if (r->rtm_tos) {
+	if (frh->tos) {
 		SPRINT_BUF(b1);
 		fprintf(fp, "tos %s ",
-			rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
+			rtnl_dsfield_n2a(frh->tos, b1, sizeof(b1)));
 	}
 
 	if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) {
@@ -252,13 +260,13 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 
 	if (tb[FRA_IFNAME]) {
 		fprintf(fp, "iif %s ", rta_getattr_str(tb[FRA_IFNAME]));
-		if (r->rtm_flags & FIB_RULE_IIF_DETACHED)
+		if (frh->flags & FIB_RULE_IIF_DETACHED)
 			fprintf(fp, "[detached] ");
 	}
 
 	if (tb[FRA_OIFNAME]) {
 		fprintf(fp, "oif %s ", rta_getattr_str(tb[FRA_OIFNAME]));
-		if (r->rtm_flags & FIB_RULE_OIF_DETACHED)
+		if (frh->flags & FIB_RULE_OIF_DETACHED)
 			fprintf(fp, "[detached] ");
 	}
 
@@ -273,7 +281,7 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 		fprintf(fp, "uidrange %u-%u ", r->start, r->end);
 	}
 
-	table = rtm_get_table(r, tb);
+	table = frh_get_table(frh, tb);
 	if (table) {
 		fprintf(fp, "lookup %s ",
 			rtnl_rttable_n2a(table, b1, sizeof(b1)));
@@ -308,26 +316,26 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 			rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
 	}
 
-	if (r->rtm_type == RTN_NAT) {
+	if (frh->action == RTN_NAT) {
 		if (tb[RTA_GATEWAY]) {
 			fprintf(fp, "map-to %s ",
-				format_host_rta(r->rtm_family,
+				format_host_rta(frh->family,
 						tb[RTA_GATEWAY]));
 		} else
 			fprintf(fp, "masquerade");
-	} else if (r->rtm_type == FR_ACT_GOTO) {
+	} else if (frh->action == FR_ACT_GOTO) {
 		fprintf(fp, "goto ");
 		if (tb[FRA_GOTO])
 			fprintf(fp, "%u", rta_getattr_u32(tb[FRA_GOTO]));
 		else
 			fprintf(fp, "none");
-		if (r->rtm_flags & FIB_RULE_UNRESOLVED)
+		if (frh->flags & FIB_RULE_UNRESOLVED)
 			fprintf(fp, " [unresolved]");
-	} else if (r->rtm_type == FR_ACT_NOP)
+	} else if (frh->action == FR_ACT_NOP)
 		fprintf(fp, "nop");
-	else if (r->rtm_type != RTN_UNICAST)
+	else if (frh->action != FR_ACT_TO_TBL)
 		fprintf(fp, "%s",
-			rtnl_rtntype_n2a(r->rtm_type,
+			rtnl_rtntype_n2a(frh->action,
 					 b1, sizeof(b1)));
 
 	fprintf(fp, "\n");
@@ -373,15 +381,15 @@ static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n,
 		      void *arg)
 {
 	struct rtnl_handle rth2;
-	struct rtmsg *r = NLMSG_DATA(n);
+	struct fib_rule_hdr *frh = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	struct rtattr *tb[FRA_MAX+1];
 
-	len -= NLMSG_LENGTH(sizeof(*r));
+	len -= NLMSG_LENGTH(sizeof(*frh));
 	if (len < 0)
 		return -1;
 
-	parse_rtattr(tb, FRA_MAX, RTM_RTA(r), len);
+	parse_rtattr(tb, FRA_MAX, RTM_RTA(frh), len);
 
 	if (tb[FRA_PRIORITY]) {
 		n->nlmsg_type = RTM_DELRULE;
@@ -577,21 +585,19 @@ static int iprule_modify(int cmd, int argc, char **argv)
 	__u32 tid = 0;
 	struct {
 		struct nlmsghdr	n;
-		struct rtmsg		r;
+		struct fib_rule_hdr	frh;
 		char			buf[1024];
 	} req = {
 		.n.nlmsg_type = cmd,
-		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)),
+		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)),
 		.n.nlmsg_flags = NLM_F_REQUEST,
-		.r.rtm_family = preferred_family,
-		.r.rtm_protocol = RTPROT_BOOT,
-		.r.rtm_scope = RT_SCOPE_UNIVERSE,
-		.r.rtm_type = RTN_UNSPEC,
+		.frh.family = preferred_family,
+		.frh.action = FR_ACT_UNSPEC,
 	};
 
 	if (cmd == RTM_NEWRULE) {
 		req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
-		req.r.rtm_type = RTN_UNICAST;
+		req.frh.action = FR_ACT_TO_TBL;
 	}
 
 	if (cmd == RTM_DELRULE && argc == 0) {
@@ -601,21 +607,21 @@ static int iprule_modify(int cmd, int argc, char **argv)
 
 	while (argc > 0) {
 		if (strcmp(*argv, "not") == 0) {
-			req.r.rtm_flags |= FIB_RULE_INVERT;
+			req.frh.flags |= FIB_RULE_INVERT;
 		} else if (strcmp(*argv, "from") == 0) {
 			inet_prefix dst;
 
 			NEXT_ARG();
-			get_prefix(&dst, *argv, req.r.rtm_family);
-			req.r.rtm_src_len = dst.bitlen;
+			get_prefix(&dst, *argv, req.frh.family);
+			req.frh.src_len = dst.bitlen;
 			addattr_l(&req.n, sizeof(req), FRA_SRC,
 				  &dst.data, dst.bytelen);
 		} else if (strcmp(*argv, "to") == 0) {
 			inet_prefix dst;
 
 			NEXT_ARG();
-			get_prefix(&dst, *argv, req.r.rtm_family);
-			req.r.rtm_dst_len = dst.bitlen;
+			get_prefix(&dst, *argv, req.frh.family);
+			req.frh.dst_len = dst.bitlen;
 			addattr_l(&req.n, sizeof(req), FRA_DST,
 				  &dst.data, dst.bytelen);
 		} else if (matches(*argv, "preference") == 0 ||
@@ -634,7 +640,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
 			NEXT_ARG();
 			if (rtnl_dsfield_a2n(&tos, *argv))
 				invarg("TOS value is invalid\n", *argv);
-			req.r.rtm_tos = tos;
+			req.frh.tos = tos;
 		} else if (strcmp(*argv, "fwmark") == 0) {
 			char *slash;
 			__u32 fwmark, fwmask;
@@ -667,9 +673,9 @@ static int iprule_modify(int cmd, int argc, char **argv)
 			if (rtnl_rttable_a2n(&tid, *argv))
 				invarg("invalid table ID\n", *argv);
 			if (tid < 256)
-				req.r.rtm_table = tid;
+				req.frh.table = tid;
 			else {
-				req.r.rtm_table = RT_TABLE_UNSPEC;
+				req.frh.table = RT_TABLE_UNSPEC;
 				addattr32(&req.n, sizeof(req), FRA_TABLE, tid);
 			}
 			table_ok = 1;
@@ -724,7 +730,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
 			fprintf(stderr, "Warning: route NAT is deprecated\n");
 			addattr32(&req.n, sizeof(req), RTA_GATEWAY,
 				  get_addr32(*argv));
-			req.r.rtm_type = RTN_NAT;
+			req.frh.action = RTN_NAT;
 		} else {
 			int type;
 
@@ -746,7 +752,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
 				type = FR_ACT_NOP;
 			else if (rtnl_rtntype_a2n(&type, *argv))
 				invarg("Failed to parse rule type", *argv);
-			req.r.rtm_type = type;
+			req.frh.action = type;
 			table_ok = 1;
 		}
 		argc--;
@@ -759,11 +765,11 @@ static int iprule_modify(int cmd, int argc, char **argv)
 		return -EINVAL;
 	}
 
-	if (req.r.rtm_family == AF_UNSPEC)
-		req.r.rtm_family = AF_INET;
+	if (req.frh.family == AF_UNSPEC)
+		req.frh.family = AF_INET;
 
 	if (!table_ok && cmd == RTM_NEWRULE)
-		req.r.rtm_table = RT_TABLE_MAIN;
+		req.frh.table = RT_TABLE_MAIN;
 
 	if (rtnl_talk(&rth, &req.n, NULL) < 0)
 		return -2;
-- 
2.14.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ