[PATCH 2/3] ip: Add support for "noprefixroute" option

Christian Eggers ceggers at arri.de
Mon Jun 29 15:57:25 UTC 2020


The "noprefixroute" option suppresses automatic generation of a routing
table entry based on the interface's ip address.

The ifa_flags field has only 8 bit. If higher bits are set,
rta_tb[IFA_FLAGS] has to be used instead.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 networking/ip.c                   |  4 ++-
 networking/libiproute/ipaddress.c | 45 ++++++++++++++++++++-----------
 2 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/networking/ip.c b/networking/ip.c
index 034ee4fc8..45bf1dc0a 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -146,11 +146,13 @@
 //usage:#define ipaddr_trivial_usage
 //usage:       "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]"
 //usage:#define ipaddr_full_usage "\n\n"
-//usage:       "ipaddr add|change|replace|delete dev IFACE IFADDR\n"
+//usage:       "ipaddr add|change|replace|delete dev IFACE [CONFFLAG-LIST] IFADDR\n"
 //usage:       "	IFADDR := PREFIX | ADDR peer PREFIX [broadcast ADDR|+|-]\n"
 //usage:       "		[anycast ADDR] [label STRING] [scope SCOPE]\n"
 //usage:       "	PREFIX := ADDR[/MASK]\n"
 //usage:       "	SCOPE := [host|link|global|NUMBER]\n"
+//usage:       "	CONFFLAG-LIST := [CONFFLAG-LIST] CONFFLAG\n"
+//usage:       "	CONFFLAG := [noprefixroute]\n"
 //usage:       "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]"
 //usage:
 //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 86cf3beea..6cfd3c398 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -217,6 +217,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
 {
 	struct ifaddrmsg *ifa = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
+	unsigned int ifa_flags;
 	struct rtattr *rta_tb[IFA_MAX+1];
 
 	if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
@@ -233,6 +234,8 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
 	//memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr does this
 	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
 
+	ifa_flags = rta_tb[IFA_FLAGS] ? *(__u32*)RTA_DATA(rta_tb[IFA_FLAGS]) : ifa->ifa_flags;
+
 	if (!rta_tb[IFA_LOCAL])
 		rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
 	if (!rta_tb[IFA_ADDRESS])
@@ -242,7 +245,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
 		return 0;
 	if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
 		return 0;
-	if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask)
+	if ((G_filter.flags ^ ifa_flags) & G_filter.flagmask)
 		return 0;
 	if (G_filter.label) {
 		const char *label;
@@ -322,28 +325,32 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
 		);
 	}
 	printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope));
-	if (ifa->ifa_flags & IFA_F_SECONDARY) {
-		ifa->ifa_flags &= ~IFA_F_SECONDARY;
+	if (ifa_flags & IFA_F_SECONDARY) {
+		ifa_flags &= ~IFA_F_SECONDARY;
 		printf("secondary ");
 	}
-	if (ifa->ifa_flags & IFA_F_TENTATIVE) {
-		ifa->ifa_flags &= ~IFA_F_TENTATIVE;
+	if (ifa_flags & IFA_F_TENTATIVE) {
+		ifa_flags &= ~IFA_F_TENTATIVE;
 		printf("tentative ");
 	}
-	if (ifa->ifa_flags & IFA_F_DADFAILED) {
-		ifa->ifa_flags &= ~IFA_F_DADFAILED;
+	if (ifa_flags & IFA_F_DADFAILED) {
+		ifa_flags &= ~IFA_F_DADFAILED;
 		printf("dadfailed ");
 	}
-	if (ifa->ifa_flags & IFA_F_DEPRECATED) {
-		ifa->ifa_flags &= ~IFA_F_DEPRECATED;
+	if (ifa_flags & IFA_F_DEPRECATED) {
+		ifa_flags &= ~IFA_F_DEPRECATED;
 		printf("deprecated ");
 	}
-	if (!(ifa->ifa_flags & IFA_F_PERMANENT)) {
+	if (!(ifa_flags & IFA_F_PERMANENT)) {
 		printf("dynamic ");
 	} else
-		ifa->ifa_flags &= ~IFA_F_PERMANENT;
-	if (ifa->ifa_flags)
-		printf("flags %02x ", ifa->ifa_flags);
+		ifa_flags &= ~IFA_F_PERMANENT;
+	if (ifa_flags & IFA_F_NOPREFIXROUTE) {
+		ifa_flags &= ~IFA_F_NOPREFIXROUTE;
+		printf("noprefixroute ");
+	}
+	if (ifa_flags)
+		printf("flags %02x ", ifa_flags);
 	if (rta_tb[IFA_LABEL])
 		fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout);
 	if (rta_tb[IFA_CACHEINFO]) {
@@ -600,7 +607,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
 	/* If you add stuff here, update ipaddr_full_usage */
 	static const char option[] ALIGN1 =
 		"peer\0""remote\0""broadcast\0""brd\0"
-		"anycast\0""scope\0""dev\0""label\0""local\0";
+		"anycast\0""scope\0""dev\0""label\0""noprefixroute\0""local\0";
 #define option_peer      option
 #define option_broadcast (option           + sizeof("peer") + sizeof("remote"))
 #define option_anycast   (option_broadcast + sizeof("broadcast") + sizeof("brd"))
@@ -619,6 +626,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
 	int brd_len = 0;
 	int any_len = 0;
 	bool scoped = 0;
+	unsigned int ifa_flags = 0;
 
 	memset(&req, 0, sizeof(req));
 
@@ -630,7 +638,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
 	while (*argv) {
 		unsigned arg = index_in_strings(option, *argv);
 		/* if search fails, "local" is assumed */
-		if ((int)arg >= 0)
+		if ((int)arg >= 0 && arg != 8)
 			NEXT_ARG();
 
 		if (arg <= 1) { /* peer, remote */
@@ -683,6 +691,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
 		} else if (arg == 7) { /* label */
 			l = *argv;
 			addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
+		} else if (arg == 8) { /* noprefixroute */
+			ifa_flags |= IFA_F_NOPREFIXROUTE;
 		} else {
 			/* local (specified or assumed) */
 			if (local_len) {
@@ -698,6 +708,11 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
 		argv++;
 	}
 
+	if (ifa_flags <= 0xff)
+		req.ifa.ifa_flags = ifa_flags;
+	else
+		addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags);
+
 	if (!d) {
 		/* There was no "dev IFACE", but we need that */
 		bb_simple_error_msg_and_die("need \"dev IFACE\"");
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



More information about the busybox mailing list