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>
18 #include <sys/ioctl.h>
19 #include <sys/socket.h>
20 #include <sys/param.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
27 #include <linux/netdevice.h>
28 #include <linux/if_arp.h>
29 #include <linux/sockios.h>
30 #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 | vxcan | dummy | ifb | macvlan | macvtap |\n");
78 fprintf(stderr
, " bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |\n");
79 fprintf(stderr
, " gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan | vti |\n");
80 fprintf(stderr
, " nlmon | can | bond_slave | ipvlan | geneve | bridge_slave |\n");
81 fprintf(stderr
, " hsr | macsec\n");
86 static void print_link_flags(FILE *fp
, unsigned int flags
, unsigned int mdown
)
88 open_json_array(PRINT_ANY
, is_json_context() ? "flags" : "<");
89 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
90 print_string(PRINT_ANY
, NULL
,
91 flags
? "%s," : "%s", "NO-CARRIER");
92 flags
&= ~IFF_RUNNING
;
93 #define _PF(f) if (flags&IFF_##f) { \
95 print_string(PRINT_ANY, NULL, flags ? "%s," : "%s", #f); }
116 print_hex(PRINT_ANY
, NULL
, "%x", flags
);
118 print_string(PRINT_ANY
, NULL
, ",%s", "M-DOWN");
119 close_json_array(PRINT_ANY
, "> ");
122 static const char *oper_states
[] = {
123 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
124 "TESTING", "DORMANT", "UP"
127 static void print_operstate(FILE *f
, __u8 state
)
129 if (state
>= ARRAY_SIZE(oper_states
)) {
130 if (is_json_context())
131 print_uint(PRINT_JSON
, "operstate_index", NULL
, state
);
133 print_0xhex(PRINT_FP
, NULL
, "state %#x", state
);
135 print_color_string(PRINT_ANY
,
136 oper_state_color(state
),
141 if (is_json_context())
142 print_string(PRINT_JSON
,
144 NULL
, oper_states
[state
]);
146 fprintf(f
, "state ");
147 color_fprintf(f
, oper_state_color(state
),
148 "%s ", oper_states
[state
]);
153 int get_operstate(const char *name
)
157 for (i
= 0; i
< ARRAY_SIZE(oper_states
); i
++)
158 if (strcasecmp(name
, oper_states
[i
]) == 0)
163 static void print_queuelen(FILE *f
, struct rtattr
*tb
[IFLA_MAX
+ 1])
168 qlen
= rta_getattr_u32(tb
[IFLA_TXQLEN
]);
170 struct ifreq ifr
= {};
171 int s
= socket(AF_INET
, SOCK_STREAM
, 0);
176 strcpy(ifr
.ifr_name
, rta_getattr_str(tb
[IFLA_IFNAME
]));
177 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
178 fprintf(f
, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno
));
186 print_int(PRINT_ANY
, "txqlen", "qlen %d", qlen
);
189 static const char *link_modes
[] = {
193 static void print_linkmode(FILE *f
, struct rtattr
*tb
)
195 unsigned int mode
= rta_getattr_u8(tb
);
197 if (mode
>= ARRAY_SIZE(link_modes
))
203 print_string(PRINT_ANY
,
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
;
237 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
238 open_json_object("linkinfo");
240 if (linkinfo
[IFLA_INFO_KIND
]) {
242 = rta_getattr_str(linkinfo
[IFLA_INFO_KIND
]);
244 print_string(PRINT_FP
, NULL
, "%s", _SL_
);
245 print_string(PRINT_ANY
, "info_kind", " %s ", kind
);
247 lu
= get_link_kind(kind
);
248 if (lu
&& lu
->print_opt
) {
249 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
251 if (linkinfo
[IFLA_INFO_DATA
]) {
252 parse_rtattr_nested(attr
, lu
->maxattr
,
253 linkinfo
[IFLA_INFO_DATA
]);
256 open_json_object("info_data");
257 lu
->print_opt(lu
, fp
, data
);
260 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
262 open_json_object("info_xstats");
263 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
269 if (linkinfo
[IFLA_INFO_SLAVE_KIND
]) {
270 const char *slave_kind
271 = rta_getattr_str(linkinfo
[IFLA_INFO_SLAVE_KIND
]);
273 print_string(PRINT_FP
, NULL
, "%s", _SL_
);
274 print_string(PRINT_ANY
,
279 snprintf(slave
, sizeof(slave
), "%s_slave", slave_kind
);
281 slave_lu
= get_link_kind(slave
);
282 if (slave_lu
&& slave_lu
->print_opt
) {
283 struct rtattr
*attr
[slave_lu
->maxattr
+1], **data
= NULL
;
285 if (linkinfo
[IFLA_INFO_SLAVE_DATA
]) {
286 parse_rtattr_nested(attr
, slave_lu
->maxattr
,
287 linkinfo
[IFLA_INFO_SLAVE_DATA
]);
290 open_json_object("info_slave_data");
291 slave_lu
->print_opt(slave_lu
, fp
, data
);
298 static void print_af_spec(FILE *fp
, struct rtattr
*af_spec_attr
)
300 struct rtattr
*inet6_attr
;
301 struct rtattr
*tb
[IFLA_INET6_MAX
+ 1];
303 inet6_attr
= parse_rtattr_one_nested(AF_INET6
, af_spec_attr
);
307 parse_rtattr_nested(tb
, IFLA_INET6_MAX
, inet6_attr
);
309 if (tb
[IFLA_INET6_ADDR_GEN_MODE
]) {
310 __u8 mode
= rta_getattr_u8(tb
[IFLA_INET6_ADDR_GEN_MODE
]);
314 case IN6_ADDR_GEN_MODE_EUI64
:
315 print_string(PRINT_ANY
,
316 "inet6_addr_gen_mode",
320 case IN6_ADDR_GEN_MODE_NONE
:
321 print_string(PRINT_ANY
,
322 "inet6_addr_gen_mode",
326 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY
:
327 print_string(PRINT_ANY
,
328 "inet6_addr_gen_mode",
332 case IN6_ADDR_GEN_MODE_RANDOM
:
333 print_string(PRINT_ANY
,
334 "inet6_addr_gen_mode",
339 snprintf(b1
, sizeof(b1
), "%#.2hhx", mode
);
340 print_string(PRINT_ANY
,
341 "inet6_addr_gen_mode",
349 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
);
351 static void print_vfinfo(FILE *fp
, struct rtattr
*vfinfo
)
353 struct ifla_vf_mac
*vf_mac
;
354 struct ifla_vf_tx_rate
*vf_tx_rate
;
355 struct rtattr
*vf
[IFLA_VF_MAX
+ 1] = {};
359 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
360 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
364 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
366 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
367 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
369 print_string(PRINT_FP
, NULL
, "%s ", _SL_
);
370 print_int(PRINT_ANY
, "vf", "vf %d ", vf_mac
->vf
);
371 print_string(PRINT_ANY
, "mac", "MAC %s",
372 ll_addr_n2a((unsigned char *) &vf_mac
->mac
,
373 ETH_ALEN
, 0, b1
, sizeof(b1
)));
375 if (vf
[IFLA_VF_VLAN_LIST
]) {
376 struct rtattr
*i
, *vfvlanlist
= vf
[IFLA_VF_VLAN_LIST
];
377 int rem
= RTA_PAYLOAD(vfvlanlist
);
379 open_json_array(PRINT_JSON
, "vlan_list");
380 for (i
= RTA_DATA(vfvlanlist
);
381 RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
382 struct ifla_vf_vlan_info
*vf_vlan_info
= RTA_DATA(i
);
385 open_json_object(NULL
);
386 if (vf_vlan_info
->vlan
)
391 if (vf_vlan_info
->qos
)
396 if (vf_vlan_info
->vlan_proto
&&
397 vf_vlan_info
->vlan_proto
!= htons(ETH_P_8021Q
))
398 print_string(PRINT_ANY
,
400 ", vlan protocol %s",
402 vf_vlan_info
->vlan_proto
,
406 close_json_array(PRINT_JSON
, NULL
);
408 struct ifla_vf_vlan
*vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
416 print_int(PRINT_ANY
, "qos", ", qos %d", vf_vlan
->qos
);
419 if (vf_tx_rate
->rate
)
422 ", tx rate %d (Mbps)",
425 if (vf
[IFLA_VF_RATE
]) {
426 struct ifla_vf_rate
*vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
427 int max_tx
= vf_rate
->max_tx_rate
;
428 int min_tx
= vf_rate
->min_tx_rate
;
430 if (is_json_context()) {
431 open_json_object("rate");
432 print_int(PRINT_JSON
, "max_tx", NULL
, max_tx
);
433 print_int(PRINT_ANY
, "min_tx", NULL
, min_tx
);
437 fprintf(fp
, ", max_tx_rate %dMbps", max_tx
);
439 fprintf(fp
, ", min_tx_rate %dMbps", min_tx
);
443 if (vf
[IFLA_VF_SPOOFCHK
]) {
444 struct ifla_vf_spoofchk
*vf_spoofchk
=
445 RTA_DATA(vf
[IFLA_VF_SPOOFCHK
]);
447 if (vf_spoofchk
->setting
!= -1)
448 print_bool(PRINT_ANY
,
450 vf_spoofchk
->setting
?
451 ", spoof checking on" : ", spoof checking off",
452 vf_spoofchk
->setting
);
455 if (vf
[IFLA_VF_LINK_STATE
]) {
456 struct ifla_vf_link_state
*vf_linkstate
=
457 RTA_DATA(vf
[IFLA_VF_LINK_STATE
]);
459 if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_AUTO
)
460 print_string(PRINT_ANY
,
464 else if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_ENABLE
)
465 print_string(PRINT_ANY
,
470 print_string(PRINT_ANY
,
476 if (vf
[IFLA_VF_TRUST
]) {
477 struct ifla_vf_trust
*vf_trust
= RTA_DATA(vf
[IFLA_VF_TRUST
]);
479 if (vf_trust
->setting
!= -1)
480 print_bool(PRINT_ANY
,
482 vf_trust
->setting
? ", trust on" : ", trust off",
486 if (vf
[IFLA_VF_RSS_QUERY_EN
]) {
487 struct ifla_vf_rss_query_en
*rss_query
=
488 RTA_DATA(vf
[IFLA_VF_RSS_QUERY_EN
]);
490 if (rss_query
->setting
!= -1)
491 print_bool(PRINT_ANY
,
493 rss_query
->setting
? ", query_rss on"
498 if (vf
[IFLA_VF_STATS
] && show_stats
)
499 print_vf_stats64(fp
, vf
[IFLA_VF_STATS
]);
502 void print_num(FILE *fp
, unsigned int width
, uint64_t count
)
504 const char *prefix
= "kMGTPE";
505 const unsigned int base
= use_iec
? 1024 : 1000;
508 uint8_t precision
= 2;
511 if (!human_readable
|| count
< base
) {
512 fprintf(fp
, "%-*"PRIu64
" ", width
, count
);
516 /* increase value by a factor of 1000/1024 and print
517 * if result is something a human can read
521 if (count
/ base
< powi
)
529 /* try to guess a good number of digits for precision */
530 for (; precision
> 0; precision
--) {
532 if (count
/ powi
< powj
)
536 snprintf(buf
, sizeof(buf
), "%.*f%c%s", precision
,
537 (double) count
/ powi
, *prefix
, use_iec
? "i" : "");
539 fprintf(fp
, "%-*s ", width
, buf
);
542 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
)
544 struct rtattr
*vf
[IFLA_VF_STATS_MAX
+ 1];
546 if (vfstats
->rta_type
!= IFLA_VF_STATS
) {
547 fprintf(stderr
, "BUG: rta type is %d\n", vfstats
->rta_type
);
551 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfstats
);
553 if (is_json_context()) {
554 open_json_object("stats");
557 open_json_object("rx");
558 print_uint(PRINT_JSON
, "bytes", NULL
,
559 rta_getattr_u64(vf
[IFLA_VF_STATS_RX_BYTES
]));
560 print_uint(PRINT_JSON
, "packets", NULL
,
561 rta_getattr_u64(vf
[IFLA_VF_STATS_RX_PACKETS
]));
562 print_uint(PRINT_JSON
, "multicast", NULL
,
563 rta_getattr_u64(vf
[IFLA_VF_STATS_MULTICAST
]));
564 print_uint(PRINT_JSON
, "broadcast", NULL
,
565 rta_getattr_u64(vf
[IFLA_VF_STATS_BROADCAST
]));
569 open_json_object("tx");
570 print_uint(PRINT_JSON
, "tx_bytes", NULL
,
571 rta_getattr_u64(vf
[IFLA_VF_STATS_TX_BYTES
]));
572 print_uint(PRINT_JSON
, "tx_packets", NULL
,
573 rta_getattr_u64(vf
[IFLA_VF_STATS_TX_PACKETS
]));
578 fprintf(fp
, "%s", _SL_
);
579 fprintf(fp
, " RX: bytes packets mcast bcast %s", _SL_
);
582 print_num(fp
, 10, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_BYTES
]));
583 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_PACKETS
]));
584 print_num(fp
, 7, rta_getattr_u64(vf
[IFLA_VF_STATS_MULTICAST
]));
585 print_num(fp
, 7, rta_getattr_u64(vf
[IFLA_VF_STATS_BROADCAST
]));
588 fprintf(fp
, "%s", _SL_
);
589 fprintf(fp
, " TX: bytes packets %s", _SL_
);
592 print_num(fp
, 10, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_BYTES
]));
593 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_PACKETS
]));
597 static void print_link_stats64(FILE *fp
, const struct rtnl_link_stats64
*s
,
598 const struct rtattr
*carrier_changes
)
600 if (is_json_context()) {
601 open_json_object("stats644");
604 open_json_object("rx");
605 print_uint(PRINT_JSON
, "bytes", NULL
, s
->rx_bytes
);
606 print_uint(PRINT_JSON
, "packets", NULL
, s
->rx_packets
);
607 print_uint(PRINT_JSON
, "errors", NULL
, s
->rx_errors
);
608 print_uint(PRINT_JSON
, "dropped", NULL
, s
->rx_dropped
);
609 print_uint(PRINT_JSON
, "over_errors", NULL
, s
->rx_over_errors
);
610 print_uint(PRINT_JSON
, "multicast", NULL
, s
->multicast
);
611 if (s
->rx_compressed
)
612 print_uint(PRINT_JSON
,
614 NULL
, s
->rx_compressed
);
617 if (show_stats
> 1) {
618 print_uint(PRINT_JSON
,
620 NULL
, s
->rx_length_errors
);
621 print_uint(PRINT_JSON
,
623 NULL
, s
->rx_crc_errors
);
624 print_uint(PRINT_JSON
,
626 NULL
, s
->rx_frame_errors
);
627 print_uint(PRINT_JSON
,
629 NULL
, s
->rx_fifo_errors
);
630 print_uint(PRINT_JSON
,
632 NULL
, s
->rx_missed_errors
);
634 print_uint(PRINT_JSON
,
635 "nohandler", NULL
, s
->rx_nohandler
);
640 open_json_object("tx");
641 print_uint(PRINT_JSON
, "bytes", NULL
, s
->tx_bytes
);
642 print_uint(PRINT_JSON
, "packets", NULL
, s
->tx_packets
);
643 print_uint(PRINT_JSON
, "errors", NULL
, s
->tx_errors
);
644 print_uint(PRINT_JSON
, "dropped", NULL
, s
->tx_dropped
);
645 print_uint(PRINT_JSON
,
647 NULL
, s
->tx_carrier_errors
);
648 print_uint(PRINT_JSON
, "collisions", NULL
, s
->collisions
);
649 if (s
->tx_compressed
)
650 print_uint(PRINT_JSON
,
652 NULL
, s
->tx_compressed
);
655 if (show_stats
> 1) {
656 print_uint(PRINT_JSON
,
658 NULL
, s
->tx_aborted_errors
);
659 print_uint(PRINT_JSON
,
661 NULL
, s
->tx_fifo_errors
);
662 print_uint(PRINT_JSON
,
664 NULL
, s
->tx_window_errors
);
665 print_uint(PRINT_JSON
,
667 NULL
, s
->tx_heartbeat_errors
);
669 print_uint(PRINT_JSON
, "carrier_changes", NULL
,
670 rta_getattr_u32(carrier_changes
));
677 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
678 s
->rx_compressed
? "compressed" : "", _SL_
);
681 print_num(fp
, 10, s
->rx_bytes
);
682 print_num(fp
, 8, s
->rx_packets
);
683 print_num(fp
, 7, s
->rx_errors
);
684 print_num(fp
, 7, s
->rx_dropped
);
685 print_num(fp
, 7, s
->rx_over_errors
);
686 print_num(fp
, 7, s
->multicast
);
687 if (s
->rx_compressed
)
688 print_num(fp
, 7, s
->rx_compressed
);
691 if (show_stats
> 1) {
692 fprintf(fp
, "%s", _SL_
);
693 fprintf(fp
, " RX errors: length crc frame fifo missed%s%s",
694 s
->rx_nohandler
? " nohandler" : "", _SL_
);
697 print_num(fp
, 8, s
->rx_length_errors
);
698 print_num(fp
, 7, s
->rx_crc_errors
);
699 print_num(fp
, 7, s
->rx_frame_errors
);
700 print_num(fp
, 7, s
->rx_fifo_errors
);
701 print_num(fp
, 7, s
->rx_missed_errors
);
703 print_num(fp
, 7, s
->rx_nohandler
);
706 fprintf(fp
, "%s", _SL_
);
709 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
710 s
->tx_compressed
? "compressed" : "", _SL_
);
713 print_num(fp
, 10, s
->tx_bytes
);
714 print_num(fp
, 8, s
->tx_packets
);
715 print_num(fp
, 7, s
->tx_errors
);
716 print_num(fp
, 7, s
->tx_dropped
);
717 print_num(fp
, 7, s
->tx_carrier_errors
);
718 print_num(fp
, 7, s
->collisions
);
719 if (s
->tx_compressed
)
720 print_num(fp
, 7, s
->tx_compressed
);
723 if (show_stats
> 1) {
724 fprintf(fp
, "%s", _SL_
);
725 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
727 fprintf(fp
, " transns");
728 fprintf(fp
, "%s", _SL_
);
731 print_num(fp
, 8, s
->tx_aborted_errors
);
732 print_num(fp
, 7, s
->tx_fifo_errors
);
733 print_num(fp
, 7, s
->tx_window_errors
);
734 print_num(fp
, 7, s
->tx_heartbeat_errors
);
737 rta_getattr_u32(carrier_changes
));
742 static void print_link_stats32(FILE *fp
, const struct rtnl_link_stats
*s
,
743 const struct rtattr
*carrier_changes
)
745 if (is_json_context()) {
746 open_json_object("stats");
749 open_json_object("rx");
750 print_uint(PRINT_JSON
, "bytes", NULL
, s
->rx_bytes
);
751 print_uint(PRINT_JSON
, "packets", NULL
, s
->rx_packets
);
752 print_uint(PRINT_JSON
, "errors", NULL
, s
->rx_errors
);
753 print_uint(PRINT_JSON
, "dropped", NULL
, s
->rx_dropped
);
754 print_uint(PRINT_JSON
, "over_errors", NULL
, s
->rx_over_errors
);
755 print_uint(PRINT_JSON
, "multicast", NULL
, s
->multicast
);
756 if (s
->rx_compressed
)
757 print_int(PRINT_JSON
,
759 NULL
, s
->rx_compressed
);
762 if (show_stats
> 1) {
763 print_uint(PRINT_JSON
,
765 NULL
, s
->rx_length_errors
);
766 print_uint(PRINT_JSON
,
768 NULL
, s
->rx_crc_errors
);
769 print_uint(PRINT_JSON
,
771 NULL
, s
->rx_frame_errors
);
772 print_uint(PRINT_JSON
,
774 NULL
, s
->rx_fifo_errors
);
775 print_uint(PRINT_JSON
,
777 NULL
, s
->rx_missed_errors
);
779 print_int(PRINT_JSON
,
781 NULL
, s
->rx_nohandler
);
786 open_json_object("tx");
787 print_uint(PRINT_JSON
, "bytes", NULL
, s
->tx_bytes
);
788 print_uint(PRINT_JSON
, "packets", NULL
, s
->tx_packets
);
789 print_uint(PRINT_JSON
, "errors", NULL
, s
->tx_errors
);
790 print_uint(PRINT_JSON
, "dropped", NULL
, s
->tx_dropped
);
791 print_uint(PRINT_JSON
,
793 NULL
, s
->tx_carrier_errors
);
794 print_uint(PRINT_JSON
, "collisions", NULL
, s
->collisions
);
795 if (s
->tx_compressed
)
796 print_int(PRINT_JSON
,
798 NULL
, s
->tx_compressed
);
801 if (show_stats
> 1) {
802 print_uint(PRINT_JSON
,
804 NULL
, s
->tx_aborted_errors
);
805 print_uint(PRINT_JSON
,
807 NULL
, s
->tx_fifo_errors
);
808 print_uint(PRINT_JSON
,
810 NULL
, s
->tx_window_errors
);
811 print_uint(PRINT_JSON
,
813 NULL
, s
->tx_heartbeat_errors
);
815 print_uint(PRINT_JSON
,
818 rta_getattr_u32(carrier_changes
));
825 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
826 s
->rx_compressed
? "compressed" : "", _SL_
);
830 print_num(fp
, 10, s
->rx_bytes
);
831 print_num(fp
, 8, s
->rx_packets
);
832 print_num(fp
, 7, s
->rx_errors
);
833 print_num(fp
, 7, s
->rx_dropped
);
834 print_num(fp
, 7, s
->rx_over_errors
);
835 print_num(fp
, 7, s
->multicast
);
836 if (s
->rx_compressed
)
837 print_num(fp
, 7, s
->rx_compressed
);
840 if (show_stats
> 1) {
841 fprintf(fp
, "%s", _SL_
);
842 fprintf(fp
, " RX errors: length crc frame fifo missed%s%s",
843 s
->rx_nohandler
? " nohandler" : "", _SL_
);
845 print_num(fp
, 8, s
->rx_length_errors
);
846 print_num(fp
, 7, s
->rx_crc_errors
);
847 print_num(fp
, 7, s
->rx_frame_errors
);
848 print_num(fp
, 7, s
->rx_fifo_errors
);
849 print_num(fp
, 7, s
->rx_missed_errors
);
851 print_num(fp
, 7, s
->rx_nohandler
);
853 fprintf(fp
, "%s", _SL_
);
856 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
857 s
->tx_compressed
? "compressed" : "", _SL_
);
860 print_num(fp
, 10, s
->tx_bytes
);
861 print_num(fp
, 8, s
->tx_packets
);
862 print_num(fp
, 7, s
->tx_errors
);
863 print_num(fp
, 7, s
->tx_dropped
);
864 print_num(fp
, 7, s
->tx_carrier_errors
);
865 print_num(fp
, 7, s
->collisions
);
866 if (s
->tx_compressed
)
867 print_num(fp
, 7, s
->tx_compressed
);
870 if (show_stats
> 1) {
871 fprintf(fp
, "%s", _SL_
);
872 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
874 fprintf(fp
, " transns");
875 fprintf(fp
, "%s", _SL_
);
878 print_num(fp
, 8, s
->tx_aborted_errors
);
879 print_num(fp
, 7, s
->tx_fifo_errors
);
880 print_num(fp
, 7, s
->tx_window_errors
);
881 print_num(fp
, 7, s
->tx_heartbeat_errors
);
884 rta_getattr_u32(carrier_changes
));
889 static void __print_link_stats(FILE *fp
, struct rtattr
**tb
)
891 const struct rtattr
*carrier_changes
= tb
[IFLA_CARRIER_CHANGES
];
893 if (tb
[IFLA_STATS64
]) {
894 struct rtnl_link_stats64 stats
= { 0 };
896 memcpy(&stats
, RTA_DATA(tb
[IFLA_STATS64
]),
897 MIN(RTA_PAYLOAD(tb
[IFLA_STATS64
]), sizeof(stats
)));
899 print_link_stats64(fp
, &stats
, carrier_changes
);
900 } else if (tb
[IFLA_STATS
]) {
901 struct rtnl_link_stats stats
= { 0 };
903 memcpy(&stats
, RTA_DATA(tb
[IFLA_STATS
]),
904 MIN(RTA_PAYLOAD(tb
[IFLA_STATS
]), sizeof(stats
)));
906 print_link_stats32(fp
, &stats
, carrier_changes
);
910 static void print_link_stats(FILE *fp
, struct nlmsghdr
*n
)
912 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
913 struct rtattr
*tb
[IFLA_MAX
+1];
915 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
),
916 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
)));
917 __print_link_stats(fp
, tb
);
918 fprintf(fp
, "%s", _SL_
);
921 int print_linkinfo_brief(const struct sockaddr_nl
*who
,
922 struct nlmsghdr
*n
, void *arg
,
923 struct link_filter
*pfilter
)
925 FILE *fp
= (FILE *)arg
;
926 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
927 struct rtattr
*tb
[IFLA_MAX
+1];
928 int len
= n
->nlmsg_len
;
930 char buf
[32] = { 0, };
931 unsigned int m_flag
= 0;
933 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
936 len
-= NLMSG_LENGTH(sizeof(*ifi
));
943 if (pfilter
->ifindex
&& ifi
->ifi_index
!= pfilter
->ifindex
)
945 if (pfilter
->up
&& !(ifi
->ifi_flags
&IFF_UP
))
948 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
949 if (tb
[IFLA_IFNAME
] == NULL
) {
950 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
953 name
= rta_getattr_str(tb
[IFLA_IFNAME
]);
956 if (pfilter
->label
&&
957 (!pfilter
->family
|| pfilter
->family
== AF_PACKET
) &&
958 fnmatch(pfilter
->label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
961 if (tb
[IFLA_GROUP
]) {
962 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
964 if (pfilter
->group
!= -1 && group
!= pfilter
->group
)
968 if (tb
[IFLA_MASTER
]) {
969 int master
= rta_getattr_u32(tb
[IFLA_MASTER
]);
971 if (pfilter
->master
> 0 && master
!= pfilter
->master
)
973 } else if (pfilter
->master
> 0)
976 if (pfilter
->kind
&& match_link_kind(tb
, pfilter
->kind
, 0))
979 if (pfilter
->slave_kind
&& match_link_kind(tb
, pfilter
->slave_kind
, 1))
982 if (n
->nlmsg_type
== RTM_DELLINK
)
983 print_bool(PRINT_ANY
, "deleted", "Deleted ", true);
987 int iflink
= rta_getattr_u32(tb
[IFLA_LINK
]);
990 snprintf(buf
, sizeof(buf
), "%s@NONE", name
);
991 print_null(PRINT_JSON
, "link", NULL
, NULL
);
993 const char *link
= ll_idx_n2a(iflink
, b1
);
995 print_string(PRINT_JSON
, "link", NULL
, link
);
996 snprintf(buf
, sizeof(buf
), "%s@%s", name
, link
);
997 m_flag
= ll_index_to_flags(iflink
);
998 m_flag
= !(m_flag
& IFF_UP
);
1001 snprintf(buf
, sizeof(buf
), "%s", name
);
1003 print_string(PRINT_FP
, NULL
, "%-16s ", buf
);
1004 print_string(PRINT_JSON
, "ifname", NULL
, name
);
1006 if (tb
[IFLA_OPERSTATE
])
1007 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
1009 if (pfilter
->family
== AF_PACKET
) {
1012 if (tb
[IFLA_ADDRESS
]) {
1013 print_color_string(PRINT_ANY
, COLOR_MAC
,
1016 RTA_DATA(tb
[IFLA_ADDRESS
]),
1017 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
1023 if (pfilter
->family
== AF_PACKET
) {
1024 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
1025 print_string(PRINT_FP
, NULL
, "%s", "\n");
1031 static const char *link_events
[] = {
1032 [IFLA_EVENT_NONE
] = "NONE",
1033 [IFLA_EVENT_REBOOT
] = "REBOOT",
1034 [IFLA_EVENT_FEATURES
] = "FEATURE CHANGE",
1035 [IFLA_EVENT_BONDING_FAILOVER
] = "BONDING FAILOVER",
1036 [IFLA_EVENT_NOTIFY_PEERS
] = "NOTIFY PEERS",
1037 [IFLA_EVENT_IGMP_RESEND
] = "RESEND IGMP",
1038 [IFLA_EVENT_BONDING_OPTIONS
] = "BONDING OPTION"
1041 static void print_link_event(FILE *f
, __u32 event
)
1043 if (event
>= ARRAY_SIZE(link_events
))
1044 print_int(PRINT_ANY
, "event", "event %d ", event
);
1047 print_string(PRINT_ANY
,
1048 "event", "event %s ",
1049 link_events
[event
]);
1053 int print_linkinfo(const struct sockaddr_nl
*who
,
1054 struct nlmsghdr
*n
, void *arg
)
1056 FILE *fp
= (FILE *)arg
;
1057 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
1058 struct rtattr
*tb
[IFLA_MAX
+1];
1059 int len
= n
->nlmsg_len
;
1060 unsigned int m_flag
= 0;
1062 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
1065 len
-= NLMSG_LENGTH(sizeof(*ifi
));
1069 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
1071 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
1074 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
1075 if (tb
[IFLA_IFNAME
] == NULL
)
1076 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
1079 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
1080 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
1083 if (tb
[IFLA_GROUP
]) {
1084 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
1086 if (filter
.group
!= -1 && group
!= filter
.group
)
1090 if (tb
[IFLA_MASTER
]) {
1091 int master
= rta_getattr_u32(tb
[IFLA_MASTER
]);
1093 if (filter
.master
> 0 && master
!= filter
.master
)
1095 } else if (filter
.master
> 0)
1098 if (filter
.kind
&& match_link_kind(tb
, filter
.kind
, 0))
1101 if (filter
.slave_kind
&& match_link_kind(tb
, filter
.slave_kind
, 1))
1104 if (n
->nlmsg_type
== RTM_DELLINK
)
1105 print_bool(PRINT_ANY
, "deleted", "Deleted ", true);
1107 print_int(PRINT_ANY
, "ifindex", "%d: ", ifi
->ifi_index
);
1108 if (tb
[IFLA_IFNAME
]) {
1109 print_color_string(PRINT_ANY
,
1112 rta_getattr_str(tb
[IFLA_IFNAME
]));
1114 print_null(PRINT_JSON
, "ifname", NULL
, NULL
);
1115 print_color_null(PRINT_FP
, COLOR_IFNAME
,
1116 "ifname", "%s", "<nil>");
1119 if (tb
[IFLA_LINK
]) {
1120 int iflink
= rta_getattr_u32(tb
[IFLA_LINK
]);
1123 print_null(PRINT_ANY
, "link", "@%s: ", "NONE");
1125 if (tb
[IFLA_LINK_NETNSID
])
1126 print_int(PRINT_ANY
,
1127 "link_index", "@if%d: ", iflink
);
1131 print_string(PRINT_ANY
,
1134 ll_idx_n2a(iflink
, b1
));
1135 m_flag
= ll_index_to_flags(iflink
);
1136 m_flag
= !(m_flag
& IFF_UP
);
1140 print_string(PRINT_FP
, NULL
, ": ", NULL
);
1142 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
1145 print_int(PRINT_ANY
,
1147 rta_getattr_u32(tb
[IFLA_MTU
]));
1149 xdp_dump(fp
, tb
[IFLA_XDP
], do_link
, false);
1151 print_string(PRINT_ANY
,
1154 rta_getattr_str(tb
[IFLA_QDISC
]));
1155 if (tb
[IFLA_MASTER
]) {
1158 print_string(PRINT_ANY
,
1161 ll_idx_n2a(rta_getattr_u32(tb
[IFLA_MASTER
]), b1
));
1164 if (tb
[IFLA_OPERSTATE
])
1165 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
1167 if (do_link
&& tb
[IFLA_LINKMODE
])
1168 print_linkmode(fp
, tb
[IFLA_LINKMODE
]);
1170 if (tb
[IFLA_GROUP
]) {
1172 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
1174 print_string(PRINT_ANY
,
1177 rtnl_group_n2a(group
, b1
, sizeof(b1
)));
1180 if (filter
.showqueue
)
1181 print_queuelen(fp
, tb
);
1184 print_link_event(fp
, rta_getattr_u32(tb
[IFLA_EVENT
]));
1186 if (!filter
.family
|| filter
.family
== AF_PACKET
|| show_details
) {
1189 print_string(PRINT_FP
, NULL
, "%s", _SL_
);
1190 print_string(PRINT_ANY
,
1193 ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
1194 if (tb
[IFLA_ADDRESS
]) {
1195 print_color_string(PRINT_ANY
,
1199 ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
1200 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
1204 if (tb
[IFLA_BROADCAST
]) {
1205 if (ifi
->ifi_flags
&IFF_POINTOPOINT
) {
1206 print_string(PRINT_FP
, NULL
, " peer ", NULL
);
1207 print_bool(PRINT_JSON
,
1208 "link_pointtopoint", NULL
, true);
1210 print_string(PRINT_FP
, NULL
, " brd ", NULL
);
1212 print_color_string(PRINT_ANY
,
1216 ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
1217 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
1223 if (tb
[IFLA_LINK_NETNSID
]) {
1224 int id
= rta_getattr_u32(tb
[IFLA_LINK_NETNSID
]);
1226 if (is_json_context()) {
1227 print_int(PRINT_JSON
, "link_netnsid", NULL
, id
);
1230 print_int(PRINT_FP
, NULL
,
1231 " link-netnsid %d", id
);
1233 print_string(PRINT_FP
, NULL
,
1234 " link-netnsid %s", "unknown");
1238 if (tb
[IFLA_PROTO_DOWN
]) {
1239 if (rta_getattr_u8(tb
[IFLA_PROTO_DOWN
]))
1240 print_bool(PRINT_ANY
,
1241 "proto_down", " protodown on ", true);
1245 if (tb
[IFLA_PROMISCUITY
])
1246 print_uint(PRINT_ANY
,
1249 rta_getattr_u32(tb
[IFLA_PROMISCUITY
]));
1251 if (tb
[IFLA_LINKINFO
])
1252 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
1254 if (do_link
&& tb
[IFLA_AF_SPEC
])
1255 print_af_spec(fp
, tb
[IFLA_AF_SPEC
]);
1257 if (tb
[IFLA_NUM_TX_QUEUES
])
1258 print_uint(PRINT_ANY
,
1261 rta_getattr_u32(tb
[IFLA_NUM_TX_QUEUES
]));
1263 if (tb
[IFLA_NUM_RX_QUEUES
])
1264 print_uint(PRINT_ANY
,
1267 rta_getattr_u32(tb
[IFLA_NUM_RX_QUEUES
]));
1269 if (tb
[IFLA_GSO_MAX_SIZE
])
1270 print_uint(PRINT_ANY
,
1273 rta_getattr_u32(tb
[IFLA_GSO_MAX_SIZE
]));
1275 if (tb
[IFLA_GSO_MAX_SEGS
])
1276 print_uint(PRINT_ANY
,
1279 rta_getattr_u32(tb
[IFLA_GSO_MAX_SEGS
]));
1281 if (tb
[IFLA_PHYS_PORT_NAME
])
1282 print_string(PRINT_ANY
,
1285 rta_getattr_str(tb
[IFLA_PHYS_PORT_NAME
]));
1287 if (tb
[IFLA_PHYS_PORT_ID
]) {
1289 print_string(PRINT_ANY
,
1293 RTA_DATA(tb
[IFLA_PHYS_PORT_ID
]),
1294 RTA_PAYLOAD(tb
[IFLA_PHYS_PORT_ID
]),
1298 if (tb
[IFLA_PHYS_SWITCH_ID
]) {
1300 print_string(PRINT_ANY
,
1303 hexstring_n2a(RTA_DATA(tb
[IFLA_PHYS_SWITCH_ID
]),
1304 RTA_PAYLOAD(tb
[IFLA_PHYS_SWITCH_ID
]),
1309 if ((do_link
|| show_details
) && tb
[IFLA_IFALIAS
]) {
1310 print_string(PRINT_FP
, NULL
, "%s ", _SL_
);
1311 print_string(PRINT_ANY
,
1314 rta_getattr_str(tb
[IFLA_IFALIAS
]));
1317 if ((do_link
|| show_details
) && tb
[IFLA_XDP
])
1318 xdp_dump(fp
, tb
[IFLA_XDP
], true, true);
1320 if (do_link
&& show_stats
) {
1321 print_string(PRINT_FP
, NULL
, "%s", _SL_
);
1322 __print_link_stats(fp
, tb
);
1325 if ((do_link
|| show_details
) && tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
1326 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
1327 int rem
= RTA_PAYLOAD(vflist
);
1329 open_json_array(PRINT_JSON
, "vfinfo_list");
1330 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
1331 open_json_object(NULL
);
1332 print_vfinfo(fp
, i
);
1333 close_json_object();
1335 close_json_array(PRINT_JSON
, NULL
);
1338 print_string(PRINT_FP
, NULL
, "\n", NULL
);
1343 static int flush_update(void)
1347 * Note that the kernel may delete multiple addresses for one
1348 * delete request (e.g. if ipv4 address promotion is disabled).
1349 * Since a flush operation is really a series of delete requests
1350 * its possible that we may request an address delete that has
1351 * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL
1352 * errors returned from a flush request
1354 if ((rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) &&
1355 (errno
!= EADDRNOTAVAIL
)) {
1356 perror("Failed to send flush request");
1363 static int set_lifetime(unsigned int *lifetime
, char *argv
)
1365 if (strcmp(argv
, "forever") == 0)
1366 *lifetime
= INFINITY_LIFE_TIME
;
1367 else if (get_u32(lifetime
, argv
, 0))
1373 static unsigned int get_ifa_flags(struct ifaddrmsg
*ifa
,
1374 struct rtattr
*ifa_flags_attr
)
1376 return ifa_flags_attr
? rta_getattr_u32(ifa_flags_attr
) :
1380 /* Mapping from argument to address flag mask */
1383 unsigned long value
;
1384 } ifa_flag_names
[] = {
1385 { "secondary", IFA_F_SECONDARY
},
1386 { "temporary", IFA_F_SECONDARY
},
1387 { "nodad", IFA_F_NODAD
},
1388 { "optimistic", IFA_F_OPTIMISTIC
},
1389 { "dadfailed", IFA_F_DADFAILED
},
1390 { "home", IFA_F_HOMEADDRESS
},
1391 { "deprecated", IFA_F_DEPRECATED
},
1392 { "tentative", IFA_F_TENTATIVE
},
1393 { "permanent", IFA_F_PERMANENT
},
1394 { "mngtmpaddr", IFA_F_MANAGETEMPADDR
},
1395 { "noprefixroute", IFA_F_NOPREFIXROUTE
},
1396 { "autojoin", IFA_F_MCAUTOJOIN
},
1397 { "stable-privacy", IFA_F_STABLE_PRIVACY
},
1400 static void print_ifa_flags(FILE *fp
, const struct ifaddrmsg
*ifa
,
1405 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_names
); i
++) {
1406 unsigned long mask
= ifa_flag_names
[i
].value
;
1408 if (mask
== IFA_F_PERMANENT
) {
1409 if (!(flags
& mask
))
1410 print_bool(PRINT_ANY
,
1411 "dynamic", "dynamic ", true);
1412 } else if (flags
& mask
) {
1413 if (mask
== IFA_F_SECONDARY
&&
1414 ifa
->ifa_family
== AF_INET6
) {
1415 print_bool(PRINT_ANY
,
1416 "temporary", "temporary ", true);
1418 print_string(PRINT_FP
, NULL
,
1419 "%s ", ifa_flag_names
[i
].name
);
1420 print_bool(PRINT_JSON
,
1421 ifa_flag_names
[i
].name
, NULL
, true);
1429 if (is_json_context()) {
1432 snprintf(b1
, sizeof(b1
), "%02x", flags
);
1433 print_string(PRINT_JSON
, "ifa_flags", NULL
, b1
);
1435 fprintf(fp
, "flags %02x ", flags
);
1441 static int get_filter(const char *arg
)
1446 if (strcmp(arg
, "dynamic") == 0) {
1447 filter
.flags
&= ~IFA_F_PERMANENT
;
1448 filter
.flagmask
|= IFA_F_PERMANENT
;
1449 } else if (strcmp(arg
, "primary") == 0) {
1450 filter
.flags
&= ~IFA_F_SECONDARY
;
1451 filter
.flagmask
|= IFA_F_SECONDARY
;
1452 } else if (*arg
== '-') {
1453 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_names
); i
++) {
1454 if (strcmp(arg
+ 1, ifa_flag_names
[i
].name
))
1457 filter
.flags
&= ifa_flag_names
[i
].value
;
1458 filter
.flagmask
|= ifa_flag_names
[i
].value
;
1464 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_names
); i
++) {
1465 if (strcmp(arg
, ifa_flag_names
[i
].name
))
1467 filter
.flags
|= ifa_flag_names
[i
].value
;
1468 filter
.flagmask
|= ifa_flag_names
[i
].value
;
1477 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1481 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1482 int len
= n
->nlmsg_len
;
1483 unsigned int ifa_flags
;
1484 struct rtattr
*rta_tb
[IFA_MAX
+1];
1488 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
1490 len
-= NLMSG_LENGTH(sizeof(*ifa
));
1492 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
1496 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
1499 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
),
1500 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
1502 ifa_flags
= get_ifa_flags(ifa
, rta_tb
[IFA_FLAGS
]);
1504 if (!rta_tb
[IFA_LOCAL
])
1505 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
1506 if (!rta_tb
[IFA_ADDRESS
])
1507 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
1509 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
1511 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1513 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1519 if (rta_tb
[IFA_LABEL
])
1520 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
1522 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
1523 if (fnmatch(filter
.label
, label
, 0) != 0)
1526 if (filter
.pfx
.family
) {
1527 if (rta_tb
[IFA_LOCAL
]) {
1528 inet_prefix dst
= { .family
= ifa
->ifa_family
};
1530 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
1531 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
1536 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1539 if (filter
.flushb
) {
1540 struct nlmsghdr
*fn
;
1542 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
1546 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
1547 memcpy(fn
, n
, n
->nlmsg_len
);
1548 fn
->nlmsg_type
= RTM_DELADDR
;
1549 fn
->nlmsg_flags
= NLM_F_REQUEST
;
1550 fn
->nlmsg_seq
= ++rth
.seq
;
1551 filter
.flushp
= (((char *)fn
) + n
->nlmsg_len
) - filter
.flushb
;
1557 if (n
->nlmsg_type
== RTM_DELADDR
)
1558 print_bool(PRINT_ANY
, "deleted", "Deleted ", true);
1563 if (filter
.oneline
|| filter
.flushb
) {
1564 const char *dev
= ll_index_to_name(ifa
->ifa_index
);
1566 if (is_json_context()) {
1567 print_int(PRINT_JSON
,
1568 "index", NULL
, ifa
->ifa_index
);
1569 print_string(PRINT_JSON
, "dev", NULL
, dev
);
1571 fprintf(fp
, "%u: %s", ifa
->ifa_index
, dev
);
1575 name
= family_name(ifa
->ifa_family
);
1577 print_string(PRINT_ANY
, "family", " %s ", name
);
1579 print_int(PRINT_ANY
, "family_index", " family %d ",
1584 if (rta_tb
[IFA_LOCAL
]) {
1585 print_color_string(PRINT_ANY
,
1586 ifa_family_color(ifa
->ifa_family
),
1588 format_host_rta(ifa
->ifa_family
,
1589 rta_tb
[IFA_LOCAL
]));
1590 if (rta_tb
[IFA_ADDRESS
] &&
1591 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]),
1592 RTA_DATA(rta_tb
[IFA_LOCAL
]),
1593 ifa
->ifa_family
== AF_INET
? 4 : 16)) {
1594 print_string(PRINT_FP
, NULL
, " %s ", "peer");
1595 print_color_string(PRINT_ANY
,
1596 ifa_family_color(ifa
->ifa_family
),
1599 format_host_rta(ifa
->ifa_family
,
1600 rta_tb
[IFA_ADDRESS
]));
1602 print_int(PRINT_ANY
, "prefixlen", "/%d ", ifa
->ifa_prefixlen
);
1608 if (rta_tb
[IFA_BROADCAST
]) {
1609 print_string(PRINT_FP
, NULL
, "%s ", "brd");
1610 print_color_string(PRINT_ANY
,
1611 ifa_family_color(ifa
->ifa_family
),
1614 format_host_rta(ifa
->ifa_family
,
1615 rta_tb
[IFA_BROADCAST
]));
1618 if (rta_tb
[IFA_ANYCAST
]) {
1619 print_string(PRINT_FP
, NULL
, "%s ", "any");
1620 print_color_string(PRINT_ANY
,
1621 ifa_family_color(ifa
->ifa_family
),
1624 format_host_rta(ifa
->ifa_family
,
1625 rta_tb
[IFA_ANYCAST
]));
1628 print_string(PRINT_ANY
,
1631 rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
1633 print_ifa_flags(fp
, ifa
, ifa_flags
);
1635 if (rta_tb
[IFA_LABEL
])
1636 print_string(PRINT_ANY
,
1639 rta_getattr_str(rta_tb
[IFA_LABEL
]));
1641 if (rta_tb
[IFA_CACHEINFO
]) {
1642 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
1644 print_string(PRINT_FP
, NULL
, "%s", _SL_
);
1645 print_string(PRINT_FP
, NULL
, " valid_lft ", NULL
);
1647 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
) {
1648 print_uint(PRINT_JSON
,
1650 NULL
, INFINITY_LIFE_TIME
);
1651 print_string(PRINT_FP
, NULL
, "%s", "forever");
1653 print_uint(PRINT_ANY
,
1654 "valid_life_time", "%usec", ci
->ifa_valid
);
1657 print_string(PRINT_FP
, NULL
, " preferred_lft ", NULL
);
1658 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
) {
1659 print_uint(PRINT_JSON
,
1660 "preferred_life_time",
1661 NULL
, INFINITY_LIFE_TIME
);
1662 print_string(PRINT_FP
, NULL
, "%s", "forever");
1664 if (ifa_flags
& IFA_F_DEPRECATED
)
1665 print_int(PRINT_ANY
,
1666 "preferred_life_time",
1670 print_uint(PRINT_ANY
,
1671 "preferred_life_time",
1676 print_string(PRINT_FP
, NULL
, "%s", "\n");
1682 static int print_selected_addrinfo(struct ifinfomsg
*ifi
,
1683 struct nlmsg_list
*ainfo
, FILE *fp
)
1685 open_json_array(PRINT_JSON
, "addr_info");
1686 for ( ; ainfo
; ainfo
= ainfo
->next
) {
1687 struct nlmsghdr
*n
= &ainfo
->h
;
1688 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1690 if (n
->nlmsg_type
!= RTM_NEWADDR
)
1693 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifa
)))
1696 if (ifa
->ifa_index
!= ifi
->ifi_index
||
1697 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
1700 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
1703 open_json_object(NULL
);
1704 print_addrinfo(NULL
, n
, fp
);
1705 close_json_object();
1707 close_json_array(PRINT_JSON
, NULL
);
1710 print_string(PRINT_FP
, NULL
, "%s", "\n");
1717 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1720 struct nlmsg_chain
*lchain
= (struct nlmsg_chain
*)arg
;
1721 struct nlmsg_list
*h
;
1723 h
= malloc(n
->nlmsg_len
+sizeof(void *));
1727 memcpy(&h
->h
, n
, n
->nlmsg_len
);
1731 lchain
->tail
->next
= h
;
1736 ll_remember_index(who
, n
, NULL
);
1740 static __u32 ipadd_dump_magic
= 0x47361222;
1742 static int ipadd_save_prep(void)
1746 if (isatty(STDOUT_FILENO
)) {
1747 fprintf(stderr
, "Not sending a binary stream to stdout\n");
1751 ret
= write(STDOUT_FILENO
, &ipadd_dump_magic
, sizeof(ipadd_dump_magic
));
1752 if (ret
!= sizeof(ipadd_dump_magic
)) {
1753 fprintf(stderr
, "Can't write magic to dump file\n");
1760 static int ipadd_dump_check_magic(void)
1765 if (isatty(STDIN_FILENO
)) {
1766 fprintf(stderr
, "Can't restore address dump from a terminal\n");
1770 ret
= fread(&magic
, sizeof(magic
), 1, stdin
);
1771 if (magic
!= ipadd_dump_magic
) {
1772 fprintf(stderr
, "Magic mismatch (%d elems, %x magic)\n", ret
, magic
);
1779 static int save_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1784 ret
= write(STDOUT_FILENO
, n
, n
->nlmsg_len
);
1785 if ((ret
> 0) && (ret
!= n
->nlmsg_len
)) {
1786 fprintf(stderr
, "Short write while saving nlmsg\n");
1790 return ret
== n
->nlmsg_len
? 0 : ret
;
1793 static int show_handler(const struct sockaddr_nl
*nl
,
1794 struct rtnl_ctrl_data
*ctrl
,
1795 struct nlmsghdr
*n
, void *arg
)
1797 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1799 open_json_object(NULL
);
1800 print_int(PRINT_ANY
, "index", "if%d:\n", ifa
->ifa_index
);
1801 print_addrinfo(NULL
, n
, stdout
);
1802 close_json_object();
1806 static int ipaddr_showdump(void)
1810 if (ipadd_dump_check_magic())
1814 open_json_object(NULL
);
1815 open_json_array(PRINT_JSON
, "addr_info");
1817 err
= rtnl_from_file(stdin
, &show_handler
, NULL
);
1819 close_json_array(PRINT_JSON
, NULL
);
1820 close_json_object();
1826 static int restore_handler(const struct sockaddr_nl
*nl
,
1827 struct rtnl_ctrl_data
*ctrl
,
1828 struct nlmsghdr
*n
, void *arg
)
1832 n
->nlmsg_flags
|= NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_ACK
;
1836 ret
= rtnl_talk(&rth
, n
, NULL
);
1837 if ((ret
< 0) && (errno
== EEXIST
))
1843 static int ipaddr_restore(void)
1845 if (ipadd_dump_check_magic())
1848 exit(rtnl_from_file(stdin
, &restore_handler
, NULL
));
1851 void free_nlmsg_chain(struct nlmsg_chain
*info
)
1853 struct nlmsg_list
*l
, *n
;
1855 for (l
= info
->head
; l
; l
= n
) {
1861 static void ipaddr_filter(struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
1863 struct nlmsg_list
*l
, **lp
;
1866 while ((l
= *lp
) != NULL
) {
1868 int missing_net_address
= 1;
1869 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1870 struct nlmsg_list
*a
;
1872 for (a
= ainfo
->head
; a
; a
= a
->next
) {
1873 struct nlmsghdr
*n
= &a
->h
;
1874 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1875 struct rtattr
*tb
[IFA_MAX
+ 1];
1876 unsigned int ifa_flags
;
1878 if (ifa
->ifa_index
!= ifi
->ifi_index
)
1880 missing_net_address
= 0;
1881 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1883 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1886 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
1887 ifa_flags
= get_ifa_flags(ifa
, tb
[IFA_FLAGS
]);
1889 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1891 if (filter
.pfx
.family
|| filter
.label
) {
1893 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
1895 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
1897 .family
= ifa
->ifa_family
1900 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
1901 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
1909 label
= RTA_DATA(tb
[IFA_LABEL
]);
1911 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
1912 if (fnmatch(filter
.label
, label
, 0) != 0)
1920 if (missing_net_address
&&
1921 (filter
.family
== AF_UNSPEC
|| filter
.family
== AF_PACKET
))
1931 static int ipaddr_flush(void)
1934 char flushb
[4096-512];
1936 filter
.flushb
= flushb
;
1938 filter
.flushe
= sizeof(flushb
);
1940 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
1941 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
1942 perror("Cannot send dump request");
1946 if (rtnl_dump_filter_nc(&rth
, print_addrinfo
,
1947 stdout
, NLM_F_DUMP_INTR
) < 0) {
1948 fprintf(stderr
, "Flush terminated\n");
1951 if (filter
.flushed
== 0) {
1955 printf("Nothing to flush.\n");
1957 printf("*** Flush is complete after %d round%s ***\n", round
, round
> 1?"s":"");
1963 if (flush_update() < 0)
1967 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
1971 /* If we are flushing, and specifying primary, then we
1972 * want to flush only a single round. Otherwise, we'll
1973 * start flushing secondaries that were promoted to
1976 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
1979 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
1984 static int iplink_filter_req(struct nlmsghdr
*nlh
, int reqlen
)
1988 err
= addattr32(nlh
, reqlen
, IFLA_EXT_MASK
, RTEXT_FILTER_VF
);
1992 if (filter
.master
) {
1993 err
= addattr32(nlh
, reqlen
, IFLA_MASTER
, filter
.master
);
1999 struct rtattr
*linkinfo
;
2001 linkinfo
= addattr_nest(nlh
, reqlen
, IFLA_LINKINFO
);
2003 err
= addattr_l(nlh
, reqlen
, IFLA_INFO_KIND
, filter
.kind
,
2004 strlen(filter
.kind
));
2008 addattr_nest_end(nlh
, linkinfo
);
2014 /* fills in linfo with link data and optionally ainfo with address info
2015 * caller can walk lists as desired and must call free_nlmsg_chain for
2018 int ip_linkaddr_list(int family
, req_filter_fn_t filter_fn
,
2019 struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
2021 if (rtnl_wilddump_req_filter_fn(&rth
, preferred_family
, RTM_GETLINK
,
2023 perror("Cannot send dump request");
2027 if (rtnl_dump_filter(&rth
, store_nlmsg
, linfo
) < 0) {
2028 fprintf(stderr
, "Dump terminated\n");
2033 if (rtnl_wilddump_request(&rth
, family
, RTM_GETADDR
) < 0) {
2034 perror("Cannot send dump request");
2038 if (rtnl_dump_filter(&rth
, store_nlmsg
, ainfo
) < 0) {
2039 fprintf(stderr
, "Dump terminated\n");
2047 static int ipaddr_list_flush_or_save(int argc
, char **argv
, int action
)
2049 struct nlmsg_chain linfo
= { NULL
, NULL
};
2050 struct nlmsg_chain _ainfo
= { NULL
, NULL
}, *ainfo
= NULL
;
2051 struct nlmsg_list
*l
;
2052 char *filter_dev
= NULL
;
2055 ipaddr_reset_filter(oneline
, 0);
2056 filter
.showqueue
= 1;
2057 filter
.family
= preferred_family
;
2060 if (action
== IPADD_FLUSH
) {
2062 fprintf(stderr
, "Flush requires arguments.\n");
2066 if (filter
.family
== AF_PACKET
) {
2067 fprintf(stderr
, "Cannot flush link addresses.\n");
2073 if (strcmp(*argv
, "to") == 0) {
2075 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
2076 if (filter
.family
== AF_UNSPEC
)
2077 filter
.family
= filter
.pfx
.family
;
2078 } else if (strcmp(*argv
, "scope") == 0) {
2079 unsigned int scope
= 0;
2082 filter
.scopemask
= -1;
2083 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
2084 if (strcmp(*argv
, "all") != 0)
2085 invarg("invalid \"scope\"\n", *argv
);
2086 scope
= RT_SCOPE_NOWHERE
;
2087 filter
.scopemask
= 0;
2089 filter
.scope
= scope
;
2090 } else if (strcmp(*argv
, "up") == 0) {
2092 } else if (get_filter(*argv
) == 0) {
2094 } else if (strcmp(*argv
, "label") == 0) {
2096 filter
.label
= *argv
;
2097 } else if (strcmp(*argv
, "group") == 0) {
2099 if (rtnl_group_a2n(&filter
.group
, *argv
))
2100 invarg("Invalid \"group\" value\n", *argv
);
2101 } else if (strcmp(*argv
, "master") == 0) {
2105 ifindex
= ll_name_to_index(*argv
);
2107 invarg("Device does not exist\n", *argv
);
2108 filter
.master
= ifindex
;
2109 } else if (strcmp(*argv
, "vrf") == 0) {
2113 ifindex
= ll_name_to_index(*argv
);
2115 invarg("Not a valid VRF name\n", *argv
);
2116 if (!name_is_vrf(*argv
))
2117 invarg("Not a valid VRF name\n", *argv
);
2118 filter
.master
= ifindex
;
2119 } else if (strcmp(*argv
, "type") == 0) {
2123 soff
= strlen(*argv
) - strlen("_slave");
2124 if (!strcmp(*argv
+ soff
, "_slave")) {
2125 (*argv
)[soff
] = '\0';
2126 filter
.slave_kind
= *argv
;
2128 filter
.kind
= *argv
;
2131 if (strcmp(*argv
, "dev") == 0)
2133 else if (matches(*argv
, "help") == 0)
2136 duparg2("dev", *argv
);
2143 filter
.ifindex
= ll_name_to_index(filter_dev
);
2144 if (filter
.ifindex
<= 0) {
2145 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
2150 if (action
== IPADD_FLUSH
)
2151 return ipaddr_flush();
2153 if (action
== IPADD_SAVE
) {
2154 if (ipadd_save_prep())
2157 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETADDR
) < 0) {
2158 perror("Cannot send dump request");
2162 if (rtnl_dump_filter(&rth
, save_nlmsg
, stdout
) < 0) {
2163 fprintf(stderr
, "Save terminated\n");
2171 * Initialize a json_writer and open an array object
2172 * if -json was specified.
2177 * If only filter_dev present and none of the other
2178 * link filters are present, use RTM_GETLINK to get
2181 if (filter_dev
&& filter
.group
== -1 && do_link
== 1) {
2182 if (iplink_get(0, filter_dev
, RTEXT_FILTER_VF
) < 0) {
2183 perror("Cannot send link get request");
2191 if (filter
.family
!= AF_PACKET
) {
2198 if (ip_linkaddr_list(filter
.family
, iplink_filter_req
,
2199 &linfo
, ainfo
) != 0)
2202 if (filter
.family
!= AF_PACKET
)
2203 ipaddr_filter(&linfo
, ainfo
);
2205 for (l
= linfo
.head
; l
; l
= l
->next
) {
2207 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
2209 open_json_object(NULL
);
2211 if (print_linkinfo_brief(NULL
, &l
->h
,
2213 if (filter
.family
!= AF_PACKET
)
2214 print_selected_addrinfo(ifi
,
2217 } else if (no_link
||
2218 (res
= print_linkinfo(NULL
, &l
->h
, stdout
)) >= 0) {
2219 if (filter
.family
!= AF_PACKET
)
2220 print_selected_addrinfo(ifi
,
2221 ainfo
->head
, stdout
);
2222 if (res
> 0 && !do_link
&& show_stats
)
2223 print_link_stats(stdout
, &l
->h
);
2225 close_json_object();
2231 free_nlmsg_chain(ainfo
);
2232 free_nlmsg_chain(&linfo
);
2238 ipaddr_loop_each_vf(struct rtattr
*tb
[], int vfnum
, int *min
, int *max
)
2240 struct rtattr
*vflist
= tb
[IFLA_VFINFO_LIST
];
2241 struct rtattr
*i
, *vf
[IFLA_VF_MAX
+1];
2242 struct ifla_vf_rate
*vf_rate
;
2245 rem
= RTA_PAYLOAD(vflist
);
2247 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
2248 parse_rtattr_nested(vf
, IFLA_VF_MAX
, i
);
2249 vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
2250 if (vf_rate
->vf
== vfnum
) {
2251 *min
= vf_rate
->min_tx_rate
;
2252 *max
= vf_rate
->max_tx_rate
;
2256 fprintf(stderr
, "Cannot find VF %d\n", vfnum
);
2260 void ipaddr_get_vf_rate(int vfnum
, int *min
, int *max
, int idx
)
2262 struct nlmsg_chain linfo
= { NULL
, NULL
};
2263 struct rtattr
*tb
[IFLA_MAX
+1];
2264 struct ifinfomsg
*ifi
;
2265 struct nlmsg_list
*l
;
2269 if (rtnl_wilddump_request(&rth
, AF_UNSPEC
, RTM_GETLINK
) < 0) {
2270 perror("Cannot send dump request");
2273 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
2274 fprintf(stderr
, "Dump terminated\n");
2277 for (l
= linfo
.head
; l
; l
= l
->next
) {
2279 ifi
= NLMSG_DATA(n
);
2281 len
= n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
2282 if (len
< 0 || (idx
&& idx
!= ifi
->ifi_index
))
2285 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
2287 if ((tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
])) {
2288 ipaddr_loop_each_vf(tb
, vfnum
, min
, max
);
2294 int ipaddr_list_link(int argc
, char **argv
)
2296 preferred_family
= AF_PACKET
;
2298 return ipaddr_list_flush_or_save(argc
, argv
, IPADD_LIST
);
2301 void ipaddr_reset_filter(int oneline
, int ifindex
)
2303 memset(&filter
, 0, sizeof(filter
));
2304 filter
.oneline
= oneline
;
2305 filter
.ifindex
= ifindex
;
2308 static int default_scope(inet_prefix
*lcl
)
2310 if (lcl
->family
== AF_INET
) {
2311 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
2312 return RT_SCOPE_HOST
;
2317 static bool ipaddr_is_multicast(inet_prefix
*a
)
2319 if (a
->family
== AF_INET
)
2320 return IN_MULTICAST(ntohl(a
->data
[0]));
2321 else if (a
->family
== AF_INET6
)
2322 return IN6_IS_ADDR_MULTICAST(a
->data
);
2327 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
2331 struct ifaddrmsg ifa
;
2334 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
)),
2335 .n
.nlmsg_flags
= NLM_F_REQUEST
| flags
,
2336 .n
.nlmsg_type
= cmd
,
2337 .ifa
.ifa_family
= preferred_family
,
2341 char *lcl_arg
= NULL
;
2342 char *valid_lftp
= NULL
;
2343 char *preferred_lftp
= NULL
;
2344 inet_prefix lcl
= {};
2351 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
2352 __u32 valid_lft
= INFINITY_LIFE_TIME
;
2353 unsigned int ifa_flags
= 0;
2356 if (strcmp(*argv
, "peer") == 0 ||
2357 strcmp(*argv
, "remote") == 0) {
2361 duparg("peer", *argv
);
2362 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
2363 peer_len
= peer
.bytelen
;
2364 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2365 req
.ifa
.ifa_family
= peer
.family
;
2366 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
2367 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
2368 } else if (matches(*argv
, "broadcast") == 0 ||
2369 strcmp(*argv
, "brd") == 0) {
2374 duparg("broadcast", *argv
);
2375 if (strcmp(*argv
, "+") == 0)
2377 else if (strcmp(*argv
, "-") == 0)
2380 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
2381 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2382 req
.ifa
.ifa_family
= addr
.family
;
2383 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
2384 brd_len
= addr
.bytelen
;
2386 } else if (strcmp(*argv
, "anycast") == 0) {
2391 duparg("anycast", *argv
);
2392 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
2393 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2394 req
.ifa
.ifa_family
= addr
.family
;
2395 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
2396 any_len
= addr
.bytelen
;
2397 } else if (strcmp(*argv
, "scope") == 0) {
2398 unsigned int scope
= 0;
2401 if (rtnl_rtscope_a2n(&scope
, *argv
))
2402 invarg("invalid scope value.", *argv
);
2403 req
.ifa
.ifa_scope
= scope
;
2405 } else if (strcmp(*argv
, "dev") == 0) {
2408 } else if (strcmp(*argv
, "label") == 0) {
2411 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
2412 } else if (matches(*argv
, "valid_lft") == 0) {
2414 duparg("valid_lft", *argv
);
2417 if (set_lifetime(&valid_lft
, *argv
))
2418 invarg("valid_lft value", *argv
);
2419 } else if (matches(*argv
, "preferred_lft") == 0) {
2421 duparg("preferred_lft", *argv
);
2423 preferred_lftp
= *argv
;
2424 if (set_lifetime(&preferred_lft
, *argv
))
2425 invarg("preferred_lft value", *argv
);
2426 } else if (strcmp(*argv
, "home") == 0) {
2427 ifa_flags
|= IFA_F_HOMEADDRESS
;
2428 } else if (strcmp(*argv
, "nodad") == 0) {
2429 ifa_flags
|= IFA_F_NODAD
;
2430 } else if (strcmp(*argv
, "mngtmpaddr") == 0) {
2431 ifa_flags
|= IFA_F_MANAGETEMPADDR
;
2432 } else if (strcmp(*argv
, "noprefixroute") == 0) {
2433 ifa_flags
|= IFA_F_NOPREFIXROUTE
;
2434 } else if (strcmp(*argv
, "autojoin") == 0) {
2435 ifa_flags
|= IFA_F_MCAUTOJOIN
;
2437 if (strcmp(*argv
, "local") == 0)
2439 if (matches(*argv
, "help") == 0)
2442 duparg2("local", *argv
);
2444 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
2445 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2446 req
.ifa
.ifa_family
= lcl
.family
;
2447 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
2448 local_len
= lcl
.bytelen
;
2452 if (ifa_flags
<= 0xff)
2453 req
.ifa
.ifa_flags
= ifa_flags
;
2455 addattr32(&req
.n
, sizeof(req
), IFA_FLAGS
, ifa_flags
);
2458 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
2461 if (l
&& matches(d
, l
) != 0) {
2462 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
2466 if (peer_len
== 0 && local_len
) {
2467 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
2469 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n"
2470 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n"
2471 " This special behaviour is likely to disappear in further releases,\n"
2472 " fix your scripts!\n", lcl_arg
, local_len
*8);
2475 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
2478 if (req
.ifa
.ifa_prefixlen
== 0)
2479 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
2481 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
2485 if (req
.ifa
.ifa_family
!= AF_INET
) {
2486 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
2490 if (brd
.bitlen
<= 30) {
2491 for (i
= 31; i
>= brd
.bitlen
; i
--) {
2493 brd
.data
[0] |= htonl(1<<(31-i
));
2495 brd
.data
[0] &= ~htonl(1<<(31-i
));
2497 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
2498 brd_len
= brd
.bytelen
;
2501 if (!scoped
&& cmd
!= RTM_DELADDR
)
2502 req
.ifa
.ifa_scope
= default_scope(&lcl
);
2504 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
2505 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
2509 if (valid_lftp
|| preferred_lftp
) {
2510 struct ifa_cacheinfo cinfo
= {};
2513 fprintf(stderr
, "valid_lft is zero\n");
2516 if (valid_lft
< preferred_lft
) {
2517 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
2521 cinfo
.ifa_prefered
= preferred_lft
;
2522 cinfo
.ifa_valid
= valid_lft
;
2523 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
2527 if ((ifa_flags
& IFA_F_MCAUTOJOIN
) && !ipaddr_is_multicast(&lcl
)) {
2528 fprintf(stderr
, "autojoin needs multicast address\n");
2532 if (rtnl_talk(&rth
, &req
.n
, NULL
) < 0)
2538 int do_ipaddr(int argc
, char **argv
)
2541 return ipaddr_list_flush_or_save(0, NULL
, IPADD_LIST
);
2542 if (matches(*argv
, "add") == 0)
2543 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
2544 if (matches(*argv
, "change") == 0 ||
2545 strcmp(*argv
, "chg") == 0)
2546 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
2547 if (matches(*argv
, "replace") == 0)
2548 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
2549 if (matches(*argv
, "delete") == 0)
2550 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
2551 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
2552 || matches(*argv
, "lst") == 0)
2553 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_LIST
);
2554 if (matches(*argv
, "flush") == 0)
2555 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_FLUSH
);
2556 if (matches(*argv
, "save") == 0)
2557 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_SAVE
);
2558 if (matches(*argv
, "showdump") == 0)
2559 return ipaddr_showdump();
2560 if (matches(*argv
, "restore") == 0)
2561 return ipaddr_restore();
2562 if (matches(*argv
, "help") == 0)
2564 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv
);