aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Eggers <ceggers@arri.de>2020-06-29 17:57:25 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2020-07-31 18:45:36 +0200
commit31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c (patch)
tree71e199586ec96963257a76950669adff0fa739d5
parent39925026f6857979cbe603efd42073eb63f8d9de (diff)
downloadbusybox-w32-31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c.tar.gz
busybox-w32-31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c.tar.bz2
busybox-w32-31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c.zip
ip: Add support for "noprefixroute" option
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@arri.de> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/ip.c4
-rw-r--r--networking/libiproute/ipaddress.c45
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 @@
146//usage:#define ipaddr_trivial_usage 146//usage:#define ipaddr_trivial_usage
147//usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]" 147//usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]"
148//usage:#define ipaddr_full_usage "\n\n" 148//usage:#define ipaddr_full_usage "\n\n"
149//usage: "ipaddr add|change|replace|delete dev IFACE IFADDR\n" 149//usage: "ipaddr add|change|replace|delete dev IFACE [CONFFLAG-LIST] IFADDR\n"
150//usage: " IFADDR := PREFIX | ADDR peer PREFIX [broadcast ADDR|+|-]\n" 150//usage: " IFADDR := PREFIX | ADDR peer PREFIX [broadcast ADDR|+|-]\n"
151//usage: " [anycast ADDR] [label STRING] [scope SCOPE]\n" 151//usage: " [anycast ADDR] [label STRING] [scope SCOPE]\n"
152//usage: " PREFIX := ADDR[/MASK]\n" 152//usage: " PREFIX := ADDR[/MASK]\n"
153//usage: " SCOPE := [host|link|global|NUMBER]\n" 153//usage: " SCOPE := [host|link|global|NUMBER]\n"
154//usage: " CONFFLAG-LIST := [CONFFLAG-LIST] CONFFLAG\n"
155//usage: " CONFFLAG := [noprefixroute]\n"
154//usage: "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]" 156//usage: "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]"
155//usage: 157//usage:
156//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 158//--------------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,
217{ 217{
218 struct ifaddrmsg *ifa = NLMSG_DATA(n); 218 struct ifaddrmsg *ifa = NLMSG_DATA(n);
219 int len = n->nlmsg_len; 219 int len = n->nlmsg_len;
220 unsigned int ifa_flags;
220 struct rtattr *rta_tb[IFA_MAX+1]; 221 struct rtattr *rta_tb[IFA_MAX+1];
221 222
222 if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) 223 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,
233 //memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr does this 234 //memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr does this
234 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); 235 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
235 236
237 ifa_flags = rta_tb[IFA_FLAGS] ? *(__u32*)RTA_DATA(rta_tb[IFA_FLAGS]) : ifa->ifa_flags;
238
236 if (!rta_tb[IFA_LOCAL]) 239 if (!rta_tb[IFA_LOCAL])
237 rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; 240 rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
238 if (!rta_tb[IFA_ADDRESS]) 241 if (!rta_tb[IFA_ADDRESS])
@@ -242,7 +245,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
242 return 0; 245 return 0;
243 if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask) 246 if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
244 return 0; 247 return 0;
245 if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask) 248 if ((G_filter.flags ^ ifa_flags) & G_filter.flagmask)
246 return 0; 249 return 0;
247 if (G_filter.label) { 250 if (G_filter.label) {
248 const char *label; 251 const char *label;
@@ -322,28 +325,32 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
322 ); 325 );
323 } 326 }
324 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope)); 327 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope));
325 if (ifa->ifa_flags & IFA_F_SECONDARY) { 328 if (ifa_flags & IFA_F_SECONDARY) {
326 ifa->ifa_flags &= ~IFA_F_SECONDARY; 329 ifa_flags &= ~IFA_F_SECONDARY;
327 printf("secondary "); 330 printf("secondary ");
328 } 331 }
329 if (ifa->ifa_flags & IFA_F_TENTATIVE) { 332 if (ifa_flags & IFA_F_TENTATIVE) {
330 ifa->ifa_flags &= ~IFA_F_TENTATIVE; 333 ifa_flags &= ~IFA_F_TENTATIVE;
331 printf("tentative "); 334 printf("tentative ");
332 } 335 }
333 if (ifa->ifa_flags & IFA_F_DADFAILED) { 336 if (ifa_flags & IFA_F_DADFAILED) {
334 ifa->ifa_flags &= ~IFA_F_DADFAILED; 337 ifa_flags &= ~IFA_F_DADFAILED;
335 printf("dadfailed "); 338 printf("dadfailed ");
336 } 339 }
337 if (ifa->ifa_flags & IFA_F_DEPRECATED) { 340 if (ifa_flags & IFA_F_DEPRECATED) {
338 ifa->ifa_flags &= ~IFA_F_DEPRECATED; 341 ifa_flags &= ~IFA_F_DEPRECATED;
339 printf("deprecated "); 342 printf("deprecated ");
340 } 343 }
341 if (!(ifa->ifa_flags & IFA_F_PERMANENT)) { 344 if (!(ifa_flags & IFA_F_PERMANENT)) {
342 printf("dynamic "); 345 printf("dynamic ");
343 } else 346 } else
344 ifa->ifa_flags &= ~IFA_F_PERMANENT; 347 ifa_flags &= ~IFA_F_PERMANENT;
345 if (ifa->ifa_flags) 348 if (ifa_flags & IFA_F_NOPREFIXROUTE) {
346 printf("flags %02x ", ifa->ifa_flags); 349 ifa_flags &= ~IFA_F_NOPREFIXROUTE;
350 printf("noprefixroute ");
351 }
352 if (ifa_flags)
353 printf("flags %02x ", ifa_flags);
347 if (rta_tb[IFA_LABEL]) 354 if (rta_tb[IFA_LABEL])
348 fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout); 355 fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout);
349 if (rta_tb[IFA_CACHEINFO]) { 356 if (rta_tb[IFA_CACHEINFO]) {
@@ -600,7 +607,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
600 /* If you add stuff here, update ipaddr_full_usage */ 607 /* If you add stuff here, update ipaddr_full_usage */
601 static const char option[] ALIGN1 = 608 static const char option[] ALIGN1 =
602 "peer\0""remote\0""broadcast\0""brd\0" 609 "peer\0""remote\0""broadcast\0""brd\0"
603 "anycast\0""scope\0""dev\0""label\0""local\0"; 610 "anycast\0""scope\0""dev\0""label\0""noprefixroute\0""local\0";
604#define option_peer option 611#define option_peer option
605#define option_broadcast (option + sizeof("peer") + sizeof("remote")) 612#define option_broadcast (option + sizeof("peer") + sizeof("remote"))
606#define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd")) 613#define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd"))
@@ -619,6 +626,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
619 int brd_len = 0; 626 int brd_len = 0;
620 int any_len = 0; 627 int any_len = 0;
621 bool scoped = 0; 628 bool scoped = 0;
629 unsigned int ifa_flags = 0;
622 630
623 memset(&req, 0, sizeof(req)); 631 memset(&req, 0, sizeof(req));
624 632
@@ -630,7 +638,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
630 while (*argv) { 638 while (*argv) {
631 unsigned arg = index_in_strings(option, *argv); 639 unsigned arg = index_in_strings(option, *argv);
632 /* if search fails, "local" is assumed */ 640 /* if search fails, "local" is assumed */
633 if ((int)arg >= 0) 641 if ((int)arg >= 0 && arg != 8)
634 NEXT_ARG(); 642 NEXT_ARG();
635 643
636 if (arg <= 1) { /* peer, remote */ 644 if (arg <= 1) { /* peer, remote */
@@ -683,6 +691,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
683 } else if (arg == 7) { /* label */ 691 } else if (arg == 7) { /* label */
684 l = *argv; 692 l = *argv;
685 addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1); 693 addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
694 } else if (arg == 8) { /* noprefixroute */
695 ifa_flags |= IFA_F_NOPREFIXROUTE;
686 } else { 696 } else {
687 /* local (specified or assumed) */ 697 /* local (specified or assumed) */
688 if (local_len) { 698 if (local_len) {
@@ -698,6 +708,11 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
698 argv++; 708 argv++;
699 } 709 }
700 710
711 if (ifa_flags <= 0xff)
712 req.ifa.ifa_flags = ifa_flags;
713 else
714 addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags);
715
701 if (!d) { 716 if (!d) {
702 /* There was no "dev IFACE", but we need that */ 717 /* There was no "dev IFACE", but we need that */
703 bb_simple_error_msg_and_die("need \"dev IFACE\""); 718 bb_simple_error_msg_and_die("need \"dev IFACE\"");