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/if_infiniband.h>
30 #include <linux/sockios.h>
31 #include <linux/net_namespace.h>
36 #include "ip_common.h"
45 static struct link_filter filter
;
48 static void usage(void) __attribute__((noreturn
));
50 static void usage(void)
56 "Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]\n"
57 " [ CONFFLAG-LIST ]\n"
58 " ip address del IFADDR dev IFNAME [mngtmpaddr]\n"
59 " ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n"
60 " [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n"
61 " ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n"
62 " [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n"
63 " [ label LABEL ] [up] [ vrf NAME ] ]\n"
64 " ip address {showdump|restore}\n"
65 "IFADDR := PREFIX | ADDR peer PREFIX\n"
66 " [ broadcast ADDR ] [ anycast ADDR ]\n"
67 " [ label IFNAME ] [ scope SCOPE-ID ] [ metric METRIC ]\n"
68 "SCOPE-ID := [ host | link | global | NUMBER ]\n"
69 "FLAG-LIST := [ FLAG-LIST ] FLAG\n"
70 "FLAG := [ permanent | dynamic | secondary | primary |\n"
71 " [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n"
73 "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n"
74 "CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n"
75 "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n"
76 "LFT := forever | SECONDS\n"
77 "TYPE := { vlan | veth | vcan | vxcan | dummy | ifb | macvlan | macvtap |\n"
78 " bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |\n"
79 " gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan | vti |\n"
80 " nlmon | can | bond_slave | ipvlan | geneve | bridge_slave |\n"
81 " hsr | macsec | netdevsim }\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 %#llx", 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) {
179 "ioctl(SIOCGIFTXQLEN) failed: %s\n",
188 print_int(PRINT_ANY
, "txqlen", "qlen %d", qlen
);
191 static const char *link_modes
[] = {
195 static void print_linkmode(FILE *f
, struct rtattr
*tb
)
197 unsigned int mode
= rta_getattr_u8(tb
);
199 if (mode
>= ARRAY_SIZE(link_modes
))
205 print_string(PRINT_ANY
,
211 static char *parse_link_kind(struct rtattr
*tb
, bool slave
)
213 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
214 int attr
= slave
? IFLA_INFO_SLAVE_KIND
: IFLA_INFO_KIND
;
216 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
219 return RTA_DATA(linkinfo
[attr
]);
224 static int match_link_kind(struct rtattr
**tb
, const char *kind
, bool slave
)
226 if (!tb
[IFLA_LINKINFO
])
229 return strcmp(parse_link_kind(tb
[IFLA_LINKINFO
], slave
), kind
);
232 static void print_linktype(FILE *fp
, struct rtattr
*tb
)
234 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
235 struct link_util
*lu
;
236 struct link_util
*slave_lu
;
239 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
240 open_json_object("linkinfo");
242 if (linkinfo
[IFLA_INFO_KIND
]) {
244 = rta_getattr_str(linkinfo
[IFLA_INFO_KIND
]);
247 print_string(PRINT_ANY
, "info_kind", " %s ", kind
);
249 lu
= get_link_kind(kind
);
250 if (lu
&& lu
->print_opt
) {
251 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
253 if (linkinfo
[IFLA_INFO_DATA
]) {
254 parse_rtattr_nested(attr
, lu
->maxattr
,
255 linkinfo
[IFLA_INFO_DATA
]);
258 open_json_object("info_data");
259 lu
->print_opt(lu
, fp
, data
);
262 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
264 open_json_object("info_xstats");
265 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
271 if (linkinfo
[IFLA_INFO_SLAVE_KIND
]) {
272 const char *slave_kind
273 = rta_getattr_str(linkinfo
[IFLA_INFO_SLAVE_KIND
]);
276 print_string(PRINT_ANY
,
281 snprintf(slave
, sizeof(slave
), "%s_slave", slave_kind
);
283 slave_lu
= get_link_kind(slave
);
284 if (slave_lu
&& slave_lu
->print_opt
) {
285 struct rtattr
*attr
[slave_lu
->maxattr
+1], **data
= NULL
;
287 if (linkinfo
[IFLA_INFO_SLAVE_DATA
]) {
288 parse_rtattr_nested(attr
, slave_lu
->maxattr
,
289 linkinfo
[IFLA_INFO_SLAVE_DATA
]);
292 open_json_object("info_slave_data");
293 slave_lu
->print_opt(slave_lu
, fp
, data
);
300 static void print_af_spec(FILE *fp
, struct rtattr
*af_spec_attr
)
302 struct rtattr
*inet6_attr
;
303 struct rtattr
*tb
[IFLA_INET6_MAX
+ 1];
305 inet6_attr
= parse_rtattr_one_nested(AF_INET6
, af_spec_attr
);
309 parse_rtattr_nested(tb
, IFLA_INET6_MAX
, inet6_attr
);
311 if (tb
[IFLA_INET6_ADDR_GEN_MODE
]) {
312 __u8 mode
= rta_getattr_u8(tb
[IFLA_INET6_ADDR_GEN_MODE
]);
316 case IN6_ADDR_GEN_MODE_EUI64
:
317 print_string(PRINT_ANY
,
318 "inet6_addr_gen_mode",
322 case IN6_ADDR_GEN_MODE_NONE
:
323 print_string(PRINT_ANY
,
324 "inet6_addr_gen_mode",
328 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY
:
329 print_string(PRINT_ANY
,
330 "inet6_addr_gen_mode",
334 case IN6_ADDR_GEN_MODE_RANDOM
:
335 print_string(PRINT_ANY
,
336 "inet6_addr_gen_mode",
341 snprintf(b1
, sizeof(b1
), "%#.2hhx", mode
);
342 print_string(PRINT_ANY
,
343 "inet6_addr_gen_mode",
351 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
);
353 static void print_vfinfo(FILE *fp
, struct ifinfomsg
*ifi
, struct rtattr
*vfinfo
)
355 struct ifla_vf_mac
*vf_mac
;
356 struct ifla_vf_broadcast
*vf_broadcast
;
357 struct ifla_vf_tx_rate
*vf_tx_rate
;
358 struct rtattr
*vf
[IFLA_VF_MAX
+ 1] = {};
362 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
363 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
367 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
369 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
370 vf_broadcast
= RTA_DATA(vf
[IFLA_VF_BROADCAST
]);
371 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
373 print_string(PRINT_FP
, NULL
, "%s ", _SL_
);
374 print_int(PRINT_ANY
, "vf", "vf %d ", vf_mac
->vf
);
376 print_string(PRINT_ANY
,
379 ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
381 print_color_string(PRINT_ANY
, COLOR_MAC
,
383 ll_addr_n2a((unsigned char *) &vf_mac
->mac
,
384 ifi
->ifi_type
== ARPHRD_ETHER
?
385 ETH_ALEN
: INFINIBAND_ALEN
,
389 if (vf
[IFLA_VF_BROADCAST
]) {
390 if (ifi
->ifi_flags
&IFF_POINTOPOINT
) {
391 print_string(PRINT_FP
, NULL
, " peer ", NULL
);
392 print_bool(PRINT_JSON
,
393 "link_pointtopoint", NULL
, true);
395 print_string(PRINT_FP
, NULL
, " brd ", NULL
);
397 print_color_string(PRINT_ANY
, COLOR_MAC
,
399 ll_addr_n2a((unsigned char *) &vf_broadcast
->broadcast
,
400 ifi
->ifi_type
== ARPHRD_ETHER
?
401 ETH_ALEN
: INFINIBAND_ALEN
,
406 if (vf
[IFLA_VF_VLAN_LIST
]) {
407 struct rtattr
*i
, *vfvlanlist
= vf
[IFLA_VF_VLAN_LIST
];
408 int rem
= RTA_PAYLOAD(vfvlanlist
);
410 open_json_array(PRINT_JSON
, "vlan_list");
411 for (i
= RTA_DATA(vfvlanlist
);
412 RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
413 struct ifla_vf_vlan_info
*vf_vlan_info
= RTA_DATA(i
);
416 open_json_object(NULL
);
417 if (vf_vlan_info
->vlan
)
422 if (vf_vlan_info
->qos
)
427 if (vf_vlan_info
->vlan_proto
&&
428 vf_vlan_info
->vlan_proto
!= htons(ETH_P_8021Q
))
429 print_string(PRINT_ANY
,
431 ", vlan protocol %s",
433 vf_vlan_info
->vlan_proto
,
437 close_json_array(PRINT_JSON
, NULL
);
439 struct ifla_vf_vlan
*vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
447 print_int(PRINT_ANY
, "qos", ", qos %d", vf_vlan
->qos
);
450 if (vf_tx_rate
->rate
)
451 print_uint(PRINT_ANY
,
453 ", tx rate %u (Mbps)",
456 if (vf
[IFLA_VF_RATE
]) {
457 struct ifla_vf_rate
*vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
458 int max_tx
= vf_rate
->max_tx_rate
;
459 int min_tx
= vf_rate
->min_tx_rate
;
461 if (is_json_context()) {
462 open_json_object("rate");
463 print_uint(PRINT_JSON
, "max_tx", NULL
, max_tx
);
464 print_uint(PRINT_ANY
, "min_tx", NULL
, min_tx
);
468 fprintf(fp
, ", max_tx_rate %uMbps", max_tx
);
470 fprintf(fp
, ", min_tx_rate %uMbps", min_tx
);
474 if (vf
[IFLA_VF_SPOOFCHK
]) {
475 struct ifla_vf_spoofchk
*vf_spoofchk
=
476 RTA_DATA(vf
[IFLA_VF_SPOOFCHK
]);
478 if (vf_spoofchk
->setting
!= -1)
479 print_bool(PRINT_ANY
,
481 vf_spoofchk
->setting
?
482 ", spoof checking on" : ", spoof checking off",
483 vf_spoofchk
->setting
);
486 if (vf
[IFLA_VF_IB_NODE_GUID
]) {
487 struct ifla_vf_guid
*guid
= RTA_DATA(vf
[IFLA_VF_IB_NODE_GUID
]);
488 uint64_t node_guid
= ntohll(guid
->guid
);
490 print_string(PRINT_ANY
, "node guid", ", NODE_GUID %s",
491 ll_addr_n2a((const unsigned char *)&node_guid
,
492 sizeof(node_guid
), ARPHRD_INFINIBAND
,
495 if (vf
[IFLA_VF_IB_PORT_GUID
]) {
496 struct ifla_vf_guid
*guid
= RTA_DATA(vf
[IFLA_VF_IB_PORT_GUID
]);
497 uint64_t port_guid
= ntohll(guid
->guid
);
499 print_string(PRINT_ANY
, "port guid", ", PORT_GUID %s",
500 ll_addr_n2a((const unsigned char *)&port_guid
,
501 sizeof(port_guid
), ARPHRD_INFINIBAND
,
504 if (vf
[IFLA_VF_LINK_STATE
]) {
505 struct ifla_vf_link_state
*vf_linkstate
=
506 RTA_DATA(vf
[IFLA_VF_LINK_STATE
]);
508 if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_AUTO
)
509 print_string(PRINT_ANY
,
513 else if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_ENABLE
)
514 print_string(PRINT_ANY
,
519 print_string(PRINT_ANY
,
525 if (vf
[IFLA_VF_TRUST
]) {
526 struct ifla_vf_trust
*vf_trust
= RTA_DATA(vf
[IFLA_VF_TRUST
]);
528 if (vf_trust
->setting
!= -1)
529 print_bool(PRINT_ANY
,
531 vf_trust
->setting
? ", trust on" : ", trust off",
535 if (vf
[IFLA_VF_RSS_QUERY_EN
]) {
536 struct ifla_vf_rss_query_en
*rss_query
=
537 RTA_DATA(vf
[IFLA_VF_RSS_QUERY_EN
]);
539 if (rss_query
->setting
!= -1)
540 print_bool(PRINT_ANY
,
542 rss_query
->setting
? ", query_rss on"
547 if (vf
[IFLA_VF_STATS
] && show_stats
)
548 print_vf_stats64(fp
, vf
[IFLA_VF_STATS
]);
551 void print_num(FILE *fp
, unsigned int width
, uint64_t count
)
553 const char *prefix
= "kMGTPE";
554 const unsigned int base
= use_iec
? 1024 : 1000;
557 uint8_t precision
= 2;
560 if (!human_readable
|| count
< base
) {
561 fprintf(fp
, "%-*"PRIu64
" ", width
, count
);
565 /* increase value by a factor of 1000/1024 and print
566 * if result is something a human can read
570 if (count
/ base
< powi
)
578 /* try to guess a good number of digits for precision */
579 for (; precision
> 0; precision
--) {
581 if (count
/ powi
< powj
)
585 snprintf(buf
, sizeof(buf
), "%.*f%c%s", precision
,
586 (double) count
/ powi
, *prefix
, use_iec
? "i" : "");
588 fprintf(fp
, "%-*s ", width
, buf
);
591 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
)
593 struct rtattr
*vf
[IFLA_VF_STATS_MAX
+ 1];
595 if (vfstats
->rta_type
!= IFLA_VF_STATS
) {
596 fprintf(stderr
, "BUG: rta type is %d\n", vfstats
->rta_type
);
600 parse_rtattr_nested(vf
, IFLA_VF_STATS_MAX
, vfstats
);
602 if (is_json_context()) {
603 open_json_object("stats");
606 open_json_object("rx");
607 print_u64(PRINT_JSON
, "bytes", NULL
,
608 rta_getattr_u64(vf
[IFLA_VF_STATS_RX_BYTES
]));
609 print_u64(PRINT_JSON
, "packets", NULL
,
610 rta_getattr_u64(vf
[IFLA_VF_STATS_RX_PACKETS
]));
611 print_u64(PRINT_JSON
, "multicast", NULL
,
612 rta_getattr_u64(vf
[IFLA_VF_STATS_MULTICAST
]));
613 print_u64(PRINT_JSON
, "broadcast", NULL
,
614 rta_getattr_u64(vf
[IFLA_VF_STATS_BROADCAST
]));
615 if (vf
[IFLA_VF_STATS_RX_DROPPED
])
616 print_u64(PRINT_JSON
, "dropped", NULL
,
617 rta_getattr_u64(vf
[IFLA_VF_STATS_RX_DROPPED
]));
621 open_json_object("tx");
622 print_u64(PRINT_JSON
, "tx_bytes", NULL
,
623 rta_getattr_u64(vf
[IFLA_VF_STATS_TX_BYTES
]));
624 print_u64(PRINT_JSON
, "tx_packets", NULL
,
625 rta_getattr_u64(vf
[IFLA_VF_STATS_TX_PACKETS
]));
626 if (vf
[IFLA_VF_STATS_TX_DROPPED
])
627 print_u64(PRINT_JSON
, "dropped", NULL
,
628 rta_getattr_u64(vf
[IFLA_VF_STATS_TX_DROPPED
]));
633 fprintf(fp
, "%s", _SL_
);
634 fprintf(fp
, " RX: bytes packets mcast bcast ");
635 if (vf
[IFLA_VF_STATS_RX_DROPPED
])
636 fprintf(fp
, " dropped ");
637 fprintf(fp
, "%s", _SL_
);
640 print_num(fp
, 10, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_BYTES
]));
641 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_PACKETS
]));
642 print_num(fp
, 7, rta_getattr_u64(vf
[IFLA_VF_STATS_MULTICAST
]));
643 print_num(fp
, 7, rta_getattr_u64(vf
[IFLA_VF_STATS_BROADCAST
]));
644 if (vf
[IFLA_VF_STATS_RX_DROPPED
])
645 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_DROPPED
]));
648 fprintf(fp
, "%s", _SL_
);
649 fprintf(fp
, " TX: bytes packets ");
650 if (vf
[IFLA_VF_STATS_TX_DROPPED
])
651 fprintf(fp
, " dropped ");
652 fprintf(fp
, "%s", _SL_
);
655 print_num(fp
, 10, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_BYTES
]));
656 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_PACKETS
]));
657 if (vf
[IFLA_VF_STATS_TX_DROPPED
])
658 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_DROPPED
]));
662 static void __print_link_stats(FILE *fp
, struct rtattr
*tb
[])
664 const struct rtattr
*carrier_changes
= tb
[IFLA_CARRIER_CHANGES
];
665 struct rtnl_link_stats64 _s
, *s
= &_s
;
668 ret
= get_rtnl_link_stats_rta(s
, tb
);
672 if (is_json_context()) {
673 open_json_object((ret
== sizeof(*s
)) ? "stats64" : "stats");
676 open_json_object("rx");
677 print_u64(PRINT_JSON
, "bytes", NULL
, s
->rx_bytes
);
678 print_u64(PRINT_JSON
, "packets", NULL
, s
->rx_packets
);
679 print_u64(PRINT_JSON
, "errors", NULL
, s
->rx_errors
);
680 print_u64(PRINT_JSON
, "dropped", NULL
, s
->rx_dropped
);
681 print_u64(PRINT_JSON
, "over_errors", NULL
, s
->rx_over_errors
);
682 print_u64(PRINT_JSON
, "multicast", NULL
, s
->multicast
);
683 if (s
->rx_compressed
)
684 print_u64(PRINT_JSON
,
685 "compressed", NULL
, s
->rx_compressed
);
688 if (show_stats
> 1) {
689 print_u64(PRINT_JSON
,
691 NULL
, s
->rx_length_errors
);
692 print_u64(PRINT_JSON
,
694 NULL
, s
->rx_crc_errors
);
695 print_u64(PRINT_JSON
,
697 NULL
, s
->rx_frame_errors
);
698 print_u64(PRINT_JSON
,
700 NULL
, s
->rx_fifo_errors
);
701 print_u64(PRINT_JSON
,
703 NULL
, s
->rx_missed_errors
);
705 print_u64(PRINT_JSON
,
706 "nohandler", NULL
, s
->rx_nohandler
);
711 open_json_object("tx");
712 print_u64(PRINT_JSON
, "bytes", NULL
, s
->tx_bytes
);
713 print_u64(PRINT_JSON
, "packets", NULL
, s
->tx_packets
);
714 print_u64(PRINT_JSON
, "errors", NULL
, s
->tx_errors
);
715 print_u64(PRINT_JSON
, "dropped", NULL
, s
->tx_dropped
);
716 print_u64(PRINT_JSON
,
718 NULL
, s
->tx_carrier_errors
);
719 print_u64(PRINT_JSON
, "collisions", NULL
, s
->collisions
);
720 if (s
->tx_compressed
)
721 print_u64(PRINT_JSON
,
722 "compressed", NULL
, s
->tx_compressed
);
725 if (show_stats
> 1) {
726 print_u64(PRINT_JSON
,
728 NULL
, s
->tx_aborted_errors
);
729 print_u64(PRINT_JSON
,
731 NULL
, s
->tx_fifo_errors
);
732 print_u64(PRINT_JSON
,
734 NULL
, s
->tx_window_errors
);
735 print_u64(PRINT_JSON
,
737 NULL
, s
->tx_heartbeat_errors
);
739 print_u64(PRINT_JSON
, "carrier_changes", NULL
,
740 rta_getattr_u32(carrier_changes
));
747 fprintf(fp
, " RX: bytes packets errors dropped missed mcast %s%s",
748 s
->rx_compressed
? "compressed" : "", _SL_
);
751 print_num(fp
, 10, s
->rx_bytes
);
752 print_num(fp
, 8, s
->rx_packets
);
753 print_num(fp
, 7, s
->rx_errors
);
754 print_num(fp
, 7, s
->rx_dropped
);
755 print_num(fp
, 7, s
->rx_missed_errors
);
756 print_num(fp
, 7, s
->multicast
);
757 if (s
->rx_compressed
)
758 print_num(fp
, 7, s
->rx_compressed
);
761 if (show_stats
> 1) {
762 fprintf(fp
, "%s", _SL_
);
763 fprintf(fp
, " RX errors: length crc frame fifo overrun%s%s",
764 s
->rx_nohandler
? " nohandler" : "", _SL_
);
766 print_num(fp
, 8, s
->rx_length_errors
);
767 print_num(fp
, 7, s
->rx_crc_errors
);
768 print_num(fp
, 7, s
->rx_frame_errors
);
769 print_num(fp
, 7, s
->rx_fifo_errors
);
770 print_num(fp
, 7, s
->rx_over_errors
);
772 print_num(fp
, 7, s
->rx_nohandler
);
774 fprintf(fp
, "%s", _SL_
);
777 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
778 s
->tx_compressed
? "compressed" : "", _SL_
);
781 print_num(fp
, 10, s
->tx_bytes
);
782 print_num(fp
, 8, s
->tx_packets
);
783 print_num(fp
, 7, s
->tx_errors
);
784 print_num(fp
, 7, s
->tx_dropped
);
785 print_num(fp
, 7, s
->tx_carrier_errors
);
786 print_num(fp
, 7, s
->collisions
);
787 if (s
->tx_compressed
)
788 print_num(fp
, 7, s
->tx_compressed
);
791 if (show_stats
> 1) {
792 fprintf(fp
, "%s", _SL_
);
793 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
795 fprintf(fp
, " transns");
796 fprintf(fp
, "%s", _SL_
);
799 print_num(fp
, 8, s
->tx_aborted_errors
);
800 print_num(fp
, 7, s
->tx_fifo_errors
);
801 print_num(fp
, 7, s
->tx_window_errors
);
802 print_num(fp
, 7, s
->tx_heartbeat_errors
);
805 rta_getattr_u32(carrier_changes
));
810 static void print_link_stats(FILE *fp
, struct nlmsghdr
*n
)
812 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
813 struct rtattr
*tb
[IFLA_MAX
+1];
815 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
),
816 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
)));
817 __print_link_stats(fp
, tb
);
821 static int print_linkinfo_brief(FILE *fp
, const char *name
,
822 const struct ifinfomsg
*ifi
,
825 unsigned int m_flag
= 0;
827 m_flag
= print_name_and_link("%-16s ", name
, tb
);
829 if (tb
[IFLA_OPERSTATE
])
830 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
832 if (filter
.family
== AF_PACKET
) {
835 if (tb
[IFLA_ADDRESS
]) {
836 print_color_string(PRINT_ANY
, COLOR_MAC
,
839 RTA_DATA(tb
[IFLA_ADDRESS
]),
840 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
846 if (filter
.family
== AF_PACKET
) {
847 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
848 print_string(PRINT_FP
, NULL
, "%s", "\n");
855 static const char *link_events
[] = {
856 [IFLA_EVENT_NONE
] = "NONE",
857 [IFLA_EVENT_REBOOT
] = "REBOOT",
858 [IFLA_EVENT_FEATURES
] = "FEATURE CHANGE",
859 [IFLA_EVENT_BONDING_FAILOVER
] = "BONDING FAILOVER",
860 [IFLA_EVENT_NOTIFY_PEERS
] = "NOTIFY PEERS",
861 [IFLA_EVENT_IGMP_RESEND
] = "RESEND IGMP",
862 [IFLA_EVENT_BONDING_OPTIONS
] = "BONDING OPTION"
865 static void print_link_event(FILE *f
, __u32 event
)
867 if (event
>= ARRAY_SIZE(link_events
))
868 print_int(PRINT_ANY
, "event", "event %d ", event
);
871 print_string(PRINT_ANY
,
872 "event", "event %s ",
877 static void print_proto_down(FILE *f
, struct rtattr
*tb
[])
879 struct rtattr
*preason
[IFLA_PROTO_DOWN_REASON_MAX
+1];
881 if (tb
[IFLA_PROTO_DOWN
]) {
882 if (rta_getattr_u8(tb
[IFLA_PROTO_DOWN
]))
883 print_bool(PRINT_ANY
,
884 "proto_down", " protodown on ", true);
887 if (tb
[IFLA_PROTO_DOWN_REASON
]) {
892 parse_rtattr_nested(preason
, IFLA_PROTO_DOWN_REASON_MAX
,
893 tb
[IFLA_PROTO_DOWN_REASON
]);
894 if (!tb
[IFLA_PROTO_DOWN_REASON_VALUE
])
897 reason
= rta_getattr_u8(preason
[IFLA_PROTO_DOWN_REASON_VALUE
]);
901 open_json_array(PRINT_ANY
,
902 is_json_context() ? "proto_down_reason" : "protodown_reason <");
903 for (i
= 0; reason
; i
++, reason
>>= 1) {
905 if (protodown_reason_n2a(i
, buf
, sizeof(buf
)))
907 print_string(PRINT_ANY
, NULL
,
908 start
? "%s" : ",%s", buf
);
912 close_json_array(PRINT_ANY
, ">");
916 int print_linkinfo(struct nlmsghdr
*n
, void *arg
)
918 FILE *fp
= (FILE *)arg
;
919 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
920 struct rtattr
*tb
[IFLA_MAX
+1];
921 int len
= n
->nlmsg_len
;
923 unsigned int m_flag
= 0;
926 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
929 len
-= NLMSG_LENGTH(sizeof(*ifi
));
933 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
935 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
938 parse_rtattr_flags(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
, NLA_F_NESTED
);
940 name
= get_ifname_rta(ifi
->ifi_index
, tb
[IFLA_IFNAME
]);
947 if (tb
[IFLA_GROUP
]) {
948 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
950 if (filter
.group
!= -1 && group
!= filter
.group
)
954 if (tb
[IFLA_MASTER
]) {
955 int master
= rta_getattr_u32(tb
[IFLA_MASTER
]);
957 if (filter
.master
> 0 && master
!= filter
.master
)
959 } else if (filter
.master
> 0)
962 if (filter
.kind
&& match_link_kind(tb
, filter
.kind
, 0))
965 if (filter
.slave_kind
&& match_link_kind(tb
, filter
.slave_kind
, 1))
968 if (n
->nlmsg_type
== RTM_DELLINK
)
969 print_bool(PRINT_ANY
, "deleted", "Deleted ", true);
972 return print_linkinfo_brief(fp
, name
, ifi
, tb
);
974 print_int(PRINT_ANY
, "ifindex", "%d: ", ifi
->ifi_index
);
976 m_flag
= print_name_and_link("%s: ", name
, tb
);
977 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
982 rta_getattr_u32(tb
[IFLA_MTU
]));
984 xdp_dump(fp
, tb
[IFLA_XDP
], do_link
, false);
986 print_string(PRINT_ANY
,
989 rta_getattr_str(tb
[IFLA_QDISC
]));
990 if (tb
[IFLA_MASTER
]) {
991 int master
= rta_getattr_u32(tb
[IFLA_MASTER
]);
993 print_string(PRINT_ANY
,
994 "master", "master %s ",
995 ll_index_to_name(master
));
998 if (tb
[IFLA_OPERSTATE
])
999 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
1001 if (do_link
&& tb
[IFLA_LINKMODE
])
1002 print_linkmode(fp
, tb
[IFLA_LINKMODE
]);
1004 if (tb
[IFLA_GROUP
]) {
1005 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
1007 print_string(PRINT_ANY
,
1010 rtnl_group_n2a(group
, b1
, sizeof(b1
)));
1013 if (filter
.showqueue
)
1014 print_queuelen(fp
, tb
);
1017 print_link_event(fp
, rta_getattr_u32(tb
[IFLA_EVENT
]));
1019 if (!filter
.family
|| filter
.family
== AF_PACKET
|| show_details
) {
1021 print_string(PRINT_ANY
,
1024 ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
1025 if (tb
[IFLA_ADDRESS
]) {
1026 print_color_string(PRINT_ANY
,
1030 ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
1031 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
1035 if (tb
[IFLA_BROADCAST
]) {
1036 if (ifi
->ifi_flags
&IFF_POINTOPOINT
) {
1037 print_string(PRINT_FP
, NULL
, " peer ", NULL
);
1038 print_bool(PRINT_JSON
,
1039 "link_pointtopoint", NULL
, true);
1041 print_string(PRINT_FP
, NULL
, " brd ", NULL
);
1043 print_color_string(PRINT_ANY
,
1047 ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
1048 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
1052 if (tb
[IFLA_PERM_ADDRESS
]) {
1053 unsigned int len
= RTA_PAYLOAD(tb
[IFLA_PERM_ADDRESS
]);
1055 if (!tb
[IFLA_ADDRESS
] ||
1056 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]) != len
||
1057 memcmp(RTA_DATA(tb
[IFLA_PERM_ADDRESS
]),
1058 RTA_DATA(tb
[IFLA_ADDRESS
]), len
)) {
1059 print_string(PRINT_FP
, NULL
, " permaddr ", NULL
);
1060 print_color_string(PRINT_ANY
,
1064 ll_addr_n2a(RTA_DATA(tb
[IFLA_PERM_ADDRESS
]),
1065 RTA_PAYLOAD(tb
[IFLA_PERM_ADDRESS
]),
1072 if (tb
[IFLA_LINK_NETNSID
]) {
1073 int id
= rta_getattr_u32(tb
[IFLA_LINK_NETNSID
]);
1075 if (is_json_context()) {
1076 print_int(PRINT_JSON
, "link_netnsid", NULL
, id
);
1079 char *name
= get_name_from_nsid(id
);
1082 print_string(PRINT_FP
, NULL
,
1083 " link-netns %s", name
);
1085 print_int(PRINT_FP
, NULL
,
1086 " link-netnsid %d", id
);
1088 print_string(PRINT_FP
, NULL
,
1089 " link-netnsid %s", "unknown");
1093 if (tb
[IFLA_NEW_NETNSID
]) {
1094 int id
= rta_getattr_u32(tb
[IFLA_NEW_NETNSID
]);
1095 char *name
= get_name_from_nsid(id
);
1098 print_string(PRINT_FP
, NULL
, " new-netns %s", name
);
1100 print_int(PRINT_FP
, NULL
, " new-netnsid %d", id
);
1102 if (tb
[IFLA_NEW_IFINDEX
]) {
1103 int id
= rta_getattr_u32(tb
[IFLA_NEW_IFINDEX
]);
1105 print_int(PRINT_FP
, NULL
, " new-ifindex %d", id
);
1108 if (tb
[IFLA_PROTO_DOWN
])
1109 print_proto_down(fp
, tb
);
1112 if (tb
[IFLA_PROMISCUITY
])
1113 print_uint(PRINT_ANY
,
1116 rta_getattr_u32(tb
[IFLA_PROMISCUITY
]));
1118 if (tb
[IFLA_MIN_MTU
])
1119 print_uint(PRINT_ANY
,
1120 "min_mtu", "minmtu %u ",
1121 rta_getattr_u32(tb
[IFLA_MIN_MTU
]));
1123 if (tb
[IFLA_MAX_MTU
])
1124 print_uint(PRINT_ANY
,
1125 "max_mtu", "maxmtu %u ",
1126 rta_getattr_u32(tb
[IFLA_MAX_MTU
]));
1128 if (tb
[IFLA_LINKINFO
])
1129 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
1131 if (do_link
&& tb
[IFLA_AF_SPEC
])
1132 print_af_spec(fp
, tb
[IFLA_AF_SPEC
]);
1134 if (tb
[IFLA_NUM_TX_QUEUES
])
1135 print_uint(PRINT_ANY
,
1138 rta_getattr_u32(tb
[IFLA_NUM_TX_QUEUES
]));
1140 if (tb
[IFLA_NUM_RX_QUEUES
])
1141 print_uint(PRINT_ANY
,
1144 rta_getattr_u32(tb
[IFLA_NUM_RX_QUEUES
]));
1146 if (tb
[IFLA_GSO_MAX_SIZE
])
1147 print_uint(PRINT_ANY
,
1150 rta_getattr_u32(tb
[IFLA_GSO_MAX_SIZE
]));
1152 if (tb
[IFLA_GSO_MAX_SEGS
])
1153 print_uint(PRINT_ANY
,
1156 rta_getattr_u32(tb
[IFLA_GSO_MAX_SEGS
]));
1158 if (tb
[IFLA_PHYS_PORT_NAME
])
1159 print_string(PRINT_ANY
,
1162 rta_getattr_str(tb
[IFLA_PHYS_PORT_NAME
]));
1164 if (tb
[IFLA_PHYS_PORT_ID
]) {
1165 print_string(PRINT_ANY
,
1169 RTA_DATA(tb
[IFLA_PHYS_PORT_ID
]),
1170 RTA_PAYLOAD(tb
[IFLA_PHYS_PORT_ID
]),
1174 if (tb
[IFLA_PHYS_SWITCH_ID
]) {
1175 print_string(PRINT_ANY
,
1178 hexstring_n2a(RTA_DATA(tb
[IFLA_PHYS_SWITCH_ID
]),
1179 RTA_PAYLOAD(tb
[IFLA_PHYS_SWITCH_ID
]),
1184 if ((do_link
|| show_details
) && tb
[IFLA_IFALIAS
]) {
1185 print_string(PRINT_FP
, NULL
, "%s ", _SL_
);
1186 print_string(PRINT_ANY
,
1189 rta_getattr_str(tb
[IFLA_IFALIAS
]));
1192 if ((do_link
|| show_details
) && tb
[IFLA_XDP
])
1193 xdp_dump(fp
, tb
[IFLA_XDP
], true, true);
1195 if (do_link
&& show_stats
) {
1197 __print_link_stats(fp
, tb
);
1200 if ((do_link
|| show_details
) && tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
1201 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
1202 int rem
= RTA_PAYLOAD(vflist
);
1204 open_json_array(PRINT_JSON
, "vfinfo_list");
1205 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
1206 open_json_object(NULL
);
1207 print_vfinfo(fp
, ifi
, i
);
1208 close_json_object();
1210 close_json_array(PRINT_JSON
, NULL
);
1213 if (tb
[IFLA_PROP_LIST
]) {
1214 struct rtattr
*i
, *proplist
= tb
[IFLA_PROP_LIST
];
1215 int rem
= RTA_PAYLOAD(proplist
);
1217 open_json_array(PRINT_JSON
, "altnames");
1218 for (i
= RTA_DATA(proplist
); RTA_OK(i
, rem
);
1219 i
= RTA_NEXT(i
, rem
)) {
1220 if (i
->rta_type
!= IFLA_ALT_IFNAME
)
1222 print_string(PRINT_FP
, NULL
, "%s altname ", _SL_
);
1223 print_string(PRINT_ANY
, NULL
,
1224 "%s", rta_getattr_str(i
));
1226 close_json_array(PRINT_JSON
, NULL
);
1229 print_string(PRINT_FP
, NULL
, "%s", "\n");
1234 static int flush_update(void)
1238 * Note that the kernel may delete multiple addresses for one
1239 * delete request (e.g. if ipv4 address promotion is disabled).
1240 * Since a flush operation is really a series of delete requests
1241 * its possible that we may request an address delete that has
1242 * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL
1243 * errors returned from a flush request
1245 if ((rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) &&
1246 (errno
!= EADDRNOTAVAIL
)) {
1247 perror("Failed to send flush request");
1254 static int set_lifetime(unsigned int *lifetime
, char *argv
)
1256 if (strcmp(argv
, "forever") == 0)
1257 *lifetime
= INFINITY_LIFE_TIME
;
1258 else if (get_u32(lifetime
, argv
, 0))
1264 static unsigned int get_ifa_flags(struct ifaddrmsg
*ifa
,
1265 struct rtattr
*ifa_flags_attr
)
1267 return ifa_flags_attr
? rta_getattr_u32(ifa_flags_attr
) :
1271 /* Mapping from argument to address flag mask and attributes */
1272 static const struct ifa_flag_data_t
{
1277 } ifa_flag_data
[] = {
1278 { .name
= "secondary", .mask
= IFA_F_SECONDARY
, .readonly
= true, .v6only
= false},
1279 { .name
= "temporary", .mask
= IFA_F_SECONDARY
, .readonly
= true, .v6only
= false},
1280 { .name
= "nodad", .mask
= IFA_F_NODAD
, .readonly
= false, .v6only
= true},
1281 { .name
= "optimistic", .mask
= IFA_F_OPTIMISTIC
, .readonly
= false, .v6only
= true},
1282 { .name
= "dadfailed", .mask
= IFA_F_DADFAILED
, .readonly
= true, .v6only
= true},
1283 { .name
= "home", .mask
= IFA_F_HOMEADDRESS
, .readonly
= false, .v6only
= true},
1284 { .name
= "deprecated", .mask
= IFA_F_DEPRECATED
, .readonly
= true, .v6only
= true},
1285 { .name
= "tentative", .mask
= IFA_F_TENTATIVE
, .readonly
= true, .v6only
= true},
1286 { .name
= "permanent", .mask
= IFA_F_PERMANENT
, .readonly
= true, .v6only
= true},
1287 { .name
= "mngtmpaddr", .mask
= IFA_F_MANAGETEMPADDR
, .readonly
= false, .v6only
= true},
1288 { .name
= "noprefixroute", .mask
= IFA_F_NOPREFIXROUTE
, .readonly
= false, .v6only
= false},
1289 { .name
= "autojoin", .mask
= IFA_F_MCAUTOJOIN
, .readonly
= false, .v6only
= false},
1290 { .name
= "stable-privacy", .mask
= IFA_F_STABLE_PRIVACY
, .readonly
= true, .v6only
= true},
1293 /* Returns a pointer to the data structure for a particular interface flag, or null if no flag could be found */
1294 static const struct ifa_flag_data_t
* lookup_flag_data_by_name(const char* flag_name
) {
1297 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_data
); ++i
) {
1298 if (strcmp(flag_name
, ifa_flag_data
[i
].name
) == 0)
1299 return &ifa_flag_data
[i
];
1304 static void print_ifa_flags(FILE *fp
, const struct ifaddrmsg
*ifa
,
1309 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_data
); i
++) {
1310 const struct ifa_flag_data_t
* flag_data
= &ifa_flag_data
[i
];
1312 if (flag_data
->mask
== IFA_F_PERMANENT
) {
1313 if (!(flags
& flag_data
->mask
))
1314 print_bool(PRINT_ANY
,
1315 "dynamic", "dynamic ", true);
1316 } else if (flags
& flag_data
->mask
) {
1317 if (flag_data
->mask
== IFA_F_SECONDARY
&&
1318 ifa
->ifa_family
== AF_INET6
) {
1319 print_bool(PRINT_ANY
,
1320 "temporary", "temporary ", true);
1322 print_string(PRINT_FP
, NULL
,
1323 "%s ", flag_data
->name
);
1324 print_bool(PRINT_JSON
,
1325 flag_data
->name
, NULL
, true);
1329 flags
&= ~flag_data
->mask
;
1333 if (is_json_context()) {
1336 snprintf(b1
, sizeof(b1
), "%02x", flags
);
1337 print_string(PRINT_JSON
, "ifa_flags", NULL
, b1
);
1339 fprintf(fp
, "flags %02x ", flags
);
1345 static int get_filter(const char *arg
)
1349 if (arg
[0] == '-') {
1355 if (strcmp(arg
, "dynamic") == 0) {
1358 } else if (strcmp(arg
, "primary") == 0) {
1363 const struct ifa_flag_data_t
* flag_data
= lookup_flag_data_by_name(arg
);
1364 if (flag_data
== NULL
)
1368 filter
.flags
&= ~flag_data
->mask
;
1370 filter
.flags
|= flag_data
->mask
;
1371 filter
.flagmask
|= flag_data
->mask
;
1375 static int ifa_label_match_rta(int ifindex
, const struct rtattr
*rta
)
1383 label
= RTA_DATA(rta
);
1385 label
= ll_index_to_name(ifindex
);
1387 return fnmatch(filter
.label
, label
, 0);
1390 int print_addrinfo(struct nlmsghdr
*n
, void *arg
)
1393 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1394 int len
= n
->nlmsg_len
;
1395 unsigned int ifa_flags
;
1396 struct rtattr
*rta_tb
[IFA_MAX
+1];
1400 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
1402 len
-= NLMSG_LENGTH(sizeof(*ifa
));
1404 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
1408 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
1411 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
),
1412 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
1414 ifa_flags
= get_ifa_flags(ifa
, rta_tb
[IFA_FLAGS
]);
1416 if (!rta_tb
[IFA_LOCAL
])
1417 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
1418 if (!rta_tb
[IFA_ADDRESS
])
1419 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
1421 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
1423 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1425 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1428 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1431 if (ifa_label_match_rta(ifa
->ifa_index
, rta_tb
[IFA_LABEL
]))
1434 if (inet_addr_match_rta(&filter
.pfx
, rta_tb
[IFA_LOCAL
]))
1437 if (filter
.flushb
) {
1438 struct nlmsghdr
*fn
;
1440 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
1444 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
1445 memcpy(fn
, n
, n
->nlmsg_len
);
1446 fn
->nlmsg_type
= RTM_DELADDR
;
1447 fn
->nlmsg_flags
= NLM_F_REQUEST
;
1448 fn
->nlmsg_seq
= ++rth
.seq
;
1449 filter
.flushp
= (((char *)fn
) + n
->nlmsg_len
) - filter
.flushb
;
1455 if (n
->nlmsg_type
== RTM_DELADDR
)
1456 print_bool(PRINT_ANY
, "deleted", "Deleted ", true);
1461 if (filter
.oneline
|| filter
.flushb
) {
1462 const char *dev
= ll_index_to_name(ifa
->ifa_index
);
1464 if (is_json_context()) {
1465 print_int(PRINT_JSON
,
1466 "index", NULL
, ifa
->ifa_index
);
1467 print_string(PRINT_JSON
, "dev", NULL
, dev
);
1469 fprintf(fp
, "%u: %s", ifa
->ifa_index
, dev
);
1473 name
= family_name(ifa
->ifa_family
);
1475 print_string(PRINT_ANY
, "family", " %s ", name
);
1477 print_int(PRINT_ANY
, "family_index", " family %d ",
1482 if (rta_tb
[IFA_LOCAL
]) {
1483 print_color_string(PRINT_ANY
,
1484 ifa_family_color(ifa
->ifa_family
),
1486 format_host_rta(ifa
->ifa_family
,
1487 rta_tb
[IFA_LOCAL
]));
1488 if (rta_tb
[IFA_ADDRESS
] &&
1489 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]),
1490 RTA_DATA(rta_tb
[IFA_LOCAL
]),
1491 ifa
->ifa_family
== AF_INET
? 4 : 16)) {
1492 print_string(PRINT_FP
, NULL
, " %s ", "peer");
1493 print_color_string(PRINT_ANY
,
1494 ifa_family_color(ifa
->ifa_family
),
1497 format_host_rta(ifa
->ifa_family
,
1498 rta_tb
[IFA_ADDRESS
]));
1500 print_int(PRINT_ANY
, "prefixlen", "/%d ", ifa
->ifa_prefixlen
);
1502 if (rta_tb
[IFA_RT_PRIORITY
])
1503 print_uint(PRINT_ANY
, "metric", "metric %u ",
1504 rta_getattr_u32(rta_tb
[IFA_RT_PRIORITY
]));
1510 if (rta_tb
[IFA_BROADCAST
]) {
1511 print_string(PRINT_FP
, NULL
, "%s ", "brd");
1512 print_color_string(PRINT_ANY
,
1513 ifa_family_color(ifa
->ifa_family
),
1516 format_host_rta(ifa
->ifa_family
,
1517 rta_tb
[IFA_BROADCAST
]));
1520 if (rta_tb
[IFA_ANYCAST
]) {
1521 print_string(PRINT_FP
, NULL
, "%s ", "any");
1522 print_color_string(PRINT_ANY
,
1523 ifa_family_color(ifa
->ifa_family
),
1526 format_host_rta(ifa
->ifa_family
,
1527 rta_tb
[IFA_ANYCAST
]));
1530 print_string(PRINT_ANY
,
1533 rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
1535 print_ifa_flags(fp
, ifa
, ifa_flags
);
1537 if (rta_tb
[IFA_LABEL
])
1538 print_string(PRINT_ANY
,
1541 rta_getattr_str(rta_tb
[IFA_LABEL
]));
1543 if (rta_tb
[IFA_CACHEINFO
]) {
1544 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
1547 print_string(PRINT_FP
, NULL
, " valid_lft ", NULL
);
1549 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
) {
1550 print_uint(PRINT_JSON
,
1552 NULL
, INFINITY_LIFE_TIME
);
1553 print_string(PRINT_FP
, NULL
, "%s", "forever");
1555 print_uint(PRINT_ANY
,
1556 "valid_life_time", "%usec", ci
->ifa_valid
);
1559 print_string(PRINT_FP
, NULL
, " preferred_lft ", NULL
);
1560 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
) {
1561 print_uint(PRINT_JSON
,
1562 "preferred_life_time",
1563 NULL
, INFINITY_LIFE_TIME
);
1564 print_string(PRINT_FP
, NULL
, "%s", "forever");
1566 if (ifa_flags
& IFA_F_DEPRECATED
)
1567 print_int(PRINT_ANY
,
1568 "preferred_life_time",
1572 print_uint(PRINT_ANY
,
1573 "preferred_life_time",
1578 print_string(PRINT_FP
, NULL
, "%s", "\n");
1584 static int print_selected_addrinfo(struct ifinfomsg
*ifi
,
1585 struct nlmsg_list
*ainfo
, FILE *fp
)
1587 open_json_array(PRINT_JSON
, "addr_info");
1588 for ( ; ainfo
; ainfo
= ainfo
->next
) {
1589 struct nlmsghdr
*n
= &ainfo
->h
;
1590 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1592 if (n
->nlmsg_type
!= RTM_NEWADDR
)
1595 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifa
)))
1598 if (ifa
->ifa_index
!= ifi
->ifi_index
||
1599 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
1602 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
1605 open_json_object(NULL
);
1606 print_addrinfo(n
, fp
);
1607 close_json_object();
1609 close_json_array(PRINT_JSON
, NULL
);
1612 print_string(PRINT_FP
, NULL
, "%s", "\n");
1619 static int store_nlmsg(struct nlmsghdr
*n
, void *arg
)
1621 struct nlmsg_chain
*lchain
= (struct nlmsg_chain
*)arg
;
1622 struct nlmsg_list
*h
;
1624 h
= malloc(n
->nlmsg_len
+sizeof(void *));
1628 memcpy(&h
->h
, n
, n
->nlmsg_len
);
1632 lchain
->tail
->next
= h
;
1637 ll_remember_index(n
, NULL
);
1641 static __u32 ipadd_dump_magic
= 0x47361222;
1643 static int ipadd_save_prep(void)
1647 if (isatty(STDOUT_FILENO
)) {
1648 fprintf(stderr
, "Not sending a binary stream to stdout\n");
1652 ret
= write(STDOUT_FILENO
, &ipadd_dump_magic
, sizeof(ipadd_dump_magic
));
1653 if (ret
!= sizeof(ipadd_dump_magic
)) {
1654 fprintf(stderr
, "Can't write magic to dump file\n");
1661 static int ipadd_dump_check_magic(void)
1666 if (isatty(STDIN_FILENO
)) {
1667 fprintf(stderr
, "Can't restore address dump from a terminal\n");
1671 ret
= fread(&magic
, sizeof(magic
), 1, stdin
);
1672 if (magic
!= ipadd_dump_magic
) {
1673 fprintf(stderr
, "Magic mismatch (%d elems, %x magic)\n", ret
, magic
);
1680 static int save_nlmsg(struct nlmsghdr
*n
, void *arg
)
1684 ret
= write(STDOUT_FILENO
, n
, n
->nlmsg_len
);
1685 if ((ret
> 0) && (ret
!= n
->nlmsg_len
)) {
1686 fprintf(stderr
, "Short write while saving nlmsg\n");
1690 return ret
== n
->nlmsg_len
? 0 : ret
;
1693 static int show_handler(struct rtnl_ctrl_data
*ctrl
,
1694 struct nlmsghdr
*n
, void *arg
)
1696 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1698 open_json_object(NULL
);
1699 print_int(PRINT_ANY
, "index", "if%d:", ifa
->ifa_index
);
1701 print_addrinfo(n
, stdout
);
1702 close_json_object();
1706 static int ipaddr_showdump(void)
1710 if (ipadd_dump_check_magic())
1714 open_json_object(NULL
);
1715 open_json_array(PRINT_JSON
, "addr_info");
1717 err
= rtnl_from_file(stdin
, &show_handler
, NULL
);
1719 close_json_array(PRINT_JSON
, NULL
);
1720 close_json_object();
1726 static int restore_handler(struct rtnl_ctrl_data
*ctrl
,
1727 struct nlmsghdr
*n
, void *arg
)
1731 n
->nlmsg_flags
|= NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_ACK
;
1735 ret
= rtnl_talk(&rth
, n
, NULL
);
1736 if ((ret
< 0) && (errno
== EEXIST
))
1742 static int ipaddr_restore(void)
1744 if (ipadd_dump_check_magic())
1747 exit(rtnl_from_file(stdin
, &restore_handler
, NULL
));
1750 void free_nlmsg_chain(struct nlmsg_chain
*info
)
1752 struct nlmsg_list
*l
, *n
;
1754 for (l
= info
->head
; l
; l
= n
) {
1760 static void ipaddr_filter(struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
1762 struct nlmsg_list
*l
, **lp
;
1765 while ((l
= *lp
) != NULL
) {
1767 int missing_net_address
= 1;
1768 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1769 struct nlmsg_list
*a
;
1771 for (a
= ainfo
->head
; a
; a
= a
->next
) {
1772 struct nlmsghdr
*n
= &a
->h
;
1773 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1774 struct rtattr
*tb
[IFA_MAX
+ 1];
1775 unsigned int ifa_flags
;
1777 if (ifa
->ifa_index
!= ifi
->ifi_index
)
1779 missing_net_address
= 0;
1780 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1782 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1785 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
1786 ifa_flags
= get_ifa_flags(ifa
, tb
[IFA_FLAGS
]);
1788 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1791 if (ifa_label_match_rta(ifa
->ifa_index
, tb
[IFA_LABEL
]))
1795 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
1796 if (inet_addr_match_rta(&filter
.pfx
, tb
[IFA_LOCAL
]))
1802 if (missing_net_address
&&
1803 (filter
.family
== AF_UNSPEC
|| filter
.family
== AF_PACKET
))
1813 static int ipaddr_dump_filter(struct nlmsghdr
*nlh
, int reqlen
)
1815 struct ifaddrmsg
*ifa
= NLMSG_DATA(nlh
);
1817 ifa
->ifa_index
= filter
.ifindex
;
1822 static int ipaddr_flush(void)
1825 char flushb
[4096-512];
1827 filter
.flushb
= flushb
;
1829 filter
.flushe
= sizeof(flushb
);
1831 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
1832 if (rtnl_addrdump_req(&rth
, filter
.family
,
1833 ipaddr_dump_filter
) < 0) {
1834 perror("Cannot send dump request");
1838 if (rtnl_dump_filter_nc(&rth
, print_addrinfo
,
1839 stdout
, NLM_F_DUMP_INTR
) < 0) {
1840 fprintf(stderr
, "Flush terminated\n");
1843 if (filter
.flushed
== 0) {
1847 printf("Nothing to flush.\n");
1849 printf("*** Flush is complete after %d round%s ***\n", round
, round
> 1?"s":"");
1855 if (flush_update() < 0)
1859 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
1863 /* If we are flushing, and specifying primary, then we
1864 * want to flush only a single round. Otherwise, we'll
1865 * start flushing secondaries that were promoted to
1868 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
1871 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
1876 static int iplink_filter_req(struct nlmsghdr
*nlh
, int reqlen
)
1880 err
= addattr32(nlh
, reqlen
, IFLA_EXT_MASK
, RTEXT_FILTER_VF
);
1884 if (filter
.master
) {
1885 err
= addattr32(nlh
, reqlen
, IFLA_MASTER
, filter
.master
);
1891 struct rtattr
*linkinfo
;
1893 linkinfo
= addattr_nest(nlh
, reqlen
, IFLA_LINKINFO
);
1895 err
= addattr_l(nlh
, reqlen
, IFLA_INFO_KIND
, filter
.kind
,
1896 strlen(filter
.kind
));
1900 addattr_nest_end(nlh
, linkinfo
);
1906 static int ipaddr_link_get(int index
, struct nlmsg_chain
*linfo
)
1908 struct iplink_req req
= {
1909 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifinfomsg
)),
1910 .n
.nlmsg_flags
= NLM_F_REQUEST
,
1911 .n
.nlmsg_type
= RTM_GETLINK
,
1912 .i
.ifi_family
= filter
.family
,
1913 .i
.ifi_index
= index
,
1915 __u32 filt_mask
= RTEXT_FILTER_VF
;
1916 struct nlmsghdr
*answer
;
1919 filt_mask
|= RTEXT_FILTER_SKIP_STATS
;
1921 addattr32(&req
.n
, sizeof(req
), IFLA_EXT_MASK
, filt_mask
);
1923 if (rtnl_talk(&rth
, &req
.n
, &answer
) < 0) {
1924 perror("Cannot send link request");
1928 if (store_nlmsg(answer
, linfo
) < 0) {
1929 fprintf(stderr
, "Failed to process link information\n");
1936 /* fills in linfo with link data and optionally ainfo with address info
1937 * caller can walk lists as desired and must call free_nlmsg_chain for
1940 int ip_link_list(req_filter_fn_t filter_fn
, struct nlmsg_chain
*linfo
)
1942 if (rtnl_linkdump_req_filter_fn(&rth
, preferred_family
,
1944 perror("Cannot send dump request");
1948 if (rtnl_dump_filter(&rth
, store_nlmsg
, linfo
) < 0) {
1949 fprintf(stderr
, "Dump terminated\n");
1956 static int ip_addr_list(struct nlmsg_chain
*ainfo
)
1958 if (rtnl_addrdump_req(&rth
, filter
.family
, ipaddr_dump_filter
) < 0) {
1959 perror("Cannot send dump request");
1963 if (rtnl_dump_filter(&rth
, store_nlmsg
, ainfo
) < 0) {
1964 fprintf(stderr
, "Dump terminated\n");
1971 static int ipaddr_list_flush_or_save(int argc
, char **argv
, int action
)
1973 struct nlmsg_chain linfo
= { NULL
, NULL
};
1974 struct nlmsg_chain _ainfo
= { NULL
, NULL
}, *ainfo
= &_ainfo
;
1975 struct nlmsg_list
*l
;
1976 char *filter_dev
= NULL
;
1979 ipaddr_reset_filter(oneline
, 0);
1980 filter
.showqueue
= 1;
1981 filter
.family
= preferred_family
;
1983 if (action
== IPADD_FLUSH
) {
1985 fprintf(stderr
, "Flush requires arguments.\n");
1989 if (filter
.family
== AF_PACKET
) {
1990 fprintf(stderr
, "Cannot flush link addresses.\n");
1996 if (strcmp(*argv
, "to") == 0) {
1998 if (get_prefix(&filter
.pfx
, *argv
, filter
.family
))
1999 invarg("invalid \"to\"\n", *argv
);
2000 if (filter
.family
== AF_UNSPEC
)
2001 filter
.family
= filter
.pfx
.family
;
2002 } else if (strcmp(*argv
, "scope") == 0) {
2003 unsigned int scope
= 0;
2006 filter
.scopemask
= -1;
2007 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
2008 if (strcmp(*argv
, "all") != 0)
2009 invarg("invalid \"scope\"\n", *argv
);
2010 scope
= RT_SCOPE_NOWHERE
;
2011 filter
.scopemask
= 0;
2013 filter
.scope
= scope
;
2014 } else if (strcmp(*argv
, "up") == 0) {
2016 } else if (get_filter(*argv
) == 0) {
2018 } else if (strcmp(*argv
, "label") == 0) {
2020 filter
.label
= *argv
;
2021 } else if (strcmp(*argv
, "group") == 0) {
2023 if (rtnl_group_a2n(&filter
.group
, *argv
))
2024 invarg("Invalid \"group\" value\n", *argv
);
2025 } else if (strcmp(*argv
, "master") == 0) {
2029 ifindex
= ll_name_to_index(*argv
);
2031 invarg("Device does not exist\n", *argv
);
2032 filter
.master
= ifindex
;
2033 } else if (strcmp(*argv
, "vrf") == 0) {
2037 ifindex
= ll_name_to_index(*argv
);
2039 invarg("Not a valid VRF name\n", *argv
);
2040 if (!name_is_vrf(*argv
))
2041 invarg("Not a valid VRF name\n", *argv
);
2042 filter
.master
= ifindex
;
2043 } else if (strcmp(*argv
, "type") == 0) {
2047 soff
= strlen(*argv
) - strlen("_slave");
2048 if (!strcmp(*argv
+ soff
, "_slave")) {
2049 (*argv
)[soff
] = '\0';
2050 filter
.slave_kind
= *argv
;
2052 filter
.kind
= *argv
;
2055 if (strcmp(*argv
, "dev") == 0)
2057 else if (matches(*argv
, "help") == 0)
2060 duparg2("dev", *argv
);
2067 filter
.ifindex
= ll_name_to_index(filter_dev
);
2068 if (filter
.ifindex
<= 0) {
2069 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
2074 if (action
== IPADD_FLUSH
)
2075 return ipaddr_flush();
2077 if (action
== IPADD_SAVE
) {
2078 if (ipadd_save_prep())
2081 if (rtnl_addrdump_req(&rth
, preferred_family
,
2082 ipaddr_dump_filter
) < 0) {
2083 perror("Cannot send dump request");
2087 if (rtnl_dump_filter(&rth
, save_nlmsg
, stdout
) < 0) {
2088 fprintf(stderr
, "Save terminated\n");
2096 * Initialize a json_writer and open an array object
2097 * if -json was specified.
2102 * If only filter_dev present and none of the other
2103 * link filters are present, use RTM_GETLINK to get
2106 if (filter_dev
&& filter
.group
== -1 && do_link
== 1) {
2107 if (iplink_get(filter_dev
, RTEXT_FILTER_VF
) < 0) {
2108 perror("Cannot send link get request");
2116 if (filter
.ifindex
) {
2117 if (ipaddr_link_get(filter
.ifindex
, &linfo
) != 0)
2120 if (ip_link_list(iplink_filter_req
, &linfo
) != 0)
2124 if (filter
.family
!= AF_PACKET
) {
2128 if (ip_addr_list(ainfo
) != 0)
2131 ipaddr_filter(&linfo
, ainfo
);
2134 for (l
= linfo
.head
; l
; l
= l
->next
) {
2135 struct nlmsghdr
*n
= &l
->h
;
2136 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
2139 open_json_object(NULL
);
2140 if (brief
|| !no_link
)
2141 res
= print_linkinfo(n
, stdout
);
2142 if (res
>= 0 && filter
.family
!= AF_PACKET
)
2143 print_selected_addrinfo(ifi
, ainfo
->head
, stdout
);
2144 if (res
> 0 && !do_link
&& show_stats
)
2145 print_link_stats(stdout
, n
);
2146 close_json_object();
2151 free_nlmsg_chain(ainfo
);
2152 free_nlmsg_chain(&linfo
);
2158 ipaddr_loop_each_vf(struct rtattr
*tb
[], int vfnum
, int *min
, int *max
)
2160 struct rtattr
*vflist
= tb
[IFLA_VFINFO_LIST
];
2161 struct rtattr
*i
, *vf
[IFLA_VF_MAX
+1];
2162 struct ifla_vf_rate
*vf_rate
;
2165 rem
= RTA_PAYLOAD(vflist
);
2167 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
2168 parse_rtattr_nested(vf
, IFLA_VF_MAX
, i
);
2170 if (!vf
[IFLA_VF_RATE
]) {
2171 fprintf(stderr
, "VF min/max rate API not supported\n");
2175 vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
2176 if (vf_rate
->vf
== vfnum
) {
2177 *min
= vf_rate
->min_tx_rate
;
2178 *max
= vf_rate
->max_tx_rate
;
2182 fprintf(stderr
, "Cannot find VF %d\n", vfnum
);
2186 void ipaddr_get_vf_rate(int vfnum
, int *min
, int *max
, const char *dev
)
2188 struct nlmsg_chain linfo
= { NULL
, NULL
};
2189 struct rtattr
*tb
[IFLA_MAX
+1];
2190 struct ifinfomsg
*ifi
;
2191 struct nlmsg_list
*l
;
2195 idx
= ll_name_to_index(dev
);
2197 fprintf(stderr
, "Device %s does not exist\n", dev
);
2201 if (rtnl_linkdump_req(&rth
, AF_UNSPEC
) < 0) {
2202 perror("Cannot send dump request");
2205 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
2206 fprintf(stderr
, "Dump terminated\n");
2209 for (l
= linfo
.head
; l
; l
= l
->next
) {
2211 ifi
= NLMSG_DATA(n
);
2213 len
= n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
2214 if (len
< 0 || (idx
&& idx
!= ifi
->ifi_index
))
2217 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
2219 if ((tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
])) {
2220 ipaddr_loop_each_vf(tb
, vfnum
, min
, max
);
2226 int ipaddr_list_link(int argc
, char **argv
)
2228 preferred_family
= AF_PACKET
;
2230 return ipaddr_list_flush_or_save(argc
, argv
, IPADD_LIST
);
2233 void ipaddr_reset_filter(int oneline
, int ifindex
)
2235 memset(&filter
, 0, sizeof(filter
));
2236 filter
.oneline
= oneline
;
2237 filter
.ifindex
= ifindex
;
2241 static int default_scope(inet_prefix
*lcl
)
2243 if (lcl
->family
== AF_INET
) {
2244 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
2245 return RT_SCOPE_HOST
;
2250 static bool ipaddr_is_multicast(inet_prefix
*a
)
2252 if (a
->family
== AF_INET
)
2253 return IN_MULTICAST(ntohl(a
->data
[0]));
2254 else if (a
->family
== AF_INET6
)
2255 return IN6_IS_ADDR_MULTICAST(a
->data
);
2260 static bool is_valid_label(const char *dev
, const char *label
)
2262 size_t len
= strlen(dev
);
2264 if (strncmp(label
, dev
, len
) != 0)
2267 return label
[len
] == '\0' || label
[len
] == ':';
2270 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
2274 struct ifaddrmsg ifa
;
2277 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
)),
2278 .n
.nlmsg_flags
= NLM_F_REQUEST
| flags
,
2279 .n
.nlmsg_type
= cmd
,
2280 .ifa
.ifa_family
= preferred_family
,
2284 char *lcl_arg
= NULL
;
2285 char *valid_lftp
= NULL
;
2286 char *preferred_lftp
= NULL
;
2287 inet_prefix lcl
= {};
2294 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
2295 __u32 valid_lft
= INFINITY_LIFE_TIME
;
2296 unsigned int ifa_flags
= 0;
2299 if (strcmp(*argv
, "peer") == 0 ||
2300 strcmp(*argv
, "remote") == 0) {
2304 duparg("peer", *argv
);
2305 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
2306 peer_len
= peer
.bytelen
;
2307 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2308 req
.ifa
.ifa_family
= peer
.family
;
2309 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
2310 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
2311 } else if (matches(*argv
, "broadcast") == 0 ||
2312 strcmp(*argv
, "brd") == 0) {
2317 duparg("broadcast", *argv
);
2318 if (strcmp(*argv
, "+") == 0)
2320 else if (strcmp(*argv
, "-") == 0)
2323 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
2324 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2325 req
.ifa
.ifa_family
= addr
.family
;
2326 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
2327 brd_len
= addr
.bytelen
;
2329 } else if (strcmp(*argv
, "anycast") == 0) {
2334 duparg("anycast", *argv
);
2335 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
2336 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2337 req
.ifa
.ifa_family
= addr
.family
;
2338 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
2339 any_len
= addr
.bytelen
;
2340 } else if (strcmp(*argv
, "scope") == 0) {
2341 unsigned int scope
= 0;
2344 if (rtnl_rtscope_a2n(&scope
, *argv
))
2345 invarg("invalid scope value.", *argv
);
2346 req
.ifa
.ifa_scope
= scope
;
2348 } else if (strcmp(*argv
, "dev") == 0) {
2351 } else if (strcmp(*argv
, "label") == 0) {
2354 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
2355 } else if (matches(*argv
, "metric") == 0 ||
2356 matches(*argv
, "priority") == 0 ||
2357 matches(*argv
, "preference") == 0) {
2361 if (get_u32(&metric
, *argv
, 0))
2362 invarg("\"metric\" value is invalid\n", *argv
);
2363 addattr32(&req
.n
, sizeof(req
), IFA_RT_PRIORITY
, metric
);
2364 } else if (matches(*argv
, "valid_lft") == 0) {
2366 duparg("valid_lft", *argv
);
2369 if (set_lifetime(&valid_lft
, *argv
))
2370 invarg("valid_lft value", *argv
);
2371 } else if (matches(*argv
, "preferred_lft") == 0) {
2373 duparg("preferred_lft", *argv
);
2375 preferred_lftp
= *argv
;
2376 if (set_lifetime(&preferred_lft
, *argv
))
2377 invarg("preferred_lft value", *argv
);
2378 } else if (lookup_flag_data_by_name(*argv
)) {
2379 const struct ifa_flag_data_t
* flag_data
= lookup_flag_data_by_name(*argv
);
2380 if (flag_data
->readonly
) {
2381 fprintf(stderr
, "Warning: %s option is not mutable from userspace\n", flag_data
->name
);
2382 } else if (flag_data
->v6only
&& req
.ifa
.ifa_family
!= AF_INET6
) {
2383 fprintf(stderr
, "Warning: %s option can be set only for IPv6 addresses\n", flag_data
->name
);
2385 ifa_flags
|= flag_data
->mask
;
2388 if (strcmp(*argv
, "local") == 0)
2390 if (matches(*argv
, "help") == 0)
2393 duparg2("local", *argv
);
2395 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
2396 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2397 req
.ifa
.ifa_family
= lcl
.family
;
2398 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
2399 local_len
= lcl
.bytelen
;
2403 if (ifa_flags
<= 0xff)
2404 req
.ifa
.ifa_flags
= ifa_flags
;
2406 addattr32(&req
.n
, sizeof(req
), IFA_FLAGS
, ifa_flags
);
2409 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
2412 if (l
&& !is_valid_label(d
, l
)) {
2414 "\"label\" (%s) must match \"dev\" (%s) or be prefixed by \"dev\" with a colon.\n",
2419 if (peer_len
== 0 && local_len
) {
2420 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
2422 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n"
2423 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n"
2424 " This special behaviour is likely to disappear in further releases,\n"
2425 " fix your scripts!\n", lcl_arg
, local_len
*8);
2428 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
2431 if (req
.ifa
.ifa_prefixlen
== 0)
2432 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
2434 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
2438 if (req
.ifa
.ifa_family
!= AF_INET
) {
2439 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
2443 if (brd
.bitlen
<= 30) {
2444 for (i
= 31; i
>= brd
.bitlen
; i
--) {
2446 brd
.data
[0] |= htonl(1<<(31-i
));
2448 brd
.data
[0] &= ~htonl(1<<(31-i
));
2450 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
2451 brd_len
= brd
.bytelen
;
2454 if (!scoped
&& cmd
!= RTM_DELADDR
)
2455 req
.ifa
.ifa_scope
= default_scope(&lcl
);
2457 req
.ifa
.ifa_index
= ll_name_to_index(d
);
2458 if (!req
.ifa
.ifa_index
)
2461 if (valid_lftp
|| preferred_lftp
) {
2462 struct ifa_cacheinfo cinfo
= {};
2465 fprintf(stderr
, "valid_lft is zero\n");
2468 if (valid_lft
< preferred_lft
) {
2469 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
2473 cinfo
.ifa_prefered
= preferred_lft
;
2474 cinfo
.ifa_valid
= valid_lft
;
2475 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
2479 if ((ifa_flags
& IFA_F_MCAUTOJOIN
) && !ipaddr_is_multicast(&lcl
)) {
2480 fprintf(stderr
, "autojoin needs multicast address\n");
2484 if (rtnl_talk(&rth
, &req
.n
, NULL
) < 0)
2490 int do_ipaddr(int argc
, char **argv
)
2493 return ipaddr_list_flush_or_save(0, NULL
, IPADD_LIST
);
2494 if (matches(*argv
, "add") == 0)
2495 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
2496 if (matches(*argv
, "change") == 0 ||
2497 strcmp(*argv
, "chg") == 0)
2498 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
2499 if (matches(*argv
, "replace") == 0)
2500 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
2501 if (matches(*argv
, "delete") == 0)
2502 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
2503 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
2504 || matches(*argv
, "lst") == 0)
2505 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_LIST
);
2506 if (matches(*argv
, "flush") == 0)
2507 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_FLUSH
);
2508 if (matches(*argv
, "save") == 0)
2509 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_SAVE
);
2510 if (matches(*argv
, "showdump") == 0)
2511 return ipaddr_showdump();
2512 if (matches(*argv
, "restore") == 0)
2513 return ipaddr_restore();
2514 if (matches(*argv
, "help") == 0)
2516 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv
);