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"
63 static void usage(void) __attribute__((noreturn
));
65 static void usage(void)
70 fprintf(stderr
, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n");
71 fprintf(stderr
, " [ CONFFLAG-LIST ]\n");
72 fprintf(stderr
, " ip addr del IFADDR dev STRING\n");
73 fprintf(stderr
, " ip addr {show|save|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
74 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ] [up]\n");
75 fprintf(stderr
, " ip addr {showdump|restore}\n");
76 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
77 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
78 fprintf(stderr
, " [ label STRING ] [ scope SCOPE-ID ]\n");
79 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
80 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
81 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
82 fprintf(stderr
, " tentative | deprecated | dadfailed | temporary |\n");
83 fprintf(stderr
, " CONFFLAG-LIST ]\n");
84 fprintf(stderr
, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
85 fprintf(stderr
, "CONFFLAG := [ home | nodad ]\n");
86 fprintf(stderr
, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
87 fprintf(stderr
, "LFT := forever | SECONDS\n");
92 static void print_link_flags(FILE *fp
, unsigned flags
, unsigned mdown
)
95 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
96 fprintf(fp
, "NO-CARRIER%s", flags
? "," : "");
97 flags
&= ~IFF_RUNNING
;
98 #define _PF(f) if (flags&IFF_##f) { \
100 fprintf(fp, #f "%s", flags ? "," : ""); }
121 fprintf(fp
, "%x", flags
);
123 fprintf(fp
, ",M-DOWN");
127 static const char *oper_states
[] = {
128 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
129 "TESTING", "DORMANT", "UP"
132 static void print_operstate(FILE *f
, __u8 state
)
134 if (state
>= sizeof(oper_states
)/sizeof(oper_states
[0]))
135 fprintf(f
, "state %#x ", state
);
137 fprintf(f
, "state %s ", oper_states
[state
]);
140 int get_operstate(const char *name
)
144 for (i
= 0; i
< sizeof(oper_states
)/sizeof(oper_states
[0]); i
++)
145 if (strcasecmp(name
, oper_states
[i
]) == 0)
150 static void print_queuelen(FILE *f
, struct rtattr
*tb
[IFLA_MAX
+ 1])
155 qlen
= *(int *)RTA_DATA(tb
[IFLA_TXQLEN
]);
158 int s
= socket(AF_INET
, SOCK_STREAM
, 0);
163 memset(&ifr
, 0, sizeof(ifr
));
164 strcpy(ifr
.ifr_name
, rta_getattr_str(tb
[IFLA_IFNAME
]));
165 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
166 fprintf(f
, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno
));
174 fprintf(f
, "qlen %d", qlen
);
177 static const char *link_modes
[] = {
181 static void print_linkmode(FILE *f
, struct rtattr
*tb
)
183 unsigned int mode
= rta_getattr_u8(tb
);
185 if (mode
>= sizeof(link_modes
) / sizeof(link_modes
[0]))
186 fprintf(f
, "mode %d ", mode
);
188 fprintf(f
, "mode %s ", link_modes
[mode
]);
191 static void print_linktype(FILE *fp
, struct rtattr
*tb
)
193 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
194 struct link_util
*lu
;
197 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
199 if (!linkinfo
[IFLA_INFO_KIND
])
201 kind
= RTA_DATA(linkinfo
[IFLA_INFO_KIND
]);
203 fprintf(fp
, "%s", _SL_
);
204 fprintf(fp
, " %s ", kind
);
206 lu
= get_link_kind(kind
);
207 if (!lu
|| !lu
->print_opt
)
211 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
213 if (linkinfo
[IFLA_INFO_DATA
]) {
214 parse_rtattr_nested(attr
, lu
->maxattr
,
215 linkinfo
[IFLA_INFO_DATA
]);
218 lu
->print_opt(lu
, fp
, data
);
220 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
222 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
226 static void print_vfinfo(FILE *fp
, struct rtattr
*vfinfo
)
228 struct ifla_vf_mac
*vf_mac
;
229 struct ifla_vf_vlan
*vf_vlan
;
230 struct ifla_vf_tx_rate
*vf_tx_rate
;
231 struct ifla_vf_spoofchk
*vf_spoofchk
;
232 struct ifla_vf_link_state
*vf_linkstate
;
233 struct rtattr
*vf
[IFLA_VF_MAX
+1];
237 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
238 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
242 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
244 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
245 vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
246 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
248 /* Check if the spoof checking vf info type is supported by
251 tmp
= (struct rtattr
*)((char *)vf
[IFLA_VF_TX_RATE
] +
252 vf
[IFLA_VF_TX_RATE
]->rta_len
);
254 if (tmp
->rta_type
!= IFLA_VF_SPOOFCHK
)
257 vf_spoofchk
= RTA_DATA(vf
[IFLA_VF_SPOOFCHK
]);
260 /* Check if the link state vf info type is supported by
263 tmp
= (struct rtattr
*)((char *)vf
[IFLA_VF_SPOOFCHK
] +
264 vf
[IFLA_VF_SPOOFCHK
]->rta_len
);
266 if (tmp
->rta_type
!= IFLA_VF_LINK_STATE
)
269 vf_linkstate
= RTA_DATA(vf
[IFLA_VF_LINK_STATE
]);
273 fprintf(fp
, "\n vf %d MAC %s", vf_mac
->vf
,
274 ll_addr_n2a((unsigned char *)&vf_mac
->mac
,
275 ETH_ALEN
, 0, b1
, sizeof(b1
)));
277 fprintf(fp
, ", vlan %d", vf_vlan
->vlan
);
279 fprintf(fp
, ", qos %d", vf_vlan
->qos
);
280 if (vf_tx_rate
->rate
)
281 fprintf(fp
, ", tx rate %d (Mbps)", vf_tx_rate
->rate
);
282 if (vf_spoofchk
&& vf_spoofchk
->setting
!= -1) {
283 if (vf_spoofchk
->setting
)
284 fprintf(fp
, ", spoof checking on");
286 fprintf(fp
, ", spoof checking off");
289 if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_AUTO
)
290 fprintf(fp
, ", link-state auto");
291 else if (vf_linkstate
->link_state
== IFLA_VF_LINK_STATE_ENABLE
)
292 fprintf(fp
, ", link-state enable");
294 fprintf(fp
, ", link-state disable");
298 static void print_link_stats64(FILE *fp
, const struct rtnl_link_stats64
*s
) {
299 fprintf(fp
, "%s", _SL_
);
300 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
301 s
->rx_compressed
? "compressed" : "", _SL_
);
302 fprintf(fp
, " %-10"PRIu64
" %-8"PRIu64
" %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
"",
303 (uint64_t)s
->rx_bytes
,
304 (uint64_t)s
->rx_packets
,
305 (uint64_t)s
->rx_errors
,
306 (uint64_t)s
->rx_dropped
,
307 (uint64_t)s
->rx_over_errors
,
308 (uint64_t)s
->multicast
);
309 if (s
->rx_compressed
)
310 fprintf(fp
, " %-7"PRIu64
"",
311 (uint64_t)s
->rx_compressed
);
312 if (show_stats
> 1) {
313 fprintf(fp
, "%s", _SL_
);
314 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
315 fprintf(fp
, " %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
"",
316 (uint64_t)s
->rx_length_errors
,
317 (uint64_t)s
->rx_crc_errors
,
318 (uint64_t)s
->rx_frame_errors
,
319 (uint64_t)s
->rx_fifo_errors
,
320 (uint64_t)s
->rx_missed_errors
);
322 fprintf(fp
, "%s", _SL_
);
323 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
324 (uint64_t)s
->tx_compressed
? "compressed" : "", _SL_
);
325 fprintf(fp
, " %-10"PRIu64
" %-8"PRIu64
" %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
"",
326 (uint64_t)s
->tx_bytes
,
327 (uint64_t)s
->tx_packets
,
328 (uint64_t)s
->tx_errors
,
329 (uint64_t)s
->tx_dropped
,
330 (uint64_t)s
->tx_carrier_errors
,
331 (uint64_t)s
->collisions
);
332 if (s
->tx_compressed
)
333 fprintf(fp
, " %-7"PRIu64
"",
334 (uint64_t)s
->tx_compressed
);
335 if (show_stats
> 1) {
336 fprintf(fp
, "%s", _SL_
);
337 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
338 fprintf(fp
, " %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
" %-7"PRIu64
"",
339 (uint64_t)s
->tx_aborted_errors
,
340 (uint64_t)s
->tx_fifo_errors
,
341 (uint64_t)s
->tx_window_errors
,
342 (uint64_t)s
->tx_heartbeat_errors
);
346 static void print_link_stats(FILE *fp
, const struct rtnl_link_stats
*s
)
348 fprintf(fp
, "%s", _SL_
);
349 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
350 s
->rx_compressed
? "compressed" : "", _SL_
);
351 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
352 s
->rx_bytes
, s
->rx_packets
, s
->rx_errors
,
353 s
->rx_dropped
, s
->rx_over_errors
,
356 if (s
->rx_compressed
)
357 fprintf(fp
, " %-7u", s
->rx_compressed
);
358 if (show_stats
> 1) {
359 fprintf(fp
, "%s", _SL_
);
360 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
361 fprintf(fp
, " %-7u %-7u %-7u %-7u %-7u",
369 fprintf(fp
, "%s", _SL_
);
370 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
371 s
->tx_compressed
? "compressed" : "", _SL_
);
372 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
373 s
->tx_bytes
, s
->tx_packets
, s
->tx_errors
,
374 s
->tx_dropped
, s
->tx_carrier_errors
, s
->collisions
);
375 if (s
->tx_compressed
)
376 fprintf(fp
, " %-7u", s
->tx_compressed
);
377 if (show_stats
> 1) {
378 fprintf(fp
, "%s", _SL_
);
379 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
380 fprintf(fp
, " %-7u %-7u %-7u %-7u",
381 s
->tx_aborted_errors
,
384 s
->tx_heartbeat_errors
389 int print_linkinfo(const struct sockaddr_nl
*who
,
390 struct nlmsghdr
*n
, void *arg
)
392 FILE *fp
= (FILE*)arg
;
393 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
394 struct rtattr
* tb
[IFLA_MAX
+1];
395 int len
= n
->nlmsg_len
;
398 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
401 len
-= NLMSG_LENGTH(sizeof(*ifi
));
405 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
407 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
410 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
411 if (tb
[IFLA_IFNAME
] == NULL
) {
412 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
415 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
416 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
419 if (tb
[IFLA_GROUP
]) {
420 int group
= *(int*)RTA_DATA(tb
[IFLA_GROUP
]);
421 if (filter
.group
!= -1 && group
!= filter
.group
)
425 if (n
->nlmsg_type
== RTM_DELLINK
)
426 fprintf(fp
, "Deleted ");
428 fprintf(fp
, "%d: %s", ifi
->ifi_index
,
429 tb
[IFLA_IFNAME
] ? rta_getattr_str(tb
[IFLA_IFNAME
]) : "<nil>");
433 int iflink
= *(int*)RTA_DATA(tb
[IFLA_LINK
]);
435 fprintf(fp
, "@NONE: ");
437 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
438 m_flag
= ll_index_to_flags(iflink
);
439 m_flag
= !(m_flag
& IFF_UP
);
444 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
447 fprintf(fp
, "mtu %u ", *(int*)RTA_DATA(tb
[IFLA_MTU
]));
449 fprintf(fp
, "qdisc %s ", rta_getattr_str(tb
[IFLA_QDISC
]));
450 if (tb
[IFLA_MASTER
]) {
452 fprintf(fp
, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb
[IFLA_MASTER
]), b1
));
455 if (tb
[IFLA_OPERSTATE
])
456 print_operstate(fp
, rta_getattr_u8(tb
[IFLA_OPERSTATE
]));
458 if (do_link
&& tb
[IFLA_LINKMODE
])
459 print_linkmode(fp
, tb
[IFLA_LINKMODE
]);
461 if (tb
[IFLA_GROUP
]) {
463 int group
= *(int*)RTA_DATA(tb
[IFLA_GROUP
]);
464 fprintf(fp
, "group %s ", rtnl_group_n2a(group
, b1
, sizeof(b1
)));
467 if (filter
.showqueue
)
468 print_queuelen(fp
, tb
);
470 if (!filter
.family
|| filter
.family
== AF_PACKET
) {
472 fprintf(fp
, "%s", _SL_
);
473 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
475 if (tb
[IFLA_ADDRESS
]) {
476 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
477 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
481 if (tb
[IFLA_BROADCAST
]) {
482 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
483 fprintf(fp
, " peer ");
485 fprintf(fp
, " brd ");
486 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
487 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
493 if (do_link
&& tb
[IFLA_PROMISCUITY
] && show_details
)
494 fprintf(fp
, " promiscuity %u ",
495 *(int*)RTA_DATA(tb
[IFLA_PROMISCUITY
]));
497 if (do_link
&& tb
[IFLA_LINKINFO
] && show_details
)
498 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
500 if (do_link
&& tb
[IFLA_IFALIAS
]) {
501 fprintf(fp
, "%s alias %s", _SL_
,
502 rta_getattr_str(tb
[IFLA_IFALIAS
]));
505 if (do_link
&& show_stats
) {
506 if (tb
[IFLA_STATS64
])
507 print_link_stats64(fp
, RTA_DATA(tb
[IFLA_STATS64
]));
508 else if (tb
[IFLA_STATS
])
509 print_link_stats(fp
, RTA_DATA(tb
[IFLA_STATS
]));
512 if (do_link
&& tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
513 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
514 int rem
= RTA_PAYLOAD(vflist
);
515 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
))
524 static int flush_update(void)
526 if (rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) {
527 perror("Failed to send flush request");
534 static int set_lifetime(unsigned int *lifetime
, char *argv
)
536 if (strcmp(argv
, "forever") == 0)
537 *lifetime
= INFINITY_LIFE_TIME
;
538 else if (get_u32(lifetime
, argv
, 0))
544 static unsigned int get_ifa_flags(struct ifaddrmsg
*ifa
,
545 struct rtattr
*ifa_flags_attr
)
547 return ifa_flags_attr
? rta_getattr_u32(ifa_flags_attr
) :
551 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
554 FILE *fp
= (FILE*)arg
;
555 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
556 int len
= n
->nlmsg_len
;
558 /* Use local copy of ifa_flags to not interfere with filtering code */
559 unsigned int ifa_flags
;
560 struct rtattr
* rta_tb
[IFA_MAX
+1];
564 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
566 len
-= NLMSG_LENGTH(sizeof(*ifa
));
568 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
572 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
575 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
), n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
577 ifa_flags
= get_ifa_flags(ifa
, rta_tb
[IFA_FLAGS
]);
579 if (!rta_tb
[IFA_LOCAL
])
580 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
581 if (!rta_tb
[IFA_ADDRESS
])
582 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
584 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
586 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
588 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
593 if (rta_tb
[IFA_LABEL
])
594 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
596 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
597 if (fnmatch(filter
.label
, label
, 0) != 0)
600 if (filter
.pfx
.family
) {
601 if (rta_tb
[IFA_LOCAL
]) {
603 memset(&dst
, 0, sizeof(dst
));
604 dst
.family
= ifa
->ifa_family
;
605 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
606 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
611 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
616 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
620 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
621 memcpy(fn
, n
, n
->nlmsg_len
);
622 fn
->nlmsg_type
= RTM_DELADDR
;
623 fn
->nlmsg_flags
= NLM_F_REQUEST
;
624 fn
->nlmsg_seq
= ++rth
.seq
;
625 filter
.flushp
= (((char*)fn
) + n
->nlmsg_len
) - filter
.flushb
;
631 if (n
->nlmsg_type
== RTM_DELADDR
)
632 fprintf(fp
, "Deleted ");
634 if (filter
.oneline
|| filter
.flushb
)
635 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
636 if (ifa
->ifa_family
== AF_INET
)
637 fprintf(fp
, " inet ");
638 else if (ifa
->ifa_family
== AF_INET6
)
639 fprintf(fp
, " inet6 ");
640 else if (ifa
->ifa_family
== AF_DECnet
)
641 fprintf(fp
, " dnet ");
642 else if (ifa
->ifa_family
== AF_IPX
)
643 fprintf(fp
, " ipx ");
645 fprintf(fp
, " family %d ", ifa
->ifa_family
);
647 if (rta_tb
[IFA_LOCAL
]) {
648 fprintf(fp
, "%s", format_host(ifa
->ifa_family
,
649 RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]),
650 RTA_DATA(rta_tb
[IFA_LOCAL
]),
651 abuf
, sizeof(abuf
)));
653 if (rta_tb
[IFA_ADDRESS
] == NULL
||
654 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]), RTA_DATA(rta_tb
[IFA_LOCAL
]),
655 ifa
->ifa_family
== AF_INET
? 4 : 16) == 0) {
656 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
658 fprintf(fp
, " peer %s/%d ",
659 format_host(ifa
->ifa_family
,
660 RTA_PAYLOAD(rta_tb
[IFA_ADDRESS
]),
661 RTA_DATA(rta_tb
[IFA_ADDRESS
]),
667 if (rta_tb
[IFA_BROADCAST
]) {
668 fprintf(fp
, "brd %s ",
669 format_host(ifa
->ifa_family
,
670 RTA_PAYLOAD(rta_tb
[IFA_BROADCAST
]),
671 RTA_DATA(rta_tb
[IFA_BROADCAST
]),
672 abuf
, sizeof(abuf
)));
674 if (rta_tb
[IFA_ANYCAST
]) {
675 fprintf(fp
, "any %s ",
676 format_host(ifa
->ifa_family
,
677 RTA_PAYLOAD(rta_tb
[IFA_ANYCAST
]),
678 RTA_DATA(rta_tb
[IFA_ANYCAST
]),
679 abuf
, sizeof(abuf
)));
681 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
682 if (ifa_flags
& IFA_F_SECONDARY
) {
683 ifa_flags
&= ~IFA_F_SECONDARY
;
684 if (ifa
->ifa_family
== AF_INET6
)
685 fprintf(fp
, "temporary ");
687 fprintf(fp
, "secondary ");
689 if (ifa_flags
& IFA_F_TENTATIVE
) {
690 ifa_flags
&= ~IFA_F_TENTATIVE
;
691 fprintf(fp
, "tentative ");
693 if (ifa_flags
& IFA_F_DEPRECATED
) {
694 ifa_flags
&= ~IFA_F_DEPRECATED
;
696 fprintf(fp
, "deprecated ");
698 if (ifa_flags
& IFA_F_HOMEADDRESS
) {
699 ifa_flags
&= ~IFA_F_HOMEADDRESS
;
700 fprintf(fp
, "home ");
702 if (ifa_flags
& IFA_F_NODAD
) {
703 ifa_flags
&= ~IFA_F_NODAD
;
704 fprintf(fp
, "nodad ");
706 if (!(ifa_flags
& IFA_F_PERMANENT
)) {
707 fprintf(fp
, "dynamic ");
709 ifa_flags
&= ~IFA_F_PERMANENT
;
710 if (ifa_flags
& IFA_F_DADFAILED
) {
711 ifa_flags
&= ~IFA_F_DADFAILED
;
712 fprintf(fp
, "dadfailed ");
715 fprintf(fp
, "flags %02x ", ifa_flags
);
716 if (rta_tb
[IFA_LABEL
])
717 fprintf(fp
, "%s", rta_getattr_str(rta_tb
[IFA_LABEL
]));
718 if (rta_tb
[IFA_CACHEINFO
]) {
719 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
720 fprintf(fp
, "%s", _SL_
);
721 fprintf(fp
, " valid_lft ");
722 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
)
723 fprintf(fp
, "forever");
725 fprintf(fp
, "%usec", ci
->ifa_valid
);
726 fprintf(fp
, " preferred_lft ");
727 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
)
728 fprintf(fp
, "forever");
731 fprintf(fp
, "%dsec", ci
->ifa_prefered
);
733 fprintf(fp
, "%usec", ci
->ifa_prefered
);
741 static int print_addrinfo_primary(const struct sockaddr_nl
*who
,
742 struct nlmsghdr
*n
, void *arg
)
744 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
746 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
749 return print_addrinfo(who
, n
, arg
);
752 static int print_addrinfo_secondary(const struct sockaddr_nl
*who
,
753 struct nlmsghdr
*n
, void *arg
)
755 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
757 if (!(ifa
->ifa_flags
& IFA_F_SECONDARY
))
760 return print_addrinfo(who
, n
, arg
);
765 struct nlmsg_list
*next
;
771 struct nlmsg_list
*head
;
772 struct nlmsg_list
*tail
;
775 static int print_selected_addrinfo(int ifindex
, struct nlmsg_list
*ainfo
, FILE *fp
)
777 for ( ;ainfo
; ainfo
= ainfo
->next
) {
778 struct nlmsghdr
*n
= &ainfo
->h
;
779 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
781 if (n
->nlmsg_type
!= RTM_NEWADDR
)
784 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifa
)))
787 if (ifa
->ifa_index
!= ifindex
||
788 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
791 print_addrinfo(NULL
, n
, fp
);
797 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
800 struct nlmsg_chain
*lchain
= (struct nlmsg_chain
*)arg
;
801 struct nlmsg_list
*h
;
803 h
= malloc(n
->nlmsg_len
+sizeof(void*));
807 memcpy(&h
->h
, n
, n
->nlmsg_len
);
811 lchain
->tail
->next
= h
;
816 ll_remember_index(who
, n
, NULL
);
820 static __u32 ipadd_dump_magic
= 0x47361222;
822 static int ipadd_save_prep(void)
826 if (isatty(STDOUT_FILENO
)) {
827 fprintf(stderr
, "Not sending a binary stream to stdout\n");
831 ret
= write(STDOUT_FILENO
, &ipadd_dump_magic
, sizeof(ipadd_dump_magic
));
832 if (ret
!= sizeof(ipadd_dump_magic
)) {
833 fprintf(stderr
, "Can't write magic to dump file\n");
840 static int ipadd_dump_check_magic(void)
845 if (isatty(STDIN_FILENO
)) {
846 fprintf(stderr
, "Can't restore addr dump from a terminal\n");
850 ret
= fread(&magic
, sizeof(magic
), 1, stdin
);
851 if (magic
!= ipadd_dump_magic
) {
852 fprintf(stderr
, "Magic mismatch (%d elems, %x magic)\n", ret
, magic
);
859 static int save_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
864 ret
= write(STDOUT_FILENO
, n
, n
->nlmsg_len
);
865 if ((ret
> 0) && (ret
!= n
->nlmsg_len
)) {
866 fprintf(stderr
, "Short write while saving nlmsg\n");
870 return ret
== n
->nlmsg_len
? 0 : ret
;
873 static int show_handler(const struct sockaddr_nl
*nl
, struct nlmsghdr
*n
, void *arg
)
875 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
877 printf("if%d:\n", ifa
->ifa_index
);
878 print_addrinfo(NULL
, n
, stdout
);
882 static int ipaddr_showdump(void)
884 if (ipadd_dump_check_magic())
887 exit(rtnl_from_file(stdin
, &show_handler
, NULL
));
890 static int restore_handler(const struct sockaddr_nl
*nl
, struct nlmsghdr
*n
, void *arg
)
894 n
->nlmsg_flags
|= NLM_F_REQUEST
| NLM_F_CREATE
| NLM_F_ACK
;
898 ret
= rtnl_talk(&rth
, n
, 0, 0, n
);
899 if ((ret
< 0) && (errno
== EEXIST
))
905 static int ipaddr_restore(void)
907 if (ipadd_dump_check_magic())
910 exit(rtnl_from_file(stdin
, &restore_handler
, NULL
));
913 static void free_nlmsg_chain(struct nlmsg_chain
*info
)
915 struct nlmsg_list
*l
, *n
;
917 for (l
= info
->head
; l
; l
= n
) {
923 static void ipaddr_filter(struct nlmsg_chain
*linfo
, struct nlmsg_chain
*ainfo
)
925 struct nlmsg_list
*l
, **lp
;
928 while ( (l
= *lp
) != NULL
) {
930 int missing_net_address
= 1;
931 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
932 struct nlmsg_list
*a
;
934 for (a
= ainfo
->head
; a
; a
= a
->next
) {
935 struct nlmsghdr
*n
= &a
->h
;
936 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
937 struct rtattr
*tb
[IFA_MAX
+ 1];
938 unsigned int ifa_flags
;
940 if (ifa
->ifa_index
!= ifi
->ifi_index
)
942 missing_net_address
= 0;
943 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
945 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
948 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
949 ifa_flags
= get_ifa_flags(ifa
, tb
[IFA_FLAGS
]);
951 if ((filter
.flags
^ ifa_flags
) & filter
.flagmask
)
953 if (filter
.pfx
.family
|| filter
.label
) {
955 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
957 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
959 memset(&dst
, 0, sizeof(dst
));
960 dst
.family
= ifa
->ifa_family
;
961 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
962 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
969 label
= RTA_DATA(tb
[IFA_LABEL
]);
971 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
972 if (fnmatch(filter
.label
, label
, 0) != 0)
980 if (missing_net_address
&&
981 (filter
.family
== AF_UNSPEC
|| filter
.family
== AF_PACKET
))
991 static int ipaddr_flush(void)
994 char flushb
[4096-512];
996 filter
.flushb
= flushb
;
998 filter
.flushe
= sizeof(flushb
);
1000 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
1001 const struct rtnl_dump_filter_arg a
[3] = {
1003 .filter
= print_addrinfo_secondary
,
1007 .filter
= print_addrinfo_primary
,
1015 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
1016 perror("Cannot send dump request");
1020 if (rtnl_dump_filter_l(&rth
, a
) < 0) {
1021 fprintf(stderr
, "Flush terminated\n");
1024 if (filter
.flushed
== 0) {
1028 printf("Nothing to flush.\n");
1030 printf("*** Flush is complete after %d round%s ***\n", round
, round
>1?"s":"");
1036 if (flush_update() < 0)
1040 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
1044 /* If we are flushing, and specifying primary, then we
1045 * want to flush only a single round. Otherwise, we'll
1046 * start flushing secondaries that were promoted to
1049 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
1052 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
1057 static int ipaddr_list_flush_or_save(int argc
, char **argv
, int action
)
1059 struct nlmsg_chain linfo
= { NULL
, NULL
};
1060 struct nlmsg_chain ainfo
= { NULL
, NULL
};
1061 struct nlmsg_list
*l
;
1062 char *filter_dev
= NULL
;
1065 ipaddr_reset_filter(oneline
);
1066 filter
.showqueue
= 1;
1068 if (filter
.family
== AF_UNSPEC
)
1069 filter
.family
= preferred_family
;
1073 if (action
== IPADD_FLUSH
) {
1075 fprintf(stderr
, "Flush requires arguments.\n");
1079 if (filter
.family
== AF_PACKET
) {
1080 fprintf(stderr
, "Cannot flush link addresses.\n");
1086 if (strcmp(*argv
, "to") == 0) {
1088 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
1089 if (filter
.family
== AF_UNSPEC
)
1090 filter
.family
= filter
.pfx
.family
;
1091 } else if (strcmp(*argv
, "scope") == 0) {
1094 filter
.scopemask
= -1;
1095 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
1096 if (strcmp(*argv
, "all") != 0)
1097 invarg("invalid \"scope\"\n", *argv
);
1098 scope
= RT_SCOPE_NOWHERE
;
1099 filter
.scopemask
= 0;
1101 filter
.scope
= scope
;
1102 } else if (strcmp(*argv
, "up") == 0) {
1104 } else if (strcmp(*argv
, "dynamic") == 0) {
1105 filter
.flags
&= ~IFA_F_PERMANENT
;
1106 filter
.flagmask
|= IFA_F_PERMANENT
;
1107 } else if (strcmp(*argv
, "permanent") == 0) {
1108 filter
.flags
|= IFA_F_PERMANENT
;
1109 filter
.flagmask
|= IFA_F_PERMANENT
;
1110 } else if (strcmp(*argv
, "secondary") == 0 ||
1111 strcmp(*argv
, "temporary") == 0) {
1112 filter
.flags
|= IFA_F_SECONDARY
;
1113 filter
.flagmask
|= IFA_F_SECONDARY
;
1114 } else if (strcmp(*argv
, "primary") == 0) {
1115 filter
.flags
&= ~IFA_F_SECONDARY
;
1116 filter
.flagmask
|= IFA_F_SECONDARY
;
1117 } else if (strcmp(*argv
, "tentative") == 0) {
1118 filter
.flags
|= IFA_F_TENTATIVE
;
1119 filter
.flagmask
|= IFA_F_TENTATIVE
;
1120 } else if (strcmp(*argv
, "deprecated") == 0) {
1121 filter
.flags
|= IFA_F_DEPRECATED
;
1122 filter
.flagmask
|= IFA_F_DEPRECATED
;
1123 } else if (strcmp(*argv
, "home") == 0) {
1124 filter
.flags
|= IFA_F_HOMEADDRESS
;
1125 filter
.flagmask
|= IFA_F_HOMEADDRESS
;
1126 } else if (strcmp(*argv
, "nodad") == 0) {
1127 filter
.flags
|= IFA_F_NODAD
;
1128 filter
.flagmask
|= IFA_F_NODAD
;
1129 } else if (strcmp(*argv
, "dadfailed") == 0) {
1130 filter
.flags
|= IFA_F_DADFAILED
;
1131 filter
.flagmask
|= IFA_F_DADFAILED
;
1132 } else if (strcmp(*argv
, "label") == 0) {
1134 filter
.label
= *argv
;
1135 } else if (strcmp(*argv
, "group") == 0) {
1137 if (rtnl_group_a2n(&filter
.group
, *argv
))
1138 invarg("Invalid \"group\" value\n", *argv
);
1140 if (strcmp(*argv
, "dev") == 0) {
1143 if (matches(*argv
, "help") == 0)
1146 duparg2("dev", *argv
);
1153 filter
.ifindex
= ll_name_to_index(filter_dev
);
1154 if (filter
.ifindex
<= 0) {
1155 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
1160 if (action
== IPADD_FLUSH
)
1161 return ipaddr_flush();
1163 if (action
== IPADD_SAVE
) {
1164 if (ipadd_save_prep())
1167 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETADDR
) < 0) {
1168 perror("Cannot send dump request");
1172 if (rtnl_dump_filter(&rth
, save_nlmsg
, stdout
) < 0) {
1173 fprintf(stderr
, "Save terminated\n");
1180 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETLINK
) < 0) {
1181 perror("Cannot send dump request");
1185 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
) < 0) {
1186 fprintf(stderr
, "Dump terminated\n");
1190 if (filter
.family
!= AF_PACKET
) {
1194 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
1195 perror("Cannot send dump request");
1199 if (rtnl_dump_filter(&rth
, store_nlmsg
, &ainfo
) < 0) {
1200 fprintf(stderr
, "Dump terminated\n");
1204 ipaddr_filter(&linfo
, &ainfo
);
1207 for (l
= linfo
.head
; l
; l
= l
->next
) {
1208 if (no_link
|| print_linkinfo(NULL
, &l
->h
, stdout
) == 0) {
1209 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
1210 if (filter
.family
!= AF_PACKET
)
1211 print_selected_addrinfo(ifi
->ifi_index
,
1212 ainfo
.head
, stdout
);
1217 free_nlmsg_chain(&ainfo
);
1218 free_nlmsg_chain(&linfo
);
1223 int ipaddr_list_link(int argc
, char **argv
)
1225 preferred_family
= AF_PACKET
;
1227 return ipaddr_list_flush_or_save(argc
, argv
, IPADD_LIST
);
1230 void ipaddr_reset_filter(int oneline
)
1232 memset(&filter
, 0, sizeof(filter
));
1233 filter
.oneline
= oneline
;
1236 static int default_scope(inet_prefix
*lcl
)
1238 if (lcl
->family
== AF_INET
) {
1239 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
1240 return RT_SCOPE_HOST
;
1245 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
1249 struct ifaddrmsg ifa
;
1254 char *lcl_arg
= NULL
;
1255 char *valid_lftp
= NULL
;
1256 char *preferred_lftp
= NULL
;
1264 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
1265 __u32 valid_lft
= INFINITY_LIFE_TIME
;
1266 struct ifa_cacheinfo cinfo
;
1267 unsigned int ifa_flags
= 0;
1269 memset(&req
, 0, sizeof(req
));
1271 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1272 req
.n
.nlmsg_flags
= NLM_F_REQUEST
| flags
;
1273 req
.n
.nlmsg_type
= cmd
;
1274 req
.ifa
.ifa_family
= preferred_family
;
1277 if (strcmp(*argv
, "peer") == 0 ||
1278 strcmp(*argv
, "remote") == 0) {
1282 duparg("peer", *argv
);
1283 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
1284 peer_len
= peer
.bytelen
;
1285 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1286 req
.ifa
.ifa_family
= peer
.family
;
1287 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
1288 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
1289 } else if (matches(*argv
, "broadcast") == 0 ||
1290 strcmp(*argv
, "brd") == 0) {
1294 duparg("broadcast", *argv
);
1295 if (strcmp(*argv
, "+") == 0)
1297 else if (strcmp(*argv
, "-") == 0)
1300 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1301 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1302 req
.ifa
.ifa_family
= addr
.family
;
1303 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
1304 brd_len
= addr
.bytelen
;
1306 } else if (strcmp(*argv
, "anycast") == 0) {
1310 duparg("anycast", *argv
);
1311 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1312 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1313 req
.ifa
.ifa_family
= addr
.family
;
1314 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
1315 any_len
= addr
.bytelen
;
1316 } else if (strcmp(*argv
, "scope") == 0) {
1319 if (rtnl_rtscope_a2n(&scope
, *argv
))
1320 invarg("invalid scope value.", *argv
);
1321 req
.ifa
.ifa_scope
= scope
;
1323 } else if (strcmp(*argv
, "dev") == 0) {
1326 } else if (strcmp(*argv
, "label") == 0) {
1329 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
1330 } else if (matches(*argv
, "valid_lft") == 0) {
1332 duparg("valid_lft", *argv
);
1335 if (set_lifetime(&valid_lft
, *argv
))
1336 invarg("valid_lft value", *argv
);
1337 } else if (matches(*argv
, "preferred_lft") == 0) {
1339 duparg("preferred_lft", *argv
);
1341 preferred_lftp
= *argv
;
1342 if (set_lifetime(&preferred_lft
, *argv
))
1343 invarg("preferred_lft value", *argv
);
1344 } else if (strcmp(*argv
, "home") == 0) {
1345 ifa_flags
|= IFA_F_HOMEADDRESS
;
1346 } else if (strcmp(*argv
, "nodad") == 0) {
1347 ifa_flags
|= IFA_F_NODAD
;
1349 if (strcmp(*argv
, "local") == 0) {
1352 if (matches(*argv
, "help") == 0)
1355 duparg2("local", *argv
);
1357 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
1358 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1359 req
.ifa
.ifa_family
= lcl
.family
;
1360 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
1361 local_len
= lcl
.bytelen
;
1365 req
.ifa
.ifa_flags
= ifa_flags
;
1366 addattr32(&req
.n
, sizeof(req
), IFA_FLAGS
, ifa_flags
);
1369 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
1372 if (l
&& matches(d
, l
) != 0) {
1373 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
1377 if (peer_len
== 0 && local_len
) {
1378 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
1380 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1381 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1382 " This special behaviour is likely to disappear in further releases,\n" \
1383 " fix your scripts!\n", lcl_arg
, local_len
*8);
1386 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
1389 if (req
.ifa
.ifa_prefixlen
== 0)
1390 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
1392 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
1395 if (req
.ifa
.ifa_family
!= AF_INET
) {
1396 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
1400 if (brd
.bitlen
<= 30) {
1401 for (i
=31; i
>=brd
.bitlen
; i
--) {
1403 brd
.data
[0] |= htonl(1<<(31-i
));
1405 brd
.data
[0] &= ~htonl(1<<(31-i
));
1407 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
1408 brd_len
= brd
.bytelen
;
1411 if (!scoped
&& cmd
!= RTM_DELADDR
)
1412 req
.ifa
.ifa_scope
= default_scope(&lcl
);
1414 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
1415 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
1419 if (valid_lftp
|| preferred_lftp
) {
1421 fprintf(stderr
, "valid_lft is zero\n");
1424 if (valid_lft
< preferred_lft
) {
1425 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
1429 memset(&cinfo
, 0, sizeof(cinfo
));
1430 cinfo
.ifa_prefered
= preferred_lft
;
1431 cinfo
.ifa_valid
= valid_lft
;
1432 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
1436 if (rtnl_talk(&rth
, &req
.n
, 0, 0, NULL
) < 0)
1442 int do_ipaddr(int argc
, char **argv
)
1445 return ipaddr_list_flush_or_save(0, NULL
, IPADD_LIST
);
1446 if (matches(*argv
, "add") == 0)
1447 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
1448 if (matches(*argv
, "change") == 0 ||
1449 strcmp(*argv
, "chg") == 0)
1450 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
1451 if (matches(*argv
, "replace") == 0)
1452 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
1453 if (matches(*argv
, "delete") == 0)
1454 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
1455 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
1456 || matches(*argv
, "lst") == 0)
1457 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_LIST
);
1458 if (matches(*argv
, "flush") == 0)
1459 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_FLUSH
);
1460 if (matches(*argv
, "save") == 0)
1461 return ipaddr_list_flush_or_save(argc
-1, argv
+1, IPADD_SAVE
);
1462 if (matches(*argv
, "showdump") == 0)
1463 return ipaddr_showdump();
1464 if (matches(*argv
, "restore") == 0)
1465 return ipaddr_restore();
1466 if (matches(*argv
, "help") == 0)
1468 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv
);