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 <cegg...@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

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to