2 * ipaddress.c "ip address".
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
19 #include <sys/ioctl.h>
20 #include <sys/socket.h>
21 #include <sys/ioctl.h>
22 #include <sys/param.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
29 #include <linux/netdevice.h>
30 #include <linux/if_arp.h>
31 #include <linux/sockios.h>
32 #include <linux/net_namespace.h>
37 #include "ip_common.h"
69 static void usage(void) __attribute__((noreturn
));
71 static void usage(void)
76 fprintf(stderr
, "Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]\n");
77 fprintf(stderr
, " [ CONFFLAG-LIST ]\n");
78 fprintf(stderr
, " ip address del IFADDR dev IFNAME [mngtmpaddr]\n");
79 fprintf(stderr
, " ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n");
80 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n");
81 fprintf(stderr
, " ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n");
82 fprintf(stderr
, " [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n");
83 fprintf(stderr
, " [ label LABEL ] [up] [ vrf NAME ] ]\n");
84 fprintf(stderr
, " ip address {showdump|restore}\n");
85 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
86 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
87 fprintf(stderr
, " [ label IFNAME ] [ scope SCOPE-ID ]\n");
88 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
89 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
90 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
91 fprintf(stderr
, " [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n");
92 fprintf(stderr
, " CONFFLAG-LIST ]\n");
93 fprintf(stderr
, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
94 fprintf(stderr
, "CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n");
95 fprintf(stderr
, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
96 fprintf(stderr
, "LFT := forever | SECONDS\n");
97 fprintf(stderr
, "TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |\n");
98 fprintf(stderr
, " bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |\n");
99 fprintf(stderr
, " gre | gretap | ip6gre | ip6gretap | vti | nlmon | can |\n");
100 fprintf(stderr
, " bond_slave | ipvlan | geneve | bridge_slave | vrf | hsr | macsec }\n");
105 static void print_link_flags(FILE *fp
, unsigned int flags
, unsigned int mdown
)
108 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
109 fprintf(fp
, "NO-CARRIER%s", flags
? "," : "");
110 flags
&= ~IFF_RUNNING
;
111 #define _PF(f) if (flags&IFF_##f) { \
112 flags &= ~IFF_##f ; \
113 fprintf(fp, #f "%s", flags ? "," : ""); }
134 fprintf(fp
, "%x", flags
);
136 fprintf(fp
, ",M-DOWN");
140 static const char *oper_states
[] = {
141 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
142 "TESTING", "DORMANT", "UP"
145 static void print_operstate(FILE *f
, __u8 state
)
147 if (state
>= ARRAY_SIZE(oper_states
)) {
148 fprintf(f
, "state %#x ", state
);
150 color_fprintf(f
, oper_state_color(state
),
151 "%-14s ", oper_states
[state
]);
153 fprintf(f
, "state ");
154 color_fprintf(f
, oper_state_color(state
),
155 "%s ", oper_states
[state
]);
159 int get_operstate(const char *name
)
163 for (i
= 0; i
< ARRAY_SIZE(oper_states
); i
++)
164 if (strcasecmp(name
, oper_states
[i
]) == 0)
169 static void print_queuelen(FILE *f
, struct rtattr
*tb
[IFLA_MAX
+ 1])
174 qlen
= *(int *)RTA_DATA(tb
[IFLA_TXQLEN
]);
176 struct ifreq ifr
= {};
177 int s
= socket(AF_INET
, SOCK_STREAM
, 0);
182 strcpy(ifr
.ifr_name
, rta_getattr_str(tb
[IFLA_IFNAME
]));
183 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
184 fprintf(f
, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno
));
192 fprintf(f
, "qlen %d", qlen
);
195 static const char *link_modes
[] = {
199 static void print_linkmode(FILE *f
, struct rtattr
*tb
)
201 unsigned int mode
= rta_getattr_u8(tb
);
203 if (mode
>= ARRAY_SIZE(link_modes
))
204 fprintf(f
, "mode %d ", mode
);
206 fprintf(f
, "mode %s ", link_modes
[mode
]);
209 static char *parse_link_kind(struct rtattr
*tb
, bool slave
)
211 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
212 int attr
= slave
? IFLA_INFO_SLAVE_KIND
: IFLA_INFO_KIND
;
214 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
217 return RTA_DATA(linkinfo
[attr
]);
222 static int match_link_kind(struct rtattr
**tb
, const char *kind
, bool slave
)
224 if (!tb
[IFLA_LINKINFO
])
227 return strcmp(parse_link_kind(tb
[IFLA_LINKINFO
], slave
), kind
);
230 static void print_linktype(FILE *fp
, struct rtattr
*tb
)
232 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
233 struct link_util
*lu
;
234 struct link_util
*slave_lu
;
238 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
240 if (linkinfo
[IFLA_INFO_KIND
]) {
241 kind
= RTA_DATA(linkinfo
[IFLA_INFO_KIND
]);
243 fprintf(fp
, "%s", _SL_
);
244 fprintf(fp
, " %s ", kind
);
246 lu
= get_link_kind(kind
);
247 if (lu
&& lu
->print_opt
) {
248 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
250 if (linkinfo
[IFLA_INFO_DATA
]) {
251 parse_rtattr_nested(attr
, lu
->maxattr
,
252 linkinfo
[IFLA_INFO_DATA
]);
255 lu
->print_opt(lu
, fp
, data
);
257 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
259 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
263 if (linkinfo
[IFLA_INFO_SLAVE_KIND
]) {
264 slave_kind
= RTA_DATA(linkinfo
[IFLA_INFO_SLAVE_KIND
]);
266 fprintf(fp
, "%s", _SL_
);
267 fprintf(fp
, " %s_slave ", slave_kind
);
269 slave_lu
= get_link_slave_kind(slave_kind
);
270 if (slave_lu
&& slave_lu
->print_opt
) {
271 struct rtattr
*attr
[slave_lu
->maxattr
+1], **data
= NULL
;
273 if (linkinfo
[IFLA_INFO_SLAVE_DATA
]) {
274 parse_rtattr_nested(attr
, slave_lu
->maxattr
,
275 linkinfo
[IFLA_INFO_SLAVE_DATA
]);
278 slave_lu
->print_opt(slave_lu
, fp
, data
);
283 static void print_af_spec(FILE *fp
, struct rtattr
*af_spec_attr
)
285 struct rtattr
*inet6_attr
;
286 struct rtattr
*tb
[IFLA_INET6_MAX
+ 1];
288 inet6_attr
= parse_rtattr_one_nested(AF_INET6
, af_spec_attr
);
292 parse_rtattr_nested(tb
, IFLA_INET6_MAX
, inet6_attr
);
294 if (tb
[IFLA_INET6_ADDR_GEN_MODE
]) {
295 __u8 mode
= rta_getattr_u8(tb
[IFLA_INET6_ADDR_GEN_MODE
]);
298 case IN6_ADDR_GEN_MODE_EUI64
:
299 fprintf(fp
, "addrgenmode eui64 ");
301 case IN6_ADDR_GEN_MODE_NONE
:
302 fprintf(fp
, "addrgenmode none ");
304 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY
:
305 fprintf(fp
, "addrgenmode stable_secret ");
307 case IN6_ADDR_GEN_MODE_RANDOM
:
308 fprintf(fp
, "addrgenmode random ");
311 fprintf(fp
, "addrgenmode %#.2hhx ", mode
);
317 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
);
319 static void print_vfinfo(FILE *fp
, struct rtattr
*vfinfo
)
321 struct ifla_vf_mac
*vf_mac
;
322 struct ifla_vf_vlan
*vf_vlan
;
323 struct ifla_vf_tx_rate
*vf_tx_rate
;
324 struct ifla_vf_spoofchk
*vf_spoofchk
;
325 struct ifla_vf_link_state
*vf_linkstate
;
326 struct rtattr
*vf
[IFLA_VF_MAX
+ 1] = {};
331 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
332 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
336 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
338 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
339 vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
340 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
342 /* Check if the spoof checking vf info type is supported by
345 tmp
= (struct rtattr
*)((char *)vf
[IFLA_VF_TX_RATE
] +
346 vf
[IFLA_VF_TX_RATE
]->rta_len
);
348 if (tmp
->rta_type
!= IFLA_VF_SPOOFCHK
)
351 vf_spoofchk
= RTA_DATA(vf
[IFLA_VF_SPOOFCHK
]);
354 /* Check if the link state vf info type is supported by
357 tmp
= (struct rtattr
*)((char *)vf
[IFLA_VF_SPOOFCHK
] +
358 vf
[IFLA_VF_SPOOFCHK
]->rta_len
);
360 if (tmp
->rta_type
!= IFLA_VF_LINK_STATE
)
363 vf_linkstate
= RTA_DATA(vf
[IFLA_VF_LINK_STATE
]);
367 fprintf(fp
, "%s vf %d MAC %s", _SL_
, vf_mac
->vf
,
368 ll_addr_n2a((unsigned char *)&vf_mac
->mac
,
369 ETH_ALEN
, 0, b1
, sizeof(b1
)));
371 fprintf(fp
, ", vlan %d", vf_vlan
->vlan
);
373 fprintf(fp
, ", qos %d", vf_vlan
->qos
);
374 if (vf_tx_rate
->rate
)
375 fprintf(fp
, ", tx rate %d (Mbps)", vf_tx_rate
->rate
);
377 if (vf
[IFLA_VF_RATE
]) {
378 struct ifla_vf_rate
*vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
380 if (vf_rate
->max_tx_rate
)
381 fprintf(fp
, ", max_tx_rate %dMbps", vf_rate
->max_tx_rate
);
382 if (vf_rate
->min_tx_rate
)
383 fprintf(fp
, ", min_tx_rate %dMbps", vf_rate
->min_tx_rate
);
386 if (vf_spoofchk
&& vf_spoofchk
->setting
!= -1) {
387 if (vf_spoofchk
->setting
)
388 fprintf(fp
, ", spoof checking on");
390 fprintf(fp
, ", spoof checking off");
393 if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_AUTO
)
394 fprintf(fp
, ", link-state auto");
395 else if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_ENABLE
)
396 fprintf(fp
, ", link-state enable");
398 fprintf(fp
, ", link-state disable");
400 if (vf
[IFLA_VF_TRUST
]) {
401 struct ifla_vf_trust
*vf_trust
= RTA_DATA(vf
[IFLA_VF_TRUST
]);
403 if (vf_trust
->setting
!= -1)
404 fprintf(fp
, ", trust %s",
405 vf_trust
->setting
? "on" : "off");
407 if (vf
[IFLA_VF_STATS
] && show_stats
)
408 print_vf_stats64(fp
, vf
[IFLA_VF_STATS
]);
411 static void print_num(FILE *fp
, unsigned int width
, uint64_t count
)
413 const char *prefix
= "kMGTPE";
414 const unsigned int base
= use_iec
? 1024 : 1000;
417 uint8_t precision
= 2;
420 if (!human_readable
|| count
< base
) {
421 fprintf(fp
, "%-*"PRIu64
" ", width
, count
);
425 /* increase value by a factor of 1000/1024 and print
426 * if result is something a human can read */
429 if (count
/ base
< powi
)
437 /* try to guess a good number of digits for precision */
438 for (; precision
> 0; precision
--) {
440 if (count
/ powi
< powj
)
444 snprintf(buf
, sizeof(buf
), "%.*f%c%s", precision
,
445 (double) count
/ powi
, *prefix
, use_iec
? "i" : "");
447 fprintf(fp
, "%-*s ", width
, buf
);
450 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
)
452 struct rtattr
*vf
[IFLA_VF_STATS_MAX
+ 1];
454 if (vfstats
->rta_type
!= IFLA_VF_STATS
) {
455 fprintf(stderr
, "BUG: rta type is %d\n", vfstats
->rta_type
);
459 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfstats
);
462 fprintf(fp
, "%s", _SL_
);
463 fprintf(fp
, " RX: bytes packets mcast bcast %s", _SL_
);
466 print_num(fp
, 10, *(__u64
*)RTA_DATA(vf
[IFLA_VF_STATS_RX_BYTES
]));
467 print_num(fp
, 8, *(__u64
*)RTA_DATA(vf
[IFLA_VF_STATS_RX_PACKETS
]));
468 print_num(fp
, 7, *(__u64
*)RTA_DATA(vf
[IFLA_VF_STATS_MULTICAST
]));
469 print_num(fp
, 7, *(__u64
*)RTA_DATA(vf
[IFLA_VF_STATS_BROADCAST
]));
472 fprintf(fp
, "%s", _SL_
);
473 fprintf(fp
, " TX: bytes packets %s", _SL_
);
476 print_num(fp
, 10, *(__u64
*)RTA_DATA(vf
[IFLA_VF_STATS_TX_BYTES
]));
477 print_num(fp
, 8, *(__u64
*)RTA_DATA(vf
[IFLA_VF_STATS_TX_PACKETS
]));
480 static void print_link_stats64(FILE *fp
, const struct rtnl_link_stats64
*s
,
481 const struct rtattr
*carrier_changes
)
484 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
485 s
->rx_compressed
? "compressed" : "", _SL_
);
488 print_num(fp
, 10, s
->rx_bytes
);
489 print_num(fp
, 8, s
->rx_packets
);
490 print_num(fp
, 7, s
->rx_errors
);
491 print_num(fp
, 7, s
->rx_dropped
);
492 print_num(fp
, 7, s
->rx_over_errors
);
493 print_num(fp
, 7, s
->multicast
);
494 if (s
->rx_compressed
)
495 print_num(fp
, 7, s
->rx_compressed
);
498 if (show_stats
> 1) {
499 fprintf(fp
, "%s", _SL_
);
500 fprintf(fp
, " RX errors: length crc frame fifo missed%s%s",
501 s
->rx_nohandler
? " nohandler" : "", _SL_
);
504 print_num(fp
, 8, s
->rx_length_errors
);
505 print_num(fp
, 7, s
->rx_crc_errors
);
506 print_num(fp
, 7, s
->rx_frame_errors
);
507 print_num(fp
, 7, s
->rx_fifo_errors
);
508 print_num(fp
, 7, s
->rx_missed_errors
);
510 print_num(fp
, 7, s
->rx_nohandler
);
513 fprintf(fp
, "%s", _SL_
);
516 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
517 s
->tx_compressed
? "compressed" : "", _SL_
);
520 print_num(fp
, 10, s
->tx_bytes
);
521 print_num(fp
, 8, s
->tx_packets
);
522 print_num(fp
, 7, s
->tx_errors
);
523 print_num(fp
, 7, s
->tx_dropped
);
524 print_num(fp
, 7, s
->tx_carrier_errors
);
525 print_num(fp
, 7, s
->collisions
);
526 if (s
->tx_compressed
)
527 print_num(fp
, 7, s
->tx_compressed
);
530 if (show_stats
> 1) {
531 fprintf(fp
, "%s", _SL_
);
532 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
534 fprintf(fp
, " transns");
535 fprintf(fp
, "%s", _SL_
);
538 print_num(fp
, 8, s
->tx_aborted_errors
);
539 print_num(fp
, 7, s
->tx_fifo_errors
);
540 print_num(fp
, 7, s
->tx_window_errors
);
541 print_num(fp
, 7, s
->tx_heartbeat_errors
);
543 print_num(fp
, 7, *(uint32_t *)RTA_DATA(carrier_changes
));
547 static void print_link_stats32(FILE *fp
, const struct rtnl_link_stats
*s
,
548 const struct rtattr
*carrier_changes
)
551 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
552 s
->rx_compressed
? "compressed" : "", _SL_
);
556 print_num(fp
, 10, s
->rx_bytes
);
557 print_num(fp
, 8, s
->rx_packets
);
558 print_num(fp
, 7, s
->rx_errors
);
559 print_num(fp
, 7, s
->rx_dropped
);
560 print_num(fp
, 7, s
->rx_over_errors
);
561 print_num(fp
, 7, s
->multicast
);
562 if (s
->rx_compressed
)
563 print_num(fp
, 7, s
->rx_compressed
);
566 if (show_stats
> 1) {
567 fprintf(fp
, "%s", _SL_
);
568 fprintf(fp
, " RX errors: length crc frame fifo missed%s%s",
569 s
->rx_nohandler
? " nohandler" : "", _SL_
);
571 print_num(fp
, 8, s
->rx_length_errors
);
572 print_num(fp
, 7, s
->rx_crc_errors
);
573 print_num(fp
, 7, s
->rx_frame_errors
);
574 print_num(fp
, 7, s
->rx_fifo_errors
);
575 print_num(fp
, 7, s
->rx_missed_errors
);
577 print_num(fp
, 7, s
->rx_nohandler
);
579 fprintf(fp
, "%s", _SL_
);
582 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
583 s
->tx_compressed
? "compressed" : "", _SL_
);
586 print_num(fp
, 10, s
->tx_bytes
);
587 print_num(fp
, 8, s
->tx_packets
);
588 print_num(fp
, 7, s
->tx_errors
);
589 print_num(fp
, 7, s
->tx_dropped
);
590 print_num(fp
, 7, s
->tx_carrier_errors
);
591 print_num(fp
, 7, s
->collisions
);
592 if (s
->tx_compressed
)
593 print_num(fp
, 7, s
->tx_compressed
);
596 if (show_stats
> 1) {
597 fprintf(fp
, "%s", _SL_
);
598 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
600 fprintf(fp
, " transns");
601 fprintf(fp
, "%s", _SL_
);
604 print_num(fp
, 8, s
->tx_aborted_errors
);
605 print_num(fp
, 7, s
->tx_fifo_errors
);
606 print_num(fp
, 7, s
->tx_window_errors
);
607 print_num(fp
, 7, s
->tx_heartbeat_errors
);
609 print_num(fp
, 7, *(uint32_t *)RTA_DATA(carrier_changes
));
613 static void __print_link_stats(FILE *fp
, struct rtattr
**tb
)
615 const struct rtattr
*carrier_changes
= tb
[IFLA_CARRIER_CHANGES
];
617 if (tb
[IFLA_STATS64
]) {
618 struct rtnl_link_stats64 stats
= { 0 };
620 memcpy(&stats
, RTA_DATA(tb
[IFLA_STATS64
]),
621 MIN(RTA_PAYLOAD(tb
[IFLA_STATS64
]), sizeof(stats
)));
623 print_link_stats64(fp
, &stats
, carrier_changes
);
624 } else if (tb
[IFLA_STATS
]) {
625 struct rtnl_link_stats stats
= { 0 };
627 memcpy(&stats
, RTA_DATA(tb
[IFLA_STATS
]),
628 MIN(RTA_PAYLOAD(tb
[IFLA_STATS
]), sizeof(stats
)));
630 print_link_stats32(fp
, &stats
, carrier_changes
);
634 static void print_link_stats(FILE *fp
, struct nlmsghdr
*n
)
636 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
637 struct rtattr
*tb
[IFLA_MAX
+1];
639 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
),
640 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
)));
641 __print_link_stats(fp
, tb
);
642 fprintf(fp
, "%s", _SL_
);
645 int print_linkinfo_brief(const struct sockaddr_nl
*who
,
646 struct nlmsghdr
*n
, void *arg
)
648 FILE *fp
= (FILE *)arg
;
649 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
650 struct rtattr
*tb
[IFLA_MAX
+1];
651 int len
= n
->nlmsg_len
;
653 char buf
[32] = { 0, };
654 unsigned int m_flag
= 0;
656 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
659 len
-= NLMSG_LENGTH(sizeof(*ifi
));
663 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
665 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
668 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
669 if (tb
[IFLA_IFNAME
] == NULL
) {
670 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
673 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
674 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
677 if (tb
[IFLA_GROUP
]) {
678 int group
= *(int *)RTA_DATA(tb
[IFLA_GROUP
]);
680 if (filter
.group
!= -1 && group
!= filter
.group
)
684 if (tb
[IFLA_MASTER
]) {
685 int master
= *(int *)RTA_DATA(tb
[IFLA_MASTER
]);
687 if (filter
.master
> 0 && master
!= filter
.master
)
689 } else if (filter
.master
> 0)
692 if (filter
.kind
&& match_link_kind(tb
, filter
.kind
, 0))
695 if (filter
.slave_kind
&& match_link_kind(tb
, filter
.slave_kind
, 1))
698 if (n
->nlmsg_type
== RTM_DELLINK
)
699 fprintf(fp
, "Deleted ");
701 name
= (char *)(tb
[IFLA_IFNAME
] ? rta_getattr_str(tb
[IFLA_IFNAME
]) : "<nil>");
705 int iflink
= *(int *)RTA_DATA(tb
[IFLA_LINK
]);
708 snprintf(buf
, sizeof(buf
), "%s@NONE", name
);
710 snprintf(buf
, sizeof(buf
),
711 "%s@%s", name
, ll_idx_n2a(iflink
, b1
));
712 m_flag
= ll_index_to_flags(iflink
);
713 m_flag
= !(m_flag
& IFF_UP
);
716 snprintf(buf
, sizeof(buf
), "%s", name
);
718 fprintf(fp
, "%-16s ", buf
);
720 if (tb
[IFLA_OPERSTATE
])
721 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
723 if (filter
.family
== AF_PACKET
) {
725 if (tb
[IFLA_ADDRESS
]) {
726 color_fprintf(fp
, COLOR_MAC
, "%s ",
727 ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
728 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
734 if (filter
.family
== AF_PACKET
)
735 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
737 if (filter
.family
== AF_PACKET
)
743 int print_linkinfo(const struct sockaddr_nl
*who
,
744 struct nlmsghdr
*n
, void *arg
)
746 FILE *fp
= (FILE *)arg
;
747 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
748 struct rtattr
*tb
[IFLA_MAX
+1];
749 int len
= n
->nlmsg_len
;
750 unsigned int m_flag
= 0;
752 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
755 len
-= NLMSG_LENGTH(sizeof(*ifi
));
759 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
761 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
764 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
765 if (tb
[IFLA_IFNAME
] == NULL
) {
766 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
769 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
770 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
773 if (tb
[IFLA_GROUP
]) {
774 int group
= *(int *)RTA_DATA(tb
[IFLA_GROUP
]);
776 if (filter
.group
!= -1 && group
!= filter
.group
)
780 if (tb
[IFLA_MASTER
]) {
781 int master
= *(int *)RTA_DATA(tb
[IFLA_MASTER
]);
783 if (filter
.master
> 0 && master
!= filter
.master
)
785 } else if (filter
.master
> 0)
788 if (filter
.kind
&& match_link_kind(tb
, filter
.kind
, 0))
791 if (filter
.slave_kind
&& match_link_kind(tb
, filter
.slave_kind
, 1))
794 if (n
->nlmsg_type
== RTM_DELLINK
)
795 fprintf(fp
, "Deleted ");
797 fprintf(fp
, "%d: ", ifi
->ifi_index
);
798 color_fprintf(fp
, COLOR_IFNAME
, "%s",
799 tb
[IFLA_IFNAME
] ? rta_getattr_str(tb
[IFLA_IFNAME
]) : "<nil>");
803 int iflink
= *(int *)RTA_DATA(tb
[IFLA_LINK
]);
806 fprintf(fp
, "@NONE: ");
808 if (tb
[IFLA_LINK_NETNSID
])
809 fprintf(fp
, "@if%d: ", iflink
);
811 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
812 m_flag
= ll_index_to_flags(iflink
);
813 m_flag
= !(m_flag
& IFF_UP
);
819 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
822 fprintf(fp
, "mtu %u ", *(int *)RTA_DATA(tb
[IFLA_MTU
]));
824 fprintf(fp
, "qdisc %s ", rta_getattr_str(tb
[IFLA_QDISC
]));
825 if (tb
[IFLA_MASTER
]) {
827 fprintf(fp
, "master %s ", ll_idx_n2a(*(int *)RTA_DATA(tb
[IFLA_MASTER
]), b1
));
830 if (tb
[IFLA_OPERSTATE
])
831 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
833 if (do_link
&& tb
[IFLA_LINKMODE
])
834 print_linkmode(fp
, tb
[IFLA_LINKMODE
]);
836 if (tb
[IFLA_GROUP
]) {
838 int group
= *(int *)RTA_DATA(tb
[IFLA_GROUP
]);
840 fprintf(fp
, "group %s ", rtnl_group_n2a(group
, b1
, sizeof(b1
)));
843 if (filter
.showqueue
)
844 print_queuelen(fp
, tb
);
846 if (!filter
.family
|| filter
.family
== AF_PACKET
|| show_details
) {
848 fprintf(fp
, "%s", _SL_
);
849 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
851 if (tb
[IFLA_ADDRESS
]) {
852 color_fprintf(fp
, COLOR_MAC
, "%s",
853 ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
854 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
858 if (tb
[IFLA_BROADCAST
]) {
859 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
860 fprintf(fp
, " peer ");
862 fprintf(fp
, " brd ");
863 color_fprintf(fp
, COLOR_MAC
, "%s",
864 ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
865 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
871 if (tb
[IFLA_LINK_NETNSID
]) {
872 int id
= *(int *)RTA_DATA(tb
[IFLA_LINK_NETNSID
]);
875 fprintf(fp
, " link-netnsid %d", id
);
877 fprintf(fp
, " link-netnsid unknown");
880 if (tb
[IFLA_PROTO_DOWN
]) {
881 if (rta_getattr_u8(tb
[IFLA_PROTO_DOWN
]))
882 fprintf(fp
, " protodown on ");
886 if (tb
[IFLA_PROMISCUITY
])
887 fprintf(fp
, " promiscuity %u ",
888 *(int *)RTA_DATA(tb
[IFLA_PROMISCUITY
]));
890 if (tb
[IFLA_LINKINFO
])
891 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
893 if (do_link
&& tb
[IFLA_AF_SPEC
])
894 print_af_spec(fp
, tb
[IFLA_AF_SPEC
]);
896 if (tb
[IFLA_NUM_TX_QUEUES
])
897 fprintf(fp
, "numtxqueues %u ",
898 rta_getattr_u32(tb
[IFLA_NUM_TX_QUEUES
]));
900 if (tb
[IFLA_NUM_RX_QUEUES
])
901 fprintf(fp
, "numrxqueues %u ",
902 rta_getattr_u32(tb
[IFLA_NUM_RX_QUEUES
]));
904 if (tb
[IFLA_PHYS_PORT_NAME
])
905 fprintf(fp
, "portname %s ",
906 rta_getattr_str(tb
[IFLA_PHYS_PORT_NAME
]));
908 if (tb
[IFLA_PHYS_PORT_ID
]) {
910 fprintf(fp
, "portid %s ",
911 hexstring_n2a(RTA_DATA(tb
[IFLA_PHYS_PORT_ID
]),
912 RTA_PAYLOAD(tb
[IFLA_PHYS_PORT_ID
]),
916 if (tb
[IFLA_PHYS_SWITCH_ID
]) {
918 fprintf(fp
, "switchid %s ",
919 hexstring_n2a(RTA_DATA(tb
[IFLA_PHYS_SWITCH_ID
]),
920 RTA_PAYLOAD(tb
[IFLA_PHYS_SWITCH_ID
]),
926 if ((do_link
|| show_details
) && tb
[IFLA_IFALIAS
]) {
927 fprintf(fp
, "%s alias %s", _SL_
,
928 rta_getattr_str(tb
[IFLA_IFALIAS
]));
931 if (do_link
&& show_stats
) {
932 fprintf(fp
, "%s", _SL_
);
933 __print_link_stats(fp
, tb
);
936 if ((do_link
|| show_details
) && tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
937 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
938 int rem
= RTA_PAYLOAD(vflist
);
940 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
))
949 static int flush_update(void)
953 * Note that the kernel may delete multiple addresses for one
954 * delete request (e.g. if ipv4 address promotion is disabled).
955 * Since a flush operation is really a series of delete requests
956 * its possible that we may request an address delete that has
957 * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL
958 * errors returned from a flush request
960 if ((rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) &&
961 (errno
!= EADDRNOTAVAIL
)) {
962 perror("Failed to send flush request");
969 static int set_lifetime(unsigned int *lifetime
, char *argv
)
971 if (strcmp(argv
, "forever") == 0)
972 *lifetime
= INFINITY_LIFE_TIME
;
973 else if (get_u32(lifetime
, argv
, 0))
979 static unsigned int get_ifa_flags(struct ifaddrmsg
*ifa
,
980 struct rtattr
*ifa_flags_attr
)
982 return ifa_flags_attr
? rta_getattr_u32(ifa_flags_attr
) :
986 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
990 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
991 int len
= n
->nlmsg_len
;
993 /* Use local copy of ifa_flags to not interfere with filtering code */
994 unsigned int ifa_flags
;
995 struct rtattr
*rta_tb
[IFA_MAX
+1];
999 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
1001 len
-= NLMSG_LENGTH(sizeof(*ifa
));
1003 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
1007 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
1010 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
),
1011 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
1013 ifa_flags
= get_ifa_flags(ifa
, rta_tb
[IFA_FLAGS
]);
1015 if (!rta_tb
[IFA_LOCAL
])
1016 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
1017 if (!rta_tb
[IFA_ADDRESS
])
1018 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
1020 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
1022 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1024 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1030 if (rta_tb
[IFA_LABEL
])
1031 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
1033 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
1034 if (fnmatch(filter
.label
, label
, 0) != 0)
1037 if (filter
.pfx
.family
) {
1038 if (rta_tb
[IFA_LOCAL
]) {
1039 inet_prefix dst
= { .family
= ifa
->ifa_family
};
1041 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
1042 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
1047 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1050 if (filter
.flushb
) {
1051 struct nlmsghdr
*fn
;
1053 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
1057 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
1058 memcpy(fn
, n
, n
->nlmsg_len
);
1059 fn
->nlmsg_type
= RTM_DELADDR
;
1060 fn
->nlmsg_flags
= NLM_F_REQUEST
;
1061 fn
->nlmsg_seq
= ++rth
.seq
;
1062 filter
.flushp
= (((char *)fn
) + n
->nlmsg_len
) - filter
.flushb
;
1068 if (n
->nlmsg_type
== RTM_DELADDR
)
1069 fprintf(fp
, "Deleted ");
1072 if (filter
.oneline
|| filter
.flushb
)
1073 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
1074 if (ifa
->ifa_family
== AF_INET
)
1075 fprintf(fp
, " inet ");
1076 else if (ifa
->ifa_family
== AF_INET6
)
1077 fprintf(fp
, " inet6 ");
1078 else if (ifa
->ifa_family
== AF_DECnet
)
1079 fprintf(fp
, " dnet ");
1080 else if (ifa
->ifa_family
== AF_IPX
)
1081 fprintf(fp
, " ipx ");
1083 fprintf(fp
, " family %d ", ifa
->ifa_family
);
1086 if (rta_tb
[IFA_LOCAL
]) {
1087 color_fprintf(fp
, ifa_family_color(ifa
->ifa_family
), "%s",
1088 format_host_rta(ifa
->ifa_family
,
1089 rta_tb
[IFA_LOCAL
]));
1090 if (rta_tb
[IFA_ADDRESS
] &&
1091 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]),
1092 RTA_DATA(rta_tb
[IFA_LOCAL
]),
1093 ifa
->ifa_family
== AF_INET
? 4 : 16)) {
1094 fprintf(fp
, " peer ");
1095 color_fprintf(fp
, ifa_family_color(ifa
->ifa_family
),
1096 "%s", format_host_rta(ifa
->ifa_family
,
1097 rta_tb
[IFA_ADDRESS
]));
1099 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
1105 if (rta_tb
[IFA_BROADCAST
]) {
1106 fprintf(fp
, "brd ");
1107 color_fprintf(fp
, ifa_family_color(ifa
->ifa_family
), "%s ",
1108 format_host_rta(ifa
->ifa_family
,
1109 rta_tb
[IFA_BROADCAST
]));
1111 if (rta_tb
[IFA_ANYCAST
]) {
1112 fprintf(fp
, "any ");
1113 color_fprintf(fp
, ifa_family_color(ifa
->ifa_family
), "%s ",
1114 format_host_rta(ifa
->ifa_family
,
1115 rta_tb
[IFA_ANYCAST
]));
1117 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
1118 if (ifa_flags
& IFA_F_SECONDARY
) {
1119 ifa_flags
&= ~IFA_F_SECONDARY
;
1120 if (ifa
->ifa_family
== AF_INET6
)
1121 fprintf(fp
, "temporary ");
1123 fprintf(fp
, "secondary ");
1125 if (ifa_flags
& IFA_F_TENTATIVE
) {
1126 ifa_flags
&= ~IFA_F_TENTATIVE
;
1127 fprintf(fp
, "tentative ");
1129 if (ifa_flags
& IFA_F_DEPRECATED
) {
1130 ifa_flags
&= ~IFA_F_DEPRECATED
;
1132 fprintf(fp
, "deprecated ");
1134 if (ifa_flags
& IFA_F_HOMEADDRESS
) {
1135 ifa_flags
&= ~IFA_F_HOMEADDRESS
;
1136 fprintf(fp
, "home ");
1138 if (ifa_flags
& IFA_F_NODAD
) {
1139 ifa_flags
&= ~IFA_F_NODAD
;
1140 fprintf(fp
, "nodad ");
1142 if (ifa_flags
& IFA_F_MANAGETEMPADDR
) {
1143 ifa_flags
&= ~IFA_F_MANAGETEMPADDR
;
1144 fprintf(fp
, "mngtmpaddr ");
1146 if (ifa_flags
& IFA_F_NOPREFIXROUTE
) {
1147 ifa_flags
&= ~IFA_F_NOPREFIXROUTE
;
1148 fprintf(fp
, "noprefixroute ");
1150 if (ifa_flags
& IFA_F_MCAUTOJOIN
) {
1151 ifa_flags
&= ~IFA_F_MCAUTOJOIN
;
1152 fprintf(fp
, "autojoin ");
1154 if (!(ifa_flags
& IFA_F_PERMANENT
)) {
1155 fprintf(fp
, "dynamic ");
1157 ifa_flags
&= ~IFA_F_PERMANENT
;
1158 if (ifa_flags
& IFA_F_DADFAILED
) {
1159 ifa_flags
&= ~IFA_F_DADFAILED
;
1160 fprintf(fp
, "dadfailed ");
1163 fprintf(fp
, "flags %02x ", ifa_flags
);
1164 if (rta_tb
[IFA_LABEL
])
1165 fprintf(fp
, "%s", rta_getattr_str(rta_tb
[IFA_LABEL
]));
1166 if (rta_tb
[IFA_CACHEINFO
]) {
1167 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
1169 fprintf(fp
, "%s", _SL_
);
1170 fprintf(fp
, " valid_lft ");
1171 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
)
1172 fprintf(fp
, "forever");
1174 fprintf(fp
, "%usec", ci
->ifa_valid
);
1175 fprintf(fp
, " preferred_lft ");
1176 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
)
1177 fprintf(fp
, "forever");
1180 fprintf(fp
, "%dsec", ci
->ifa_prefered
);
1182 fprintf(fp
, "%usec", ci
->ifa_prefered
);
1192 struct nlmsg_list
*next
;
1196 struct nlmsg_chain
{
1197 struct nlmsg_list
*head
;
1198 struct nlmsg_list
*tail
;
1201 static int print_selected_addrinfo(struct ifinfomsg
*ifi
,
1202 struct nlmsg_list
*ainfo
, FILE *fp
)
1204 for ( ; ainfo
; ainfo
= ainfo
->next
) {
1205 struct nlmsghdr
*n
= &ainfo
->h
;
1206 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1208 if (n
->nlmsg_type
!= RTM_NEWADDR
)
1211 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifa
)))
1214 if (ifa
->ifa_index
!= ifi
->ifi_index
||
1215 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
1218 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
1221 print_addrinfo(NULL
, n
, fp
);
1231 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1234 struct nlmsg_chain
*lchain
= (struct nlmsg_chain
*)arg
;
1235 struct nlmsg_list
*h
;
1237 h
= malloc(n
->nlmsg_len
+sizeof(void *));
1241 memcpy(&h
->h
, n
, n
->nlmsg_len
);
1245 lchain
->tail
->next
= h
;
1250 ll_remember_index(who
, n
, NULL
);
1254 static __u32 ipadd_dump_magic
= 0x47361222;
1256 static int ipadd_save_prep(void)
1260 if (isatty(STDOUT_FILENO
)) {
1261 fprintf(stderr
, "Not sending a binary stream to stdout\n");
1265 ret
= write(STDOUT_FILENO
, &ipadd_dump_magic
, sizeof(ipadd_dump_magic
));
1266 if (ret
!= sizeof(ipadd_dump_magic
)) {
1267 fprintf(stderr
, "Can't write magic to dump file\n");
1274 static int ipadd_dump_check_magic(void)
1279 if (isatty(STDIN_FILENO
)) {
1280 fprintf(stderr
, "Can't restore address dump from a terminal\n");
1284 ret
= fread(&magic
, sizeof(magic
), 1, stdin
);
1285 if (magic
!= ipadd_dump_magic
) {
1286 fprintf(stderr
, "Magic mismatch (%d elems, %x magic)\n", ret
, magic
);
1293 static int save_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1298 ret
= write(STDOUT_FILENO
, n
, n
->nlmsg_len
);
1299 if ((ret
> 0) && (ret
!= n
->nlmsg_len
)) {
1300 fprintf(stderr
, "Short write while saving nlmsg\n");
1304 return ret
== n
->nlmsg_len
? 0 : ret
;
1307 static int show_handler(const struct sockaddr_nl
*nl
,
1308 struct rtnl_ctrl_data
*ctrl
,
1309 struct nlmsghdr
*n
, void *arg
)
1311 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1313 printf("if%d:\n", ifa
->ifa_index
);
1314 print_addrinfo(NULL
, n
, stdout
);
1318 static int ipaddr_showdump(void)
1320 if (ipadd_dump_check_magic())
1323 exit(rtnl_from_file(stdin
, &show_handler
, NULL
));
1326 static int restore_handler(const struct sockaddr_nl
*nl
,
1327 struct rtnl_ctrl_data
*ctrl
,
1328 struct nlmsghdr
*n
, void *arg
)
1332 n
->nlmsg_flags
|= NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_ACK
;
1336 ret
= rtnl_talk(&rth
, n
, n
, sizeof(*n
));
1337 if ((ret
< 0) && (errno
== EEXIST
))
1343 static int ipaddr_restore(void)
1345 if (ipadd_dump_check_magic())
1348 exit(rtnl_from_file(stdin
, &restore_handler
, NULL
));
1351 static void free_nlmsg_chain(struct nlmsg_chain
*info
)
1353 struct nlmsg_list
*l
, *n
;
1355 for (l
= info
->head
; l
; l
= n
) {
1361 static void ipaddr_filter(struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
1363 struct nlmsg_list
*l
, **lp
;
1366 while ((l
= *lp
) != NULL
) {
1368 int missing_net_address
= 1;
1369 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1370 struct nlmsg_list
*a
;
1372 for (a
= ainfo
->head
; a
; a
= a
->next
) {
1373 struct nlmsghdr
*n
= &a
->h
;
1374 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1375 struct rtattr
*tb
[IFA_MAX
+ 1];
1376 unsigned int ifa_flags
;
1378 if (ifa
->ifa_index
!= ifi
->ifi_index
)
1380 missing_net_address
= 0;
1381 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1383 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1386 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
1387 ifa_flags
= get_ifa_flags(ifa
, tb
[IFA_FLAGS
]);
1389 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1391 if (filter
.pfx
.family
|| filter
.label
) {
1393 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
1395 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
1397 .family
= ifa
->ifa_family
1400 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
1401 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
1409 label
= RTA_DATA(tb
[IFA_LABEL
]);
1411 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
1412 if (fnmatch(filter
.label
, label
, 0) != 0)
1420 if (missing_net_address
&&
1421 (filter
.family
== AF_UNSPEC
|| filter
.family
== AF_PACKET
))
1431 static int ipaddr_flush(void)
1434 char flushb
[4096-512];
1436 filter
.flushb
= flushb
;
1438 filter
.flushe
= sizeof(flushb
);
1440 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
1441 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
1442 perror("Cannot send dump request");
1446 if (rtnl_dump_filter_nc(&rth
, print_addrinfo
,
1447 stdout
, NLM_F_DUMP_INTR
) < 0) {
1448 fprintf(stderr
, "Flush terminated\n");
1451 if (filter
.flushed
== 0) {
1455 printf("Nothing to flush.\n");
1457 printf("*** Flush is complete after %d round%s ***\n", round
, round
> 1?"s":"");
1463 if (flush_update() < 0)
1467 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
1471 /* If we are flushing, and specifying primary, then we
1472 * want to flush only a single round. Otherwise, we'll
1473 * start flushing secondaries that were promoted to
1476 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
1479 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
1484 static int iplink_filter_req(struct nlmsghdr
*nlh
, int reqlen
)
1488 err
= addattr32(nlh
, reqlen
, IFLA_EXT_MASK
, RTEXT_FILTER_VF
);
1492 if (filter
.master
) {
1493 err
= addattr32(nlh
, reqlen
, IFLA_MASTER
, filter
.master
);
1499 struct rtattr
*linkinfo
;
1501 linkinfo
= addattr_nest(nlh
, reqlen
, IFLA_LINKINFO
);
1503 err
= addattr_l(nlh
, reqlen
, IFLA_INFO_KIND
, filter
.kind
,
1504 strlen(filter
.kind
));
1508 addattr_nest_end(nlh
, linkinfo
);
1514 static int ipaddr_list_flush_or_save(int argc
, char **argv
, int action
)
1516 struct nlmsg_chain linfo
= { NULL
, NULL
};
1517 struct nlmsg_chain ainfo
= { NULL
, NULL
};
1518 struct nlmsg_list
*l
;
1519 char *filter_dev
= NULL
;
1522 ipaddr_reset_filter(oneline
, 0);
1523 filter
.showqueue
= 1;
1524 filter
.family
= preferred_family
;
1527 if (action
== IPADD_FLUSH
) {
1529 fprintf(stderr
, "Flush requires arguments.\n");
1533 if (filter
.family
== AF_PACKET
) {
1534 fprintf(stderr
, "Cannot flush link addresses.\n");
1540 if (strcmp(*argv
, "to") == 0) {
1542 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
1543 if (filter
.family
== AF_UNSPEC
)
1544 filter
.family
= filter
.pfx
.family
;
1545 } else if (strcmp(*argv
, "scope") == 0) {
1546 unsigned int scope
= 0;
1549 filter
.scopemask
= -1;
1550 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
1551 if (strcmp(*argv
, "all") != 0)
1552 invarg("invalid \"scope\"\n", *argv
);
1553 scope
= RT_SCOPE_NOWHERE
;
1554 filter
.scopemask
= 0;
1556 filter
.scope
= scope
;
1557 } else if (strcmp(*argv
, "up") == 0) {
1559 } else if (strcmp(*argv
, "dynamic") == 0) {
1560 filter
.flags
&= ~IFA_F_PERMANENT
;
1561 filter
.flagmask
|= IFA_F_PERMANENT
;
1562 } else if (strcmp(*argv
, "permanent") == 0) {
1563 filter
.flags
|= IFA_F_PERMANENT
;
1564 filter
.flagmask
|= IFA_F_PERMANENT
;
1565 } else if (strcmp(*argv
, "secondary") == 0 ||
1566 strcmp(*argv
, "temporary") == 0) {
1567 filter
.flags
|= IFA_F_SECONDARY
;
1568 filter
.flagmask
|= IFA_F_SECONDARY
;
1569 } else if (strcmp(*argv
, "primary") == 0) {
1570 filter
.flags
&= ~IFA_F_SECONDARY
;
1571 filter
.flagmask
|= IFA_F_SECONDARY
;
1572 } else if (strcmp(*argv
, "tentative") == 0) {
1573 filter
.flags
|= IFA_F_TENTATIVE
;
1574 filter
.flagmask
|= IFA_F_TENTATIVE
;
1575 } else if (strcmp(*argv
, "-tentative") == 0) {
1576 filter
.flags
&= ~IFA_F_TENTATIVE
;
1577 filter
.flagmask
|= IFA_F_TENTATIVE
;
1578 } else if (strcmp(*argv
, "deprecated") == 0) {
1579 filter
.flags
|= IFA_F_DEPRECATED
;
1580 filter
.flagmask
|= IFA_F_DEPRECATED
;
1581 } else if (strcmp(*argv
, "-deprecated") == 0) {
1582 filter
.flags
&= ~IFA_F_DEPRECATED
;
1583 filter
.flagmask
|= IFA_F_DEPRECATED
;
1584 } else if (strcmp(*argv
, "home") == 0) {
1585 filter
.flags
|= IFA_F_HOMEADDRESS
;
1586 filter
.flagmask
|= IFA_F_HOMEADDRESS
;
1587 } else if (strcmp(*argv
, "nodad") == 0) {
1588 filter
.flags
|= IFA_F_NODAD
;
1589 filter
.flagmask
|= IFA_F_NODAD
;
1590 } else if (strcmp(*argv
, "mngtmpaddr") == 0) {
1591 filter
.flags
|= IFA_F_MANAGETEMPADDR
;
1592 filter
.flagmask
|= IFA_F_MANAGETEMPADDR
;
1593 } else if (strcmp(*argv
, "noprefixroute") == 0) {
1594 filter
.flags
|= IFA_F_NOPREFIXROUTE
;
1595 filter
.flagmask
|= IFA_F_NOPREFIXROUTE
;
1596 } else if (strcmp(*argv
, "autojoin") == 0) {
1597 filter
.flags
|= IFA_F_MCAUTOJOIN
;
1598 filter
.flagmask
|= IFA_F_MCAUTOJOIN
;
1599 } else if (strcmp(*argv
, "dadfailed") == 0) {
1600 filter
.flags
|= IFA_F_DADFAILED
;
1601 filter
.flagmask
|= IFA_F_DADFAILED
;
1602 } else if (strcmp(*argv
, "-dadfailed") == 0) {
1603 filter
.flags
&= ~IFA_F_DADFAILED
;
1604 filter
.flagmask
|= IFA_F_DADFAILED
;
1605 } else if (strcmp(*argv
, "label") == 0) {
1607 filter
.label
= *argv
;
1608 } else if (strcmp(*argv
, "group") == 0) {
1610 if (rtnl_group_a2n(&filter
.group
, *argv
))
1611 invarg("Invalid \"group\" value\n", *argv
);
1612 } else if (strcmp(*argv
, "master") == 0) {
1616 ifindex
= ll_name_to_index(*argv
);
1618 invarg("Device does not exist\n", *argv
);
1619 filter
.master
= ifindex
;
1620 } else if (strcmp(*argv
, "vrf") == 0) {
1624 ifindex
= ll_name_to_index(*argv
);
1626 invarg("Not a valid VRF name\n", *argv
);
1627 if (!name_is_vrf(*argv
))
1628 invarg("Not a valid VRF name\n", *argv
);
1629 filter
.master
= ifindex
;
1630 } else if (strcmp(*argv
, "type") == 0) {
1634 soff
= strlen(*argv
) - strlen("_slave");
1635 if (!strcmp(*argv
+ soff
, "_slave")) {
1636 (*argv
)[soff
] = '\0';
1637 filter
.slave_kind
= *argv
;
1639 filter
.kind
= *argv
;
1642 if (strcmp(*argv
, "dev") == 0) {
1644 } else if (matches(*argv
, "help") == 0)
1647 duparg2("dev", *argv
);
1654 filter
.ifindex
= ll_name_to_index(filter_dev
);
1655 if (filter
.ifindex
<= 0) {
1656 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
1661 if (action
== IPADD_FLUSH
)
1662 return ipaddr_flush();
1664 if (action
== IPADD_SAVE
) {
1665 if (ipadd_save_prep())
1668 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETADDR
) < 0) {
1669 perror("Cannot send dump request");
1673 if (rtnl_dump_filter(&rth
, save_nlmsg
, stdout
) < 0) {
1674 fprintf(stderr
, "Save terminated\n");
1682 * If only filter_dev present and none of the other
1683 * link filters are present, use RTM_GETLINK to get
1686 if (filter_dev
&& filter
.group
== -1 && do_link
== 1) {
1687 if (iplink_get(0, filter_dev
, RTEXT_FILTER_VF
) < 0) {
1688 perror("Cannot send link get request");
1694 if (rtnl_wilddump_req_filter_fn(&rth
, preferred_family
, RTM_GETLINK
,
1695 iplink_filter_req
) < 0) {
1696 perror("Cannot send dump request");
1700 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
1701 fprintf(stderr
, "Dump terminated\n");
1705 if (filter
.family
!= AF_PACKET
) {
1709 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
1710 perror("Cannot send dump request");
1714 if (rtnl_dump_filter(&rth
, store_nlmsg
, &ainfo
) < 0) {
1715 fprintf(stderr
, "Dump terminated\n");
1719 ipaddr_filter(&linfo
, &ainfo
);
1722 for (l
= linfo
.head
; l
; l
= l
->next
) {
1724 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1727 if (print_linkinfo_brief(NULL
, &l
->h
, stdout
) == 0)
1728 if (filter
.family
!= AF_PACKET
)
1729 print_selected_addrinfo(ifi
,
1732 } else if (no_link
||
1733 (res
= print_linkinfo(NULL
, &l
->h
, stdout
)) >= 0) {
1734 if (filter
.family
!= AF_PACKET
)
1735 print_selected_addrinfo(ifi
,
1736 ainfo
.head
, stdout
);
1737 if (res
> 0 && !do_link
&& show_stats
)
1738 print_link_stats(stdout
, &l
->h
);
1743 free_nlmsg_chain(&ainfo
);
1744 free_nlmsg_chain(&linfo
);
1750 ipaddr_loop_each_vf(struct rtattr
*tb
[], int vfnum
, int *min
, int *max
)
1752 struct rtattr
*vflist
= tb
[IFLA_VFINFO_LIST
];
1753 struct rtattr
*i
, *vf
[IFLA_VF_MAX
+1];
1754 struct ifla_vf_rate
*vf_rate
;
1757 rem
= RTA_PAYLOAD(vflist
);
1759 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
1760 parse_rtattr_nested(vf
, IFLA_VF_MAX
, i
);
1761 vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
1762 if (vf_rate
->vf
== vfnum
) {
1763 *min
= vf_rate
->min_tx_rate
;
1764 *max
= vf_rate
->max_tx_rate
;
1768 fprintf(stderr
, "Cannot find VF %d\n", vfnum
);
1772 void ipaddr_get_vf_rate(int vfnum
, int *min
, int *max
, int idx
)
1774 struct nlmsg_chain linfo
= { NULL
, NULL
};
1775 struct rtattr
*tb
[IFLA_MAX
+1];
1776 struct ifinfomsg
*ifi
;
1777 struct nlmsg_list
*l
;
1781 if (rtnl_wilddump_request(&rth
, AF_UNSPEC
, RTM_GETLINK
) < 0) {
1782 perror("Cannot send dump request");
1785 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
1786 fprintf(stderr
, "Dump terminated\n");
1789 for (l
= linfo
.head
; l
; l
= l
->next
) {
1791 ifi
= NLMSG_DATA(n
);
1793 len
= n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
1794 if (len
< 0 || (idx
&& idx
!= ifi
->ifi_index
))
1797 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
1799 if ((tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
])) {
1800 ipaddr_loop_each_vf(tb
, vfnum
, min
, max
);
1806 int ipaddr_list_link(int argc
, char **argv
)
1808 preferred_family
= AF_PACKET
;
1810 return ipaddr_list_flush_or_save(argc
, argv
, IPADD_LIST
);
1813 void ipaddr_reset_filter(int oneline
, int ifindex
)
1815 memset(&filter
, 0, sizeof(filter
));
1816 filter
.oneline
= oneline
;
1817 filter
.ifindex
= ifindex
;
1820 static int default_scope(inet_prefix
*lcl
)
1822 if (lcl
->family
== AF_INET
) {
1823 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
1824 return RT_SCOPE_HOST
;
1829 static bool ipaddr_is_multicast(inet_prefix
*a
)
1831 if (a
->family
== AF_INET
)
1832 return IN_MULTICAST(ntohl(a
->data
[0]));
1833 else if (a
->family
== AF_INET6
)
1834 return IN6_IS_ADDR_MULTICAST(a
->data
);
1839 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
1843 struct ifaddrmsg ifa
;
1846 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
)),
1847 .n
.nlmsg_flags
= NLM_F_REQUEST
| flags
,
1848 .n
.nlmsg_type
= cmd
,
1849 .ifa
.ifa_family
= preferred_family
,
1853 char *lcl_arg
= NULL
;
1854 char *valid_lftp
= NULL
;
1855 char *preferred_lftp
= NULL
;
1863 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
1864 __u32 valid_lft
= INFINITY_LIFE_TIME
;
1865 unsigned int ifa_flags
= 0;
1868 if (strcmp(*argv
, "peer") == 0 ||
1869 strcmp(*argv
, "remote") == 0) {
1873 duparg("peer", *argv
);
1874 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
1875 peer_len
= peer
.bytelen
;
1876 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1877 req
.ifa
.ifa_family
= peer
.family
;
1878 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
1879 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
1880 } else if (matches(*argv
, "broadcast") == 0 ||
1881 strcmp(*argv
, "brd") == 0) {
1886 duparg("broadcast", *argv
);
1887 if (strcmp(*argv
, "+") == 0)
1889 else if (strcmp(*argv
, "-") == 0)
1892 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1893 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1894 req
.ifa
.ifa_family
= addr
.family
;
1895 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
1896 brd_len
= addr
.bytelen
;
1898 } else if (strcmp(*argv
, "anycast") == 0) {
1903 duparg("anycast", *argv
);
1904 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1905 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1906 req
.ifa
.ifa_family
= addr
.family
;
1907 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
1908 any_len
= addr
.bytelen
;
1909 } else if (strcmp(*argv
, "scope") == 0) {
1910 unsigned int scope
= 0;
1913 if (rtnl_rtscope_a2n(&scope
, *argv
))
1914 invarg("invalid scope value.", *argv
);
1915 req
.ifa
.ifa_scope
= scope
;
1917 } else if (strcmp(*argv
, "dev") == 0) {
1920 } else if (strcmp(*argv
, "label") == 0) {
1923 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
1924 } else if (matches(*argv
, "valid_lft") == 0) {
1926 duparg("valid_lft", *argv
);
1929 if (set_lifetime(&valid_lft
, *argv
))
1930 invarg("valid_lft value", *argv
);
1931 } else if (matches(*argv
, "preferred_lft") == 0) {
1933 duparg("preferred_lft", *argv
);
1935 preferred_lftp
= *argv
;
1936 if (set_lifetime(&preferred_lft
, *argv
))
1937 invarg("preferred_lft value", *argv
);
1938 } else if (strcmp(*argv
, "home") == 0) {
1939 ifa_flags
|= IFA_F_HOMEADDRESS
;
1940 } else if (strcmp(*argv
, "nodad") == 0) {
1941 ifa_flags
|= IFA_F_NODAD
;
1942 } else if (strcmp(*argv
, "mngtmpaddr") == 0) {
1943 ifa_flags
|= IFA_F_MANAGETEMPADDR
;
1944 } else if (strcmp(*argv
, "noprefixroute") == 0) {
1945 ifa_flags
|= IFA_F_NOPREFIXROUTE
;
1946 } else if (strcmp(*argv
, "autojoin") == 0) {
1947 ifa_flags
|= IFA_F_MCAUTOJOIN
;
1949 if (strcmp(*argv
, "local") == 0) {
1952 if (matches(*argv
, "help") == 0)
1955 duparg2("local", *argv
);
1957 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
1958 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1959 req
.ifa
.ifa_family
= lcl
.family
;
1960 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
1961 local_len
= lcl
.bytelen
;
1965 if (ifa_flags
<= 0xff)
1966 req
.ifa
.ifa_flags
= ifa_flags
;
1968 addattr32(&req
.n
, sizeof(req
), IFA_FLAGS
, ifa_flags
);
1971 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
1974 if (l
&& matches(d
, l
) != 0) {
1975 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
1979 if (peer_len
== 0 && local_len
) {
1980 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
1982 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1983 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1984 " This special behaviour is likely to disappear in further releases,\n" \
1985 " fix your scripts!\n", lcl_arg
, local_len
*8);
1988 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
1991 if (req
.ifa
.ifa_prefixlen
== 0)
1992 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
1994 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
1998 if (req
.ifa
.ifa_family
!= AF_INET
) {
1999 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
2003 if (brd
.bitlen
<= 30) {
2004 for (i
= 31; i
>= brd
.bitlen
; i
--) {
2006 brd
.data
[0] |= htonl(1<<(31-i
));
2008 brd
.data
[0] &= ~htonl(1<<(31-i
));
2010 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
2011 brd_len
= brd
.bytelen
;
2014 if (!scoped
&& cmd
!= RTM_DELADDR
)
2015 req
.ifa
.ifa_scope
= default_scope(&lcl
);
2017 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
2018 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
2022 if (valid_lftp
|| preferred_lftp
) {
2023 struct ifa_cacheinfo cinfo
= {};
2026 fprintf(stderr
, "valid_lft is zero\n");
2029 if (valid_lft
< preferred_lft
) {
2030 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
2034 cinfo
.ifa_prefered
= preferred_lft
;
2035 cinfo
.ifa_valid
= valid_lft
;
2036 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
2040 if ((ifa_flags
& IFA_F_MCAUTOJOIN
) && !ipaddr_is_multicast(&lcl
)) {
2041 fprintf(stderr
, "autojoin needs multicast address\n");
2045 if (rtnl_talk(&rth
, &req
.n
, NULL
, 0) < 0)
2051 int do_ipaddr(int argc
, char **argv
)
2054 return ipaddr_list_flush_or_save(0, NULL
, IPADD_LIST
);
2055 if (matches(*argv
, "add") == 0)
2056 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
2057 if (matches(*argv
, "change") == 0 ||
2058 strcmp(*argv
, "chg") == 0)
2059 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
2060 if (matches(*argv
, "replace") == 0)
2061 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
2062 if (matches(*argv
, "delete") == 0)
2063 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
2064 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
2065 || matches(*argv
, "lst") == 0)
2066 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_LIST
);
2067 if (matches(*argv
, "flush") == 0)
2068 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_FLUSH
);
2069 if (matches(*argv
, "save") == 0)
2070 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_SAVE
);
2071 if (matches(*argv
, "showdump") == 0)
2072 return ipaddr_showdump();
2073 if (matches(*argv
, "restore") == 0)
2074 return ipaddr_restore();
2075 if (matches(*argv
, "help") == 0)
2077 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv
);