2 * ipaddress.c "ip address".
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
19 #include <sys/ioctl.h>
20 #include <sys/socket.h>
21 #include <sys/ioctl.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
28 #include <linux/netdevice.h>
29 #include <linux/if_arp.h>
30 #include <linux/sockios.h>
35 #include "ip_common.h"
65 static void usage(void) __attribute__((noreturn
));
67 static void usage(void)
72 fprintf(stderr
, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n");
73 fprintf(stderr
, " [ CONFFLAG-LIST ]\n");
74 fprintf(stderr
, " ip addr del IFADDR dev STRING [mngtmpaddr]\n");
75 fprintf(stderr
, " ip addr {show|save|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
76 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ] [up]\n");
77 fprintf(stderr
, " ip addr {showdump|restore}\n");
78 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
79 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
80 fprintf(stderr
, " [ label STRING ] [ scope SCOPE-ID ]\n");
81 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
82 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
83 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
84 fprintf(stderr
, " [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n");
85 fprintf(stderr
, " CONFFLAG-LIST ]\n");
86 fprintf(stderr
, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
87 fprintf(stderr
, "CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute ]\n");
88 fprintf(stderr
, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
89 fprintf(stderr
, "LFT := forever | SECONDS\n");
94 static void print_link_flags(FILE *fp
, unsigned flags
, unsigned mdown
)
97 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
98 fprintf(fp
, "NO-CARRIER%s", flags
? "," : "");
99 flags
&= ~IFF_RUNNING
;
100 #define _PF(f) if (flags&IFF_##f) { \
101 flags &= ~IFF_##f ; \
102 fprintf(fp, #f "%s", flags ? "," : ""); }
123 fprintf(fp
, "%x", flags
);
125 fprintf(fp
, ",M-DOWN");
129 static const char *oper_states
[] = {
130 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
131 "TESTING", "DORMANT", "UP"
134 static void print_operstate(FILE *f
, __u8 state
)
136 if (state
>= sizeof(oper_states
)/sizeof(oper_states
[0]))
137 fprintf(f
, "state %#x ", state
);
139 fprintf(f
, "state %s ", oper_states
[state
]);
142 int get_operstate(const char *name
)
146 for (i
= 0; i
< sizeof(oper_states
)/sizeof(oper_states
[0]); i
++)
147 if (strcasecmp(name
, oper_states
[i
]) == 0)
152 static void print_queuelen(FILE *f
, struct rtattr
*tb
[IFLA_MAX
+ 1])
157 qlen
= *(int *)RTA_DATA(tb
[IFLA_TXQLEN
]);
160 int s
= socket(AF_INET
, SOCK_STREAM
, 0);
165 memset(&ifr
, 0, sizeof(ifr
));
166 strcpy(ifr
.ifr_name
, rta_getattr_str(tb
[IFLA_IFNAME
]));
167 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
168 fprintf(f
, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno
));
176 fprintf(f
, "qlen %d", qlen
);
179 static const char *link_modes
[] = {
183 static void print_linkmode(FILE *f
, struct rtattr
*tb
)
185 unsigned int mode
= rta_getattr_u8(tb
);
187 if (mode
>= sizeof(link_modes
) / sizeof(link_modes
[0]))
188 fprintf(f
, "mode %d ", mode
);
190 fprintf(f
, "mode %s ", link_modes
[mode
]);
193 static char *parse_link_kind(struct rtattr
*tb
)
195 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
197 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
199 if (linkinfo
[IFLA_INFO_KIND
])
200 return RTA_DATA(linkinfo
[IFLA_INFO_KIND
]);
205 static void print_linktype(FILE *fp
, struct rtattr
*tb
)
207 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
208 struct link_util
*lu
;
209 struct link_util
*slave_lu
;
213 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
215 if (linkinfo
[IFLA_INFO_KIND
]) {
216 kind
= RTA_DATA(linkinfo
[IFLA_INFO_KIND
]);
218 fprintf(fp
, "%s", _SL_
);
219 fprintf(fp
, " %s ", kind
);
221 lu
= get_link_kind(kind
);
222 if (lu
&& lu
->print_opt
) {
223 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
225 if (linkinfo
[IFLA_INFO_DATA
]) {
226 parse_rtattr_nested(attr
, lu
->maxattr
,
227 linkinfo
[IFLA_INFO_DATA
]);
230 lu
->print_opt(lu
, fp
, data
);
232 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
234 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
238 if (linkinfo
[IFLA_INFO_SLAVE_KIND
]) {
239 slave_kind
= RTA_DATA(linkinfo
[IFLA_INFO_SLAVE_KIND
]);
241 fprintf(fp
, "%s", _SL_
);
242 fprintf(fp
, " %s_slave ", slave_kind
);
244 slave_lu
= get_link_slave_kind(slave_kind
);
245 if (slave_lu
&& slave_lu
->print_opt
) {
246 struct rtattr
*attr
[slave_lu
->maxattr
+1], **data
= NULL
;
248 if (linkinfo
[IFLA_INFO_SLAVE_DATA
]) {
249 parse_rtattr_nested(attr
, slave_lu
->maxattr
,
250 linkinfo
[IFLA_INFO_SLAVE_DATA
]);
253 slave_lu
->print_opt(slave_lu
, fp
, data
);
258 static void print_vfinfo(FILE *fp
, struct rtattr
*vfinfo
)
260 struct ifla_vf_mac
*vf_mac
;
261 struct ifla_vf_vlan
*vf_vlan
;
262 struct ifla_vf_rate
*vf_rate
;
263 struct ifla_vf_tx_rate
*vf_tx_rate
;
264 struct ifla_vf_spoofchk
*vf_spoofchk
;
265 struct ifla_vf_link_state
*vf_linkstate
;
266 struct rtattr
*vf
[IFLA_VF_MAX
+1];
270 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
271 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
275 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
277 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
278 vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
279 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
280 vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
282 /* Check if the spoof checking vf info type is supported by
285 tmp
= (struct rtattr
*)((char *)vf
[IFLA_VF_TX_RATE
] +
286 vf
[IFLA_VF_TX_RATE
]->rta_len
);
288 if (tmp
->rta_type
!= IFLA_VF_SPOOFCHK
)
291 vf_spoofchk
= RTA_DATA(vf
[IFLA_VF_SPOOFCHK
]);
294 /* Check if the link state vf info type is supported by
297 tmp
= (struct rtattr
*)((char *)vf
[IFLA_VF_SPOOFCHK
] +
298 vf
[IFLA_VF_SPOOFCHK
]->rta_len
);
300 if (tmp
->rta_type
!= IFLA_VF_LINK_STATE
)
303 vf_linkstate
= RTA_DATA(vf
[IFLA_VF_LINK_STATE
]);
307 fprintf(fp
, "\n vf %d MAC %s", vf_mac
->vf
,
308 ll_addr_n2a((unsigned char *)&vf_mac
->mac
,
309 ETH_ALEN
, 0, b1
, sizeof(b1
)));
311 fprintf(fp
, ", vlan %d", vf_vlan
->vlan
);
313 fprintf(fp
, ", qos %d", vf_vlan
->qos
);
314 if (vf_tx_rate
->rate
)
315 fprintf(fp
, ", tx rate %d (Mbps)", vf_tx_rate
->rate
);
316 if (vf_rate
->max_tx_rate
)
317 fprintf(fp
, ", max_tx_rate %dMbps", vf_rate
->max_tx_rate
);
318 if (vf_rate
->min_tx_rate
)
319 fprintf(fp
, ", min_tx_rate %dMbps", vf_rate
->min_tx_rate
);
320 if (vf_spoofchk
&& vf_spoofchk
->setting
!= -1) {
321 if (vf_spoofchk
->setting
)
322 fprintf(fp
, ", spoof checking on");
324 fprintf(fp
, ", spoof checking off");
327 if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_AUTO
)
328 fprintf(fp
, ", link-state auto");
329 else if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_ENABLE
)
330 fprintf(fp
, ", link-state enable");
332 fprintf(fp
, ", link-state disable");
336 static void print_num(FILE *fp
, unsigned width
, uint64_t count
)
338 const char *prefix
= "kMGTPE";
339 const unsigned int base
= use_iec
? 1024 : 1000;
342 uint8_t precision
= 2;
345 if (!human_readable
|| count
< base
) {
346 fprintf(fp
, "%-*"PRIu64
" ", width
, count
);
350 /* increase value by a factor of 1000/1024 and print
351 * if result is something a human can read */
354 if (count
/ base
< powi
)
362 /* try to guess a good number of digits for precision */
363 for (; precision
> 0; precision
--) {
365 if (count
/ powi
< powj
)
369 snprintf(buf
, sizeof(buf
), "%.*f%c%s", precision
,
370 (double) count
/ powi
, *prefix
, use_iec
? "i" : "");
372 fprintf(fp
, "%-*s ", width
, buf
);
375 static void print_link_stats64(FILE *fp
, const struct rtnl_link_stats64
*s
,
376 const struct rtattr
*carrier_changes
)
379 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
380 s
->rx_compressed
? "compressed" : "", _SL_
);
383 print_num(fp
, 10, s
->rx_bytes
);
384 print_num(fp
, 8, s
->rx_packets
);
385 print_num(fp
, 7, s
->rx_errors
);
386 print_num(fp
, 7, s
->rx_dropped
);
387 print_num(fp
, 7, s
->rx_over_errors
);
388 print_num(fp
, 7, s
->multicast
);
389 if (s
->rx_compressed
)
390 print_num(fp
, 7, s
->rx_compressed
);
393 if (show_stats
> 1) {
394 fprintf(fp
, "%s", _SL_
);
395 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
398 print_num(fp
, 8, s
->rx_length_errors
);
399 print_num(fp
, 7, s
->rx_crc_errors
);
400 print_num(fp
, 7, s
->rx_frame_errors
);
401 print_num(fp
, 7, s
->rx_fifo_errors
);
402 print_num(fp
, 7, s
->rx_missed_errors
);
404 fprintf(fp
, "%s", _SL_
);
407 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
408 s
->tx_compressed
? "compressed" : "", _SL_
);
412 print_num(fp
, 10, s
->tx_bytes
);
413 print_num(fp
, 8, s
->tx_packets
);
414 print_num(fp
, 7, s
->tx_errors
);
415 print_num(fp
, 7, s
->tx_dropped
);
416 print_num(fp
, 7, s
->tx_carrier_errors
);
417 print_num(fp
, 7, s
->collisions
);
418 if (s
->tx_compressed
)
419 print_num(fp
, 7, s
->tx_compressed
);
422 if (show_stats
> 1) {
423 fprintf(fp
, "%s", _SL_
);
424 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
426 fprintf(fp
, " transns");
427 fprintf(fp
, "%s", _SL_
);
430 print_num(fp
, 8, s
->tx_aborted_errors
);
431 print_num(fp
, 7, s
->tx_fifo_errors
);
432 print_num(fp
, 7, s
->tx_window_errors
);
433 print_num(fp
, 7, s
->tx_heartbeat_errors
);
435 print_num(fp
, 7, *(uint32_t*)RTA_DATA(carrier_changes
));
439 static void print_link_stats32(FILE *fp
, const struct rtnl_link_stats
*s
,
440 const struct rtattr
*carrier_changes
)
443 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
444 s
->rx_compressed
? "compressed" : "", _SL_
);
448 print_num(fp
, 10, s
->rx_bytes
);
449 print_num(fp
, 8, s
->rx_packets
);
450 print_num(fp
, 7, s
->rx_errors
);
451 print_num(fp
, 7, s
->rx_dropped
);
452 print_num(fp
, 7, s
->rx_over_errors
);
453 print_num(fp
, 7, s
->multicast
);
454 if (s
->rx_compressed
)
455 print_num(fp
, 7, s
->rx_compressed
);
458 if (show_stats
> 1) {
459 fprintf(fp
, "%s", _SL_
);
460 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
462 print_num(fp
, 8, s
->rx_length_errors
);
463 print_num(fp
, 7, s
->rx_crc_errors
);
464 print_num(fp
, 7, s
->rx_frame_errors
);
465 print_num(fp
, 7, s
->rx_fifo_errors
);
466 print_num(fp
, 7, s
->rx_missed_errors
);
468 fprintf(fp
, "%s", _SL_
);
471 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
472 s
->tx_compressed
? "compressed" : "", _SL_
);
475 print_num(fp
, 10, s
->tx_bytes
);
476 print_num(fp
, 8, s
->tx_packets
);
477 print_num(fp
, 7, s
->tx_errors
);
478 print_num(fp
, 7, s
->tx_dropped
);
479 print_num(fp
, 7, s
->tx_carrier_errors
);
480 print_num(fp
, 7, s
->collisions
);
481 if (s
->tx_compressed
)
482 print_num(fp
, 7, s
->tx_compressed
);
485 if (show_stats
> 1) {
486 fprintf(fp
, "%s", _SL_
);
487 fprintf(fp
, " TX errors: aborted fifo window heartbeat");
489 fprintf(fp
, " transns");
490 fprintf(fp
, "%s", _SL_
);
493 print_num(fp
, 8, s
->tx_aborted_errors
);
494 print_num(fp
, 7, s
->tx_fifo_errors
);
495 print_num(fp
, 7, s
->tx_window_errors
);
496 print_num(fp
, 7, s
->tx_heartbeat_errors
);
498 print_num(fp
, 7, *(uint32_t*)RTA_DATA(carrier_changes
));
502 static void __print_link_stats(FILE *fp
, struct rtattr
**tb
)
504 if (tb
[IFLA_STATS64
])
505 print_link_stats64(fp
, RTA_DATA(tb
[IFLA_STATS64
]),
506 tb
[IFLA_CARRIER_CHANGES
]);
507 else if (tb
[IFLA_STATS
])
508 print_link_stats32(fp
, RTA_DATA(tb
[IFLA_STATS
]),
509 tb
[IFLA_CARRIER_CHANGES
]);
512 static void print_link_stats(FILE *fp
, struct nlmsghdr
*n
)
514 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
515 struct rtattr
* tb
[IFLA_MAX
+1];
517 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
),
518 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
)));
519 __print_link_stats(fp
, tb
);
520 fprintf(fp
, "%s", _SL_
);
523 int print_linkinfo(const struct sockaddr_nl
*who
,
524 struct nlmsghdr
*n
, void *arg
)
526 FILE *fp
= (FILE*)arg
;
527 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
528 struct rtattr
* tb
[IFLA_MAX
+1];
529 int len
= n
->nlmsg_len
;
532 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
535 len
-= NLMSG_LENGTH(sizeof(*ifi
));
539 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
541 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
544 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
545 if (tb
[IFLA_IFNAME
] == NULL
) {
546 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
549 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
550 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
553 if (tb
[IFLA_GROUP
]) {
554 int group
= *(int*)RTA_DATA(tb
[IFLA_GROUP
]);
555 if (filter
.group
!= -1 && group
!= filter
.group
)
559 if (tb
[IFLA_MASTER
]) {
560 int master
= *(int*)RTA_DATA(tb
[IFLA_MASTER
]);
561 if (filter
.master
> 0 && master
!= filter
.master
)
564 else if (filter
.master
> 0)
568 if (tb
[IFLA_LINKINFO
]) {
569 char *kind
= parse_link_kind(tb
[IFLA_LINKINFO
]);
571 if (strcmp(kind
, filter
.kind
))
578 if (n
->nlmsg_type
== RTM_DELLINK
)
579 fprintf(fp
, "Deleted ");
581 fprintf(fp
, "%d: %s", ifi
->ifi_index
,
582 tb
[IFLA_IFNAME
] ? rta_getattr_str(tb
[IFLA_IFNAME
]) : "<nil>");
586 int iflink
= *(int*)RTA_DATA(tb
[IFLA_LINK
]);
588 fprintf(fp
, "@NONE: ");
590 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
591 m_flag
= ll_index_to_flags(iflink
);
592 m_flag
= !(m_flag
& IFF_UP
);
597 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
600 fprintf(fp
, "mtu %u ", *(int*)RTA_DATA(tb
[IFLA_MTU
]));
602 fprintf(fp
, "qdisc %s ", rta_getattr_str(tb
[IFLA_QDISC
]));
603 if (tb
[IFLA_MASTER
]) {
605 fprintf(fp
, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb
[IFLA_MASTER
]), b1
));
608 if (tb
[IFLA_PHYS_PORT_ID
]) {
610 fprintf(fp
, "portid %s ",
611 hexstring_n2a(RTA_DATA(tb
[IFLA_PHYS_PORT_ID
]),
612 RTA_PAYLOAD(tb
[IFLA_PHYS_PORT_ID
]),
616 if (tb
[IFLA_OPERSTATE
])
617 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
619 if (do_link
&& tb
[IFLA_LINKMODE
])
620 print_linkmode(fp
, tb
[IFLA_LINKMODE
]);
622 if (tb
[IFLA_GROUP
]) {
624 int group
= *(int*)RTA_DATA(tb
[IFLA_GROUP
]);
625 fprintf(fp
, "group %s ", rtnl_group_n2a(group
, b1
, sizeof(b1
)));
628 if (filter
.showqueue
)
629 print_queuelen(fp
, tb
);
631 if (!filter
.family
|| filter
.family
== AF_PACKET
|| show_details
) {
633 fprintf(fp
, "%s", _SL_
);
634 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
636 if (tb
[IFLA_ADDRESS
]) {
637 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
638 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
642 if (tb
[IFLA_BROADCAST
]) {
643 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
644 fprintf(fp
, " peer ");
646 fprintf(fp
, " brd ");
647 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
648 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
654 if (tb
[IFLA_PROMISCUITY
] && show_details
)
655 fprintf(fp
, " promiscuity %u ",
656 *(int*)RTA_DATA(tb
[IFLA_PROMISCUITY
]));
658 if (tb
[IFLA_LINKINFO
] && show_details
)
659 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
661 if ((do_link
|| show_details
) && tb
[IFLA_IFALIAS
]) {
662 fprintf(fp
, "%s alias %s", _SL_
,
663 rta_getattr_str(tb
[IFLA_IFALIAS
]));
666 if (do_link
&& show_stats
) {
667 fprintf(fp
, "%s", _SL_
);
668 __print_link_stats(fp
, tb
);
671 if ((do_link
|| show_details
) && tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
672 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
673 int rem
= RTA_PAYLOAD(vflist
);
674 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
))
683 static int flush_update(void)
685 if (rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) {
686 perror("Failed to send flush request");
693 static int set_lifetime(unsigned int *lifetime
, char *argv
)
695 if (strcmp(argv
, "forever") == 0)
696 *lifetime
= INFINITY_LIFE_TIME
;
697 else if (get_u32(lifetime
, argv
, 0))
703 static unsigned int get_ifa_flags(struct ifaddrmsg
*ifa
,
704 struct rtattr
*ifa_flags_attr
)
706 return ifa_flags_attr
? rta_getattr_u32(ifa_flags_attr
) :
710 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
714 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
715 int len
= n
->nlmsg_len
;
717 /* Use local copy of ifa_flags to not interfere with filtering code */
718 unsigned int ifa_flags
;
719 struct rtattr
* rta_tb
[IFA_MAX
+1];
723 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
725 len
-= NLMSG_LENGTH(sizeof(*ifa
));
727 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
731 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
734 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
),
735 n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
737 ifa_flags
= get_ifa_flags(ifa
, rta_tb
[IFA_FLAGS
]);
739 if (!rta_tb
[IFA_LOCAL
])
740 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
741 if (!rta_tb
[IFA_ADDRESS
])
742 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
744 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
746 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
748 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
753 if (rta_tb
[IFA_LABEL
])
754 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
756 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
757 if (fnmatch(filter
.label
, label
, 0) != 0)
760 if (filter
.pfx
.family
) {
761 if (rta_tb
[IFA_LOCAL
]) {
763 memset(&dst
, 0, sizeof(dst
));
764 dst
.family
= ifa
->ifa_family
;
765 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
766 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
771 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
776 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
780 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
781 memcpy(fn
, n
, n
->nlmsg_len
);
782 fn
->nlmsg_type
= RTM_DELADDR
;
783 fn
->nlmsg_flags
= NLM_F_REQUEST
;
784 fn
->nlmsg_seq
= ++rth
.seq
;
785 filter
.flushp
= (((char*)fn
) + n
->nlmsg_len
) - filter
.flushb
;
791 if (n
->nlmsg_type
== RTM_DELADDR
)
792 fprintf(fp
, "Deleted ");
794 if (filter
.oneline
|| filter
.flushb
)
795 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
796 if (ifa
->ifa_family
== AF_INET
)
797 fprintf(fp
, " inet ");
798 else if (ifa
->ifa_family
== AF_INET6
)
799 fprintf(fp
, " inet6 ");
800 else if (ifa
->ifa_family
== AF_DECnet
)
801 fprintf(fp
, " dnet ");
802 else if (ifa
->ifa_family
== AF_IPX
)
803 fprintf(fp
, " ipx ");
805 fprintf(fp
, " family %d ", ifa
->ifa_family
);
807 if (rta_tb
[IFA_LOCAL
]) {
808 fprintf(fp
, "%s", format_host(ifa
->ifa_family
,
809 RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]),
810 RTA_DATA(rta_tb
[IFA_LOCAL
]),
811 abuf
, sizeof(abuf
)));
813 if (rta_tb
[IFA_ADDRESS
] == NULL
||
814 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]), RTA_DATA(rta_tb
[IFA_LOCAL
]),
815 ifa
->ifa_family
== AF_INET
? 4 : 16) == 0) {
816 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
818 fprintf(fp
, " peer %s/%d ",
819 format_host(ifa
->ifa_family
,
820 RTA_PAYLOAD(rta_tb
[IFA_ADDRESS
]),
821 RTA_DATA(rta_tb
[IFA_ADDRESS
]),
827 if (rta_tb
[IFA_BROADCAST
]) {
828 fprintf(fp
, "brd %s ",
829 format_host(ifa
->ifa_family
,
830 RTA_PAYLOAD(rta_tb
[IFA_BROADCAST
]),
831 RTA_DATA(rta_tb
[IFA_BROADCAST
]),
832 abuf
, sizeof(abuf
)));
834 if (rta_tb
[IFA_ANYCAST
]) {
835 fprintf(fp
, "any %s ",
836 format_host(ifa
->ifa_family
,
837 RTA_PAYLOAD(rta_tb
[IFA_ANYCAST
]),
838 RTA_DATA(rta_tb
[IFA_ANYCAST
]),
839 abuf
, sizeof(abuf
)));
841 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
842 if (ifa_flags
& IFA_F_SECONDARY
) {
843 ifa_flags
&= ~IFA_F_SECONDARY
;
844 if (ifa
->ifa_family
== AF_INET6
)
845 fprintf(fp
, "temporary ");
847 fprintf(fp
, "secondary ");
849 if (ifa_flags
& IFA_F_TENTATIVE
) {
850 ifa_flags
&= ~IFA_F_TENTATIVE
;
851 fprintf(fp
, "tentative ");
853 if (ifa_flags
& IFA_F_DEPRECATED
) {
854 ifa_flags
&= ~IFA_F_DEPRECATED
;
856 fprintf(fp
, "deprecated ");
858 if (ifa_flags
& IFA_F_HOMEADDRESS
) {
859 ifa_flags
&= ~IFA_F_HOMEADDRESS
;
860 fprintf(fp
, "home ");
862 if (ifa_flags
& IFA_F_NODAD
) {
863 ifa_flags
&= ~IFA_F_NODAD
;
864 fprintf(fp
, "nodad ");
866 if (ifa_flags
& IFA_F_MANAGETEMPADDR
) {
867 ifa_flags
&= ~IFA_F_MANAGETEMPADDR
;
868 fprintf(fp
, "mngtmpaddr ");
870 if (ifa_flags
& IFA_F_NOPREFIXROUTE
) {
871 ifa_flags
&= ~IFA_F_NOPREFIXROUTE
;
872 fprintf(fp
, "noprefixroute ");
874 if (!(ifa_flags
& IFA_F_PERMANENT
)) {
875 fprintf(fp
, "dynamic ");
877 ifa_flags
&= ~IFA_F_PERMANENT
;
878 if (ifa_flags
& IFA_F_DADFAILED
) {
879 ifa_flags
&= ~IFA_F_DADFAILED
;
880 fprintf(fp
, "dadfailed ");
883 fprintf(fp
, "flags %02x ", ifa_flags
);
884 if (rta_tb
[IFA_LABEL
])
885 fprintf(fp
, "%s", rta_getattr_str(rta_tb
[IFA_LABEL
]));
886 if (rta_tb
[IFA_CACHEINFO
]) {
887 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
888 fprintf(fp
, "%s", _SL_
);
889 fprintf(fp
, " valid_lft ");
890 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
)
891 fprintf(fp
, "forever");
893 fprintf(fp
, "%usec", ci
->ifa_valid
);
894 fprintf(fp
, " preferred_lft ");
895 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
)
896 fprintf(fp
, "forever");
899 fprintf(fp
, "%dsec", ci
->ifa_prefered
);
901 fprintf(fp
, "%usec", ci
->ifa_prefered
);
909 static int print_addrinfo_primary(const struct sockaddr_nl
*who
,
910 struct nlmsghdr
*n
, void *arg
)
912 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
914 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
917 return print_addrinfo(who
, n
, arg
);
920 static int print_addrinfo_secondary(const struct sockaddr_nl
*who
,
921 struct nlmsghdr
*n
, void *arg
)
923 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
925 if (!(ifa
->ifa_flags
& IFA_F_SECONDARY
))
928 return print_addrinfo(who
, n
, arg
);
933 struct nlmsg_list
*next
;
939 struct nlmsg_list
*head
;
940 struct nlmsg_list
*tail
;
943 static int print_selected_addrinfo(int ifindex
, struct nlmsg_list
*ainfo
, FILE *fp
)
945 for ( ;ainfo
; ainfo
= ainfo
->next
) {
946 struct nlmsghdr
*n
= &ainfo
->h
;
947 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
949 if (n
->nlmsg_type
!= RTM_NEWADDR
)
952 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifa
)))
955 if (ifa
->ifa_index
!= ifindex
||
956 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
959 print_addrinfo(NULL
, n
, fp
);
965 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
968 struct nlmsg_chain
*lchain
= (struct nlmsg_chain
*)arg
;
969 struct nlmsg_list
*h
;
971 h
= malloc(n
->nlmsg_len
+sizeof(void*));
975 memcpy(&h
->h
, n
, n
->nlmsg_len
);
979 lchain
->tail
->next
= h
;
984 ll_remember_index(who
, n
, NULL
);
988 static __u32 ipadd_dump_magic
= 0x47361222;
990 static int ipadd_save_prep(void)
994 if (isatty(STDOUT_FILENO
)) {
995 fprintf(stderr
, "Not sending a binary stream to stdout\n");
999 ret
= write(STDOUT_FILENO
, &ipadd_dump_magic
, sizeof(ipadd_dump_magic
));
1000 if (ret
!= sizeof(ipadd_dump_magic
)) {
1001 fprintf(stderr
, "Can't write magic to dump file\n");
1008 static int ipadd_dump_check_magic(void)
1013 if (isatty(STDIN_FILENO
)) {
1014 fprintf(stderr
, "Can't restore addr dump from a terminal\n");
1018 ret
= fread(&magic
, sizeof(magic
), 1, stdin
);
1019 if (magic
!= ipadd_dump_magic
) {
1020 fprintf(stderr
, "Magic mismatch (%d elems, %x magic)\n", ret
, magic
);
1027 static int save_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
1032 ret
= write(STDOUT_FILENO
, n
, n
->nlmsg_len
);
1033 if ((ret
> 0) && (ret
!= n
->nlmsg_len
)) {
1034 fprintf(stderr
, "Short write while saving nlmsg\n");
1038 return ret
== n
->nlmsg_len
? 0 : ret
;
1041 static int show_handler(const struct sockaddr_nl
*nl
, struct nlmsghdr
*n
, void *arg
)
1043 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1045 printf("if%d:\n", ifa
->ifa_index
);
1046 print_addrinfo(NULL
, n
, stdout
);
1050 static int ipaddr_showdump(void)
1052 if (ipadd_dump_check_magic())
1055 exit(rtnl_from_file(stdin
, &show_handler
, NULL
));
1058 static int restore_handler(const struct sockaddr_nl
*nl
, struct nlmsghdr
*n
, void *arg
)
1062 n
->nlmsg_flags
|= NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_ACK
;
1066 ret
= rtnl_talk(&rth
, n
, 0, 0, n
);
1067 if ((ret
< 0) && (errno
== EEXIST
))
1073 static int ipaddr_restore(void)
1075 if (ipadd_dump_check_magic())
1078 exit(rtnl_from_file(stdin
, &restore_handler
, NULL
));
1081 static void free_nlmsg_chain(struct nlmsg_chain
*info
)
1083 struct nlmsg_list
*l
, *n
;
1085 for (l
= info
->head
; l
; l
= n
) {
1091 static void ipaddr_filter(struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
1093 struct nlmsg_list
*l
, **lp
;
1096 while ( (l
= *lp
) != NULL
) {
1098 int missing_net_address
= 1;
1099 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1100 struct nlmsg_list
*a
;
1102 for (a
= ainfo
->head
; a
; a
= a
->next
) {
1103 struct nlmsghdr
*n
= &a
->h
;
1104 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
1105 struct rtattr
*tb
[IFA_MAX
+ 1];
1106 unsigned int ifa_flags
;
1108 if (ifa
->ifa_index
!= ifi
->ifi_index
)
1110 missing_net_address
= 0;
1111 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
1113 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
1116 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
1117 ifa_flags
= get_ifa_flags(ifa
, tb
[IFA_FLAGS
]);
1119 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
1121 if (filter
.pfx
.family
|| filter
.label
) {
1123 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
1125 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
1127 memset(&dst
, 0, sizeof(dst
));
1128 dst
.family
= ifa
->ifa_family
;
1129 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
1130 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
1137 label
= RTA_DATA(tb
[IFA_LABEL
]);
1139 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
1140 if (fnmatch(filter
.label
, label
, 0) != 0)
1148 if (missing_net_address
&&
1149 (filter
.family
== AF_UNSPEC
|| filter
.family
== AF_PACKET
))
1159 static int ipaddr_flush(void)
1162 char flushb
[4096-512];
1164 filter
.flushb
= flushb
;
1166 filter
.flushe
= sizeof(flushb
);
1168 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
1169 const struct rtnl_dump_filter_arg a
[3] = {
1171 .filter
= print_addrinfo_secondary
,
1175 .filter
= print_addrinfo_primary
,
1183 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
1184 perror("Cannot send dump request");
1188 if (rtnl_dump_filter_l(&rth
, a
) < 0) {
1189 fprintf(stderr
, "Flush terminated\n");
1192 if (filter
.flushed
== 0) {
1196 printf("Nothing to flush.\n");
1198 printf("*** Flush is complete after %d round%s ***\n", round
, round
>1?"s":"");
1204 if (flush_update() < 0)
1208 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
1212 /* If we are flushing, and specifying primary, then we
1213 * want to flush only a single round. Otherwise, we'll
1214 * start flushing secondaries that were promoted to
1217 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
1220 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
1225 static int ipaddr_list_flush_or_save(int argc
, char **argv
, int action
)
1227 struct nlmsg_chain linfo
= { NULL
, NULL
};
1228 struct nlmsg_chain ainfo
= { NULL
, NULL
};
1229 struct nlmsg_list
*l
;
1230 char *filter_dev
= NULL
;
1233 ipaddr_reset_filter(oneline
, 0);
1234 filter
.showqueue
= 1;
1236 if (filter
.family
== AF_UNSPEC
)
1237 filter
.family
= preferred_family
;
1241 if (action
== IPADD_FLUSH
) {
1243 fprintf(stderr
, "Flush requires arguments.\n");
1247 if (filter
.family
== AF_PACKET
) {
1248 fprintf(stderr
, "Cannot flush link addresses.\n");
1254 if (strcmp(*argv
, "to") == 0) {
1256 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
1257 if (filter
.family
== AF_UNSPEC
)
1258 filter
.family
= filter
.pfx
.family
;
1259 } else if (strcmp(*argv
, "scope") == 0) {
1262 filter
.scopemask
= -1;
1263 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
1264 if (strcmp(*argv
, "all") != 0)
1265 invarg("invalid \"scope\"\n", *argv
);
1266 scope
= RT_SCOPE_NOWHERE
;
1267 filter
.scopemask
= 0;
1269 filter
.scope
= scope
;
1270 } else if (strcmp(*argv
, "up") == 0) {
1272 } else if (strcmp(*argv
, "dynamic") == 0) {
1273 filter
.flags
&= ~IFA_F_PERMANENT
;
1274 filter
.flagmask
|= IFA_F_PERMANENT
;
1275 } else if (strcmp(*argv
, "permanent") == 0) {
1276 filter
.flags
|= IFA_F_PERMANENT
;
1277 filter
.flagmask
|= IFA_F_PERMANENT
;
1278 } else if (strcmp(*argv
, "secondary") == 0 ||
1279 strcmp(*argv
, "temporary") == 0) {
1280 filter
.flags
|= IFA_F_SECONDARY
;
1281 filter
.flagmask
|= IFA_F_SECONDARY
;
1282 } else if (strcmp(*argv
, "primary") == 0) {
1283 filter
.flags
&= ~IFA_F_SECONDARY
;
1284 filter
.flagmask
|= IFA_F_SECONDARY
;
1285 } else if (strcmp(*argv
, "tentative") == 0) {
1286 filter
.flags
|= IFA_F_TENTATIVE
;
1287 filter
.flagmask
|= IFA_F_TENTATIVE
;
1288 } else if (strcmp(*argv
, "-tentative") == 0) {
1289 filter
.flags
&= ~IFA_F_TENTATIVE
;
1290 filter
.flagmask
|= IFA_F_TENTATIVE
;
1291 } else if (strcmp(*argv
, "deprecated") == 0) {
1292 filter
.flags
|= IFA_F_DEPRECATED
;
1293 filter
.flagmask
|= IFA_F_DEPRECATED
;
1294 } else if (strcmp(*argv
, "-deprecated") == 0) {
1295 filter
.flags
&= ~IFA_F_DEPRECATED
;
1296 filter
.flagmask
|= IFA_F_DEPRECATED
;
1297 } else if (strcmp(*argv
, "home") == 0) {
1298 filter
.flags
|= IFA_F_HOMEADDRESS
;
1299 filter
.flagmask
|= IFA_F_HOMEADDRESS
;
1300 } else if (strcmp(*argv
, "nodad") == 0) {
1301 filter
.flags
|= IFA_F_NODAD
;
1302 filter
.flagmask
|= IFA_F_NODAD
;
1303 } else if (strcmp(*argv
, "mngtmpaddr") == 0) {
1304 filter
.flags
|= IFA_F_MANAGETEMPADDR
;
1305 filter
.flagmask
|= IFA_F_MANAGETEMPADDR
;
1306 } else if (strcmp(*argv
, "noprefixroute") == 0) {
1307 filter
.flags
|= IFA_F_NOPREFIXROUTE
;
1308 filter
.flagmask
|= IFA_F_NOPREFIXROUTE
;
1309 } else if (strcmp(*argv
, "dadfailed") == 0) {
1310 filter
.flags
|= IFA_F_DADFAILED
;
1311 filter
.flagmask
|= IFA_F_DADFAILED
;
1312 } else if (strcmp(*argv
, "-dadfailed") == 0) {
1313 filter
.flags
&= ~IFA_F_DADFAILED
;
1314 filter
.flagmask
|= IFA_F_DADFAILED
;
1315 } else if (strcmp(*argv
, "label") == 0) {
1317 filter
.label
= *argv
;
1318 } else if (strcmp(*argv
, "group") == 0) {
1320 if (rtnl_group_a2n(&filter
.group
, *argv
))
1321 invarg("Invalid \"group\" value\n", *argv
);
1322 } else if (strcmp(*argv
, "master") == 0) {
1325 ifindex
= ll_name_to_index(*argv
);
1327 invarg("Device does not exist\n", *argv
);
1328 filter
.master
= ifindex
;
1329 } else if (do_link
&& strcmp(*argv
, "type") == 0) {
1331 filter
.kind
= *argv
;
1333 if (strcmp(*argv
, "dev") == 0) {
1336 if (matches(*argv
, "help") == 0)
1339 duparg2("dev", *argv
);
1346 filter
.ifindex
= ll_name_to_index(filter_dev
);
1347 if (filter
.ifindex
<= 0) {
1348 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
1353 if (action
== IPADD_FLUSH
)
1354 return ipaddr_flush();
1356 if (action
== IPADD_SAVE
) {
1357 if (ipadd_save_prep())
1360 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETADDR
) < 0) {
1361 perror("Cannot send dump request");
1365 if (rtnl_dump_filter(&rth
, save_nlmsg
, stdout
) < 0) {
1366 fprintf(stderr
, "Save terminated\n");
1374 * If only filter_dev present and none of the other
1375 * link filters are present, use RTM_GETLINK to get
1378 if (filter_dev
&& filter
.group
== -1 && do_link
== 1) {
1379 if (iplink_get(0, filter_dev
, RTEXT_FILTER_VF
) < 0) {
1380 perror("Cannot send link get request");
1386 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETLINK
) < 0) {
1387 perror("Cannot send dump request");
1391 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
1392 fprintf(stderr
, "Dump terminated\n");
1396 if (filter
.family
!= AF_PACKET
) {
1400 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
1401 perror("Cannot send dump request");
1405 if (rtnl_dump_filter(&rth
, store_nlmsg
, &ainfo
) < 0) {
1406 fprintf(stderr
, "Dump terminated\n");
1410 ipaddr_filter(&linfo
, &ainfo
);
1413 for (l
= linfo
.head
; l
; l
= l
->next
) {
1416 if (no_link
|| (res
= print_linkinfo(NULL
, &l
->h
, stdout
)) >= 0) {
1417 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1418 if (filter
.family
!= AF_PACKET
)
1419 print_selected_addrinfo(ifi
->ifi_index
,
1420 ainfo
.head
, stdout
);
1421 if (res
> 0 && !do_link
&& show_stats
)
1422 print_link_stats(stdout
, &l
->h
);
1427 free_nlmsg_chain(&ainfo
);
1428 free_nlmsg_chain(&linfo
);
1434 ipaddr_loop_each_vf(struct rtattr
*tb
[], int vfnum
, int *min
, int *max
)
1436 struct rtattr
*vflist
= tb
[IFLA_VFINFO_LIST
];
1437 struct rtattr
*i
, *vf
[IFLA_VF_MAX
+1];
1438 struct ifla_vf_rate
*vf_rate
;
1441 rem
= RTA_PAYLOAD(vflist
);
1443 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
1444 parse_rtattr_nested(vf
, IFLA_VF_MAX
, i
);
1445 vf_rate
= RTA_DATA(vf
[IFLA_VF_RATE
]);
1446 if (vf_rate
->vf
== vfnum
) {
1447 *min
= vf_rate
->min_tx_rate
;
1448 *max
= vf_rate
->max_tx_rate
;
1452 fprintf(stderr
, "Cannot find VF %d\n", vfnum
);
1456 void ipaddr_get_vf_rate(int vfnum
, int *min
, int *max
, int idx
)
1458 struct nlmsg_chain linfo
= { NULL
, NULL
};
1459 struct rtattr
*tb
[IFLA_MAX
+1];
1460 struct ifinfomsg
*ifi
;
1461 struct nlmsg_list
*l
;
1465 if (rtnl_wilddump_request(&rth
, AF_UNSPEC
, RTM_GETLINK
) < 0) {
1466 perror("Cannot send dump request");
1469 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
1470 fprintf(stderr
, "Dump terminated\n");
1473 for (l
= linfo
.head
; l
; l
= l
->next
) {
1475 ifi
= NLMSG_DATA(n
);
1477 len
= n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
));
1478 if (len
< 0 || (idx
&& idx
!= ifi
->ifi_index
))
1481 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
1483 if ((tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
])) {
1484 ipaddr_loop_each_vf(tb
, vfnum
, min
, max
);
1490 int ipaddr_list_link(int argc
, char **argv
)
1492 preferred_family
= AF_PACKET
;
1494 return ipaddr_list_flush_or_save(argc
, argv
, IPADD_LIST
);
1497 void ipaddr_reset_filter(int oneline
, int ifindex
)
1499 memset(&filter
, 0, sizeof(filter
));
1500 filter
.oneline
= oneline
;
1501 filter
.ifindex
= ifindex
;
1504 static int default_scope(inet_prefix
*lcl
)
1506 if (lcl
->family
== AF_INET
) {
1507 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
1508 return RT_SCOPE_HOST
;
1513 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
1517 struct ifaddrmsg ifa
;
1522 char *lcl_arg
= NULL
;
1523 char *valid_lftp
= NULL
;
1524 char *preferred_lftp
= NULL
;
1532 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
1533 __u32 valid_lft
= INFINITY_LIFE_TIME
;
1534 struct ifa_cacheinfo cinfo
;
1535 unsigned int ifa_flags
= 0;
1537 memset(&req
, 0, sizeof(req
));
1539 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1540 req
.n
.nlmsg_flags
= NLM_F_REQUEST
| flags
;
1541 req
.n
.nlmsg_type
= cmd
;
1542 req
.ifa
.ifa_family
= preferred_family
;
1545 if (strcmp(*argv
, "peer") == 0 ||
1546 strcmp(*argv
, "remote") == 0) {
1550 duparg("peer", *argv
);
1551 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
1552 peer_len
= peer
.bytelen
;
1553 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1554 req
.ifa
.ifa_family
= peer
.family
;
1555 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
1556 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
1557 } else if (matches(*argv
, "broadcast") == 0 ||
1558 strcmp(*argv
, "brd") == 0) {
1562 duparg("broadcast", *argv
);
1563 if (strcmp(*argv
, "+") == 0)
1565 else if (strcmp(*argv
, "-") == 0)
1568 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1569 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1570 req
.ifa
.ifa_family
= addr
.family
;
1571 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
1572 brd_len
= addr
.bytelen
;
1574 } else if (strcmp(*argv
, "anycast") == 0) {
1578 duparg("anycast", *argv
);
1579 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1580 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1581 req
.ifa
.ifa_family
= addr
.family
;
1582 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
1583 any_len
= addr
.bytelen
;
1584 } else if (strcmp(*argv
, "scope") == 0) {
1587 if (rtnl_rtscope_a2n(&scope
, *argv
))
1588 invarg("invalid scope value.", *argv
);
1589 req
.ifa
.ifa_scope
= scope
;
1591 } else if (strcmp(*argv
, "dev") == 0) {
1594 } else if (strcmp(*argv
, "label") == 0) {
1597 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
1598 } else if (matches(*argv
, "valid_lft") == 0) {
1600 duparg("valid_lft", *argv
);
1603 if (set_lifetime(&valid_lft
, *argv
))
1604 invarg("valid_lft value", *argv
);
1605 } else if (matches(*argv
, "preferred_lft") == 0) {
1607 duparg("preferred_lft", *argv
);
1609 preferred_lftp
= *argv
;
1610 if (set_lifetime(&preferred_lft
, *argv
))
1611 invarg("preferred_lft value", *argv
);
1612 } else if (strcmp(*argv
, "home") == 0) {
1613 ifa_flags
|= IFA_F_HOMEADDRESS
;
1614 } else if (strcmp(*argv
, "nodad") == 0) {
1615 ifa_flags
|= IFA_F_NODAD
;
1616 } else if (strcmp(*argv
, "mngtmpaddr") == 0) {
1617 ifa_flags
|= IFA_F_MANAGETEMPADDR
;
1618 } else if (strcmp(*argv
, "noprefixroute") == 0) {
1619 ifa_flags
|= IFA_F_NOPREFIXROUTE
;
1621 if (strcmp(*argv
, "local") == 0) {
1624 if (matches(*argv
, "help") == 0)
1627 duparg2("local", *argv
);
1629 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
1630 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1631 req
.ifa
.ifa_family
= lcl
.family
;
1632 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
1633 local_len
= lcl
.bytelen
;
1637 if (ifa_flags
<= 0xff)
1638 req
.ifa
.ifa_flags
= ifa_flags
;
1640 addattr32(&req
.n
, sizeof(req
), IFA_FLAGS
, ifa_flags
);
1643 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
1646 if (l
&& matches(d
, l
) != 0) {
1647 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
1651 if (peer_len
== 0 && local_len
) {
1652 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
1654 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1655 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1656 " This special behaviour is likely to disappear in further releases,\n" \
1657 " fix your scripts!\n", lcl_arg
, local_len
*8);
1660 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
1663 if (req
.ifa
.ifa_prefixlen
== 0)
1664 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
1666 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
1669 if (req
.ifa
.ifa_family
!= AF_INET
) {
1670 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
1674 if (brd
.bitlen
<= 30) {
1675 for (i
= 31; i
>= brd
.bitlen
; i
--) {
1677 brd
.data
[0] |= htonl(1<<(31-i
));
1679 brd
.data
[0] &= ~htonl(1<<(31-i
));
1681 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
1682 brd_len
= brd
.bytelen
;
1685 if (!scoped
&& cmd
!= RTM_DELADDR
)
1686 req
.ifa
.ifa_scope
= default_scope(&lcl
);
1688 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
1689 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
1693 if (valid_lftp
|| preferred_lftp
) {
1695 fprintf(stderr
, "valid_lft is zero\n");
1698 if (valid_lft
< preferred_lft
) {
1699 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
1703 memset(&cinfo
, 0, sizeof(cinfo
));
1704 cinfo
.ifa_prefered
= preferred_lft
;
1705 cinfo
.ifa_valid
= valid_lft
;
1706 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
1710 if (rtnl_talk(&rth
, &req
.n
, 0, 0, NULL
) < 0)
1716 int do_ipaddr(int argc
, char **argv
)
1719 return ipaddr_list_flush_or_save(0, NULL
, IPADD_LIST
);
1720 if (matches(*argv
, "add") == 0)
1721 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
1722 if (matches(*argv
, "change") == 0 ||
1723 strcmp(*argv
, "chg") == 0)
1724 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
1725 if (matches(*argv
, "replace") == 0)
1726 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
1727 if (matches(*argv
, "delete") == 0)
1728 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
1729 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
1730 || matches(*argv
, "lst") == 0)
1731 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_LIST
);
1732 if (matches(*argv
, "flush") == 0)
1733 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_FLUSH
);
1734 if (matches(*argv
, "save") == 0)
1735 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_SAVE
);
1736 if (matches(*argv
, "showdump") == 0)
1737 return ipaddr_showdump();
1738 if (matches(*argv
, "restore") == 0)
1739 return ipaddr_restore();
1740 if (matches(*argv
, "help") == 0)
1742 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv
);