diff options
author | Christian Eggers <ceggers@arri.de> | 2020-06-29 17:57:25 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-07-31 18:45:36 +0200 |
commit | 31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c (patch) | |
tree | 71e199586ec96963257a76950669adff0fa739d5 | |
parent | 39925026f6857979cbe603efd42073eb63f8d9de (diff) | |
download | busybox-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.c | 4 | ||||
-rw-r--r-- | 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 @@ | |||
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\""); |