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"
45 static struct link_filter filter
;
48 static void usage(void) __attribute__((noreturn
));
50 static void usage(void)
55 fprintf(stderr
, "Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]\n");
56 fprintf(stderr
, " [ CONFFLAG-LIST ]\n");
57 fprintf(stderr
, " ip address del IFADDR dev IFNAME [mngtmpaddr]\n");
58 fprintf(stderr
, " ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n");
59 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n");
60 fprintf(stderr
, " ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n");
61 fprintf(stderr
, " [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n");
62 fprintf(stderr
, " [ label LABEL ] [up] [ vrf NAME ] ]\n");
63 fprintf(stderr
, " ip address {showdump|restore}\n");
64 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
65 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
66 fprintf(stderr
, " [ label IFNAME ] [ scope SCOPE-ID ] [ metric METRIC ]\n");
67 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
68 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
69 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
70 fprintf(stderr
, " [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n");
71 fprintf(stderr
, " CONFFLAG-LIST ]\n");
72 fprintf(stderr
, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
73 fprintf(stderr
, "CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n");
74 fprintf(stderr
, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
75 fprintf(stderr
, "LFT := forever | SECONDS\n");
76 fprintf(stderr
, "TYPE := { vlan | veth | vcan | vxcan | dummy | ifb | macvlan | macvtap |\n");
77 fprintf(stderr
, " bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |\n");
78 fprintf(stderr
, " gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan | vti |\n");
79 fprintf(stderr
, " nlmon | can | bond_slave | ipvlan | geneve | bridge_slave |\n");
80 fprintf(stderr
, " hsr | macsec | netdevsim }\n");
85 static void print_link_flags(FILE *fp
, unsigned int flags
, unsigned int mdown
)
87 open_json_array(PRINT_ANY
, is_json_context() ? "flags" : "<");
88 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
89 print_string(PRINT_ANY
, NULL
,
90 flags
? "%s," : "%s", "NO-CARRIER");
91 flags
&= ~IFF_RUNNING
;
92 #define _PF(f) if (flags&IFF_##f) { \
94 print_string(PRINT_ANY, NULL, flags ? "%s," : "%s", #f); }
115 print_hex(PRINT_ANY
, NULL
, "%x", flags
);
117 print_string(PRINT_ANY
, NULL
, ",%s", "M-DOWN");
118 close_json_array(PRINT_ANY
, "> ");
121 static const char *oper_states
[] = {
122 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
123 "TESTING", "DORMANT", "UP"
126 static void print_operstate(FILE *f
, __u8 state
)
128 if (state
>= ARRAY_SIZE(oper_states
)) {
129 if (is_json_context())
130 print_uint(PRINT_JSON
, "operstate_index", NULL
, state
);
132 print_0xhex(PRINT_FP
, NULL
, "state %#llx", state
);
134 print_color_string(PRINT_ANY
,
135 oper_state_color(state
),
140 if (is_json_context())
141 print_string(PRINT_JSON
,
143 NULL
, oper_states
[state
]);
145 fprintf(f
, "state ");
146 color_fprintf(f
, oper_state_color(state
),
147 "%s ", oper_states
[state
]);
152 int get_operstate(const char *name
)
156 for (i
= 0; i
< ARRAY_SIZE(oper_states
); i
++)
157 if (strcasecmp(name
, oper_states
[i
]) == 0)
162 static void print_queuelen(FILE *f
, struct rtattr
*tb
[IFLA_MAX
+ 1])
167 qlen
= rta_getattr_u32(tb
[IFLA_TXQLEN
]);
169 struct ifreq ifr
= {};
170 int s
= socket(AF_INET
, SOCK_STREAM
, 0);
175 strcpy(ifr
.ifr_name
, rta_getattr_str(tb
[IFLA_IFNAME
]));
176 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
178 "ioctl(SIOCGIFTXQLEN) failed: %s\n",
187 print_int(PRINT_ANY
, "txqlen", "qlen %d", qlen
);
190 static const char *link_modes
[] = {
194 static void print_linkmode(FILE *f
, struct rtattr
*tb
)
196 unsigned int mode
= rta_getattr_u8(tb
);
198 if (mode
>= ARRAY_SIZE(link_modes
))
204 print_string(PRINT_ANY
,
210 static char *parse_link_kind(struct rtattr
*tb
, bool slave
)
212 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
213 int attr
= slave
? IFLA_INFO_SLAVE_KIND
: IFLA_INFO_KIND
;
215 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
218 return RTA_DATA(linkinfo
[attr
]);
223 static int match_link_kind(struct rtattr
**tb
, const char *kind
, bool slave
)
225 if (!tb
[IFLA_LINKINFO
])
228 return strcmp(parse_link_kind(tb
[IFLA_LINKINFO
], slave
), kind
);
231 static void print_linktype(FILE *fp
, struct rtattr
*tb
)
233 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
234 struct link_util
*lu
;
235 struct link_util
*slave_lu
;
238 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
239 open_json_object("linkinfo");
241 if (linkinfo
[IFLA_INFO_KIND
]) {
243 = rta_getattr_str(linkinfo
[IFLA_INFO_KIND
]);
246 print_string(PRINT_ANY
, "info_kind", " %s ", kind
);
248 lu
= get_link_kind(kind
);
249 if (lu
&& lu
->print_opt
) {
250 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
252 if (linkinfo
[IFLA_INFO_DATA
]) {
253 parse_rtattr_nested(attr
, lu
->maxattr
,
254 linkinfo
[IFLA_INFO_DATA
]);
257 open_json_object("info_data");
258 lu
->print_opt(lu
, fp
, data
);
261 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
263 open_json_object("info_xstats");
264 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
270 if (linkinfo
[IFLA_INFO_SLAVE_KIND
]) {
271 const char *slave_kind
272 = rta_getattr_str(linkinfo
[IFLA_INFO_SLAVE_KIND
]);
275 print_string(PRINT_ANY
,
280 snprintf(slave
, sizeof(slave
), "%s_slave", slave_kind
);
282 slave_lu
= get_link_kind(slave
);
283 if (slave_lu
&& slave_lu
->print_opt
) {
284 struct rtattr
*attr
[slave_lu
->maxattr
+1], **data
= NULL
;
286 if (linkinfo
[IFLA_INFO_SLAVE_DATA
]) {
287 parse_rtattr_nested(attr
, slave_lu
->maxattr
,
288 linkinfo
[IFLA_INFO_SLAVE_DATA
]);
291 open_json_object("info_slave_data");
292 slave_lu
->print_opt(slave_lu
, fp
, data
);
299 static void print_af_spec(FILE *fp
, struct rtattr
*af_spec_attr
)
301 struct rtattr
*inet6_attr
;
302 struct rtattr
*tb
[IFLA_INET6_MAX
+ 1];
304 inet6_attr
= parse_rtattr_one_nested(AF_INET6
, af_spec_attr
);
308 parse_rtattr_nested(tb
, IFLA_INET6_MAX
, inet6_attr
);
310 if (tb
[IFLA_INET6_ADDR_GEN_MODE
]) {
311 __u8 mode
= rta_getattr_u8(tb
[IFLA_INET6_ADDR_GEN_MODE
]);
315 case IN6_ADDR_GEN_MODE_EUI64
:
316 print_string(PRINT_ANY
,
317 "inet6_addr_gen_mode",
321 case IN6_ADDR_GEN_MODE_NONE
:
322 print_string(PRINT_ANY
,
323 "inet6_addr_gen_mode",
327 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY
:
328 print_string(PRINT_ANY
,
329 "inet6_addr_gen_mode",
333 case IN6_ADDR_GEN_MODE_RANDOM
:
334 print_string(PRINT_ANY
,
335 "inet6_addr_gen_mode",
340 snprintf(b1
, sizeof(b1
), "%#.2hhx", mode
);
341 print_string(PRINT_ANY
,
342 "inet6_addr_gen_mode",
350 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
);
352 static void print_vfinfo(FILE *fp
, struct rtattr
*vfinfo
)
354 struct ifla_vf_mac
*vf_mac
;
355 struct ifla_vf_tx_rate
*vf_tx_rate
;
356 struct rtattr
*vf
[IFLA_VF_MAX
+ 1] = {};
360 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
361 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
365 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
367 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
368 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
370 print_string(PRINT_FP
, NULL
, "%s ", _SL_
);
371 print_int(PRINT_ANY
, "vf", "vf %d ", vf_mac
->vf
);
372 print_string(PRINT_ANY
, "mac", "MAC %s",
373 ll_addr_n2a((unsigned char *) &vf_mac
->mac
,
374 ETH_ALEN
, 0, b1
, sizeof(b1
)));
376 if (vf
[IFLA_VF_VLAN_LIST
]) {
377 struct rtattr
*i
, *vfvlanlist
= vf
[IFLA_VF_VLAN_LIST
];
378 int rem
= RTA_PAYLOAD(vfvlanlist
);
380 open_json_array(PRINT_JSON
, "vlan_list");
381 for (i
= RTA_DATA(vfvlanlist
);
382 RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
383 struct ifla_vf_vlan_info
*vf_vlan_info
= RTA_DATA(i
);
386 open_json_object(NULL
);
387 if (vf_vlan_info
->vlan
)
392 if (vf_vlan_info
->qos
)
397 if (vf_vlan_info
->vlan_proto
&&
398 vf_vlan_info
->vlan_proto
!= htons(ETH_P_8021Q
))
399 print_string(PRINT_ANY
,
401 ", vlan protocol %s",
403 vf_vlan_info
->vlan_proto
,
407 close_json_array(PRINT_JSON
, NULL
);
409 struct ifla_vf_vlan
*vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
417 print_int(PRINT_ANY
, "qos", ", qos %d", vf_vlan
->qos
);
420 if (vf_tx_rate
->rate
)
421 print_uint(PRINT_ANY
,
423 ", tx rate %u (Mbps)",
426 if (vf
[IFLA_VF_RATE
]) {
427 struct ifla_vf_rate
*vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
428 int max_tx
= vf_rate
->max_tx_rate
;
429 int min_tx
= vf_rate
->min_tx_rate
;
431 if (is_json_context()) {
432 open_json_object("rate");
433 print_uint(PRINT_JSON
, "max_tx", NULL
, max_tx
);
434 print_uint(PRINT_ANY
, "min_tx", NULL
, min_tx
);
438 fprintf(fp
, ", max_tx_rate %uMbps", max_tx
);
440 fprintf(fp
, ", min_tx_rate %uMbps", min_tx
);
444 if (vf
[IFLA_VF_SPOOFCHK
]) {
445 struct ifla_vf_spoofchk
*vf_spoofchk
=
446 RTA_DATA(vf
[IFLA_VF_SPOOFCHK
]);
448 if (vf_spoofchk
->setting
!= -1)
449 print_bool(PRINT_ANY
,
451 vf_spoofchk
->setting
?
452 ", spoof checking on" : ", spoof checking off",
453 vf_spoofchk
->setting
);
456 if (vf
[IFLA_VF_LINK_STATE
]) {
457 struct ifla_vf_link_state
*vf_linkstate
=
458 RTA_DATA(vf
[IFLA_VF_LINK_STATE
]);
460 if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_AUTO
)
461 print_string(PRINT_ANY
,
465 else if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_ENABLE
)
466 print_string(PRINT_ANY
,
471 print_string(PRINT_ANY
,
477 if (vf
[IFLA_VF_TRUST
]) {
478 struct ifla_vf_trust
*vf_trust
= RTA_DATA(vf
[IFLA_VF_TRUST
]);
480 if (vf_trust
->setting
!= -1)
481 print_bool(PRINT_ANY
,
483 vf_trust
->setting
? ", trust on" : ", trust off",
487 if (vf
[IFLA_VF_RSS_QUERY_EN
]) {
488 struct ifla_vf_rss_query_en
*rss_query
=
489 RTA_DATA(vf
[IFLA_VF_RSS_QUERY_EN
]);
491 if (rss_query
->setting
!= -1)
492 print_bool(PRINT_ANY
,
494 rss_query
->setting
? ", query_rss on"
499 if (vf
[IFLA_VF_STATS
] && show_stats
)
500 print_vf_stats64(fp
, vf
[IFLA_VF_STATS
]);
503 void print_num(FILE *fp
, unsigned int width
, uint64_t count
)
505 const char *prefix
= "kMGTPE";
506 const unsigned int base
= use_iec
? 1024 : 1000;
509 uint8_t precision
= 2;
512 if (!human_readable
|| count
< base
) {
513 fprintf(fp
, "%-*"PRIu64
" ", width
, count
);
517 /* increase value by a factor of 1000/1024 and print
518 * if result is something a human can read
522 if (count
/ base
< powi
)
530 /* try to guess a good number of digits for precision */
531 for (; precision
> 0; precision
--) {
533 if (count
/ powi
< powj
)
537 snprintf(buf
, sizeof(buf
), "%.*f%c%s", precision
,
538 (double) count
/ powi
, *prefix
, use_iec
? "i" : "");
540 fprintf(fp
, "%-*s ", width
, buf
);
543 static void print_vf_stats64(FILE *fp
, struct rtattr
*vfstats
)
545 struct rtattr
*vf
[IFLA_VF_STATS_MAX
+ 1];
547 if (vfstats
->rta_type
!= IFLA_VF_STATS
) {
548 fprintf(stderr
, "BUG: rta type is %d\n", vfstats
->rta_type
);
552 parse_rtattr_nested(vf
, IFLA_VF_STATS_MAX
, vfstats
);
554 if (is_json_context()) {
555 open_json_object("stats");
558 open_json_object("rx");
559 print_u64(PRINT_JSON
, "bytes", NULL
,
560 rta_getattr_u64(vf
[IFLA_VF_STATS_RX_BYTES
]));
561 print_u64(PRINT_JSON
, "packets", NULL
,
562 rta_getattr_u64(vf
[IFLA_VF_STATS_RX_PACKETS
]));
563 print_u64(PRINT_JSON
, "multicast", NULL
,
564 rta_getattr_u64(vf
[IFLA_VF_STATS_MULTICAST
]));
565 print_u64(PRINT_JSON
, "broadcast", NULL
,
566 rta_getattr_u64(vf
[IFLA_VF_STATS_BROADCAST
]));
567 if (vf
[IFLA_VF_STATS_RX_DROPPED
])
568 print_u64(PRINT_JSON
, "dropped", NULL
,
569 rta_getattr_u64(vf
[IFLA_VF_STATS_RX_DROPPED
]));
573 open_json_object("tx");
574 print_u64(PRINT_JSON
, "tx_bytes", NULL
,
575 rta_getattr_u64(vf
[IFLA_VF_STATS_TX_BYTES
]));
576 print_u64(PRINT_JSON
, "tx_packets", NULL
,
577 rta_getattr_u64(vf
[IFLA_VF_STATS_TX_PACKETS
]));
578 if (vf
[IFLA_VF_STATS_TX_DROPPED
])
579 print_u64(PRINT_JSON
, "dropped", NULL
,
580 rta_getattr_u64(vf
[IFLA_VF_STATS_TX_DROPPED
]));
585 fprintf(fp
, "%s", _SL_
);
586 fprintf(fp
, " RX: bytes packets mcast bcast ");
587 if (vf
[IFLA_VF_STATS_RX_DROPPED
])
588 fprintf(fp
, " dropped ");
589 fprintf(fp
, "%s", _SL_
);
592 print_num(fp
, 10, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_BYTES
]));
593 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_PACKETS
]));
594 print_num(fp
, 7, rta_getattr_u64(vf
[IFLA_VF_STATS_MULTICAST
]));
595 print_num(fp
, 7, rta_getattr_u64(vf
[IFLA_VF_STATS_BROADCAST
]));
596 if (vf
[IFLA_VF_STATS_RX_DROPPED
])
597 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_RX_DROPPED
]));
600 fprintf(fp
, "%s", _SL_
);
601 fprintf(fp
, " TX: bytes packets ");
602 if (vf
[IFLA_VF_STATS_TX_DROPPED
])
603 fprintf(fp
, " dropped ");
604 fprintf(fp
, "%s", _SL_
);
607 print_num(fp
, 10, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_BYTES
]));
608 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_PACKETS
]));
609 if (vf
[IFLA_VF_STATS_TX_DROPPED
])
610 print_num(fp
, 8, rta_getattr_u64(vf
[IFLA_VF_STATS_TX_DROPPED
]));
614 static void __print_link_stats(FILE *fp
, struct rtattr
*tb
[])
616 const struct rtattr
*carrier_changes
= tb
[IFLA_CARRIER_CHANGES
];
617 struct rtnl_link_stats64 _s
, *s
= &_s
;
620 ret
= get_rtnl_link_stats_rta(s
, tb
);
624 if (is_json_context()) {
625 open_json_object((ret
== sizeof(*s
)) ? "stats64" : "stats");
628 open_json_object("rx");
629 print_u64(PRINT_JSON
, "bytes", NULL
, s
->rx_bytes
);
630 print_u64(PRINT_JSON
, "packets", NULL
, s
->rx_packets
);
631 print_u64(PRINT_JSON
, "errors", NULL
, s
->rx_errors
);
632 print_u64(PRINT_JSON
, "dropped", NULL
, s
->rx_dropped
);
633 print_u64(PRINT_JSON
, "over_errors", NULL
, s
->rx_over_errors
);
634 print_u64(PRINT_JSON
, "multicast", NULL
, s
->multicast
);
635 if (s
->rx_compressed
)
636 print_u64(PRINT_JSON
,
637 "compressed", NULL
, s
->rx_compressed
);
640 if (show_stats
> 1) {
641 print_u64(PRINT_JSON
,
643 NULL
, s
->rx_length_errors
);
644 print_u64(PRINT_JSON
,
646 NULL
, s
->rx_crc_errors
);
647 print_u64(PRINT_JSON
,
649 NULL
, s
->rx_frame_errors
);
650 print_u64(PRINT_JSON
,
652 NULL
, s
->rx_fifo_errors
);
653 print_u64(PRINT_JSON
,
655 NULL
, s
->rx_missed_errors
);
657 print_u64(PRINT_JSON
,
658 "nohandler", NULL
, s
->rx_nohandler
);
663 open_json_object("tx");
664 print_u64(PRINT_JSON
, "bytes", NULL
, s
->tx_bytes
);
665 print_u64(PRINT_JSON
, "packets", NULL
, s
->tx_packets
);
666 print_u64(PRINT_JSON
, "errors", NULL
, s
->tx_errors
);
667 print_u64(PRINT_JSON
, "dropped", NULL
, s
->tx_dropped
);
668 print_u64(PRINT_JSON
,
670 NULL
, s
->tx_carrier_errors
);
671 print_u64(PRINT_JSON
, "collisions", NULL
, s
->collisions
);
672 if (s
->tx_compressed
)
673 print_u64(PRINT_JSON
,
674 "compressed", NULL
, s
->tx_compressed
);
677 if (show_stats
> 1) {
678 print_u64(PRINT_JSON
,
680 NULL
, s
->tx_aborted_errors
);
681 print_u64(PRINT_JSON
,
683 NULL
, s
->tx_fifo_errors
);
684 print_u64(PRINT_JSON
,
686 NULL
, s
->tx_window_errors
);
687 print_u64(PRINT_JSON
,
689 NULL
, s
->tx_heartbeat_errors
);
691 print_u64(PRINT_JSON
, "carrier_changes", NULL
,
692 rta_getattr_u32(carrier_changes
));
699 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
700 s
->rx_compressed
? "compressed" : "", _SL_
);
703 print_num(fp
, 10, s
->rx_bytes
);
704 print_num(fp
, 8, s
->rx_packets
);
705 print_num(fp
, 7, s
->rx_errors
);
706 print_num(fp
, 7, s
->rx_dropped
);
707 print_num(fp
, 7, s
->rx_over_errors
);
708 print_num(fp
, 7, s
->multicast
);
709 if (s
->rx_compressed
)
710 print_num(fp
, 7, s
->rx_compressed
);
713 if (show_stats
> 1) {
714 fprintf(fp
, "%s", _SL_
);
715 fprintf(fp
, " RX errors: length crc frame fifo missed%s%s",
716 s
->rx_nohandler
? " nohandler" : "", _SL_
);
718 print_num(fp
, 8, s
->rx_length_errors
);
719 print_num(fp
, 7, s
->rx_crc_errors
);
720 print_num(fp
, 7, s
->rx_frame_errors
);
721 print_num(fp
, 7, s
->rx_fifo_errors
);
722 print_num(fp
, 7, s
->rx_missed_errors
);
724 print_num(fp
, 7, s
->rx_nohandler
);
726 fprintf(fp
, "%s", _SL_
);
729 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
730 s
->tx_compressed
? "compressed" : "", _SL_
);
733 print_num(fp
, 10, s
->tx_bytes
);
734 print_num(fp
, 8, s
->tx_packets
);
735 print_num(fp
, 7, s
->tx_errors
);
736 print_num(fp
, 7, s
->tx_dropped
);
737 print_num(fp
, 7, s
->tx_carrier_errors
);
738 print_num(fp
, 7, s
->collisions
);
739 if (s
->tx_compressed
)
740 print_num(fp
, 7, s
->tx_compressed
);
743 if (show_stats
> 1) {
744 fprintf(fp
, "%s", _SL_
);
745 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
747 fprintf(fp
, " transns");
748 fprintf(fp
, "%s", _SL_
);
751 print_num(fp
, 8, s
->tx_aborted_errors
);
752 print_num(fp
, 7, s
->tx_fifo_errors
);
753 print_num(fp
, 7, s
->tx_window_errors
);
754 print_num(fp
, 7, s
->tx_heartbeat_errors
);
757 rta_getattr_u32(carrier_changes
));
762 static void print_link_stats(FILE *fp
, struct nlmsghdr
*n
)
764 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
765 struct rtattr
*tb
[IFLA_MAX
+1];
767 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
),
768 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
)));
769 __print_link_stats(fp
, tb
);
773 static int print_linkinfo_brief(FILE *fp
, const char *name
,
774 const struct ifinfomsg
*ifi
,
777 unsigned int m_flag
= 0;
779 m_flag
= print_name_and_link("%-16s ", name
, tb
);
781 if (tb
[IFLA_OPERSTATE
])
782 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
784 if (filter
.family
== AF_PACKET
) {
787 if (tb
[IFLA_ADDRESS
]) {
788 print_color_string(PRINT_ANY
, COLOR_MAC
,
791 RTA_DATA(tb
[IFLA_ADDRESS
]),
792 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
798 if (filter
.family
== AF_PACKET
) {
799 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
800 print_string(PRINT_FP
, NULL
, "%s", "\n");
807 static const char *link_events
[] = {
808 [IFLA_EVENT_NONE
] = "NONE",
809 [IFLA_EVENT_REBOOT
] = "REBOOT",
810 [IFLA_EVENT_FEATURES
] = "FEATURE CHANGE",
811 [IFLA_EVENT_BONDING_FAILOVER
] = "BONDING FAILOVER",
812 [IFLA_EVENT_NOTIFY_PEERS
] = "NOTIFY PEERS",
813 [IFLA_EVENT_IGMP_RESEND
] = "RESEND IGMP",
814 [IFLA_EVENT_BONDING_OPTIONS
] = "BONDING OPTION"
817 static void print_link_event(FILE *f
, __u32 event
)
819 if (event
>= ARRAY_SIZE(link_events
))
820 print_int(PRINT_ANY
, "event", "event %d ", event
);
823 print_string(PRINT_ANY
,
824 "event", "event %s ",
829 int print_linkinfo(struct nlmsghdr
*n
, void *arg
)
831 FILE *fp
= (FILE *)arg
;
832 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
833 struct rtattr
*tb
[IFLA_MAX
+1];
834 int len
= n
->nlmsg_len
;
836 unsigned int m_flag
= 0;
839 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
842 len
-= NLMSG_LENGTH(sizeof(*ifi
));
846 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
848 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
851 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
853 name
= get_ifname_rta(ifi
->ifi_index
, tb
[IFLA_IFNAME
]);
860 if (tb
[IFLA_GROUP
]) {
861 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
863 if (filter
.group
!= -1 && group
!= filter
.group
)
867 if (tb
[IFLA_MASTER
]) {
868 int master
= rta_getattr_u32(tb
[IFLA_MASTER
]);
870 if (filter
.master
> 0 && master
!= filter
.master
)
872 } else if (filter
.master
> 0)
875 if (filter
.kind
&& match_link_kind(tb
, filter
.kind
, 0))
878 if (filter
.slave_kind
&& match_link_kind(tb
, filter
.slave_kind
, 1))
881 if (n
->nlmsg_type
== RTM_DELLINK
)
882 print_bool(PRINT_ANY
, "deleted", "Deleted ", true);
885 return print_linkinfo_brief(fp
, name
, ifi
, tb
);
887 print_int(PRINT_ANY
, "ifindex", "%d: ", ifi
->ifi_index
);
889 m_flag
= print_name_and_link("%s: ", name
, tb
);
890 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
895 rta_getattr_u32(tb
[IFLA_MTU
]));
897 xdp_dump(fp
, tb
[IFLA_XDP
], do_link
, false);
899 print_string(PRINT_ANY
,
902 rta_getattr_str(tb
[IFLA_QDISC
]));
903 if (tb
[IFLA_MASTER
]) {
904 int master
= rta_getattr_u32(tb
[IFLA_MASTER
]);
906 print_string(PRINT_ANY
,
907 "master", "master %s ",
908 ll_index_to_name(master
));
911 if (tb
[IFLA_OPERSTATE
])
912 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
914 if (do_link
&& tb
[IFLA_LINKMODE
])
915 print_linkmode(fp
, tb
[IFLA_LINKMODE
]);
917 if (tb
[IFLA_GROUP
]) {
918 int group
= rta_getattr_u32(tb
[IFLA_GROUP
]);
920 print_string(PRINT_ANY
,
923 rtnl_group_n2a(group
, b1
, sizeof(b1
)));
926 if (filter
.showqueue
)
927 print_queuelen(fp
, tb
);
930 print_link_event(fp
, rta_getattr_u32(tb
[IFLA_EVENT
]));
932 if (!filter
.family
|| filter
.family
== AF_PACKET
|| show_details
) {
934 print_string(PRINT_ANY
,
937 ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
938 if (tb
[IFLA_ADDRESS
]) {
939 print_color_string(PRINT_ANY
,
943 ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
944 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
948 if (tb
[IFLA_BROADCAST
]) {
949 if (ifi
->ifi_flags
&IFF_POINTOPOINT
) {
950 print_string(PRINT_FP
, NULL
, " peer ", NULL
);
951 print_bool(PRINT_JSON
,
952 "link_pointtopoint", NULL
, true);
954 print_string(PRINT_FP
, NULL
, " brd ", NULL
);
956 print_color_string(PRINT_ANY
,
960 ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
961 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
967 if (tb
[IFLA_LINK_NETNSID
]) {
968 int id
= rta_getattr_u32(tb
[IFLA_LINK_NETNSID
]);
970 if (is_json_context()) {
971 print_int(PRINT_JSON
, "link_netnsid", NULL
, id
);
974 char *name
= get_name_from_nsid(id
);
977 print_string(PRINT_FP
, NULL
,
978 " link-netns %s", name
);
980 print_int(PRINT_FP
, NULL
,
981 " link-netnsid %d", id
);
983 print_string(PRINT_FP
, NULL
,
984 " link-netnsid %s", "unknown");
988 if (tb
[IFLA_NEW_NETNSID
]) {
989 int id
= rta_getattr_u32(tb
[IFLA_NEW_NETNSID
]);
990 char *name
= get_name_from_nsid(id
);
993 print_string(PRINT_FP
, NULL
, " new-netns %s", name
);
995 print_int(PRINT_FP
, NULL
, " new-netnsid %d", id
);
997 if (tb
[IFLA_NEW_IFINDEX
]) {
998 int id
= rta_getattr_u32(tb
[IFLA_NEW_IFINDEX
]);
1000 print_int(PRINT_FP
, NULL
, " new-ifindex %d", id
);
1003 if (tb
[IFLA_PROTO_DOWN
]) {
1004 if (rta_getattr_u8(tb
[IFLA_PROTO_DOWN
]))
1005 print_bool(PRINT_ANY
,
1006 "proto_down", " protodown on ", true);
1010 if (tb
[IFLA_PROMISCUITY
])
1011 print_uint(PRINT_ANY
,
1014 rta_getattr_u32(tb
[IFLA_PROMISCUITY
]));
1016 if (tb
[IFLA_MIN_MTU
])
1017 print_uint(PRINT_ANY
,
1018 "min_mtu", "minmtu %u ",
1019 rta_getattr_u32(tb
[IFLA_MIN_MTU
]));
1021 if (tb
[IFLA_MAX_MTU
])
1022 print_uint(PRINT_ANY
,
1023 "max_mtu", "maxmtu %u ",
1024 rta_getattr_u32(tb
[IFLA_MAX_MTU
]));
1026 if (tb
[IFLA_LINKINFO
])
1027 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
1029 if (do_link
&& tb
[IFLA_AF_SPEC
])
1030 print_af_spec(fp
, tb
[IFLA_AF_SPEC
]);
1032 if (tb
[IFLA_NUM_TX_QUEUES
])
1033 print_uint(PRINT_ANY
,
1036 rta_getattr_u32(tb
[IFLA_NUM_TX_QUEUES
]));
1038 if (tb
[IFLA_NUM_RX_QUEUES
])
1039 print_uint(PRINT_ANY
,
1042 rta_getattr_u32(tb
[IFLA_NUM_RX_QUEUES
]));
1044 if (tb
[IFLA_GSO_MAX_SIZE
])
1045 print_uint(PRINT_ANY
,
1048 rta_getattr_u32(tb
[IFLA_GSO_MAX_SIZE
]));
1050 if (tb
[IFLA_GSO_MAX_SEGS
])
1051 print_uint(PRINT_ANY
,
1054 rta_getattr_u32(tb
[IFLA_GSO_MAX_SEGS
]));
1056 if (tb
[IFLA_PHYS_PORT_NAME
])
1057 print_string(PRINT_ANY
,
1060 rta_getattr_str(tb
[IFLA_PHYS_PORT_NAME
]));
1062 if (tb
[IFLA_PHYS_PORT_ID
]) {
1063 print_string(PRINT_ANY
,
1067 RTA_DATA(tb
[IFLA_PHYS_PORT_ID
]),
1068 RTA_PAYLOAD(tb
[IFLA_PHYS_PORT_ID
]),
1072 if (tb
[IFLA_PHYS_SWITCH_ID
]) {
1073 print_string(PRINT_ANY
,
1076 hexstring_n2a(RTA_DATA(tb
[IFLA_PHYS_SWITCH_ID
]),
1077 RTA_PAYLOAD(tb
[IFLA_PHYS_SWITCH_ID
]),
1082 if ((do_link
|| show_details
) && tb
[IFLA_IFALIAS
]) {
1083 print_string(PRINT_FP
, NULL
, "%s ", _SL_
);
1084 print_string(PRINT_ANY
,
1087 rta_getattr_str(tb
[IFLA_IFALIAS
]));
1090 if ((do_link
|| show_details
) && tb
[IFLA_XDP
])
1091 xdp_dump(fp
, tb
[IFLA_XDP
], true, true);
1093 if (do_link
&& show_stats
) {
1095 __print_link_stats(fp
, tb
);
1098 if ((do_link
|| show_details
) && tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
1099 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
1100 int rem
= RTA_PAYLOAD(vflist
);
1102 open_json_array(PRINT_JSON
, "vfinfo_list");
1103 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
1104 open_json_object(NULL
);
1105 print_vfinfo(fp
, i
);
1106 close_json_object();
1108 close_json_array(PRINT_JSON
, NULL
);
1111 print_string(PRINT_FP
, NULL
, "%s", "\n");
1116 static int flush_update(void)
1120 * Note that the kernel may delete multiple addresses for one
1121 * delete request (e.g. if ipv4 address promotion is disabled).
1122 * Since a flush operation is really a series of delete requests
1123 * its possible that we may request an address delete that has
1124 * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL
1125 * errors returned from a flush request
1127 if ((rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) &&
1128 (errno
!= EADDRNOTAVAIL
)) {
1129 perror("Failed to send flush request");
1136 static int set_lifetime(unsigned int *lifetime
, char *argv
)
1138 if (strcmp(argv
, "forever") == 0)
1139 *lifetime
= INFINITY_LIFE_TIME
;
1140 else if (get_u32(lifetime
, argv
, 0))
1146 static unsigned int get_ifa_flags(struct ifaddrmsg
*ifa
,
1147 struct rtattr
*ifa_flags_attr
)
1149 return ifa_flags_attr
? rta_getattr_u32(ifa_flags_attr
) :
1153 /* Mapping from argument to address flag mask */
1154 static const struct {
1156 unsigned long value
;
1157 } ifa_flag_names
[] = {
1158 { "secondary", IFA_F_SECONDARY
},
1159 { "temporary", IFA_F_SECONDARY
},
1160 { "nodad", IFA_F_NODAD
},
1161 { "optimistic", IFA_F_OPTIMISTIC
},
1162 { "dadfailed", IFA_F_DADFAILED
},
1163 { "home", IFA_F_HOMEADDRESS
},
1164 { "deprecated", IFA_F_DEPRECATED
},
1165 { "tentative", IFA_F_TENTATIVE
},
1166 { "permanent", IFA_F_PERMANENT
},
1167 { "mngtmpaddr", IFA_F_MANAGETEMPADDR
},
1168 { "noprefixroute", IFA_F_NOPREFIXROUTE
},
1169 { "autojoin", IFA_F_MCAUTOJOIN
},
1170 { "stable-privacy", IFA_F_STABLE_PRIVACY
},
1173 static void print_ifa_flags(FILE *fp
, const struct ifaddrmsg
*ifa
,
1178 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_names
); i
++) {
1179 unsigned long mask
= ifa_flag_names
[i
].value
;
1181 if (mask
== IFA_F_PERMANENT
) {
1182 if (!(flags
& mask
))
1183 print_bool(PRINT_ANY
,
1184 "dynamic", "dynamic ", true);
1185 } else if (flags
& mask
) {
1186 if (mask
== IFA_F_SECONDARY
&&
1187 ifa
->ifa_family
== AF_INET6
) {
1188 print_bool(PRINT_ANY
,
1189 "temporary", "temporary ", true);
1191 print_string(PRINT_FP
, NULL
,
1192 "%s ", ifa_flag_names
[i
].name
);
1193 print_bool(PRINT_JSON
,
1194 ifa_flag_names
[i
].name
, NULL
, true);
1202 if (is_json_context()) {
1205 snprintf(b1
, sizeof(b1
), "%02x", flags
);
1206 print_string(PRINT_JSON
, "ifa_flags", NULL
, b1
);
1208 fprintf(fp
, "flags %02x ", flags
);
1214 static int get_filter(const char *arg
)
1219 if (arg
[0] == '-') {
1225 if (strcmp(arg
, "dynamic") == 0) {
1228 } else if (strcmp(arg
, "primary") == 0) {
1233 for (i
= 0; i
< ARRAY_SIZE(ifa_flag_names
); i
++) {
1234 if (strcmp(arg
, ifa_flag_names
[i
].name
))
1238 filter
.flags
&= ~ifa_flag_names
[i
].value
;
1240 filter
.flags
|= ifa_flag_names
[i
].value
;
1241 filter
.flagmask
|= ifa_flag_names
[i
].value
;
1247 static int ifa_label_match_rta(int ifindex
, const struct rtattr
*rta
)
1255 label
= RTA_DATA(rta
);
1257 label
= ll_index_to_name(ifindex
);
1259 return fnmatch(filter
.label
, label
, 0);
1262 int print_addrinfo(struct nlmsghdr
*n
, void *arg
)
1265 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1266 int len
= n
->nlmsg_len
;
1267 unsigned int ifa_flags
;
1268 struct rtattr
*rta_tb
[IFA_MAX
+1];
1272 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
1274 len
-= NLMSG_LENGTH(sizeof(*ifa
));
1276 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
1280 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
1283 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
),
1284 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
1286 ifa_flags
= get_ifa_flags(ifa
, rta_tb
[IFA_FLAGS
]);
1288 if (!rta_tb
[IFA_LOCAL
])
1289 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
1290 if (!rta_tb
[IFA_ADDRESS
])
1291 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
1293 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
1295 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1297 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1300 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1303 if (ifa_label_match_rta(ifa
->ifa_index
, rta_tb
[IFA_LABEL
]))
1306 if (inet_addr_match_rta(&filter
.pfx
, rta_tb
[IFA_LOCAL
]))
1309 if (filter
.flushb
) {
1310 struct nlmsghdr
*fn
;
1312 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
1316 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
1317 memcpy(fn
, n
, n
->nlmsg_len
);
1318 fn
->nlmsg_type
= RTM_DELADDR
;
1319 fn
->nlmsg_flags
= NLM_F_REQUEST
;
1320 fn
->nlmsg_seq
= ++rth
.seq
;
1321 filter
.flushp
= (((char *)fn
) + n
->nlmsg_len
) - filter
.flushb
;
1327 if (n
->nlmsg_type
== RTM_DELADDR
)
1328 print_bool(PRINT_ANY
, "deleted", "Deleted ", true);
1333 if (filter
.oneline
|| filter
.flushb
) {
1334 const char *dev
= ll_index_to_name(ifa
->ifa_index
);
1336 if (is_json_context()) {
1337 print_int(PRINT_JSON
,
1338 "index", NULL
, ifa
->ifa_index
);
1339 print_string(PRINT_JSON
, "dev", NULL
, dev
);
1341 fprintf(fp
, "%u: %s", ifa
->ifa_index
, dev
);
1345 name
= family_name(ifa
->ifa_family
);
1347 print_string(PRINT_ANY
, "family", " %s ", name
);
1349 print_int(PRINT_ANY
, "family_index", " family %d ",
1354 if (rta_tb
[IFA_LOCAL
]) {
1355 print_color_string(PRINT_ANY
,
1356 ifa_family_color(ifa
->ifa_family
),
1358 format_host_rta(ifa
->ifa_family
,
1359 rta_tb
[IFA_LOCAL
]));
1360 if (rta_tb
[IFA_ADDRESS
] &&
1361 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]),
1362 RTA_DATA(rta_tb
[IFA_LOCAL
]),
1363 ifa
->ifa_family
== AF_INET
? 4 : 16)) {
1364 print_string(PRINT_FP
, NULL
, " %s ", "peer");
1365 print_color_string(PRINT_ANY
,
1366 ifa_family_color(ifa
->ifa_family
),
1369 format_host_rta(ifa
->ifa_family
,
1370 rta_tb
[IFA_ADDRESS
]));
1372 print_int(PRINT_ANY
, "prefixlen", "/%d ", ifa
->ifa_prefixlen
);
1374 if (rta_tb
[IFA_RT_PRIORITY
])
1375 print_uint(PRINT_ANY
, "metric", "metric %u ",
1376 rta_getattr_u32(rta_tb
[IFA_RT_PRIORITY
]));
1382 if (rta_tb
[IFA_BROADCAST
]) {
1383 print_string(PRINT_FP
, NULL
, "%s ", "brd");
1384 print_color_string(PRINT_ANY
,
1385 ifa_family_color(ifa
->ifa_family
),
1388 format_host_rta(ifa
->ifa_family
,
1389 rta_tb
[IFA_BROADCAST
]));
1392 if (rta_tb
[IFA_ANYCAST
]) {
1393 print_string(PRINT_FP
, NULL
, "%s ", "any");
1394 print_color_string(PRINT_ANY
,
1395 ifa_family_color(ifa
->ifa_family
),
1398 format_host_rta(ifa
->ifa_family
,
1399 rta_tb
[IFA_ANYCAST
]));
1402 print_string(PRINT_ANY
,
1405 rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
1407 print_ifa_flags(fp
, ifa
, ifa_flags
);
1409 if (rta_tb
[IFA_LABEL
])
1410 print_string(PRINT_ANY
,
1413 rta_getattr_str(rta_tb
[IFA_LABEL
]));
1415 if (rta_tb
[IFA_CACHEINFO
]) {
1416 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
1419 print_string(PRINT_FP
, NULL
, " valid_lft ", NULL
);
1421 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
) {
1422 print_uint(PRINT_JSON
,
1424 NULL
, INFINITY_LIFE_TIME
);
1425 print_string(PRINT_FP
, NULL
, "%s", "forever");
1427 print_uint(PRINT_ANY
,
1428 "valid_life_time", "%usec", ci
->ifa_valid
);
1431 print_string(PRINT_FP
, NULL
, " preferred_lft ", NULL
);
1432 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
) {
1433 print_uint(PRINT_JSON
,
1434 "preferred_life_time",
1435 NULL
, INFINITY_LIFE_TIME
);
1436 print_string(PRINT_FP
, NULL
, "%s", "forever");
1438 if (ifa_flags
& IFA_F_DEPRECATED
)
1439 print_int(PRINT_ANY
,
1440 "preferred_life_time",
1444 print_uint(PRINT_ANY
,
1445 "preferred_life_time",
1450 print_string(PRINT_FP
, NULL
, "%s", "\n");
1456 static int print_selected_addrinfo(struct ifinfomsg
*ifi
,
1457 struct nlmsg_list
*ainfo
, FILE *fp
)
1459 open_json_array(PRINT_JSON
, "addr_info");
1460 for ( ; ainfo
; ainfo
= ainfo
->next
) {
1461 struct nlmsghdr
*n
= &ainfo
->h
;
1462 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1464 if (n
->nlmsg_type
!= RTM_NEWADDR
)
1467 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifa
)))
1470 if (ifa
->ifa_index
!= ifi
->ifi_index
||
1471 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
1474 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
1477 open_json_object(NULL
);
1478 print_addrinfo(n
, fp
);
1479 close_json_object();
1481 close_json_array(PRINT_JSON
, NULL
);
1484 print_string(PRINT_FP
, NULL
, "%s", "\n");
1491 static int store_nlmsg(struct nlmsghdr
*n
, void *arg
)
1493 struct nlmsg_chain
*lchain
= (struct nlmsg_chain
*)arg
;
1494 struct nlmsg_list
*h
;
1496 h
= malloc(n
->nlmsg_len
+sizeof(void *));
1500 memcpy(&h
->h
, n
, n
->nlmsg_len
);
1504 lchain
->tail
->next
= h
;
1509 ll_remember_index(n
, NULL
);
1513 static __u32 ipadd_dump_magic
= 0x47361222;
1515 static int ipadd_save_prep(void)
1519 if (isatty(STDOUT_FILENO
)) {
1520 fprintf(stderr
, "Not sending a binary stream to stdout\n");
1524 ret
= write(STDOUT_FILENO
, &ipadd_dump_magic
, sizeof(ipadd_dump_magic
));
1525 if (ret
!= sizeof(ipadd_dump_magic
)) {
1526 fprintf(stderr
, "Can't write magic to dump file\n");
1533 static int ipadd_dump_check_magic(void)
1538 if (isatty(STDIN_FILENO
)) {
1539 fprintf(stderr
, "Can't restore address dump from a terminal\n");
1543 ret
= fread(&magic
, sizeof(magic
), 1, stdin
);
1544 if (magic
!= ipadd_dump_magic
) {
1545 fprintf(stderr
, "Magic mismatch (%d elems, %x magic)\n", ret
, magic
);
1552 static int save_nlmsg(struct nlmsghdr
*n
, void *arg
)
1556 ret
= write(STDOUT_FILENO
, n
, n
->nlmsg_len
);
1557 if ((ret
> 0) && (ret
!= n
->nlmsg_len
)) {
1558 fprintf(stderr
, "Short write while saving nlmsg\n");
1562 return ret
== n
->nlmsg_len
? 0 : ret
;
1565 static int show_handler(struct rtnl_ctrl_data
*ctrl
,
1566 struct nlmsghdr
*n
, void *arg
)
1568 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1570 open_json_object(NULL
);
1571 print_int(PRINT_ANY
, "index", "if%d:\n", ifa
->ifa_index
);
1572 print_addrinfo(n
, stdout
);
1573 close_json_object();
1577 static int ipaddr_showdump(void)
1581 if (ipadd_dump_check_magic())
1585 open_json_object(NULL
);
1586 open_json_array(PRINT_JSON
, "addr_info");
1588 err
= rtnl_from_file(stdin
, &show_handler
, NULL
);
1590 close_json_array(PRINT_JSON
, NULL
);
1591 close_json_object();
1597 static int restore_handler(struct rtnl_ctrl_data
*ctrl
,
1598 struct nlmsghdr
*n
, void *arg
)
1602 n
->nlmsg_flags
|= NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_ACK
;
1606 ret
= rtnl_talk(&rth
, n
, NULL
);
1607 if ((ret
< 0) && (errno
== EEXIST
))
1613 static int ipaddr_restore(void)
1615 if (ipadd_dump_check_magic())
1618 exit(rtnl_from_file(stdin
, &restore_handler
, NULL
));
1621 void free_nlmsg_chain(struct nlmsg_chain
*info
)
1623 struct nlmsg_list
*l
, *n
;
1625 for (l
= info
->head
; l
; l
= n
) {
1631 static void ipaddr_filter(struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
1633 struct nlmsg_list
*l
, **lp
;
1636 while ((l
= *lp
) != NULL
) {
1638 int missing_net_address
= 1;
1639 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1640 struct nlmsg_list
*a
;
1642 for (a
= ainfo
->head
; a
; a
= a
->next
) {
1643 struct nlmsghdr
*n
= &a
->h
;
1644 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1645 struct rtattr
*tb
[IFA_MAX
+ 1];
1646 unsigned int ifa_flags
;
1648 if (ifa
->ifa_index
!= ifi
->ifi_index
)
1650 missing_net_address
= 0;
1651 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1653 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1656 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
1657 ifa_flags
= get_ifa_flags(ifa
, tb
[IFA_FLAGS
]);
1659 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1662 if (ifa_label_match_rta(ifa
->ifa_index
, tb
[IFA_LABEL
]))
1666 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
1667 if (inet_addr_match_rta(&filter
.pfx
, tb
[IFA_LOCAL
]))
1673 if (missing_net_address
&&
1674 (filter
.family
== AF_UNSPEC
|| filter
.family
== AF_PACKET
))
1684 static int ipaddr_dump_filter(struct nlmsghdr
*nlh
, int reqlen
)
1686 struct ifaddrmsg
*ifa
= NLMSG_DATA(nlh
);
1688 ifa
->ifa_index
= filter
.ifindex
;
1693 static int ipaddr_flush(void)
1696 char flushb
[4096-512];
1698 filter
.flushb
= flushb
;
1700 filter
.flushe
= sizeof(flushb
);
1702 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
1703 if (rtnl_addrdump_req(&rth
, filter
.family
,
1704 ipaddr_dump_filter
) < 0) {
1705 perror("Cannot send dump request");
1709 if (rtnl_dump_filter_nc(&rth
, print_addrinfo
,
1710 stdout
, NLM_F_DUMP_INTR
) < 0) {
1711 fprintf(stderr
, "Flush terminated\n");
1714 if (filter
.flushed
== 0) {
1718 printf("Nothing to flush.\n");
1720 printf("*** Flush is complete after %d round%s ***\n", round
, round
> 1?"s":"");
1726 if (flush_update() < 0)
1730 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
1734 /* If we are flushing, and specifying primary, then we
1735 * want to flush only a single round. Otherwise, we'll
1736 * start flushing secondaries that were promoted to
1739 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
1742 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
1747 static int iplink_filter_req(struct nlmsghdr
*nlh
, int reqlen
)
1751 err
= addattr32(nlh
, reqlen
, IFLA_EXT_MASK
, RTEXT_FILTER_VF
);
1755 if (filter
.master
) {
1756 err
= addattr32(nlh
, reqlen
, IFLA_MASTER
, filter
.master
);
1762 struct rtattr
*linkinfo
;
1764 linkinfo
= addattr_nest(nlh
, reqlen
, IFLA_LINKINFO
);
1766 err
= addattr_l(nlh
, reqlen
, IFLA_INFO_KIND
, filter
.kind
,
1767 strlen(filter
.kind
));
1771 addattr_nest_end(nlh
, linkinfo
);
1777 static int ipaddr_link_get(int index
, struct nlmsg_chain
*linfo
)
1779 struct iplink_req req
= {
1780 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifinfomsg
)),
1781 .n
.nlmsg_flags
= NLM_F_REQUEST
,
1782 .n
.nlmsg_type
= RTM_GETLINK
,
1783 .i
.ifi_family
= filter
.family
,
1784 .i
.ifi_index
= index
,
1786 __u32 filt_mask
= RTEXT_FILTER_VF
;
1787 struct nlmsghdr
*answer
;
1790 filt_mask
|= RTEXT_FILTER_SKIP_STATS
;
1792 addattr32(&req
.n
, sizeof(req
), IFLA_EXT_MASK
, filt_mask
);
1794 if (rtnl_talk(&rth
, &req
.n
, &answer
) < 0) {
1795 perror("Cannot send link request");
1799 if (store_nlmsg(answer
, linfo
) < 0) {
1800 fprintf(stderr
, "Failed to process link information\n");
1807 /* fills in linfo with link data and optionally ainfo with address info
1808 * caller can walk lists as desired and must call free_nlmsg_chain for
1811 int ip_link_list(req_filter_fn_t filter_fn
, struct nlmsg_chain
*linfo
)
1813 if (rtnl_linkdump_req_filter_fn(&rth
, preferred_family
,
1815 perror("Cannot send dump request");
1819 if (rtnl_dump_filter(&rth
, store_nlmsg
, linfo
) < 0) {
1820 fprintf(stderr
, "Dump terminated\n");
1827 static int ip_addr_list(struct nlmsg_chain
*ainfo
)
1829 if (rtnl_addrdump_req(&rth
, filter
.family
, ipaddr_dump_filter
) < 0) {
1830 perror("Cannot send dump request");
1834 if (rtnl_dump_filter(&rth
, store_nlmsg
, ainfo
) < 0) {
1835 fprintf(stderr
, "Dump terminated\n");
1842 static int ipaddr_list_flush_or_save(int argc
, char **argv
, int action
)
1844 struct nlmsg_chain linfo
= { NULL
, NULL
};
1845 struct nlmsg_chain _ainfo
= { NULL
, NULL
}, *ainfo
= &_ainfo
;
1846 struct nlmsg_list
*l
;
1847 char *filter_dev
= NULL
;
1850 ipaddr_reset_filter(oneline
, 0);
1851 filter
.showqueue
= 1;
1852 filter
.family
= preferred_family
;
1854 if (action
== IPADD_FLUSH
) {
1856 fprintf(stderr
, "Flush requires arguments.\n");
1860 if (filter
.family
== AF_PACKET
) {
1861 fprintf(stderr
, "Cannot flush link addresses.\n");
1867 if (strcmp(*argv
, "to") == 0) {
1869 if (get_prefix(&filter
.pfx
, *argv
, filter
.family
))
1870 invarg("invalid \"to\"\n", *argv
);
1871 if (filter
.family
== AF_UNSPEC
)
1872 filter
.family
= filter
.pfx
.family
;
1873 } else if (strcmp(*argv
, "scope") == 0) {
1874 unsigned int scope
= 0;
1877 filter
.scopemask
= -1;
1878 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
1879 if (strcmp(*argv
, "all") != 0)
1880 invarg("invalid \"scope\"\n", *argv
);
1881 scope
= RT_SCOPE_NOWHERE
;
1882 filter
.scopemask
= 0;
1884 filter
.scope
= scope
;
1885 } else if (strcmp(*argv
, "up") == 0) {
1887 } else if (get_filter(*argv
) == 0) {
1889 } else if (strcmp(*argv
, "label") == 0) {
1891 filter
.label
= *argv
;
1892 } else if (strcmp(*argv
, "group") == 0) {
1894 if (rtnl_group_a2n(&filter
.group
, *argv
))
1895 invarg("Invalid \"group\" value\n", *argv
);
1896 } else if (strcmp(*argv
, "master") == 0) {
1900 ifindex
= ll_name_to_index(*argv
);
1902 invarg("Device does not exist\n", *argv
);
1903 filter
.master
= ifindex
;
1904 } else if (strcmp(*argv
, "vrf") == 0) {
1908 ifindex
= ll_name_to_index(*argv
);
1910 invarg("Not a valid VRF name\n", *argv
);
1911 if (!name_is_vrf(*argv
))
1912 invarg("Not a valid VRF name\n", *argv
);
1913 filter
.master
= ifindex
;
1914 } else if (strcmp(*argv
, "type") == 0) {
1918 soff
= strlen(*argv
) - strlen("_slave");
1919 if (!strcmp(*argv
+ soff
, "_slave")) {
1920 (*argv
)[soff
] = '\0';
1921 filter
.slave_kind
= *argv
;
1923 filter
.kind
= *argv
;
1926 if (strcmp(*argv
, "dev") == 0)
1928 else if (matches(*argv
, "help") == 0)
1931 duparg2("dev", *argv
);
1938 filter
.ifindex
= ll_name_to_index(filter_dev
);
1939 if (filter
.ifindex
<= 0) {
1940 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
1945 if (action
== IPADD_FLUSH
)
1946 return ipaddr_flush();
1948 if (action
== IPADD_SAVE
) {
1949 if (ipadd_save_prep())
1952 if (rtnl_addrdump_req(&rth
, preferred_family
,
1953 ipaddr_dump_filter
) < 0) {
1954 perror("Cannot send dump request");
1958 if (rtnl_dump_filter(&rth
, save_nlmsg
, stdout
) < 0) {
1959 fprintf(stderr
, "Save terminated\n");
1967 * Initialize a json_writer and open an array object
1968 * if -json was specified.
1973 * If only filter_dev present and none of the other
1974 * link filters are present, use RTM_GETLINK to get
1977 if (filter_dev
&& filter
.group
== -1 && do_link
== 1) {
1978 if (iplink_get(filter_dev
, RTEXT_FILTER_VF
) < 0) {
1979 perror("Cannot send link get request");
1987 if (filter
.ifindex
) {
1988 if (ipaddr_link_get(filter
.ifindex
, &linfo
) != 0)
1991 if (ip_link_list(iplink_filter_req
, &linfo
) != 0)
1995 if (filter
.family
!= AF_PACKET
) {
1999 if (ip_addr_list(ainfo
) != 0)
2002 ipaddr_filter(&linfo
, ainfo
);
2005 for (l
= linfo
.head
; l
; l
= l
->next
) {
2006 struct nlmsghdr
*n
= &l
->h
;
2007 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
2010 open_json_object(NULL
);
2011 if (brief
|| !no_link
)
2012 res
= print_linkinfo(n
, stdout
);
2013 if (res
>= 0 && filter
.family
!= AF_PACKET
)
2014 print_selected_addrinfo(ifi
, ainfo
->head
, stdout
);
2015 if (res
> 0 && !do_link
&& show_stats
)
2016 print_link_stats(stdout
, n
);
2017 close_json_object();
2022 free_nlmsg_chain(ainfo
);
2023 free_nlmsg_chain(&linfo
);
2029 ipaddr_loop_each_vf(struct rtattr
*tb
[], int vfnum
, int *min
, int *max
)
2031 struct rtattr
*vflist
= tb
[IFLA_VFINFO_LIST
];
2032 struct rtattr
*i
, *vf
[IFLA_VF_MAX
+1];
2033 struct ifla_vf_rate
*vf_rate
;
2036 rem
= RTA_PAYLOAD(vflist
);
2038 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
2039 parse_rtattr_nested(vf
, IFLA_VF_MAX
, i
);
2041 if (!vf
[IFLA_VF_RATE
]) {
2042 fprintf(stderr
, "VF min/max rate API not supported\n");
2046 vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
2047 if (vf_rate
->vf
== vfnum
) {
2048 *min
= vf_rate
->min_tx_rate
;
2049 *max
= vf_rate
->max_tx_rate
;
2053 fprintf(stderr
, "Cannot find VF %d\n", vfnum
);
2057 void ipaddr_get_vf_rate(int vfnum
, int *min
, int *max
, const char *dev
)
2059 struct nlmsg_chain linfo
= { NULL
, NULL
};
2060 struct rtattr
*tb
[IFLA_MAX
+1];
2061 struct ifinfomsg
*ifi
;
2062 struct nlmsg_list
*l
;
2066 idx
= ll_name_to_index(dev
);
2068 fprintf(stderr
, "Device %s does not exist\n", dev
);
2072 if (rtnl_linkdump_req(&rth
, AF_UNSPEC
) < 0) {
2073 perror("Cannot send dump request");
2076 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
2077 fprintf(stderr
, "Dump terminated\n");
2080 for (l
= linfo
.head
; l
; l
= l
->next
) {
2082 ifi
= NLMSG_DATA(n
);
2084 len
= n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
2085 if (len
< 0 || (idx
&& idx
!= ifi
->ifi_index
))
2088 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
2090 if ((tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
])) {
2091 ipaddr_loop_each_vf(tb
, vfnum
, min
, max
);
2097 int ipaddr_list_link(int argc
, char **argv
)
2099 preferred_family
= AF_PACKET
;
2101 return ipaddr_list_flush_or_save(argc
, argv
, IPADD_LIST
);
2104 void ipaddr_reset_filter(int oneline
, int ifindex
)
2106 memset(&filter
, 0, sizeof(filter
));
2107 filter
.oneline
= oneline
;
2108 filter
.ifindex
= ifindex
;
2112 static int default_scope(inet_prefix
*lcl
)
2114 if (lcl
->family
== AF_INET
) {
2115 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
2116 return RT_SCOPE_HOST
;
2121 static bool ipaddr_is_multicast(inet_prefix
*a
)
2123 if (a
->family
== AF_INET
)
2124 return IN_MULTICAST(ntohl(a
->data
[0]));
2125 else if (a
->family
== AF_INET6
)
2126 return IN6_IS_ADDR_MULTICAST(a
->data
);
2131 static bool is_valid_label(const char *dev
, const char *label
)
2133 size_t len
= strlen(dev
);
2135 if (strncmp(label
, dev
, len
) != 0)
2138 return label
[len
] == '\0' || label
[len
] == ':';
2141 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
2145 struct ifaddrmsg ifa
;
2148 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
)),
2149 .n
.nlmsg_flags
= NLM_F_REQUEST
| flags
,
2150 .n
.nlmsg_type
= cmd
,
2151 .ifa
.ifa_family
= preferred_family
,
2155 char *lcl_arg
= NULL
;
2156 char *valid_lftp
= NULL
;
2157 char *preferred_lftp
= NULL
;
2158 inet_prefix lcl
= {};
2165 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
2166 __u32 valid_lft
= INFINITY_LIFE_TIME
;
2167 unsigned int ifa_flags
= 0;
2170 if (strcmp(*argv
, "peer") == 0 ||
2171 strcmp(*argv
, "remote") == 0) {
2175 duparg("peer", *argv
);
2176 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
2177 peer_len
= peer
.bytelen
;
2178 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2179 req
.ifa
.ifa_family
= peer
.family
;
2180 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
2181 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
2182 } else if (matches(*argv
, "broadcast") == 0 ||
2183 strcmp(*argv
, "brd") == 0) {
2188 duparg("broadcast", *argv
);
2189 if (strcmp(*argv
, "+") == 0)
2191 else if (strcmp(*argv
, "-") == 0)
2194 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
2195 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2196 req
.ifa
.ifa_family
= addr
.family
;
2197 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
2198 brd_len
= addr
.bytelen
;
2200 } else if (strcmp(*argv
, "anycast") == 0) {
2205 duparg("anycast", *argv
);
2206 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
2207 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2208 req
.ifa
.ifa_family
= addr
.family
;
2209 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
2210 any_len
= addr
.bytelen
;
2211 } else if (strcmp(*argv
, "scope") == 0) {
2212 unsigned int scope
= 0;
2215 if (rtnl_rtscope_a2n(&scope
, *argv
))
2216 invarg("invalid scope value.", *argv
);
2217 req
.ifa
.ifa_scope
= scope
;
2219 } else if (strcmp(*argv
, "dev") == 0) {
2222 } else if (strcmp(*argv
, "label") == 0) {
2225 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
2226 } else if (matches(*argv
, "metric") == 0 ||
2227 matches(*argv
, "priority") == 0 ||
2228 matches(*argv
, "preference") == 0) {
2232 if (get_u32(&metric
, *argv
, 0))
2233 invarg("\"metric\" value is invalid\n", *argv
);
2234 addattr32(&req
.n
, sizeof(req
), IFA_RT_PRIORITY
, metric
);
2235 } else if (matches(*argv
, "valid_lft") == 0) {
2237 duparg("valid_lft", *argv
);
2240 if (set_lifetime(&valid_lft
, *argv
))
2241 invarg("valid_lft value", *argv
);
2242 } else if (matches(*argv
, "preferred_lft") == 0) {
2244 duparg("preferred_lft", *argv
);
2246 preferred_lftp
= *argv
;
2247 if (set_lifetime(&preferred_lft
, *argv
))
2248 invarg("preferred_lft value", *argv
);
2249 } else if (strcmp(*argv
, "home") == 0) {
2250 if (req
.ifa
.ifa_family
== AF_INET6
)
2251 ifa_flags
|= IFA_F_HOMEADDRESS
;
2253 fprintf(stderr
, "Warning: home option can be set only for IPv6 addresses\n");
2254 } else if (strcmp(*argv
, "nodad") == 0) {
2255 if (req
.ifa
.ifa_family
== AF_INET6
)
2256 ifa_flags
|= IFA_F_NODAD
;
2258 fprintf(stderr
, "Warning: nodad option can be set only for IPv6 addresses\n");
2259 } else if (strcmp(*argv
, "mngtmpaddr") == 0) {
2260 if (req
.ifa
.ifa_family
== AF_INET6
)
2261 ifa_flags
|= IFA_F_MANAGETEMPADDR
;
2263 fprintf(stderr
, "Warning: mngtmpaddr option can be set only for IPv6 addresses\n");
2264 } else if (strcmp(*argv
, "noprefixroute") == 0) {
2265 ifa_flags
|= IFA_F_NOPREFIXROUTE
;
2266 } else if (strcmp(*argv
, "autojoin") == 0) {
2267 ifa_flags
|= IFA_F_MCAUTOJOIN
;
2269 if (strcmp(*argv
, "local") == 0)
2271 if (matches(*argv
, "help") == 0)
2274 duparg2("local", *argv
);
2276 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
2277 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
2278 req
.ifa
.ifa_family
= lcl
.family
;
2279 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
2280 local_len
= lcl
.bytelen
;
2284 if (ifa_flags
<= 0xff)
2285 req
.ifa
.ifa_flags
= ifa_flags
;
2287 addattr32(&req
.n
, sizeof(req
), IFA_FLAGS
, ifa_flags
);
2290 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
2293 if (l
&& !is_valid_label(d
, l
)) {
2295 "\"label\" (%s) must match \"dev\" (%s) or be prefixed by \"dev\" with a colon.\n",
2300 if (peer_len
== 0 && local_len
) {
2301 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
2303 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n"
2304 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n"
2305 " This special behaviour is likely to disappear in further releases,\n"
2306 " fix your scripts!\n", lcl_arg
, local_len
*8);
2309 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
2312 if (req
.ifa
.ifa_prefixlen
== 0)
2313 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
2315 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
2319 if (req
.ifa
.ifa_family
!= AF_INET
) {
2320 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
2324 if (brd
.bitlen
<= 30) {
2325 for (i
= 31; i
>= brd
.bitlen
; i
--) {
2327 brd
.data
[0] |= htonl(1<<(31-i
));
2329 brd
.data
[0] &= ~htonl(1<<(31-i
));
2331 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
2332 brd_len
= brd
.bytelen
;
2335 if (!scoped
&& cmd
!= RTM_DELADDR
)
2336 req
.ifa
.ifa_scope
= default_scope(&lcl
);
2338 req
.ifa
.ifa_index
= ll_name_to_index(d
);
2339 if (!req
.ifa
.ifa_index
)
2342 if (valid_lftp
|| preferred_lftp
) {
2343 struct ifa_cacheinfo cinfo
= {};
2346 fprintf(stderr
, "valid_lft is zero\n");
2349 if (valid_lft
< preferred_lft
) {
2350 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
2354 cinfo
.ifa_prefered
= preferred_lft
;
2355 cinfo
.ifa_valid
= valid_lft
;
2356 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
2360 if ((ifa_flags
& IFA_F_MCAUTOJOIN
) && !ipaddr_is_multicast(&lcl
)) {
2361 fprintf(stderr
, "autojoin needs multicast address\n");
2365 if (rtnl_talk(&rth
, &req
.n
, NULL
) < 0)
2371 int do_ipaddr(int argc
, char **argv
)
2374 return ipaddr_list_flush_or_save(0, NULL
, IPADD_LIST
);
2375 if (matches(*argv
, "add") == 0)
2376 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
2377 if (matches(*argv
, "change") == 0 ||
2378 strcmp(*argv
, "chg") == 0)
2379 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
2380 if (matches(*argv
, "replace") == 0)
2381 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
2382 if (matches(*argv
, "delete") == 0)
2383 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
2384 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
2385 || matches(*argv
, "lst") == 0)
2386 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_LIST
);
2387 if (matches(*argv
, "flush") == 0)
2388 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_FLUSH
);
2389 if (matches(*argv
, "save") == 0)
2390 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_SAVE
);
2391 if (matches(*argv
, "showdump") == 0)
2392 return ipaddr_showdump();
2393 if (matches(*argv
, "restore") == 0)
2394 return ipaddr_restore();
2395 if (matches(*argv
, "help") == 0)
2397 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv
);