]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
Improvements to address utilities
authorThomas Graf <tgr@lsx.localdomain>
Tue, 17 Jun 2008 00:52:18 +0000 (02:52 +0200)
committerThomas Graf <tgr@lsx.localdomain>
Tue, 17 Jun 2008 00:52:18 +0000 (02:52 +0200)
- Moved env var dumping to nl-addr-list.c
- support for ipv6 lifetimes
- correct and complete help texts

include/netlink/route/addr.h
lib/route/addr.c
src/addr-utils.c
src/addr-utils.h
src/nl-addr-add.c
src/nl-addr-delete.c
src/nl-addr-list.c

index a3e18965b5a63d19b3c7977c20d7dc5d0244b4b9..826deae97863cf8554d8353de82937cc4805a460 100644 (file)
@@ -74,6 +74,13 @@ extern struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *);
 extern int     rtnl_addr_set_multicast(struct rtnl_addr *, struct nl_addr *);
 extern struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *);
 
+extern uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *);
+extern void    rtnl_addr_set_valid_lifetime(struct rtnl_addr *, uint32_t);
+extern uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *);
+extern void    rtnl_addr_set_preferred_lifetime(struct rtnl_addr *, uint32_t);
+extern uint32_t rtnl_addr_get_create_time(struct rtnl_addr *);
+extern uint32_t rtnl_addr_get_last_update_time(struct rtnl_addr *);
+
 #ifdef __cplusplus
 }
 #endif
index f4c55d3e4e1fc679fd4b317ef911dc4a403f3a16..000501173683bc4e41a4a7b424149570a0638e60 100644 (file)
@@ -131,6 +131,13 @@ static struct nl_cache_ops rtnl_addr_ops;
 static struct nl_object_ops addr_obj_ops;
 /** @endcond */
 
+static void addr_constructor(struct nl_object *obj)
+{
+       struct rtnl_addr *addr = nl_object_priv(obj);
+
+       addr->a_scope = RT_SCOPE_NOWHERE;
+}
+
 static void addr_free_data(struct nl_object *obj)
 {
        struct rtnl_addr *addr = nl_object_priv(obj);
@@ -383,28 +390,16 @@ static void addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
        nl_dump_line(p, "  <family>%s</family>\n",
                     nl_af2str(addr->a_family, buf, sizeof(buf)));
 
-       if (addr->ce_mask & ADDR_ATTR_LOCAL)
-               nl_dump_line(p, "  <local>%s</local>\n",
-                            nl_addr2str(addr->a_local, buf, sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_PEER)
-               nl_dump_line(p, "  <peer>%s</peer>\n",
-                            nl_addr2str(addr->a_peer, buf, sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_BROADCAST)
-               nl_dump_line(p, "  <broadcast>%s</broadcast>\n",
-                            nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
+       nl_dump_line(p, "  <local>%s</local>\n",
+                    nl_addr2str(addr->a_local, buf, sizeof(buf)));
+       nl_dump_line(p, "  <peer>%s</peer>\n",
+                    nl_addr2str(addr->a_peer, buf, sizeof(buf)));
+       nl_dump_line(p, "  <broadcast>%s</broadcast>\n",
+                    nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
+       nl_dump_line(p, "  <multicast>%s</multicast>\n",
+                    nl_addr2str(addr->a_multicast, buf, sizeof(buf)));
 
-       if (addr->ce_mask & ADDR_ATTR_MULTICAST)
-               nl_dump_line(p, "  <multicast>%s</multicast>\n",
-                            nl_addr2str(addr->a_multicast, buf,
-                                          sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
-               nl_dump_line(p, "  <prefixlen>%u</prefixlen>\n",
-                            addr->a_prefixlen);
        link_cache = nl_cache_mngt_require("route/link");
-
        if (link_cache)
                nl_dump_line(p, "  <device>%s</device>\n",
                             rtnl_link_i2name(link_cache, addr->a_ifindex,
@@ -412,12 +407,10 @@ static void addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
        else
                nl_dump_line(p, "  <device>%u</device>\n", addr->a_ifindex);
 
-       if (addr->ce_mask & ADDR_ATTR_SCOPE)
-               nl_dump_line(p, "  <scope>%s</scope>\n",
-                            rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
+       nl_dump_line(p, "  <scope>%s</scope>\n",
+                    rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
 
-       if (addr->ce_mask & ADDR_ATTR_LABEL)
-               nl_dump_line(p, "  <label>%s</label>\n", addr->a_label);
+       nl_dump_line(p, "  <label>%s</label>\n", addr->a_label);
 
        rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
        if (buf[0])
@@ -427,23 +420,23 @@ static void addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
                struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
 
                nl_dump_line(p, "  <cacheinfo>\n");
-               nl_dump_line(p, "    <valid>%s</valid>\n",
-                            ci->aci_valid == 0xFFFFFFFFU ? "forever" :
-                            nl_msec2str(ci->aci_valid * 1000,
-                                          buf, sizeof(buf)));
+               if (ci->aci_valid == 0xFFFFFFFFU)
+                       nl_dump_line(p, "    <valid>forever</valid>\n");
+               else
+                       nl_dump_line(p, "    <valid>%u</valid>\n",
+                                    ci->aci_valid);
 
-               nl_dump_line(p, "    <prefered>%s</prefered>\n",
-                            ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
-                            nl_msec2str(ci->aci_prefered * 1000,
-                                        buf, sizeof(buf)));
+               if (ci->aci_prefered == 0xFFFFFFFFU)
+                       nl_dump_line(p, "    <preferred>forever</preferred>\n");
+               else
+                       nl_dump_line(p, "    <preferred>%s</preferred>\n",
+                                    ci->aci_prefered);
 
-               nl_dump_line(p, "    <created>%s</created>\n",
-                            nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
-                                        buf, sizeof(buf)));
+               nl_dump_line(p, "    <created>%u</created>\n",
+                            addr->a_cacheinfo.aci_cstamp);
 
-               nl_dump_line(p, "    <last-update>%s</last-update>\n",
-                            nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
-                                        buf, sizeof(buf)));
+               nl_dump_line(p, "    <last-update>%u</last-update>\n",
+                            addr->a_cacheinfo.aci_tstamp);
 
                nl_dump_line(p, "  </cacheinfo>\n");
        }
@@ -451,77 +444,6 @@ static void addr_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
        nl_dump_line(p, "</address>\n");
 }
 
-static void addr_dump_env(struct nl_object *obj, struct nl_dump_params *p)
-{
-       struct rtnl_addr *addr = (struct rtnl_addr *) obj;
-       struct nl_cache *link_cache;
-       char buf[128];
-
-       nl_dump_line(p, "ADDR_FAMILY=%s\n",
-                    nl_af2str(addr->a_family, buf, sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_LOCAL)
-               nl_dump_line(p, "ADDR_LOCAL=%s\n",
-                            nl_addr2str(addr->a_local, buf, sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_PEER)
-               nl_dump_line(p, "ADDR_PEER=%s\n",
-                            nl_addr2str(addr->a_peer, buf, sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_BROADCAST)
-               nl_dump_line(p, "ADDR_BROADCAST=%s\n",
-                            nl_addr2str(addr->a_bcast, buf, sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_MULTICAST)
-               nl_dump_line(p, "ADDR_MULTICAST=%s\n",
-                            nl_addr2str(addr->a_multicast, buf,
-                                          sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
-               nl_dump_line(p, "ADDR_PREFIXLEN=%u\n",
-                            addr->a_prefixlen);
-       link_cache = nl_cache_mngt_require("route/link");
-
-       nl_dump_line(p, "ADDR_IFINDEX=%u\n", addr->a_ifindex);
-       if (link_cache)
-               nl_dump_line(p, "ADDR_IFNAME=%s\n",
-                            rtnl_link_i2name(link_cache, addr->a_ifindex,
-                                             buf, sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_SCOPE)
-               nl_dump_line(p, "ADDR_SCOPE=%s\n",
-                            rtnl_scope2str(addr->a_scope, buf, sizeof(buf)));
-
-       if (addr->ce_mask & ADDR_ATTR_LABEL)
-               nl_dump_line(p, "ADDR_LABEL=%s\n", addr->a_label);
-
-       rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf));
-       if (buf[0])
-               nl_dump_line(p, "ADDR_FLAGS=%s\n", buf);
-
-       if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
-               struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
-
-               nl_dump_line(p, "ADDR_CACHEINFO_VALID=%s\n",
-                            ci->aci_valid == 0xFFFFFFFFU ? "forever" :
-                            nl_msec2str(ci->aci_valid * 1000,
-                                          buf, sizeof(buf)));
-
-               nl_dump_line(p, "ADDR_CACHEINFO_PREFERED=%s\n",
-                            ci->aci_prefered == 0xFFFFFFFFU ? "forever" :
-                            nl_msec2str(ci->aci_prefered * 1000,
-                                        buf, sizeof(buf)));
-
-               nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%s\n",
-                            nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10,
-                                        buf, sizeof(buf)));
-
-               nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%s\n",
-                            nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10,
-                                        buf, sizeof(buf)));
-       }
-}
-
 static int addr_compare(struct nl_object *_a, struct nl_object *_b,
                        uint32_t attrs, int flags)
 {
@@ -644,6 +566,16 @@ static int build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags,
        if (tmpl->ce_mask & ADDR_ATTR_BROADCAST)
                NLA_PUT_ADDR(msg, IFA_BROADCAST, tmpl->a_bcast);
 
+       if (tmpl->ce_mask & ADDR_ATTR_CACHEINFO) {
+               struct ifa_cacheinfo ca = {
+                       .ifa_valid = tmpl->a_cacheinfo.aci_valid,
+                       .ifa_prefered = tmpl->a_cacheinfo.aci_prefered,
+               };
+
+               NLA_PUT(msg, IFA_CACHEINFO, sizeof(ca), &ca);
+       }
+
+
        *result = msg;
        return 0;
 
@@ -849,10 +781,7 @@ void rtnl_addr_set_prefixlen(struct rtnl_addr *addr, int prefix)
 
 int rtnl_addr_get_prefixlen(struct rtnl_addr *addr)
 {
-       if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
-               return addr->a_prefixlen;
-       else
-               return -1;
+       return addr->a_prefixlen;
 }
 
 void rtnl_addr_set_scope(struct rtnl_addr *addr, int scope)
@@ -863,10 +792,7 @@ void rtnl_addr_set_scope(struct rtnl_addr *addr, int scope)
 
 int rtnl_addr_get_scope(struct rtnl_addr *addr)
 {
-       if (addr->ce_mask & ADDR_ATTR_SCOPE)
-               return addr->a_scope;
-       else
-               return -1;
+       return addr->a_scope;
 }
 
 void rtnl_addr_set_flags(struct rtnl_addr *addr, unsigned int flags)
@@ -924,10 +850,7 @@ int rtnl_addr_set_local(struct rtnl_addr *addr, struct nl_addr *local)
 
 struct nl_addr *rtnl_addr_get_local(struct rtnl_addr *addr)
 {
-       if (addr->ce_mask & ADDR_ATTR_LOCAL)
-               return addr->a_local;
-       else
-               return NULL;
+       return addr->a_local;
 }
 
 int rtnl_addr_set_peer(struct rtnl_addr *addr, struct nl_addr *peer)
@@ -942,10 +865,7 @@ int rtnl_addr_set_peer(struct rtnl_addr *addr, struct nl_addr *peer)
 
 struct nl_addr *rtnl_addr_get_peer(struct rtnl_addr *addr)
 {
-       if (addr->ce_mask & ADDR_ATTR_PEER)
-               return addr->a_peer;
-       else
-               return NULL;
+       return addr->a_peer;
 }
 
 int rtnl_addr_set_broadcast(struct rtnl_addr *addr, struct nl_addr *bcast)
@@ -955,10 +875,7 @@ int rtnl_addr_set_broadcast(struct rtnl_addr *addr, struct nl_addr *bcast)
 
 struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *addr)
 {
-       if (addr->ce_mask & ADDR_ATTR_BROADCAST)
-               return addr->a_bcast;
-       else
-               return NULL;
+       return addr->a_bcast;
 }
 
 int rtnl_addr_set_multicast(struct rtnl_addr *addr, struct nl_addr *multicast)
@@ -969,10 +886,45 @@ int rtnl_addr_set_multicast(struct rtnl_addr *addr, struct nl_addr *multicast)
 
 struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *addr)
 {
-       if (addr->ce_mask & ADDR_ATTR_MULTICAST)
-               return addr->a_multicast;
+       return addr->a_multicast;
+}
+
+uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *addr)
+{
+       if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
+               return addr->a_cacheinfo.aci_valid;
        else
-               return NULL;
+               return 0xFFFFFFFFU;
+}
+
+void rtnl_addr_set_valid_lifetime(struct rtnl_addr *addr, uint32_t lifetime)
+{
+       addr->a_cacheinfo.aci_valid = lifetime;
+       addr->ce_mask |= ADDR_ATTR_CACHEINFO;
+}
+
+uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *addr)
+{
+       if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
+               return addr->a_cacheinfo.aci_prefered;
+       else
+               return 0xFFFFFFFFU;
+}
+
+void rtnl_addr_set_preferred_lifetime(struct rtnl_addr *addr, uint32_t lifetime)
+{
+       addr->a_cacheinfo.aci_prefered = lifetime;
+       addr->ce_mask |= ADDR_ATTR_CACHEINFO;
+}
+
+uint32_t rtnl_addr_get_create_time(struct rtnl_addr *addr)
+{
+       return addr->a_cacheinfo.aci_cstamp;
+}
+
+uint32_t rtnl_addr_get_last_update_time(struct rtnl_addr *addr)
+{
+       return addr->a_cacheinfo.aci_tstamp;
 }
 
 /** @} */
@@ -984,6 +936,9 @@ struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *addr)
 
 static struct trans_tbl addr_flags[] = {
        __ADD(IFA_F_SECONDARY, secondary)
+       __ADD(IFA_F_NODAD, nodad)
+       __ADD(IFA_F_OPTIMISTIC, optimistic)
+       __ADD(IFA_F_HOMEADDRESS, homeaddress)
        __ADD(IFA_F_DEPRECATED, deprecated)
        __ADD(IFA_F_TENTATIVE, tentative)
        __ADD(IFA_F_PERMANENT, permanent)
@@ -1005,6 +960,7 @@ int rtnl_addr_str2flags(const char *name)
 static struct nl_object_ops addr_obj_ops = {
        .oo_name                = "route/addr",
        .oo_size                = sizeof(struct rtnl_addr),
+       .oo_constructor         = addr_constructor,
        .oo_free_data           = addr_free_data,
        .oo_clone               = addr_clone,
        .oo_dump = {
@@ -1012,7 +968,6 @@ static struct nl_object_ops addr_obj_ops = {
            [NL_DUMP_DETAILS]   = addr_dump_details,
            [NL_DUMP_STATS]     = addr_dump_stats,
            [NL_DUMP_XML]       = addr_dump_xml,
-           [NL_DUMP_ENV]       = addr_dump_env,
        },
        .oo_compare             = addr_compare,
        .oo_attrs2str           = addr_attrs2str,
index 900be141cf76f784d864358dff4396cf2fd39fc9..3cbe4f48f51bf4e5598657a92a9ec6d632fe510b 100644 (file)
@@ -96,3 +96,27 @@ void parse_broadcast(struct rtnl_addr *addr, char *arg)
        nl_addr_put(a);
 }
 
+static uint32_t parse_lifetime(const char *arg)
+{
+       uint64_t msecs;
+       int err;
+
+       if (!strcasecmp(arg, "forever"))
+               return 0xFFFFFFFFU;
+
+       if ((err = nl_str2msec(arg, &msecs)) < 0)
+               fatal(err, "Unable to parse time string \"%s\": %s",
+                     arg, nl_geterror(err));
+
+       return (msecs / 1000);
+}
+
+void parse_preferred(struct rtnl_addr *addr, char *arg)
+{
+       rtnl_addr_set_preferred_lifetime(addr, parse_lifetime(arg));
+}
+
+void parse_valid(struct rtnl_addr *addr, char *arg)
+{
+       rtnl_addr_set_valid_lifetime(addr, parse_lifetime(arg));
+}
index 45a9709ec019e414da10b3e3c39dfb1b53994a4e..5efa07f6bb14eded41f9e2dace383fa9b4b9b20f 100644 (file)
@@ -22,5 +22,7 @@ extern void parse_label(struct rtnl_addr *, char *);
 extern void parse_peer(struct rtnl_addr *, char *);
 extern void parse_scope(struct rtnl_addr *, char *);
 extern void parse_broadcast(struct rtnl_addr *, char *);
+extern void parse_preferred(struct rtnl_addr *, char *);
+extern void parse_valid(struct rtnl_addr *, char *);
 
 #endif
index 207989a2627eb5c1fdb0daaa24882dd4c5782be5..74911a6040f1cd8aa0167350f11b842fcd0cd833 100644 (file)
@@ -15,21 +15,24 @@ static int quiet = 0;
 static void print_usage(void)
 {
        printf(
-       "Usage: nl-addr-add [OPTION]... [ADDRESS]\n"
-       "\n"
-       "Options\n"
-       " -q, --quiet           Do not print informal notifications\n"
-       " -h, --help            Show this help\n"
-       " -v, --version         Show versioning information\n"
-       "\n"
-       "Address Options\n"
-       " -a, --local=ADDR      local address, e.g. 10.0.0.1\n"
-       " -d, --dev=DEV         device the address is on\n"
-       "     --family=FAMILY   address family\n"
-       "     --label=STRING    address label\n"
-       "     --peer=ADDR       peer address\n"
-       "     --scope=SCOPE     address scope\n"
-       "     --broadcast=ADDR  broadcast address\n"
+"Usage: nl-addr-add [OPTION]... [ADDRESS]\n"
+"\n"
+"Options\n"
+"     --replace             Replace the address if it exists.\n"
+" -q, --quiet               Do not print informal notifications.\n"
+" -h, --help                Show this help.\n"
+" -v, --version             Show versioning information.\n"
+"\n"
+"Address Options\n"
+" -a, --local=ADDR          Address to be considered local.\n"
+" -d, --dev=DEV             Device the address should be assigned to.\n"
+"     --family=FAMILY       Address family (normally autodetected).\n"
+"     --broadcast=ADDR      Broadcast address of network (IPv4).\n"
+"     --peer=ADDR           Peer address (IPv4).\n"
+"     --label=STRING        Additional address label (IPv4).\n"
+"     --scope=SCOPE         Scope of local address (IPv4).\n"
+"     --preferred=TIME      Preferred lifetime (IPv6).\n"
+"     --valid=TIME          Valid lifetime (IPv6).\n"
        );
 
        exit(0);
@@ -44,7 +47,7 @@ int main(int argc, char *argv[])
                .dp_type = NL_DUMP_LINE,
                .dp_fd = stdout,
        };
-       int err;
+       int err, nlflags = NLM_F_CREATE;
  
        sock = nlt_alloc_socket();
        nlt_connect(sock, NETLINK_ROUTE);
@@ -59,8 +62,12 @@ int main(int argc, char *argv[])
                        ARG_PEER,
                        ARG_SCOPE,
                        ARG_BROADCAST,
+                       ARG_REPLACE,
+                       ARG_PREFERRED,
+                       ARG_VALID,
                };
                static struct option long_opts[] = {
+                       { "replace", 0, 0, ARG_REPLACE },
                        { "quiet", 0, 0, 'q' },
                        { "help", 0, 0, 'h' },
                        { "version", 0, 0, 'v' },
@@ -71,6 +78,8 @@ int main(int argc, char *argv[])
                        { "peer", 1, 0, ARG_PEER },
                        { "scope", 1, 0, ARG_SCOPE },
                        { "broadcast", 1, 0, ARG_BROADCAST },
+                       { "preferred", 1, 0, ARG_PREFERRED },
+                       { "valid", 1, 0, ARG_VALID },
                        { 0, 0, 0, 0 }
                };
        
@@ -79,6 +88,8 @@ int main(int argc, char *argv[])
                        break;
 
                switch (c) {
+               case '?': exit(NLE_INVAL);
+               case ARG_REPLACE: nlflags |= NLM_F_REPLACE; break;
                case 'q': quiet = 1; break;
                case 'h': print_usage(); break;
                case 'v': nlt_print_version(); break;
@@ -89,11 +100,13 @@ int main(int argc, char *argv[])
                case ARG_PEER: parse_peer(addr, optarg); break;
                case ARG_SCOPE: parse_scope(addr, optarg); break;
                case ARG_BROADCAST: parse_broadcast(addr, optarg); break;
+               case ARG_PREFERRED: parse_preferred(addr, optarg); break;
+               case ARG_VALID: parse_valid(addr, optarg); break;
                }
        }
 
-       if ((err = rtnl_addr_add(sock, addr, 0)) < 0)
-               fatal(err, "Unable to add address: %s\n", nl_geterror(err));
+       if ((err = rtnl_addr_add(sock, addr, nlflags)) < 0)
+               fatal(err, "Unable to add address: %s", nl_geterror(err));
 
        if (!quiet) {
                printf("Added ");
index e7cb0a985608f98e90817bf3cfd43109cb408269..42111916caf63df476ac0f5d70173191635345b5 100644 (file)
@@ -17,23 +17,26 @@ static int deleted = 0;
 static void print_usage(void)
 {
        printf(
-       "Usage: nl-addr-delete [OPTION]... [ADDRESS]\n"
-       "\n"
-       "Options\n"
-       " -i, --interactive     Run interactively\n"
-       "     --yes             Set default answer to yes\n"
-       " -q, --quiet           Do not print informal notifications\n"
-       " -h, --help            Show this help\n"
-       " -v, --version         Show versioning information\n"
-       "\n"
-       "Address Options\n"
-       " -a, --local=ADDR      local address, e.g. 10.0.0.1\n"
-       " -d, --dev=DEV         device the address is on\n"
-       "     --family=FAMILY   address family\n"
-       "     --label=STRING    address label\n"
-       "     --peer=ADDR       peer address\n"
-       "     --scope=SCOPE     address scope\n"
-       "     --broadcast=ADDR  broadcast address\n"
+"Usage: nl-addr-delete [OPTION]... [ADDRESS]\n"
+"\n"
+"Options\n"
+" -i, --interactive         Run interactively.\n"
+"     --yes                 Set default answer to yes.\n"
+" -q, --quiet               Do not print informal notifications.\n"
+" -h, --help                Show this help.\n"
+" -v, --version             Show versioning information.\n"
+"\n"
+"Address Options\n"
+" -a, --local=ADDR          Local address.\n"
+" -d, --dev=DEV             Associated network device.\n"
+"     --family=FAMILY       Family of local address.\n"
+"     --label=STRING        Address label (IPv4).\n"
+"     --peer=ADDR           Peer address (IPv4).\n"
+"     --scope=SCOPE         Address scope (IPv4).\n"
+"     --broadcast=ADDR      Broadcast address of network (IPv4).\n"
+"     --valid-lifetime=TS   Valid lifetime before route expires (IPv6).\n"
+"     --preferred=TIME      Preferred lifetime (IPv6).\n"
+"     --valid=TIME          Valid lifetime (IPv6).\n"
        );
 
        exit(0);
@@ -82,6 +85,8 @@ int main(int argc, char *argv[])
                        ARG_PEER,
                        ARG_SCOPE,
                        ARG_BROADCAST,
+                       ARG_PREFERRED,
+                       ARG_VALID,
                };
                static struct option long_opts[] = {
                        { "interactive", 0, 0, 'i' },
@@ -96,6 +101,8 @@ int main(int argc, char *argv[])
                        { "peer", 1, 0, ARG_PEER },
                        { "scope", 1, 0, ARG_SCOPE },
                        { "broadcast", 1, 0, ARG_BROADCAST },
+                       { "preferred", 1, 0, ARG_PREFERRED },
+                       { "valid", 1, 0, ARG_VALID },
                        { 0, 0, 0, 0 }
                };
        
@@ -116,6 +123,8 @@ int main(int argc, char *argv[])
                case ARG_PEER: parse_peer(addr, optarg); break;
                case ARG_SCOPE: parse_scope(addr, optarg); break;
                case ARG_BROADCAST: parse_broadcast(addr, optarg); break;
+               case ARG_PREFERRED: parse_preferred(addr, optarg); break;
+               case ARG_VALID: parse_valid(addr, optarg); break;
                }
        }
 
index 7c7806dbc626881c6247aa0dc74455086266e0c0..0a3fb64a9e2091c73722cf2a59596f8798551f22 100644 (file)
 static void print_usage(void)
 {
        printf(
-       "Usage: nl-addr-list [OPTION]... [ADDRESS]\n"
-       "\n"
-       "Options\n"
-       " -f, --format=TYPE     Output format { brief | details | stats }\n"
-       " -h, --help            Show this help\n"
-       " -v, --version         Show versioning information\n"
-       "\n"
-       "Address Options\n"
-       " -a, --local=ADDR      local address, e.g. 10.0.0.1\n"
-       " -d, --dev=DEV         device the address is on\n"
-       "     --family=FAMILY   address family\n"
-       "     --label=STRING    address label\n"
-       "     --peer=ADDR       peer address\n"
-       "     --scope=SCOPE     address scope\n"
-       "     --broadcast=ADDR  broadcast address\n"
+"Usage: nl-addr-list [OPTION]... [ADDRESS]\n"
+"\n"
+"Options\n"
+"     --details             Show details on multiple lines.\n"
+"     --env                 Print address details in sh env variable syntax.\n"
+"     --prefix=STRING       Prefix each printed line.\n"
+" -h, --help                Show this help.\n"
+" -v, --version             Show versioning information.\n"
+"\n"
+"Address Selection\n"
+" -a, --local=ADDR          Local address.\n"
+" -d, --dev=DEV             Associated network device.\n"
+"     --family=FAMILY       Family of local address.\n"
+"     --label=STRING        Address label (IPv4).\n"
+"     --peer=ADDR           Peer address (IPv4).\n"
+"     --scope=SCOPE         Address scope (IPv4).\n"
+"     --broadcast=ADDR      Broadcast address of network (IPv4).\n"
+"     --valid-lifetime=TS   Valid lifetime before route expires (IPv6).\n"
+"     --preferred=TIME      Preferred lifetime (IPv6).\n"
+"     --valid=TIME          Valid lifetime (IPv6).\n"
        );
        exit(0);
 }
 
+static char *prefix;
+
+void print_prefix(struct nl_dump_params *p, int line)
+{
+       if (prefix)
+               nl_dump(p, "%s", prefix);
+}
+
+static void env_dump(struct nl_object *obj, void *arg)
+{
+       struct nl_dump_params *p = arg;
+       struct rtnl_addr *addr = (struct rtnl_addr *) obj;
+       struct nl_cache *link_cache;
+       struct nl_addr *a;
+       static int index = 0;
+       char buf[128], pfx[32], *s;
+
+       snprintf(pfx, sizeof(pfx), "ADDR%d", index++);
+
+       nl_dump_line(p, "%s_FAMILY=%s\n", pfx,
+                    nl_af2str(rtnl_addr_get_family(addr), buf, sizeof(buf)));
+
+       nl_dump_line(p, "%s_LOCAL=%s\n", pfx,
+                    nl_addr2str(rtnl_addr_get_local(addr), buf, sizeof(buf)));
+
+       nl_dump_line(p, "%s_IFINDEX=%u\n", pfx, rtnl_addr_get_ifindex(addr));
+       link_cache = nl_cache_mngt_require("route/link");
+       if (link_cache)
+               nl_dump_line(p, "%s_IFNAME=%s\n", pfx,
+                            rtnl_link_i2name(link_cache,
+                                             rtnl_addr_get_ifindex(addr),
+                                             buf, sizeof(buf)));
+
+       if ((a = rtnl_addr_get_peer(addr)))
+               nl_dump_line(p, "%s_PEER=%s\n", pfx,
+                            nl_addr2str(a, buf, sizeof(buf)));
+
+       if ((a = rtnl_addr_get_broadcast(addr)))
+               nl_dump_line(p, "%s_BROADCAST=%s\n", pfx,
+                            nl_addr2str(a, buf, sizeof(buf)));
+
+       nl_dump_line(p, "%s_SCOPE=%s\n", pfx,
+                    rtnl_scope2str(rtnl_addr_get_scope(addr),
+                                   buf, sizeof(buf)));
+
+       if ((s = rtnl_addr_get_label(addr)))
+               nl_dump_line(p, "%s_LABEL=%s\n", pfx, s);
+
+       rtnl_addr_flags2str(rtnl_addr_get_flags(addr), buf, sizeof(buf));
+       if (buf[0])
+               nl_dump_line(p, "%s_FLAGS=%s\n", pfx, buf);
+
+       nl_dump_line(p, "%s_CACHEINFO_VALID=%u\n", pfx,
+                    rtnl_addr_get_valid_lifetime(addr));
+
+#if 0
+       if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
+               struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
+
+               nl_dump_line(p, "ADDR_CACHEINFO_PREFERRED=%u\n",
+                            ci->aci_prefered);
+
+               nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%u\n", ci->aci_cstamp);
+               nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%u\n",
+                            ci->aci_tstamp);
+       }
+#endif
+}
+
 int main(int argc, char *argv[])
 {
        struct nl_handle *sock;
@@ -39,8 +113,10 @@ int main(int argc, char *argv[])
        struct nl_cache *link_cache, *addr_cache;
        struct nl_dump_params params = {
                .dp_type = NL_DUMP_LINE,
+               .dp_nl_cb = print_prefix,
                .dp_fd = stdout,
        };
+       int dump_env = 0;
 
        sock = nlt_alloc_socket();
        nlt_connect(sock, NETLINK_ROUTE);
@@ -56,9 +132,16 @@ int main(int argc, char *argv[])
                        ARG_PEER,
                        ARG_SCOPE,
                        ARG_BROADCAST,
+                       ARG_DETAILS,
+                       ARG_ENV,
+                       ARG_PREFIX,
+                       ARG_PREFERRED,
+                       ARG_VALID,
                };
                static struct option long_opts[] = {
-                       { "format", 1, 0, 'f' },
+                       { "details", 0, 0, ARG_DETAILS },
+                       { "env", 0, 0, ARG_ENV },
+                       { "prefix", 1, 0, ARG_PREFIX },
                        { "help", 0, 0, 'h' },
                        { "version", 0, 0, 'v' },
                        { "local", 1, 0, 'a' },
@@ -68,15 +151,22 @@ int main(int argc, char *argv[])
                        { "peer", 1, 0, ARG_PEER },
                        { "scope", 1, 0, ARG_SCOPE },
                        { "broadcast", 1, 0, ARG_BROADCAST },
+                       { "preferred", 1, 0, ARG_PREFERRED },
+                       { "valid", 1, 0, ARG_VALID },
                        { 0, 0, 0, 0 }
                };
 
-               c = getopt_long(argc, argv, "f:hva:d:", long_opts, &optidx);
+               c = getopt_long(argc, argv, "46hva:d:", long_opts, &optidx);
                if (c == -1)
                        break;
 
                switch (c) {
-               case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
+               case '?': exit(NLE_INVAL);
+               case '4': rtnl_addr_set_family(addr, AF_INET); break;
+               case '6': rtnl_addr_set_family(addr, AF_INET6); break;
+               case ARG_DETAILS: params.dp_type = NL_DUMP_DETAILS; break;
+               case ARG_ENV: dump_env = 1; break;
+               case ARG_PREFIX: prefix = strdup(optarg); break;
                case 'h': print_usage(); break;
                case 'v': nlt_print_version(); break;
                case 'a': parse_local(addr, optarg); break;
@@ -86,10 +176,16 @@ int main(int argc, char *argv[])
                case ARG_PEER: parse_peer(addr, optarg); break;
                case ARG_SCOPE: parse_scope(addr, optarg); break;
                case ARG_BROADCAST: parse_broadcast(addr, optarg); break;
+               case ARG_PREFERRED: parse_preferred(addr, optarg); break;
+               case ARG_VALID: parse_valid(addr, optarg); break;
                }
        }
 
-       nl_cache_dump_filter(addr_cache, &params, OBJ_CAST(addr));
+       if (dump_env)
+               nl_cache_foreach_filter(addr_cache, OBJ_CAST(addr), env_dump,
+                                       &params);
+       else
+               nl_cache_dump_filter(addr_cache, &params, OBJ_CAST(addr));
 
        return 0;
 }