summaryrefslogtreecommitdiff
path: root/networking/libiproute/ipaddress.c
diff options
context:
space:
mode:
authorChristian Eggers2020-06-29 17:57:25 +0200
committerDenys Vlasenko2020-07-31 18:45:36 +0200
commit31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c (patch)
tree71e199586ec96963257a76950669adff0fa739d5 /networking/libiproute/ipaddress.c
parent39925026f6857979cbe603efd42073eb63f8d9de (diff)
downloadbusybox-31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c.zip
busybox-31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c.tar.gz
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>
Diffstat (limited to 'networking/libiproute/ipaddress.c')
-rw-r--r--networking/libiproute/ipaddress.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 86cf3be..6cfd3c3 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\"");