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/param.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
28 #include <linux/netdevice.h>
29 #include <linux/if_arp.h>
30 #include <linux/sockios.h>
31 #include <linux/net_namespace.h>
36 #include "ip_common.h"
46 static struct link_filter filter
;
49 static void usage(void) __attribute__((noreturn
));
51 static void usage(void)
56 fprintf(stderr
, "Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]\n");
57 fprintf(stderr
, " [ CONFFLAG-LIST ]\n");
58 fprintf(stderr
, " ip address del IFADDR dev IFNAME [mngtmpaddr]\n");
59 fprintf(stderr
, " ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n");
60 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n");
61 fprintf(stderr
, " ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n");
62 fprintf(stderr
, " [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n");
63 fprintf(stderr
, " [ label LABEL ] [up] [ vrf NAME ] ]\n");
64 fprintf(stderr
, " ip address {showdump|restore}\n");
65 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
66 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
67 fprintf(stderr
, " [ label IFNAME ] [ scope SCOPE-ID ]\n");
68 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
69 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
70 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
71 fprintf(stderr
, " [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n");
72 fprintf(stderr
, " CONFFLAG-LIST ]\n");
73 fprintf(stderr
, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
74 fprintf(stderr
, "CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n");
75 fprintf(stderr
, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
76 fprintf(stderr
, "LFT := forever | SECONDS\n");
77 fprintf(stderr
, "TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |\n");
78 fprintf(stderr
, " bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |\n");
79 fprintf(stderr
, " gre | gretap | ip6gre | ip6gretap | vti | nlmon | can |\n");
80 fprintf(stderr
, " bond_slave | ipvlan | geneve | bridge_slave | vrf | hsr | macsec }\n");
85 static void print_link_flags(FILE *fp
, unsigned int flags
, unsigned int mdown
)
88 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
89 fprintf(fp
, "NO-CARRIER%s", flags
? "," : "");
90 flags
&= ~IFF_RUNNING
;
91 #define _PF(f) if (flags&IFF_##f) { \
93 fprintf(fp, #f "%s", flags ? "," : ""); }
114 fprintf(fp
, "%x", flags
);
116 fprintf(fp
, ",M-DOWN");
120 static const char *oper_states
[] = {
121 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
122 "TESTING", "DORMANT", "UP"
125 static void print_operstate(FILE *f
, __u8 state
)
127 if (state
>= ARRAY_SIZE(oper_states
)) {
128 fprintf(f
, "state %#x ", state
);
130 color_fprintf(f
, oper_state_color(state
),
131 "%-14s ", oper_states
[state
]);
133 fprintf(f
, "state ");
134 color_fprintf(f
, oper_state_color(state
),
135 "%s ", oper_states
[state
]);
139 int get_operstate(const char *name
)
143 for (i
= 0; i
< ARRAY_SIZE(oper_states
); i
++)
144 if (strcasecmp(name
, oper_states
[i
]) == 0)
149 static void print_queuelen(FILE *f
, struct rtattr
*tb
[IFLA_MAX
+ 1])
154 qlen
= rta_getattr_u32(tb
[IFLA_TXQLEN
]);
156 struct ifreq ifr
= {};
157 int s
= socket(AF_INET
, SOCK_STREAM
, 0);
162 strcpy(ifr
.ifr_name
, rta_getattr_str(tb
[IFLA_IFNAME
]));
163 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
164 fprintf(f
, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno
));
172 fprintf(f
, "qlen %d", qlen
);
175 static const char *link_modes
[] = {
179 static void print_linkmode(FILE *f
, struct rtattr
*tb
)
181 unsigned int mode
= rta_getattr_u8(tb
);
183 if (mode
>= ARRAY_SIZE(link_modes
))
184 fprintf(f
, "mode %d ", mode
);
186 fprintf(f
, "mode %s ", link_modes
[mode
]);
189 static char *parse_link_kind(struct rtattr
*tb
, bool slave
)
191 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
192 int attr
= slave
? IFLA_INFO_SLAVE_KIND
: IFLA_INFO_KIND
;
194 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
197 return RTA_DATA(linkinfo
[attr
]);
202 static int match_link_kind(struct rtattr
**tb
, const char *kind
, bool slave
)
204 if (!tb
[IFLA_LINKINFO
])
207 return strcmp(parse_link_kind(tb
[IFLA_LINKINFO
], slave
), kind
);
210 static void print_linktype(FILE *fp
, struct rtattr
*tb
)
212 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
213 struct link_util
*lu
;
214 struct link_util
*slave_lu
;
217 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
219 if (linkinfo
[IFLA_INFO_KIND
]) {
221 = rta_getattr_str(linkinfo
[IFLA_INFO_KIND
]);
223 fprintf(fp
, "%s", _SL_
);
224 fprintf(fp
, " %s ", kind
);
226 lu
= get_link_kind(kind
);
227 if (lu
&& lu
->print_opt
) {
228 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
230 if (linkinfo
[IFLA_INFO_DATA
]) {
231 parse_rtattr_nested(attr
, lu
->maxattr
,
232 linkinfo
[IFLA_INFO_DATA
]);
235 lu
->print_opt(lu
, fp
, data
);
237 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
239 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
243 if (linkinfo
[IFLA_INFO_SLAVE_KIND
]) {
244 const char *slave_kind
245 = rta_getattr_str(linkinfo
[IFLA_INFO_SLAVE_KIND
]);
247 fprintf(fp
, "%s", _SL_
);
248 fprintf(fp
, " %s_slave ", slave_kind
);
249 snprintf(slave
, sizeof(slave
), "%s_slave", slave_kind
);
251 slave_lu
= get_link_kind(slave
);
252 if (slave_lu
&& slave_lu
->print_opt
) {
253 struct rtattr
*attr
[slave_lu
->maxattr
+1], **data
= NULL
;
255 if (linkinfo
[IFLA_INFO_SLAVE_DATA
]) {
256 parse_rtattr_nested(attr
, slave_lu
->maxattr
,
257 linkinfo
[IFLA_INFO_SLAVE_DATA
]);
260 slave_lu
->print_opt(slave_lu
, fp
, data
);
265 static void print_af_spec(FILE *fp
, struct rtattr
*af_spec_attr
)
267 struct rtattr
*inet6_attr
;
268 struct rtattr
*tb
[IFLA_INET6_MAX
+ 1];
270 inet6_attr
= parse_rtattr_one_nested(AF_INET6
, af_spec_attr
);
274 parse_rtattr_nested(tb
, IFLA_INET6_MAX
, inet6_attr
);
276 if (tb
[IFLA_INET6_ADDR_GEN_MODE
]) {
277 __u8 mode
= rta_getattr_u8(tb
[IFLA_INET6_ADDR_GEN_MODE
]);
280 case IN6_ADDR_GEN_MODE_EUI64
:
281 fprintf(fp
, "addrgenmode eui64 ");
283 case IN6_ADDR_GEN_MODE_NONE
:
284 fprintf(fp
, "addrgenmode none ");
286 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY
:
287 fprintf(fp
, "addrgenmode stable_secret ");
289 case IN6_ADDR_GEN_MODE_RANDOM
:
290 fprintf(fp
, "addrgenmode random ");
293 fprintf(fp
, "addrgenmode %#.2hhx ", mode
);
299 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
);
301 static void print_vfinfo(FILE *fp
, struct rtattr
*vfinfo
)
303 struct ifla_vf_mac
*vf_mac
;
304 struct ifla_vf_tx_rate
*vf_tx_rate
;
305 struct rtattr
*vf
[IFLA_VF_MAX
+ 1] = {};
309 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
310 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
314 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
316 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
317 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
319 fprintf(fp
, "%s vf %d MAC %s", _SL_
, vf_mac
->vf
,
320 ll_addr_n2a((unsigned char *)&vf_mac
->mac
,
321 ETH_ALEN
, 0, b1
, sizeof(b1
)));
322 if (vf
[IFLA_VF_VLAN_LIST
]) {
323 struct rtattr
*i
, *vfvlanlist
= vf
[IFLA_VF_VLAN_LIST
];
324 int rem
= RTA_PAYLOAD(vfvlanlist
);
326 for (i
= RTA_DATA(vfvlanlist
);
327 RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
328 struct ifla_vf_vlan_info
*vf_vlan_info
=
332 if (vf_vlan_info
->vlan
)
333 fprintf(fp
, ", vlan %d", vf_vlan_info
->vlan
);
334 if (vf_vlan_info
->qos
)
335 fprintf(fp
, ", qos %d", vf_vlan_info
->qos
);
336 if (vf_vlan_info
->vlan_proto
&&
337 vf_vlan_info
->vlan_proto
!= htons(ETH_P_8021Q
))
338 fprintf(fp
, ", vlan protocol %s",
339 ll_proto_n2a(vf_vlan_info
->vlan_proto
,
344 struct ifla_vf_vlan
*vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
347 fprintf(fp
, ", vlan %d", vf_vlan
->vlan
);
349 fprintf(fp
, ", qos %d", vf_vlan
->qos
);
351 if (vf_tx_rate
->rate
)
352 fprintf(fp
, ", tx rate %d (Mbps)", vf_tx_rate
->rate
);
354 if (vf
[IFLA_VF_RATE
]) {
355 struct ifla_vf_rate
*vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
357 if (vf_rate
->max_tx_rate
)
358 fprintf(fp
, ", max_tx_rate %dMbps", vf_rate
->max_tx_rate
);
359 if (vf_rate
->min_tx_rate
)
360 fprintf(fp
, ", min_tx_rate %dMbps", vf_rate
->min_tx_rate
);
362 if (vf
[IFLA_VF_SPOOFCHK
]) {
363 struct ifla_vf_spoofchk
*vf_spoofchk
=
364 RTA_DATA(vf
[IFLA_VF_SPOOFCHK
]);
366 if (vf_spoofchk
->setting
!= -1)
367 fprintf(fp
, ", spoof checking %s",
368 vf_spoofchk
->setting
? "on" : "off");
370 if (vf
[IFLA_VF_LINK_STATE
]) {
371 struct ifla_vf_link_state
*vf_linkstate
=
372 RTA_DATA(vf
[IFLA_VF_LINK_STATE
]);
374 if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_AUTO
)
375 fprintf(fp
, ", link-state auto");
376 else if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_ENABLE
)
377 fprintf(fp
, ", link-state enable");
379 fprintf(fp
, ", link-state disable");
381 if (vf
[IFLA_VF_TRUST
]) {
382 struct ifla_vf_trust
*vf_trust
= RTA_DATA(vf
[IFLA_VF_TRUST
]);
384 if (vf_trust
->setting
!= -1)
385 fprintf(fp
, ", trust %s",
386 vf_trust
->setting
? "on" : "off");
388 if (vf
[IFLA_VF_RSS_QUERY_EN
]) {
389 struct ifla_vf_rss_query_en
*rss_query
=
390 RTA_DATA(vf
[IFLA_VF_RSS_QUERY_EN
]);
392 if (rss_query
->setting
!= -1)
393 fprintf(fp
, ", query_rss %s",
394 rss_query
->setting
? "on" : "off");
396 if (vf
[IFLA_VF_STATS
] && show_stats
)
397 print_vf_stats64(fp
, vf
[IFLA_VF_STATS
]);
400 void print_num(FILE *fp
, unsigned int width
, uint64_t count
)
402 const char *prefix
= "kMGTPE";
403 const unsigned int base
= use_iec
? 1024 : 1000;
406 uint8_t precision
= 2;
409 if (!human_readable
|| count
< base
) {
410 fprintf(fp
, "%-*"PRIu64
" ", width
, count
);
414 /* increase value by a factor of 1000/1024 and print
415 * if result is something a human can read
419 if (count
/ base
< powi
)
427 /* try to guess a good number of digits for precision */
428 for (; precision
> 0; precision
--) {
430 if (count
/ powi
< powj
)
434 snprintf(buf
, sizeof(buf
), "%.*f%c%s", precision
,
435 (double) count
/ powi
, *prefix
, use_iec
? "i" : "");
437 fprintf(fp
, "%-*s ", width
, buf
);
440 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
)
442 struct rtattr
*vf
[IFLA_VF_STATS_MAX
+ 1];
444 if (vfstats
->rta_type
!= IFLA_VF_STATS
) {
445 fprintf(stderr
, "BUG: rta type is %d\n", vfstats
->rta_type
);
449 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfstats
);
452 fprintf(fp
, "%s", _SL_
);
453 fprintf(fp
, " RX: bytes packets mcast bcast %s", _SL_
);
456 print_num(fp
, 10, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_BYTES
]));
457 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_PACKETS
]));
458 print_num(fp
, 7, rta_getattr_u64(vf
[IFLA_VF_STATS_MULTICAST
]));
459 print_num(fp
, 7, rta_getattr_u64(vf
[IFLA_VF_STATS_BROADCAST
]));
462 fprintf(fp
, "%s", _SL_
);
463 fprintf(fp
, " TX: bytes packets %s", _SL_
);
466 print_num(fp
, 10, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_BYTES
]));
467 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_PACKETS
]));
470 static void print_link_stats64(FILE *fp
, const struct rtnl_link_stats64
*s
,
471 const struct rtattr
*carrier_changes
)
474 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
475 s
->rx_compressed
? "compressed" : "", _SL_
);
478 print_num(fp
, 10, s
->rx_bytes
);
479 print_num(fp
, 8, s
->rx_packets
);
480 print_num(fp
, 7, s
->rx_errors
);
481 print_num(fp
, 7, s
->rx_dropped
);
482 print_num(fp
, 7, s
->rx_over_errors
);
483 print_num(fp
, 7, s
->multicast
);
484 if (s
->rx_compressed
)
485 print_num(fp
, 7, s
->rx_compressed
);
488 if (show_stats
> 1) {
489 fprintf(fp
, "%s", _SL_
);
490 fprintf(fp
, " RX errors: length crc frame fifo missed%s%s",
491 s
->rx_nohandler
? " nohandler" : "", _SL_
);
494 print_num(fp
, 8, s
->rx_length_errors
);
495 print_num(fp
, 7, s
->rx_crc_errors
);
496 print_num(fp
, 7, s
->rx_frame_errors
);
497 print_num(fp
, 7, s
->rx_fifo_errors
);
498 print_num(fp
, 7, s
->rx_missed_errors
);
500 print_num(fp
, 7, s
->rx_nohandler
);
503 fprintf(fp
, "%s", _SL_
);
506 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
507 s
->tx_compressed
? "compressed" : "", _SL_
);
510 print_num(fp
, 10, s
->tx_bytes
);
511 print_num(fp
, 8, s
->tx_packets
);
512 print_num(fp
, 7, s
->tx_errors
);
513 print_num(fp
, 7, s
->tx_dropped
);
514 print_num(fp
, 7, s
->tx_carrier_errors
);
515 print_num(fp
, 7, s
->collisions
);
516 if (s
->tx_compressed
)
517 print_num(fp
, 7, s
->tx_compressed
);
520 if (show_stats
> 1) {
521 fprintf(fp
, "%s", _SL_
);
522 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
524 fprintf(fp
, " transns");
525 fprintf(fp
, "%s", _SL_
);
528 print_num(fp
, 8, s
->tx_aborted_errors
);
529 print_num(fp
, 7, s
->tx_fifo_errors
);
530 print_num(fp
, 7, s
->tx_window_errors
);
531 print_num(fp
, 7, s
->tx_heartbeat_errors
);
533 print_num(fp
, 7, rta_getattr_u32(carrier_changes
));
537 static void print_link_stats32(FILE *fp
, const struct rtnl_link_stats
*s
,
538 const struct rtattr
*carrier_changes
)
541 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
542 s
->rx_compressed
? "compressed" : "", _SL_
);
546 print_num(fp
, 10, s
->rx_bytes
);
547 print_num(fp
, 8, s
->rx_packets
);
548 print_num(fp
, 7, s
->rx_errors
);
549 print_num(fp
, 7, s
->rx_dropped
);
550 print_num(fp
, 7, s
->rx_over_errors
);
551 print_num(fp
, 7, s
->multicast
);
552 if (s
->rx_compressed
)
553 print_num(fp
, 7, s
->rx_compressed
);
556 if (show_stats
> 1) {
557 fprintf(fp
, "%s", _SL_
);
558 fprintf(fp
, " RX errors: length crc frame fifo missed%s%s",
559 s
->rx_nohandler
? " nohandler" : "", _SL_
);
561 print_num(fp
, 8, s
->rx_length_errors
);
562 print_num(fp
, 7, s
->rx_crc_errors
);
563 print_num(fp
, 7, s
->rx_frame_errors
);
564 print_num(fp
, 7, s
->rx_fifo_errors
);
565 print_num(fp
, 7, s
->rx_missed_errors
);
567 print_num(fp
, 7, s
->rx_nohandler
);
569 fprintf(fp
, "%s", _SL_
);
572 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
573 s
->tx_compressed
? "compressed" : "", _SL_
);
576 print_num(fp
, 10, s
->tx_bytes
);
577 print_num(fp
, 8, s
->tx_packets
);
578 print_num(fp
, 7, s
->tx_errors
);
579 print_num(fp
, 7, s
->tx_dropped
);
580 print_num(fp
, 7, s
->tx_carrier_errors
);
581 print_num(fp
, 7, s
->collisions
);
582 if (s
->tx_compressed
)
583 print_num(fp
, 7, s
->tx_compressed
);
586 if (show_stats
> 1) {
587 fprintf(fp
, "%s", _SL_
);
588 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
590 fprintf(fp
, " transns");
591 fprintf(fp
, "%s", _SL_
);
594 print_num(fp
, 8, s
->tx_aborted_errors
);
595 print_num(fp
, 7, s
->tx_fifo_errors
);
596 print_num(fp
, 7, s
->tx_window_errors
);
597 print_num(fp
, 7, s
->tx_heartbeat_errors
);
599 print_num(fp
, 7, rta_getattr_u32(carrier_changes
));
603 static void __print_link_stats(FILE *fp
, struct rtattr
**tb
)
605 const struct rtattr
*carrier_changes
= tb
[IFLA_CARRIER_CHANGES
];
607 if (tb
[IFLA_STATS64
]) {
608 struct rtnl_link_stats64 stats
= { 0 };
610 memcpy(&stats
, RTA_DATA(tb
[IFLA_STATS64
]),
611 MIN(RTA_PAYLOAD(tb
[IFLA_STATS64
]), sizeof(stats
)));
613 print_link_stats64(fp
, &stats
, carrier_changes
);
614 } else if (tb
[IFLA_STATS
]) {
615 struct rtnl_link_stats stats
= { 0 };
617 memcpy(&stats
, RTA_DATA(tb
[IFLA_STATS
]),
618 MIN(RTA_PAYLOAD(tb
[IFLA_STATS
]), sizeof(stats
)));
620 print_link_stats32(fp
, &stats
, carrier_changes
);
624 static void print_link_stats(FILE *fp
, struct nlmsghdr
*n
)
626 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
627 struct rtattr
*tb
[IFLA_MAX
+1];
629 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
),
630 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
)));
631 __print_link_stats(fp
, tb
);
632 fprintf(fp
, "%s", _SL_
);
635 int print_linkinfo_brief(const struct sockaddr_nl
*who
,
636 struct nlmsghdr
*n
, void *arg
,
637 struct link_filter
*pfilter
)
639 FILE *fp
= (FILE *)arg
;
640 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
641 struct rtattr
*tb
[IFLA_MAX
+1];
642 int len
= n
->nlmsg_len
;
644 char buf
[32] = { 0, };
645 unsigned int m_flag
= 0;
647 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
650 len
-= NLMSG_LENGTH(sizeof(*ifi
));
657 if (pfilter
->ifindex
&& ifi
->ifi_index
!= pfilter
->ifindex
)
659 if (pfilter
->up
&& !(ifi
->ifi_flags
&IFF_UP
))
662 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
663 if (tb
[IFLA_IFNAME
] == NULL
) {
664 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
667 name
= rta_getattr_str(tb
[IFLA_IFNAME
]);
670 if (pfilter
->label
&&
671 (!pfilter
->family
|| pfilter
->family
== AF_PACKET
) &&
672 fnmatch(pfilter
->label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
675 if (tb
[IFLA_GROUP
]) {
676 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
678 if (pfilter
->group
!= -1 && group
!= pfilter
->group
)
682 if (tb
[IFLA_MASTER
]) {
683 int master
= rta_getattr_u32(tb
[IFLA_MASTER
]);
685 if (pfilter
->master
> 0 && master
!= pfilter
->master
)
687 } else if (pfilter
->master
> 0)
690 if (pfilter
->kind
&& match_link_kind(tb
, pfilter
->kind
, 0))
693 if (pfilter
->slave_kind
&& match_link_kind(tb
, pfilter
->slave_kind
, 1))
696 if (n
->nlmsg_type
== RTM_DELLINK
)
697 fprintf(fp
, "Deleted ");
701 int iflink
= rta_getattr_u32(tb
[IFLA_LINK
]);
704 snprintf(buf
, sizeof(buf
), "%s@NONE", name
);
706 snprintf(buf
, sizeof(buf
),
707 "%s@%s", name
, ll_idx_n2a(iflink
, b1
));
708 m_flag
= ll_index_to_flags(iflink
);
709 m_flag
= !(m_flag
& IFF_UP
);
712 snprintf(buf
, sizeof(buf
), "%s", name
);
714 fprintf(fp
, "%-16s ", buf
);
716 if (tb
[IFLA_OPERSTATE
])
717 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
719 if (pfilter
->family
== AF_PACKET
) {
721 if (tb
[IFLA_ADDRESS
]) {
722 color_fprintf(fp
, COLOR_MAC
, "%s ",
723 ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
724 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
730 if (pfilter
->family
== AF_PACKET
)
731 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
733 if (pfilter
->family
== AF_PACKET
)
739 static const char *link_events
[] = {
740 [IFLA_EVENT_NONE
] = "NONE",
741 [IFLA_EVENT_REBOOT
] = "REBOOT",
742 [IFLA_EVENT_FEATURES
] = "FEATURE CHANGE",
743 [IFLA_EVENT_BONDING_FAILOVER
] = "BONDING FAILOVER",
744 [IFLA_EVENT_NOTIFY_PEERS
] = "NOTIFY PEERS",
745 [IFLA_EVENT_IGMP_RESEND
] = "RESEND IGMP",
746 [IFLA_EVENT_BONDING_OPTIONS
] = "BONDING OPTION"
749 static void print_link_event(FILE *f
, __u32 event
)
751 if (event
>= ARRAY_SIZE(link_events
))
752 fprintf(f
, "event %d ", event
);
755 fprintf(f
, "event %s ", link_events
[event
]);
759 int print_linkinfo(const struct sockaddr_nl
*who
,
760 struct nlmsghdr
*n
, void *arg
)
762 FILE *fp
= (FILE *)arg
;
763 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
764 struct rtattr
*tb
[IFLA_MAX
+1];
765 int len
= n
->nlmsg_len
;
766 unsigned int m_flag
= 0;
768 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
771 len
-= NLMSG_LENGTH(sizeof(*ifi
));
775 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
777 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
780 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
781 if (tb
[IFLA_IFNAME
] == NULL
)
782 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
785 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
786 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
789 if (tb
[IFLA_GROUP
]) {
790 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
792 if (filter
.group
!= -1 && group
!= filter
.group
)
796 if (tb
[IFLA_MASTER
]) {
797 int master
= rta_getattr_u32(tb
[IFLA_MASTER
]);
799 if (filter
.master
> 0 && master
!= filter
.master
)
801 } else if (filter
.master
> 0)
804 if (filter
.kind
&& match_link_kind(tb
, filter
.kind
, 0))
807 if (filter
.slave_kind
&& match_link_kind(tb
, filter
.slave_kind
, 1))
810 if (n
->nlmsg_type
== RTM_DELLINK
)
811 fprintf(fp
, "Deleted ");
813 fprintf(fp
, "%d: ", ifi
->ifi_index
);
814 color_fprintf(fp
, COLOR_IFNAME
, "%s",
815 tb
[IFLA_IFNAME
] ? rta_getattr_str(tb
[IFLA_IFNAME
]) : "<nil>");
819 int iflink
= rta_getattr_u32(tb
[IFLA_LINK
]);
822 fprintf(fp
, "@NONE: ");
824 if (tb
[IFLA_LINK_NETNSID
])
825 fprintf(fp
, "@if%d: ", iflink
);
827 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
828 m_flag
= ll_index_to_flags(iflink
);
829 m_flag
= !(m_flag
& IFF_UP
);
835 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
838 fprintf(fp
, "mtu %u ", rta_getattr_u32(tb
[IFLA_MTU
]));
840 xdp_dump(fp
, tb
[IFLA_XDP
]);
842 fprintf(fp
, "qdisc %s ", rta_getattr_str(tb
[IFLA_QDISC
]));
843 if (tb
[IFLA_MASTER
]) {
845 fprintf(fp
, "master %s ", ll_idx_n2a(rta_getattr_u32(tb
[IFLA_MASTER
]), b1
));
848 if (tb
[IFLA_OPERSTATE
])
849 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
851 if (do_link
&& tb
[IFLA_LINKMODE
])
852 print_linkmode(fp
, tb
[IFLA_LINKMODE
]);
854 if (tb
[IFLA_GROUP
]) {
856 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
858 fprintf(fp
, "group %s ", rtnl_group_n2a(group
, b1
, sizeof(b1
)));
861 if (filter
.showqueue
)
862 print_queuelen(fp
, tb
);
865 print_link_event(fp
, rta_getattr_u32(tb
[IFLA_EVENT
]));
867 if (!filter
.family
|| filter
.family
== AF_PACKET
|| show_details
) {
869 fprintf(fp
, "%s", _SL_
);
870 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
872 if (tb
[IFLA_ADDRESS
]) {
873 color_fprintf(fp
, COLOR_MAC
, "%s",
874 ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
875 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
879 if (tb
[IFLA_BROADCAST
]) {
880 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
881 fprintf(fp
, " peer ");
883 fprintf(fp
, " brd ");
884 color_fprintf(fp
, COLOR_MAC
, "%s",
885 ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
886 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
892 if (tb
[IFLA_LINK_NETNSID
]) {
893 int id
= rta_getattr_u32(tb
[IFLA_LINK_NETNSID
]);
896 fprintf(fp
, " link-netnsid %d", id
);
898 fprintf(fp
, " link-netnsid unknown");
901 if (tb
[IFLA_PROTO_DOWN
]) {
902 if (rta_getattr_u8(tb
[IFLA_PROTO_DOWN
]))
903 fprintf(fp
, " protodown on ");
907 if (tb
[IFLA_PROMISCUITY
])
908 fprintf(fp
, " promiscuity %u ",
909 rta_getattr_u32(tb
[IFLA_PROMISCUITY
]));
911 if (tb
[IFLA_LINKINFO
])
912 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
914 if (do_link
&& tb
[IFLA_AF_SPEC
])
915 print_af_spec(fp
, tb
[IFLA_AF_SPEC
]);
917 if (tb
[IFLA_NUM_TX_QUEUES
])
918 fprintf(fp
, "numtxqueues %u ",
919 rta_getattr_u32(tb
[IFLA_NUM_TX_QUEUES
]));
921 if (tb
[IFLA_NUM_RX_QUEUES
])
922 fprintf(fp
, "numrxqueues %u ",
923 rta_getattr_u32(tb
[IFLA_NUM_RX_QUEUES
]));
925 if (tb
[IFLA_GSO_MAX_SIZE
])
926 fprintf(fp
, "gso_max_size %u ",
927 rta_getattr_u32(tb
[IFLA_GSO_MAX_SIZE
]));
929 if (tb
[IFLA_GSO_MAX_SEGS
])
930 fprintf(fp
, "gso_max_segs %u ",
931 rta_getattr_u32(tb
[IFLA_GSO_MAX_SEGS
]));
933 if (tb
[IFLA_PHYS_PORT_NAME
])
934 fprintf(fp
, "portname %s ",
935 rta_getattr_str(tb
[IFLA_PHYS_PORT_NAME
]));
937 if (tb
[IFLA_PHYS_PORT_ID
]) {
939 fprintf(fp
, "portid %s ",
940 hexstring_n2a(RTA_DATA(tb
[IFLA_PHYS_PORT_ID
]),
941 RTA_PAYLOAD(tb
[IFLA_PHYS_PORT_ID
]),
945 if (tb
[IFLA_PHYS_SWITCH_ID
]) {
947 fprintf(fp
, "switchid %s ",
948 hexstring_n2a(RTA_DATA(tb
[IFLA_PHYS_SWITCH_ID
]),
949 RTA_PAYLOAD(tb
[IFLA_PHYS_SWITCH_ID
]),
955 if ((do_link
|| show_details
) && tb
[IFLA_IFALIAS
]) {
956 fprintf(fp
, "%s alias %s", _SL_
,
957 rta_getattr_str(tb
[IFLA_IFALIAS
]));
960 if (do_link
&& show_stats
) {
961 fprintf(fp
, "%s", _SL_
);
962 __print_link_stats(fp
, tb
);
965 if ((do_link
|| show_details
) && tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
966 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
967 int rem
= RTA_PAYLOAD(vflist
);
969 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
))
978 static int flush_update(void)
982 * Note that the kernel may delete multiple addresses for one
983 * delete request (e.g. if ipv4 address promotion is disabled).
984 * Since a flush operation is really a series of delete requests
985 * its possible that we may request an address delete that has
986 * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL
987 * errors returned from a flush request
989 if ((rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) &&
990 (errno
!= EADDRNOTAVAIL
)) {
991 perror("Failed to send flush request");
998 static int set_lifetime(unsigned int *lifetime
, char *argv
)
1000 if (strcmp(argv
, "forever") == 0)
1001 *lifetime
= INFINITY_LIFE_TIME
;
1002 else if (get_u32(lifetime
, argv
, 0))
1008 static unsigned int get_ifa_flags(struct ifaddrmsg
*ifa
,
1009 struct rtattr
*ifa_flags_attr
)
1011 return ifa_flags_attr
? rta_getattr_u32(ifa_flags_attr
) :
1015 /* Mapping from argument to address flag mask */
1018 unsigned long value
;
1019 } ifa_flag_names
[] = {
1020 { "secondary", IFA_F_SECONDARY
},
1021 { "temporary", IFA_F_SECONDARY
},
1022 { "nodad", IFA_F_NODAD
},
1023 { "optimistic", IFA_F_OPTIMISTIC
},
1024 { "dadfailed", IFA_F_DADFAILED
},
1025 { "home", IFA_F_HOMEADDRESS
},
1026 { "deprecated", IFA_F_DEPRECATED
},
1027 { "tentative", IFA_F_TENTATIVE
},
1028 { "permanent", IFA_F_PERMANENT
},
1029 { "mngtmpaddr", IFA_F_MANAGETEMPADDR
},
1030 { "noprefixroute", IFA_F_NOPREFIXROUTE
},
1031 { "autojoin", IFA_F_MCAUTOJOIN
},
1032 { "stable-privacy", IFA_F_STABLE_PRIVACY
},
1035 static void print_ifa_flags(FILE *fp
, const struct ifaddrmsg
*ifa
,
1040 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_names
); i
++) {
1041 unsigned long mask
= ifa_flag_names
[i
].value
;
1043 if (mask
== IFA_F_PERMANENT
) {
1044 if (!(flags
& mask
))
1045 fprintf(fp
, "dynamic ");
1046 } else if (flags
& mask
) {
1047 if (mask
== IFA_F_SECONDARY
&&
1048 ifa
->ifa_family
== AF_INET6
)
1049 fprintf(fp
, "temporary ");
1051 fprintf(fp
, "%s ", ifa_flag_names
[i
].name
);
1058 fprintf(fp
, "flags %02x ", flags
);
1062 static int get_filter(const char *arg
)
1067 if (strcmp(arg
, "dynamic") == 0) {
1068 filter
.flags
&= ~IFA_F_PERMANENT
;
1069 filter
.flagmask
|= IFA_F_PERMANENT
;
1070 } else if (strcmp(arg
, "primary") == 0) {
1071 filter
.flags
&= ~IFA_F_SECONDARY
;
1072 filter
.flagmask
|= IFA_F_SECONDARY
;
1073 } else if (*arg
== '-') {
1074 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_names
); i
++) {
1075 if (strcmp(arg
+ 1, ifa_flag_names
[i
].name
))
1078 filter
.flags
&= ifa_flag_names
[i
].value
;
1079 filter
.flagmask
|= ifa_flag_names
[i
].value
;
1085 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_names
); i
++) {
1086 if (strcmp(arg
, ifa_flag_names
[i
].name
))
1088 filter
.flags
|= ifa_flag_names
[i
].value
;
1089 filter
.flagmask
|= ifa_flag_names
[i
].value
;
1098 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1102 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1103 int len
= n
->nlmsg_len
;
1104 unsigned int ifa_flags
;
1105 struct rtattr
*rta_tb
[IFA_MAX
+1];
1109 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
1111 len
-= NLMSG_LENGTH(sizeof(*ifa
));
1113 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
1117 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
1120 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
),
1121 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
1123 ifa_flags
= get_ifa_flags(ifa
, rta_tb
[IFA_FLAGS
]);
1125 if (!rta_tb
[IFA_LOCAL
])
1126 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
1127 if (!rta_tb
[IFA_ADDRESS
])
1128 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
1130 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
1132 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1134 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1140 if (rta_tb
[IFA_LABEL
])
1141 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
1143 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
1144 if (fnmatch(filter
.label
, label
, 0) != 0)
1147 if (filter
.pfx
.family
) {
1148 if (rta_tb
[IFA_LOCAL
]) {
1149 inet_prefix dst
= { .family
= ifa
->ifa_family
};
1151 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
1152 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
1157 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1160 if (filter
.flushb
) {
1161 struct nlmsghdr
*fn
;
1163 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
1167 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
1168 memcpy(fn
, n
, n
->nlmsg_len
);
1169 fn
->nlmsg_type
= RTM_DELADDR
;
1170 fn
->nlmsg_flags
= NLM_F_REQUEST
;
1171 fn
->nlmsg_seq
= ++rth
.seq
;
1172 filter
.flushp
= (((char *)fn
) + n
->nlmsg_len
) - filter
.flushb
;
1178 if (n
->nlmsg_type
== RTM_DELADDR
)
1179 fprintf(fp
, "Deleted ");
1182 if (filter
.oneline
|| filter
.flushb
)
1183 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
1184 if (ifa
->ifa_family
== AF_INET
)
1185 fprintf(fp
, " inet ");
1186 else if (ifa
->ifa_family
== AF_INET6
)
1187 fprintf(fp
, " inet6 ");
1188 else if (ifa
->ifa_family
== AF_DECnet
)
1189 fprintf(fp
, " dnet ");
1190 else if (ifa
->ifa_family
== AF_IPX
)
1191 fprintf(fp
, " ipx ");
1193 fprintf(fp
, " family %d ", ifa
->ifa_family
);
1196 if (rta_tb
[IFA_LOCAL
]) {
1197 color_fprintf(fp
, ifa_family_color(ifa
->ifa_family
), "%s",
1198 format_host_rta(ifa
->ifa_family
,
1199 rta_tb
[IFA_LOCAL
]));
1200 if (rta_tb
[IFA_ADDRESS
] &&
1201 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]),
1202 RTA_DATA(rta_tb
[IFA_LOCAL
]),
1203 ifa
->ifa_family
== AF_INET
? 4 : 16)) {
1204 fprintf(fp
, " peer ");
1205 color_fprintf(fp
, ifa_family_color(ifa
->ifa_family
),
1206 "%s", format_host_rta(ifa
->ifa_family
,
1207 rta_tb
[IFA_ADDRESS
]));
1209 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
1215 if (rta_tb
[IFA_BROADCAST
]) {
1216 fprintf(fp
, "brd ");
1217 color_fprintf(fp
, ifa_family_color(ifa
->ifa_family
), "%s ",
1218 format_host_rta(ifa
->ifa_family
,
1219 rta_tb
[IFA_BROADCAST
]));
1221 if (rta_tb
[IFA_ANYCAST
]) {
1222 fprintf(fp
, "any ");
1223 color_fprintf(fp
, ifa_family_color(ifa
->ifa_family
), "%s ",
1224 format_host_rta(ifa
->ifa_family
,
1225 rta_tb
[IFA_ANYCAST
]));
1227 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
1229 print_ifa_flags(fp
, ifa
, ifa_flags
);
1231 if (rta_tb
[IFA_LABEL
])
1232 fprintf(fp
, "%s", rta_getattr_str(rta_tb
[IFA_LABEL
]));
1233 if (rta_tb
[IFA_CACHEINFO
]) {
1234 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
1236 fprintf(fp
, "%s", _SL_
);
1237 fprintf(fp
, " valid_lft ");
1238 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
)
1239 fprintf(fp
, "forever");
1241 fprintf(fp
, "%usec", ci
->ifa_valid
);
1242 fprintf(fp
, " preferred_lft ");
1243 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
)
1244 fprintf(fp
, "forever");
1246 if (ifa_flags
& IFA_F_DEPRECATED
)
1247 fprintf(fp
, "%dsec", ci
->ifa_prefered
);
1249 fprintf(fp
, "%usec", ci
->ifa_prefered
);
1258 static int print_selected_addrinfo(struct ifinfomsg
*ifi
,
1259 struct nlmsg_list
*ainfo
, FILE *fp
)
1261 for ( ; ainfo
; ainfo
= ainfo
->next
) {
1262 struct nlmsghdr
*n
= &ainfo
->h
;
1263 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1265 if (n
->nlmsg_type
!= RTM_NEWADDR
)
1268 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifa
)))
1271 if (ifa
->ifa_index
!= ifi
->ifi_index
||
1272 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
1275 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
1278 print_addrinfo(NULL
, n
, fp
);
1288 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1291 struct nlmsg_chain
*lchain
= (struct nlmsg_chain
*)arg
;
1292 struct nlmsg_list
*h
;
1294 h
= malloc(n
->nlmsg_len
+sizeof(void *));
1298 memcpy(&h
->h
, n
, n
->nlmsg_len
);
1302 lchain
->tail
->next
= h
;
1307 ll_remember_index(who
, n
, NULL
);
1311 static __u32 ipadd_dump_magic
= 0x47361222;
1313 static int ipadd_save_prep(void)
1317 if (isatty(STDOUT_FILENO
)) {
1318 fprintf(stderr
, "Not sending a binary stream to stdout\n");
1322 ret
= write(STDOUT_FILENO
, &ipadd_dump_magic
, sizeof(ipadd_dump_magic
));
1323 if (ret
!= sizeof(ipadd_dump_magic
)) {
1324 fprintf(stderr
, "Can't write magic to dump file\n");
1331 static int ipadd_dump_check_magic(void)
1336 if (isatty(STDIN_FILENO
)) {
1337 fprintf(stderr
, "Can't restore address dump from a terminal\n");
1341 ret
= fread(&magic
, sizeof(magic
), 1, stdin
);
1342 if (magic
!= ipadd_dump_magic
) {
1343 fprintf(stderr
, "Magic mismatch (%d elems, %x magic)\n", ret
, magic
);
1350 static int save_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1355 ret
= write(STDOUT_FILENO
, n
, n
->nlmsg_len
);
1356 if ((ret
> 0) && (ret
!= n
->nlmsg_len
)) {
1357 fprintf(stderr
, "Short write while saving nlmsg\n");
1361 return ret
== n
->nlmsg_len
? 0 : ret
;
1364 static int show_handler(const struct sockaddr_nl
*nl
,
1365 struct rtnl_ctrl_data
*ctrl
,
1366 struct nlmsghdr
*n
, void *arg
)
1368 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1370 printf("if%d:\n", ifa
->ifa_index
);
1371 print_addrinfo(NULL
, n
, stdout
);
1375 static int ipaddr_showdump(void)
1377 if (ipadd_dump_check_magic())
1380 exit(rtnl_from_file(stdin
, &show_handler
, NULL
));
1383 static int restore_handler(const struct sockaddr_nl
*nl
,
1384 struct rtnl_ctrl_data
*ctrl
,
1385 struct nlmsghdr
*n
, void *arg
)
1389 n
->nlmsg_flags
|= NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_ACK
;
1393 ret
= rtnl_talk(&rth
, n
, n
, sizeof(*n
));
1394 if ((ret
< 0) && (errno
== EEXIST
))
1400 static int ipaddr_restore(void)
1402 if (ipadd_dump_check_magic())
1405 exit(rtnl_from_file(stdin
, &restore_handler
, NULL
));
1408 void free_nlmsg_chain(struct nlmsg_chain
*info
)
1410 struct nlmsg_list
*l
, *n
;
1412 for (l
= info
->head
; l
; l
= n
) {
1418 static void ipaddr_filter(struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
1420 struct nlmsg_list
*l
, **lp
;
1423 while ((l
= *lp
) != NULL
) {
1425 int missing_net_address
= 1;
1426 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1427 struct nlmsg_list
*a
;
1429 for (a
= ainfo
->head
; a
; a
= a
->next
) {
1430 struct nlmsghdr
*n
= &a
->h
;
1431 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1432 struct rtattr
*tb
[IFA_MAX
+ 1];
1433 unsigned int ifa_flags
;
1435 if (ifa
->ifa_index
!= ifi
->ifi_index
)
1437 missing_net_address
= 0;
1438 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1440 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1443 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
1444 ifa_flags
= get_ifa_flags(ifa
, tb
[IFA_FLAGS
]);
1446 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1448 if (filter
.pfx
.family
|| filter
.label
) {
1450 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
1452 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
1454 .family
= ifa
->ifa_family
1457 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
1458 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
1466 label
= RTA_DATA(tb
[IFA_LABEL
]);
1468 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
1469 if (fnmatch(filter
.label
, label
, 0) != 0)
1477 if (missing_net_address
&&
1478 (filter
.family
== AF_UNSPEC
|| filter
.family
== AF_PACKET
))
1488 static int ipaddr_flush(void)
1491 char flushb
[4096-512];
1493 filter
.flushb
= flushb
;
1495 filter
.flushe
= sizeof(flushb
);
1497 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
1498 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
1499 perror("Cannot send dump request");
1503 if (rtnl_dump_filter_nc(&rth
, print_addrinfo
,
1504 stdout
, NLM_F_DUMP_INTR
) < 0) {
1505 fprintf(stderr
, "Flush terminated\n");
1508 if (filter
.flushed
== 0) {
1512 printf("Nothing to flush.\n");
1514 printf("*** Flush is complete after %d round%s ***\n", round
, round
> 1?"s":"");
1520 if (flush_update() < 0)
1524 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
1528 /* If we are flushing, and specifying primary, then we
1529 * want to flush only a single round. Otherwise, we'll
1530 * start flushing secondaries that were promoted to
1533 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
1536 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
1541 static int iplink_filter_req(struct nlmsghdr
*nlh
, int reqlen
)
1545 err
= addattr32(nlh
, reqlen
, IFLA_EXT_MASK
, RTEXT_FILTER_VF
);
1549 if (filter
.master
) {
1550 err
= addattr32(nlh
, reqlen
, IFLA_MASTER
, filter
.master
);
1556 struct rtattr
*linkinfo
;
1558 linkinfo
= addattr_nest(nlh
, reqlen
, IFLA_LINKINFO
);
1560 err
= addattr_l(nlh
, reqlen
, IFLA_INFO_KIND
, filter
.kind
,
1561 strlen(filter
.kind
));
1565 addattr_nest_end(nlh
, linkinfo
);
1571 /* fills in linfo with link data and optionally ainfo with address info
1572 * caller can walk lists as desired and must call free_nlmsg_chain for
1575 int ip_linkaddr_list(int family
, req_filter_fn_t filter_fn
,
1576 struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
1578 if (rtnl_wilddump_req_filter_fn(&rth
, preferred_family
, RTM_GETLINK
,
1580 perror("Cannot send dump request");
1584 if (rtnl_dump_filter(&rth
, store_nlmsg
, linfo
) < 0) {
1585 fprintf(stderr
, "Dump terminated\n");
1590 if (rtnl_wilddump_request(&rth
, family
, RTM_GETADDR
) < 0) {
1591 perror("Cannot send dump request");
1595 if (rtnl_dump_filter(&rth
, store_nlmsg
, ainfo
) < 0) {
1596 fprintf(stderr
, "Dump terminated\n");
1604 static int ipaddr_list_flush_or_save(int argc
, char **argv
, int action
)
1606 struct nlmsg_chain linfo
= { NULL
, NULL
};
1607 struct nlmsg_chain _ainfo
= { NULL
, NULL
}, *ainfo
= NULL
;
1608 struct nlmsg_list
*l
;
1609 char *filter_dev
= NULL
;
1612 ipaddr_reset_filter(oneline
, 0);
1613 filter
.showqueue
= 1;
1614 filter
.family
= preferred_family
;
1617 if (action
== IPADD_FLUSH
) {
1619 fprintf(stderr
, "Flush requires arguments.\n");
1623 if (filter
.family
== AF_PACKET
) {
1624 fprintf(stderr
, "Cannot flush link addresses.\n");
1630 if (strcmp(*argv
, "to") == 0) {
1632 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
1633 if (filter
.family
== AF_UNSPEC
)
1634 filter
.family
= filter
.pfx
.family
;
1635 } else if (strcmp(*argv
, "scope") == 0) {
1636 unsigned int scope
= 0;
1639 filter
.scopemask
= -1;
1640 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
1641 if (strcmp(*argv
, "all") != 0)
1642 invarg("invalid \"scope\"\n", *argv
);
1643 scope
= RT_SCOPE_NOWHERE
;
1644 filter
.scopemask
= 0;
1646 filter
.scope
= scope
;
1647 } else if (strcmp(*argv
, "up") == 0) {
1649 } else if (get_filter(*argv
) == 0) {
1651 } else if (strcmp(*argv
, "label") == 0) {
1653 filter
.label
= *argv
;
1654 } else if (strcmp(*argv
, "group") == 0) {
1656 if (rtnl_group_a2n(&filter
.group
, *argv
))
1657 invarg("Invalid \"group\" value\n", *argv
);
1658 } else if (strcmp(*argv
, "master") == 0) {
1662 ifindex
= ll_name_to_index(*argv
);
1664 invarg("Device does not exist\n", *argv
);
1665 filter
.master
= ifindex
;
1666 } else if (strcmp(*argv
, "vrf") == 0) {
1670 ifindex
= ll_name_to_index(*argv
);
1672 invarg("Not a valid VRF name\n", *argv
);
1673 if (!name_is_vrf(*argv
))
1674 invarg("Not a valid VRF name\n", *argv
);
1675 filter
.master
= ifindex
;
1676 } else if (strcmp(*argv
, "type") == 0) {
1680 soff
= strlen(*argv
) - strlen("_slave");
1681 if (!strcmp(*argv
+ soff
, "_slave")) {
1682 (*argv
)[soff
] = '\0';
1683 filter
.slave_kind
= *argv
;
1685 filter
.kind
= *argv
;
1688 if (strcmp(*argv
, "dev") == 0)
1690 else if (matches(*argv
, "help") == 0)
1693 duparg2("dev", *argv
);
1700 filter
.ifindex
= ll_name_to_index(filter_dev
);
1701 if (filter
.ifindex
<= 0) {
1702 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
1707 if (action
== IPADD_FLUSH
)
1708 return ipaddr_flush();
1710 if (action
== IPADD_SAVE
) {
1711 if (ipadd_save_prep())
1714 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETADDR
) < 0) {
1715 perror("Cannot send dump request");
1719 if (rtnl_dump_filter(&rth
, save_nlmsg
, stdout
) < 0) {
1720 fprintf(stderr
, "Save terminated\n");
1728 * If only filter_dev present and none of the other
1729 * link filters are present, use RTM_GETLINK to get
1732 if (filter_dev
&& filter
.group
== -1 && do_link
== 1) {
1733 if (iplink_get(0, filter_dev
, RTEXT_FILTER_VF
) < 0) {
1734 perror("Cannot send link get request");
1740 if (filter
.family
!= AF_PACKET
) {
1747 if (ip_linkaddr_list(filter
.family
, iplink_filter_req
,
1748 &linfo
, ainfo
) != 0)
1751 if (filter
.family
!= AF_PACKET
)
1752 ipaddr_filter(&linfo
, ainfo
);
1754 for (l
= linfo
.head
; l
; l
= l
->next
) {
1756 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1759 if (print_linkinfo_brief(NULL
, &l
->h
,
1761 if (filter
.family
!= AF_PACKET
)
1762 print_selected_addrinfo(ifi
,
1765 } else if (no_link
||
1766 (res
= print_linkinfo(NULL
, &l
->h
, stdout
)) >= 0) {
1767 if (filter
.family
!= AF_PACKET
)
1768 print_selected_addrinfo(ifi
,
1769 ainfo
->head
, stdout
);
1770 if (res
> 0 && !do_link
&& show_stats
)
1771 print_link_stats(stdout
, &l
->h
);
1778 free_nlmsg_chain(ainfo
);
1779 free_nlmsg_chain(&linfo
);
1785 ipaddr_loop_each_vf(struct rtattr
*tb
[], int vfnum
, int *min
, int *max
)
1787 struct rtattr
*vflist
= tb
[IFLA_VFINFO_LIST
];
1788 struct rtattr
*i
, *vf
[IFLA_VF_MAX
+1];
1789 struct ifla_vf_rate
*vf_rate
;
1792 rem
= RTA_PAYLOAD(vflist
);
1794 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
1795 parse_rtattr_nested(vf
, IFLA_VF_MAX
, i
);
1796 vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
1797 if (vf_rate
->vf
== vfnum
) {
1798 *min
= vf_rate
->min_tx_rate
;
1799 *max
= vf_rate
->max_tx_rate
;
1803 fprintf(stderr
, "Cannot find VF %d\n", vfnum
);
1807 void ipaddr_get_vf_rate(int vfnum
, int *min
, int *max
, int idx
)
1809 struct nlmsg_chain linfo
= { NULL
, NULL
};
1810 struct rtattr
*tb
[IFLA_MAX
+1];
1811 struct ifinfomsg
*ifi
;
1812 struct nlmsg_list
*l
;
1816 if (rtnl_wilddump_request(&rth
, AF_UNSPEC
, RTM_GETLINK
) < 0) {
1817 perror("Cannot send dump request");
1820 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
1821 fprintf(stderr
, "Dump terminated\n");
1824 for (l
= linfo
.head
; l
; l
= l
->next
) {
1826 ifi
= NLMSG_DATA(n
);
1828 len
= n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
1829 if (len
< 0 || (idx
&& idx
!= ifi
->ifi_index
))
1832 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
1834 if ((tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
])) {
1835 ipaddr_loop_each_vf(tb
, vfnum
, min
, max
);
1841 int ipaddr_list_link(int argc
, char **argv
)
1843 preferred_family
= AF_PACKET
;
1845 return ipaddr_list_flush_or_save(argc
, argv
, IPADD_LIST
);
1848 void ipaddr_reset_filter(int oneline
, int ifindex
)
1850 memset(&filter
, 0, sizeof(filter
));
1851 filter
.oneline
= oneline
;
1852 filter
.ifindex
= ifindex
;
1855 static int default_scope(inet_prefix
*lcl
)
1857 if (lcl
->family
== AF_INET
) {
1858 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
1859 return RT_SCOPE_HOST
;
1864 static bool ipaddr_is_multicast(inet_prefix
*a
)
1866 if (a
->family
== AF_INET
)
1867 return IN_MULTICAST(ntohl(a
->data
[0]));
1868 else if (a
->family
== AF_INET6
)
1869 return IN6_IS_ADDR_MULTICAST(a
->data
);
1874 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
1878 struct ifaddrmsg ifa
;
1881 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
)),
1882 .n
.nlmsg_flags
= NLM_F_REQUEST
| flags
,
1883 .n
.nlmsg_type
= cmd
,
1884 .ifa
.ifa_family
= preferred_family
,
1888 char *lcl_arg
= NULL
;
1889 char *valid_lftp
= NULL
;
1890 char *preferred_lftp
= NULL
;
1898 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
1899 __u32 valid_lft
= INFINITY_LIFE_TIME
;
1900 unsigned int ifa_flags
= 0;
1903 if (strcmp(*argv
, "peer") == 0 ||
1904 strcmp(*argv
, "remote") == 0) {
1908 duparg("peer", *argv
);
1909 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
1910 peer_len
= peer
.bytelen
;
1911 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1912 req
.ifa
.ifa_family
= peer
.family
;
1913 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
1914 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
1915 } else if (matches(*argv
, "broadcast") == 0 ||
1916 strcmp(*argv
, "brd") == 0) {
1921 duparg("broadcast", *argv
);
1922 if (strcmp(*argv
, "+") == 0)
1924 else if (strcmp(*argv
, "-") == 0)
1927 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1928 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1929 req
.ifa
.ifa_family
= addr
.family
;
1930 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
1931 brd_len
= addr
.bytelen
;
1933 } else if (strcmp(*argv
, "anycast") == 0) {
1938 duparg("anycast", *argv
);
1939 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1940 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1941 req
.ifa
.ifa_family
= addr
.family
;
1942 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
1943 any_len
= addr
.bytelen
;
1944 } else if (strcmp(*argv
, "scope") == 0) {
1945 unsigned int scope
= 0;
1948 if (rtnl_rtscope_a2n(&scope
, *argv
))
1949 invarg("invalid scope value.", *argv
);
1950 req
.ifa
.ifa_scope
= scope
;
1952 } else if (strcmp(*argv
, "dev") == 0) {
1955 } else if (strcmp(*argv
, "label") == 0) {
1958 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
1959 } else if (matches(*argv
, "valid_lft") == 0) {
1961 duparg("valid_lft", *argv
);
1964 if (set_lifetime(&valid_lft
, *argv
))
1965 invarg("valid_lft value", *argv
);
1966 } else if (matches(*argv
, "preferred_lft") == 0) {
1968 duparg("preferred_lft", *argv
);
1970 preferred_lftp
= *argv
;
1971 if (set_lifetime(&preferred_lft
, *argv
))
1972 invarg("preferred_lft value", *argv
);
1973 } else if (strcmp(*argv
, "home") == 0) {
1974 ifa_flags
|= IFA_F_HOMEADDRESS
;
1975 } else if (strcmp(*argv
, "nodad") == 0) {
1976 ifa_flags
|= IFA_F_NODAD
;
1977 } else if (strcmp(*argv
, "mngtmpaddr") == 0) {
1978 ifa_flags
|= IFA_F_MANAGETEMPADDR
;
1979 } else if (strcmp(*argv
, "noprefixroute") == 0) {
1980 ifa_flags
|= IFA_F_NOPREFIXROUTE
;
1981 } else if (strcmp(*argv
, "autojoin") == 0) {
1982 ifa_flags
|= IFA_F_MCAUTOJOIN
;
1984 if (strcmp(*argv
, "local") == 0)
1986 if (matches(*argv
, "help") == 0)
1989 duparg2("local", *argv
);
1991 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
1992 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1993 req
.ifa
.ifa_family
= lcl
.family
;
1994 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
1995 local_len
= lcl
.bytelen
;
1999 if (ifa_flags
<= 0xff)
2000 req
.ifa
.ifa_flags
= ifa_flags
;
2002 addattr32(&req
.n
, sizeof(req
), IFA_FLAGS
, ifa_flags
);
2005 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
2008 if (l
&& matches(d
, l
) != 0) {
2009 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
2013 if (peer_len
== 0 && local_len
) {
2014 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
2016 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n"
2017 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n"
2018 " This special behaviour is likely to disappear in further releases,\n"
2019 " fix your scripts!\n", lcl_arg
, local_len
*8);
2022 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
2025 if (req
.ifa
.ifa_prefixlen
== 0)
2026 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
2028 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
2032 if (req
.ifa
.ifa_family
!= AF_INET
) {
2033 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
2037 if (brd
.bitlen
<= 30) {
2038 for (i
= 31; i
>= brd
.bitlen
; i
--) {
2040 brd
.data
[0] |= htonl(1<<(31-i
));
2042 brd
.data
[0] &= ~htonl(1<<(31-i
));
2044 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
2045 brd_len
= brd
.bytelen
;
2048 if (!scoped
&& cmd
!= RTM_DELADDR
)
2049 req
.ifa
.ifa_scope
= default_scope(&lcl
);
2051 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
2052 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
2056 if (valid_lftp
|| preferred_lftp
) {
2057 struct ifa_cacheinfo cinfo
= {};
2060 fprintf(stderr
, "valid_lft is zero\n");
2063 if (valid_lft
< preferred_lft
) {
2064 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
2068 cinfo
.ifa_prefered
= preferred_lft
;
2069 cinfo
.ifa_valid
= valid_lft
;
2070 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
2074 if ((ifa_flags
& IFA_F_MCAUTOJOIN
) && !ipaddr_is_multicast(&lcl
)) {
2075 fprintf(stderr
, "autojoin needs multicast address\n");
2079 if (rtnl_talk(&rth
, &req
.n
, NULL
, 0) < 0)
2085 int do_ipaddr(int argc
, char **argv
)
2088 return ipaddr_list_flush_or_save(0, NULL
, IPADD_LIST
);
2089 if (matches(*argv
, "add") == 0)
2090 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
2091 if (matches(*argv
, "change") == 0 ||
2092 strcmp(*argv
, "chg") == 0)
2093 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
2094 if (matches(*argv
, "replace") == 0)
2095 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
2096 if (matches(*argv
, "delete") == 0)
2097 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
2098 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
2099 || matches(*argv
, "lst") == 0)
2100 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_LIST
);
2101 if (matches(*argv
, "flush") == 0)
2102 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_FLUSH
);
2103 if (matches(*argv
, "save") == 0)
2104 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_SAVE
);
2105 if (matches(*argv
, "showdump") == 0)
2106 return ipaddr_showdump();
2107 if (matches(*argv
, "restore") == 0)
2108 return ipaddr_restore();
2109 if (matches(*argv
, "help") == 0)
2111 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv
);