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>
This commit is contained in:
parent
39925026f6
commit
31d34f3bd8
@ -146,11 +146,13 @@
|
|||||||
//usage:#define ipaddr_trivial_usage
|
//usage:#define ipaddr_trivial_usage
|
||||||
//usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]"
|
//usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]"
|
||||||
//usage:#define ipaddr_full_usage "\n\n"
|
//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: " IFADDR := PREFIX | ADDR peer PREFIX [broadcast ADDR|+|-]\n"
|
||||||
//usage: " [anycast ADDR] [label STRING] [scope SCOPE]\n"
|
//usage: " [anycast ADDR] [label STRING] [scope SCOPE]\n"
|
||||||
//usage: " PREFIX := ADDR[/MASK]\n"
|
//usage: " PREFIX := ADDR[/MASK]\n"
|
||||||
//usage: " SCOPE := [host|link|global|NUMBER]\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: "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]"
|
||||||
//usage:
|
//usage:
|
||||||
//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
|
//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
|
||||||
|
@ -217,6 +217,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
|
|||||||
{
|
{
|
||||||
struct ifaddrmsg *ifa = NLMSG_DATA(n);
|
struct ifaddrmsg *ifa = NLMSG_DATA(n);
|
||||||
int len = n->nlmsg_len;
|
int len = n->nlmsg_len;
|
||||||
|
unsigned int ifa_flags;
|
||||||
struct rtattr *rta_tb[IFA_MAX+1];
|
struct rtattr *rta_tb[IFA_MAX+1];
|
||||||
|
|
||||||
if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
|
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
|
//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)));
|
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])
|
if (!rta_tb[IFA_LOCAL])
|
||||||
rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
|
rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
|
||||||
if (!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;
|
return 0;
|
||||||
if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
|
if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
|
||||||
return 0;
|
return 0;
|
||||||
if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask)
|
if ((G_filter.flags ^ ifa_flags) & G_filter.flagmask)
|
||||||
return 0;
|
return 0;
|
||||||
if (G_filter.label) {
|
if (G_filter.label) {
|
||||||
const char *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));
|
printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope));
|
||||||
if (ifa->ifa_flags & IFA_F_SECONDARY) {
|
if (ifa_flags & IFA_F_SECONDARY) {
|
||||||
ifa->ifa_flags &= ~IFA_F_SECONDARY;
|
ifa_flags &= ~IFA_F_SECONDARY;
|
||||||
printf("secondary ");
|
printf("secondary ");
|
||||||
}
|
}
|
||||||
if (ifa->ifa_flags & IFA_F_TENTATIVE) {
|
if (ifa_flags & IFA_F_TENTATIVE) {
|
||||||
ifa->ifa_flags &= ~IFA_F_TENTATIVE;
|
ifa_flags &= ~IFA_F_TENTATIVE;
|
||||||
printf("tentative ");
|
printf("tentative ");
|
||||||
}
|
}
|
||||||
if (ifa->ifa_flags & IFA_F_DADFAILED) {
|
if (ifa_flags & IFA_F_DADFAILED) {
|
||||||
ifa->ifa_flags &= ~IFA_F_DADFAILED;
|
ifa_flags &= ~IFA_F_DADFAILED;
|
||||||
printf("dadfailed ");
|
printf("dadfailed ");
|
||||||
}
|
}
|
||||||
if (ifa->ifa_flags & IFA_F_DEPRECATED) {
|
if (ifa_flags & IFA_F_DEPRECATED) {
|
||||||
ifa->ifa_flags &= ~IFA_F_DEPRECATED;
|
ifa_flags &= ~IFA_F_DEPRECATED;
|
||||||
printf("deprecated ");
|
printf("deprecated ");
|
||||||
}
|
}
|
||||||
if (!(ifa->ifa_flags & IFA_F_PERMANENT)) {
|
if (!(ifa_flags & IFA_F_PERMANENT)) {
|
||||||
printf("dynamic ");
|
printf("dynamic ");
|
||||||
} else
|
} else
|
||||||
ifa->ifa_flags &= ~IFA_F_PERMANENT;
|
ifa_flags &= ~IFA_F_PERMANENT;
|
||||||
if (ifa->ifa_flags)
|
if (ifa_flags & IFA_F_NOPREFIXROUTE) {
|
||||||
printf("flags %02x ", ifa->ifa_flags);
|
ifa_flags &= ~IFA_F_NOPREFIXROUTE;
|
||||||
|
printf("noprefixroute ");
|
||||||
|
}
|
||||||
|
if (ifa_flags)
|
||||||
|
printf("flags %02x ", ifa_flags);
|
||||||
if (rta_tb[IFA_LABEL])
|
if (rta_tb[IFA_LABEL])
|
||||||
fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout);
|
fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout);
|
||||||
if (rta_tb[IFA_CACHEINFO]) {
|
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 */
|
/* If you add stuff here, update ipaddr_full_usage */
|
||||||
static const char option[] ALIGN1 =
|
static const char option[] ALIGN1 =
|
||||||
"peer\0""remote\0""broadcast\0""brd\0"
|
"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_peer option
|
||||||
#define option_broadcast (option + sizeof("peer") + sizeof("remote"))
|
#define option_broadcast (option + sizeof("peer") + sizeof("remote"))
|
||||||
#define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd"))
|
#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 brd_len = 0;
|
||||||
int any_len = 0;
|
int any_len = 0;
|
||||||
bool scoped = 0;
|
bool scoped = 0;
|
||||||
|
unsigned int ifa_flags = 0;
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
|
|
||||||
@ -630,7 +638,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
|
|||||||
while (*argv) {
|
while (*argv) {
|
||||||
unsigned arg = index_in_strings(option, *argv);
|
unsigned arg = index_in_strings(option, *argv);
|
||||||
/* if search fails, "local" is assumed */
|
/* if search fails, "local" is assumed */
|
||||||
if ((int)arg >= 0)
|
if ((int)arg >= 0 && arg != 8)
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
|
|
||||||
if (arg <= 1) { /* peer, remote */
|
if (arg <= 1) { /* peer, remote */
|
||||||
@ -683,6 +691,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
|
|||||||
} else if (arg == 7) { /* label */
|
} else if (arg == 7) { /* label */
|
||||||
l = *argv;
|
l = *argv;
|
||||||
addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
|
addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
|
||||||
|
} else if (arg == 8) { /* noprefixroute */
|
||||||
|
ifa_flags |= IFA_F_NOPREFIXROUTE;
|
||||||
} else {
|
} else {
|
||||||
/* local (specified or assumed) */
|
/* local (specified or assumed) */
|
||||||
if (local_len) {
|
if (local_len) {
|
||||||
@ -698,6 +708,11 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
|
|||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ifa_flags <= 0xff)
|
||||||
|
req.ifa.ifa_flags = ifa_flags;
|
||||||
|
else
|
||||||
|
addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags);
|
||||||
|
|
||||||
if (!d) {
|
if (!d) {
|
||||||
/* There was no "dev IFACE", but we need that */
|
/* There was no "dev IFACE", but we need that */
|
||||||
bb_simple_error_msg_and_die("need \"dev IFACE\"");
|
bb_simple_error_msg_and_die("need \"dev IFACE\"");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user