All of lore.kernel.org
 help / color / mirror / Atom feed
From: Donald Sharp <sharpd@cumulusnetworks.com>
To: netdev@vger.kernel.org
Subject: [PATCH 1/3] ip: Use the `struct fib_rule_hdr` for rules
Date: Sat, 17 Feb 2018 07:47:51 -0500	[thread overview]
Message-ID: <20180217124753.2879-2-sharpd@cumulusnetworks.com> (raw)

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@cumulusnetworks.com>
---
 include/linux/fib_rules.h |   2 +-
 ip/iprule.c               | 105 ++++++++++++++++++++++++----------------------
 2 files changed, 56 insertions(+), 51 deletions(-)

diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
index bbf02a63..21f1fbf3 100644
--- a/include/linux/fib_rules.h
+++ b/include/linux/fib_rules.h
@@ -22,8 +22,8 @@ struct fib_rule_hdr {
 	__u8		tos;
 
 	__u8		table;
+	__u8		proto;	/* reserved */
 	__u8		res1;	/* reserved */
-	__u8		res2;	/* reserved */
 	__u8		action;
 
 	__u32		flags;
diff --git a/ip/iprule.c b/ip/iprule.c
index 854a3d8e..82e22fee 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -50,7 +50,7 @@ static void usage(void)
 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;
@@ -61,13 +61,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 (n->nlmsg_type == RTM_DELRULE)
 		fprintf(fp, "Deleted ");
@@ -77,51 +77,51 @@ 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) {
-			fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family,
+		if (frh->src_len != host_len) {
+			fprintf(fp, "from %s/%u ", rt_addr_n2a(frh->family,
 						       RTA_PAYLOAD(tb[FRA_SRC]),
 						       RTA_DATA(tb[FRA_SRC]),
 						       abuf, sizeof(abuf)),
-				r->rtm_src_len
+				frh->src_len
 				);
 		} else {
-			fprintf(fp, "from %s ", format_host(r->rtm_family,
+			fprintf(fp, "from %s ", format_host(frh->family,
 						       RTA_PAYLOAD(tb[FRA_SRC]),
 						       RTA_DATA(tb[FRA_SRC]),
 						       abuf, sizeof(abuf))
 				);
 		}
-	} 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) {
-			fprintf(fp, "to %s/%u ", rt_addr_n2a(r->rtm_family,
+		if (frh->dst_len != host_len) {
+			fprintf(fp, "to %s/%u ", rt_addr_n2a(frh->family,
 						       RTA_PAYLOAD(tb[FRA_DST]),
 						       RTA_DATA(tb[FRA_DST]),
 						       abuf, sizeof(abuf)),
-				r->rtm_dst_len
+				frh->dst_len
 				);
 		} else {
-			fprintf(fp, "to %s ", format_host(r->rtm_family,
+			fprintf(fp, "to %s ", format_host(frh->family,
 						       RTA_PAYLOAD(tb[FRA_DST]),
 						       RTA_DATA(tb[FRA_DST]),
 						       abuf, sizeof(abuf)));
 		}
-	} 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)));
+		fprintf(fp, "tos %s ", rtnl_dsfield_n2a(frh->tos, b1, sizeof(b1)));
 	}
 
 	if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) {
@@ -139,13 +139,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] ");
 	}
 
@@ -154,7 +154,13 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 			fprintf(fp, "lookup [l3mdev-table] ");
 	}
 
-	table = rtm_get_table(r, tb);
+	/*
+	 * struct fib_rule_hdr and struct rtmsg
+	 * were intentionally the same.  Since
+	 * the table is the rtm_table, just call
+	 * it.
+	 */
+	table = rtm_get_table((struct rtmsg *)frh, tb);
 	if (table) {
 		fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
 
@@ -185,27 +191,27 @@ 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(r->rtm_family,
+				format_host(frh->family,
 					    RTA_PAYLOAD(tb[RTA_GATEWAY]),
 					    RTA_DATA(tb[RTA_GATEWAY]),
 					    abuf, sizeof(abuf)));
 		} 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)
-		fprintf(fp, "%s", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
+	else if (frh->action != RTN_UNICAST)
+		fprintf(fp, "%s", rtnl_rtntype_n2a(frh->action, b1, sizeof(b1)));
 
 	fprintf(fp, "\n");
 	fflush(fp);
@@ -245,7 +251,7 @@ 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;
 
@@ -254,32 +260,31 @@ static int iprule_modify(int cmd, int argc, char **argv)
 	req.n.nlmsg_type = cmd;
 	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
 	req.n.nlmsg_flags = NLM_F_REQUEST;
-	req.r.rtm_family = preferred_family;
-	req.r.rtm_protocol = RTPROT_BOOT;
-	req.r.rtm_scope = RT_SCOPE_UNIVERSE;
-	req.r.rtm_table = 0;
-	req.r.rtm_type = RTN_UNSPEC;
-	req.r.rtm_flags = 0;
+	req.frh.family = preferred_family;
+	req.frh.proto = RTPROT_BOOT;
+	req.frh.table = 0;
+	req.frh.action = RTN_UNSPEC;
+	req.frh.flags = 0;
 
 	if (cmd == RTM_NEWRULE) {
 		req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
-		req.r.rtm_type = RTN_UNICAST;
+		req.frh.action = RTN_UNICAST;
 	}
 
 	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 ||
 			   matches(*argv, "order") == 0 ||
@@ -295,7 +300,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;
@@ -322,9 +327,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;
@@ -358,7 +363,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
 			NEXT_ARG();
 			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;
 
@@ -378,7 +383,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--;
@@ -391,11 +396,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) < 0)
 		return -2;
-- 
2.14.3

                 reply	other threads:[~2018-02-17 12:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180217124753.2879-2-sharpd@cumulusnetworks.com \
    --to=sharpd@cumulusnetworks.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.