]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/ipaddress.c
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/ioctl.h>
21 #include <sys/errno.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>
34 #include "ip_common.h"
56 static void usage(void) __attribute__((noreturn
));
58 static void usage(void)
63 fprintf(stderr
, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n");
64 fprintf(stderr
, " [ CONFFLAG-LIST ]\n");
65 fprintf(stderr
, " ip addr del IFADDR dev STRING\n");
66 fprintf(stderr
, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
67 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
68 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
69 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
70 fprintf(stderr
, " [ label STRING ] [ scope SCOPE-ID ]\n");
71 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
72 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
73 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
74 fprintf(stderr
, " tentative | deprecated | dadfailed | temporary |\n");
75 fprintf(stderr
, " CONFFLAG-LIST ]\n");
76 fprintf(stderr
, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
77 fprintf(stderr
, "CONFFLAG := [ home | nodad ]\n");
78 fprintf(stderr
, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
79 fprintf(stderr
, "LFT := forever | SECONDS\n");
84 void print_link_flags(FILE *fp
, unsigned flags
, unsigned mdown
)
87 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
88 fprintf(fp
, "NO-CARRIER%s", flags
? "," : "");
89 flags
&= ~IFF_RUNNING
;
90 #define _PF(f) if (flags&IFF_##f) { \
92 fprintf(fp, #f "%s", flags ? "," : ""); }
113 fprintf(fp
, "%x", flags
);
115 fprintf(fp
, ",M-DOWN");
119 static const char *oper_states
[] = {
120 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
121 "TESTING", "DORMANT", "UP"
124 static void print_operstate(FILE *f
, __u8 state
)
126 if (state
>= sizeof(oper_states
)/sizeof(oper_states
[0]))
127 fprintf(f
, "state %#x ", state
);
129 fprintf(f
, "state %s ", oper_states
[state
]);
132 static void print_queuelen(FILE *f
, const char *name
)
137 s
= socket(AF_INET
, SOCK_STREAM
, 0);
141 memset(&ifr
, 0, sizeof(ifr
));
142 strcpy(ifr
.ifr_name
, name
);
143 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
144 fprintf(f
, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno
));
151 fprintf(f
, "qlen %d", ifr
.ifr_qlen
);
154 static void print_linktype(FILE *fp
, struct rtattr
*tb
)
156 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
157 struct link_util
*lu
;
160 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
162 if (!linkinfo
[IFLA_INFO_KIND
])
164 kind
= RTA_DATA(linkinfo
[IFLA_INFO_KIND
]);
166 fprintf(fp
, "%s", _SL_
);
167 fprintf(fp
, " %s ", kind
);
169 lu
= get_link_kind(kind
);
170 if (!lu
|| !lu
->print_opt
)
174 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
176 if (linkinfo
[IFLA_INFO_DATA
]) {
177 parse_rtattr_nested(attr
, lu
->maxattr
,
178 linkinfo
[IFLA_INFO_DATA
]);
181 lu
->print_opt(lu
, fp
, data
);
183 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
185 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
189 static void print_vfinfo(FILE *fp
, struct rtattr
*vfinfo
)
191 struct ifla_vf_mac
*vf_mac
;
192 struct ifla_vf_vlan
*vf_vlan
;
193 struct ifla_vf_tx_rate
*vf_tx_rate
;
194 struct rtattr
*vf
[IFLA_VF_MAX
+1];
197 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
198 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
202 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
204 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
205 vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
206 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
208 fprintf(fp
, "\n vf %d MAC %s", vf_mac
->vf
,
209 ll_addr_n2a((unsigned char *)&vf_mac
->mac
,
210 ETH_ALEN
, 0, b1
, sizeof(b1
)));
212 fprintf(fp
, ", vlan %d", vf_vlan
->vlan
);
214 fprintf(fp
, ", qos %d", vf_vlan
->qos
);
215 if (vf_tx_rate
->rate
)
216 fprintf(fp
, ", tx rate %d (Mbps)", vf_tx_rate
->rate
);
219 int print_linkinfo(const struct sockaddr_nl
*who
,
220 struct nlmsghdr
*n
, void *arg
)
222 FILE *fp
= (FILE*)arg
;
223 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
224 struct rtattr
* tb
[IFLA_MAX
+1];
225 int len
= n
->nlmsg_len
;
228 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
231 len
-= NLMSG_LENGTH(sizeof(*ifi
));
235 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
237 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
240 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
241 if (tb
[IFLA_IFNAME
] == NULL
) {
242 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
245 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
246 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
249 if (n
->nlmsg_type
== RTM_DELLINK
)
250 fprintf(fp
, "Deleted ");
252 fprintf(fp
, "%d: %s", ifi
->ifi_index
,
253 tb
[IFLA_IFNAME
] ? (char*)RTA_DATA(tb
[IFLA_IFNAME
]) : "<nil>");
257 int iflink
= *(int*)RTA_DATA(tb
[IFLA_LINK
]);
259 fprintf(fp
, "@NONE: ");
261 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
262 m_flag
= ll_index_to_flags(iflink
);
263 m_flag
= !(m_flag
& IFF_UP
);
268 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
271 fprintf(fp
, "mtu %u ", *(int*)RTA_DATA(tb
[IFLA_MTU
]));
273 fprintf(fp
, "qdisc %s ", (char*)RTA_DATA(tb
[IFLA_QDISC
]));
275 if (tb
[IFLA_MASTER
]) {
277 fprintf(fp
, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb
[IFLA_MASTER
]), b1
));
280 if (tb
[IFLA_OPERSTATE
])
281 print_operstate(fp
, *(__u8
*)RTA_DATA(tb
[IFLA_OPERSTATE
]));
283 if (filter
.showqueue
)
284 print_queuelen(fp
, (char*)RTA_DATA(tb
[IFLA_IFNAME
]));
286 if (!filter
.family
|| filter
.family
== AF_PACKET
) {
288 fprintf(fp
, "%s", _SL_
);
289 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
291 if (tb
[IFLA_ADDRESS
]) {
292 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
293 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
297 if (tb
[IFLA_BROADCAST
]) {
298 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
299 fprintf(fp
, " peer ");
301 fprintf(fp
, " brd ");
302 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
303 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
309 if (do_link
&& tb
[IFLA_LINKINFO
] && show_details
)
310 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
312 if (do_link
&& tb
[IFLA_IFALIAS
])
313 fprintf(fp
,"\n alias %s",
314 (const char *) RTA_DATA(tb
[IFLA_IFALIAS
]));
316 if (do_link
&& tb
[IFLA_STATS64
] && show_stats
) {
317 struct rtnl_link_stats64 slocal
;
318 struct rtnl_link_stats64
*s
= RTA_DATA(tb
[IFLA_STATS64
]);
319 if (((unsigned long)s
) & (sizeof(unsigned long)-1)) {
320 memcpy(&slocal
, s
, sizeof(slocal
));
323 fprintf(fp
, "%s", _SL_
);
324 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
325 s
->rx_compressed
? "compressed" : "", _SL_
);
326 fprintf(fp
, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
327 (unsigned long long)s
->rx_bytes
,
328 (unsigned long long)s
->rx_packets
,
329 (unsigned long long)s
->rx_errors
,
330 (unsigned long long)s
->rx_dropped
,
331 (unsigned long long)s
->rx_over_errors
,
332 (unsigned long long)s
->multicast
);
333 if (s
->rx_compressed
)
334 fprintf(fp
, " %-7llu",
335 (unsigned long long)s
->rx_compressed
);
336 if (show_stats
> 1) {
337 fprintf(fp
, "%s", _SL_
);
338 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
339 fprintf(fp
, " %-7llu %-7llu %-7llu %-7llu %-7llu",
340 (unsigned long long)s
->rx_length_errors
,
341 (unsigned long long)s
->rx_crc_errors
,
342 (unsigned long long)s
->rx_frame_errors
,
343 (unsigned long long)s
->rx_fifo_errors
,
344 (unsigned long long)s
->rx_missed_errors
);
346 fprintf(fp
, "%s", _SL_
);
347 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
348 s
->tx_compressed
? "compressed" : "", _SL_
);
349 fprintf(fp
, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
350 (unsigned long long)s
->tx_bytes
,
351 (unsigned long long)s
->tx_packets
,
352 (unsigned long long)s
->tx_errors
,
353 (unsigned long long)s
->tx_dropped
,
354 (unsigned long long)s
->tx_carrier_errors
,
355 (unsigned long long)s
->collisions
);
356 if (s
->tx_compressed
)
357 fprintf(fp
, " %-7llu",
358 (unsigned long long)s
->tx_compressed
);
359 if (show_stats
> 1) {
360 fprintf(fp
, "%s", _SL_
);
361 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
362 fprintf(fp
, " %-7llu %-7llu %-7llu %-7llu",
363 (unsigned long long)s
->tx_aborted_errors
,
364 (unsigned long long)s
->tx_fifo_errors
,
365 (unsigned long long)s
->tx_window_errors
,
366 (unsigned long long)s
->tx_heartbeat_errors
);
369 if (do_link
&& !tb
[IFLA_STATS64
] && tb
[IFLA_STATS
] && show_stats
) {
370 struct rtnl_link_stats slocal
;
371 struct rtnl_link_stats
*s
= RTA_DATA(tb
[IFLA_STATS
]);
372 if (((unsigned long)s
) & (sizeof(unsigned long)-1)) {
373 memcpy(&slocal
, s
, sizeof(slocal
));
376 fprintf(fp
, "%s", _SL_
);
377 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
378 s
->rx_compressed
? "compressed" : "", _SL_
);
379 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
380 s
->rx_bytes
, s
->rx_packets
, s
->rx_errors
,
381 s
->rx_dropped
, s
->rx_over_errors
,
384 if (s
->rx_compressed
)
385 fprintf(fp
, " %-7u", s
->rx_compressed
);
386 if (show_stats
> 1) {
387 fprintf(fp
, "%s", _SL_
);
388 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
389 fprintf(fp
, " %-7u %-7u %-7u %-7u %-7u",
397 fprintf(fp
, "%s", _SL_
);
398 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
399 s
->tx_compressed
? "compressed" : "", _SL_
);
400 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
401 s
->tx_bytes
, s
->tx_packets
, s
->tx_errors
,
402 s
->tx_dropped
, s
->tx_carrier_errors
, s
->collisions
);
403 if (s
->tx_compressed
)
404 fprintf(fp
, " %-7u", s
->tx_compressed
);
405 if (show_stats
> 1) {
406 fprintf(fp
, "%s", _SL_
);
407 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
408 fprintf(fp
, " %-7u %-7u %-7u %-7u",
409 s
->tx_aborted_errors
,
412 s
->tx_heartbeat_errors
416 if (do_link
&& tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
417 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
418 int rem
= RTA_PAYLOAD(vflist
);
419 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
))
428 static int flush_update(void)
430 if (rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) {
431 perror("Failed to send flush request");
438 static int set_lifetime(unsigned int *lifetime
, char *argv
)
440 if (strcmp(argv
, "forever") == 0)
441 *lifetime
= INFINITY_LIFE_TIME
;
442 else if (get_u32(lifetime
, argv
, 0))
448 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
451 FILE *fp
= (FILE*)arg
;
452 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
453 int len
= n
->nlmsg_len
;
455 /* Use local copy of ifa_flags to not interfere with filtering code */
456 unsigned int ifa_flags
;
457 struct rtattr
* rta_tb
[IFA_MAX
+1];
461 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
463 len
-= NLMSG_LENGTH(sizeof(*ifa
));
465 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
469 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
472 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
), n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
474 if (!rta_tb
[IFA_LOCAL
])
475 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
476 if (!rta_tb
[IFA_ADDRESS
])
477 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
479 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
481 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
483 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
488 if (rta_tb
[IFA_LABEL
])
489 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
491 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
492 if (fnmatch(filter
.label
, label
, 0) != 0)
495 if (filter
.pfx
.family
) {
496 if (rta_tb
[IFA_LOCAL
]) {
498 memset(&dst
, 0, sizeof(dst
));
499 dst
.family
= ifa
->ifa_family
;
500 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
501 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
506 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
511 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
515 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
516 memcpy(fn
, n
, n
->nlmsg_len
);
517 fn
->nlmsg_type
= RTM_DELADDR
;
518 fn
->nlmsg_flags
= NLM_F_REQUEST
;
519 fn
->nlmsg_seq
= ++rth
.seq
;
520 filter
.flushp
= (((char*)fn
) + n
->nlmsg_len
) - filter
.flushb
;
526 if (n
->nlmsg_type
== RTM_DELADDR
)
527 fprintf(fp
, "Deleted ");
529 if (filter
.oneline
|| filter
.flushb
)
530 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
531 if (ifa
->ifa_family
== AF_INET
)
532 fprintf(fp
, " inet ");
533 else if (ifa
->ifa_family
== AF_INET6
)
534 fprintf(fp
, " inet6 ");
535 else if (ifa
->ifa_family
== AF_DECnet
)
536 fprintf(fp
, " dnet ");
537 else if (ifa
->ifa_family
== AF_IPX
)
538 fprintf(fp
, " ipx ");
540 fprintf(fp
, " family %d ", ifa
->ifa_family
);
542 if (rta_tb
[IFA_LOCAL
]) {
543 fprintf(fp
, "%s", rt_addr_n2a(ifa
->ifa_family
,
544 RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]),
545 RTA_DATA(rta_tb
[IFA_LOCAL
]),
546 abuf
, sizeof(abuf
)));
548 if (rta_tb
[IFA_ADDRESS
] == NULL
||
549 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]), RTA_DATA(rta_tb
[IFA_LOCAL
]), 4) == 0) {
550 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
552 fprintf(fp
, " peer %s/%d ",
553 rt_addr_n2a(ifa
->ifa_family
,
554 RTA_PAYLOAD(rta_tb
[IFA_ADDRESS
]),
555 RTA_DATA(rta_tb
[IFA_ADDRESS
]),
561 if (rta_tb
[IFA_BROADCAST
]) {
562 fprintf(fp
, "brd %s ",
563 rt_addr_n2a(ifa
->ifa_family
,
564 RTA_PAYLOAD(rta_tb
[IFA_BROADCAST
]),
565 RTA_DATA(rta_tb
[IFA_BROADCAST
]),
566 abuf
, sizeof(abuf
)));
568 if (rta_tb
[IFA_ANYCAST
]) {
569 fprintf(fp
, "any %s ",
570 rt_addr_n2a(ifa
->ifa_family
,
571 RTA_PAYLOAD(rta_tb
[IFA_ANYCAST
]),
572 RTA_DATA(rta_tb
[IFA_ANYCAST
]),
573 abuf
, sizeof(abuf
)));
575 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
576 ifa_flags
= ifa
->ifa_flags
;
577 if (ifa
->ifa_flags
&IFA_F_SECONDARY
) {
578 ifa_flags
&= ~IFA_F_SECONDARY
;
579 if (ifa
->ifa_family
== AF_INET6
)
580 fprintf(fp
, "temporary ");
582 fprintf(fp
, "secondary ");
584 if (ifa
->ifa_flags
&IFA_F_TENTATIVE
) {
585 ifa_flags
&= ~IFA_F_TENTATIVE
;
586 fprintf(fp
, "tentative ");
588 if (ifa
->ifa_flags
&IFA_F_DEPRECATED
) {
589 ifa_flags
&= ~IFA_F_DEPRECATED
;
591 fprintf(fp
, "deprecated ");
593 if (ifa
->ifa_flags
&IFA_F_HOMEADDRESS
) {
594 ifa_flags
&= ~IFA_F_HOMEADDRESS
;
595 fprintf(fp
, "home ");
597 if (ifa
->ifa_flags
&IFA_F_NODAD
) {
598 ifa_flags
&= ~IFA_F_NODAD
;
599 fprintf(fp
, "nodad ");
601 if (!(ifa
->ifa_flags
&IFA_F_PERMANENT
)) {
602 fprintf(fp
, "dynamic ");
604 ifa_flags
&= ~IFA_F_PERMANENT
;
605 if (ifa
->ifa_flags
&IFA_F_DADFAILED
) {
606 ifa_flags
&= ~IFA_F_DADFAILED
;
607 fprintf(fp
, "dadfailed ");
610 fprintf(fp
, "flags %02x ", ifa_flags
);
611 if (rta_tb
[IFA_LABEL
])
612 fprintf(fp
, "%s", (char*)RTA_DATA(rta_tb
[IFA_LABEL
]));
613 if (rta_tb
[IFA_CACHEINFO
]) {
614 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
615 fprintf(fp
, "%s", _SL_
);
616 fprintf(fp
, " valid_lft ");
617 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
)
618 fprintf(fp
, "forever");
620 fprintf(fp
, "%usec", ci
->ifa_valid
);
621 fprintf(fp
, " preferred_lft ");
622 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
)
623 fprintf(fp
, "forever");
626 fprintf(fp
, "%dsec", ci
->ifa_prefered
);
628 fprintf(fp
, "%usec", ci
->ifa_prefered
);
636 int print_addrinfo_primary(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
639 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
641 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
644 return print_addrinfo(who
, n
, arg
);
647 int print_addrinfo_secondary(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
650 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
652 if (!(ifa
->ifa_flags
& IFA_F_SECONDARY
))
655 return print_addrinfo(who
, n
, arg
);
660 struct nlmsg_list
*next
;
664 static int print_selected_addrinfo(int ifindex
, struct nlmsg_list
*ainfo
, FILE *fp
)
666 for ( ;ainfo
; ainfo
= ainfo
->next
) {
667 struct nlmsghdr
*n
= &ainfo
->h
;
668 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
670 if (n
->nlmsg_type
!= RTM_NEWADDR
)
673 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifa
)))
676 if (ifa
->ifa_index
!= ifindex
||
677 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
680 print_addrinfo(NULL
, n
, fp
);
686 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
689 struct nlmsg_list
**linfo
= (struct nlmsg_list
**)arg
;
690 struct nlmsg_list
*h
;
691 struct nlmsg_list
**lp
;
693 h
= malloc(n
->nlmsg_len
+sizeof(void*));
697 memcpy(&h
->h
, n
, n
->nlmsg_len
);
700 for (lp
= linfo
; *lp
; lp
= &(*lp
)->next
) /* NOTHING */;
703 ll_remember_index(who
, n
, NULL
);
707 static int ipaddr_list_or_flush(int argc
, char **argv
, int flush
)
709 struct nlmsg_list
*linfo
= NULL
;
710 struct nlmsg_list
*ainfo
= NULL
;
711 struct nlmsg_list
*l
, *n
;
712 char *filter_dev
= NULL
;
715 ipaddr_reset_filter(oneline
);
716 filter
.showqueue
= 1;
718 if (filter
.family
== AF_UNSPEC
)
719 filter
.family
= preferred_family
;
723 fprintf(stderr
, "Flush requires arguments.\n");
726 if (filter
.family
== AF_PACKET
) {
727 fprintf(stderr
, "Cannot flush link addresses.\n");
733 if (strcmp(*argv
, "to") == 0) {
735 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
736 if (filter
.family
== AF_UNSPEC
)
737 filter
.family
= filter
.pfx
.family
;
738 } else if (strcmp(*argv
, "scope") == 0) {
741 filter
.scopemask
= -1;
742 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
743 if (strcmp(*argv
, "all") != 0)
744 invarg("invalid \"scope\"\n", *argv
);
745 scope
= RT_SCOPE_NOWHERE
;
746 filter
.scopemask
= 0;
748 filter
.scope
= scope
;
749 } else if (strcmp(*argv
, "up") == 0) {
751 } else if (strcmp(*argv
, "dynamic") == 0) {
752 filter
.flags
&= ~IFA_F_PERMANENT
;
753 filter
.flagmask
|= IFA_F_PERMANENT
;
754 } else if (strcmp(*argv
, "permanent") == 0) {
755 filter
.flags
|= IFA_F_PERMANENT
;
756 filter
.flagmask
|= IFA_F_PERMANENT
;
757 } else if (strcmp(*argv
, "secondary") == 0 ||
758 strcmp(*argv
, "temporary") == 0) {
759 filter
.flags
|= IFA_F_SECONDARY
;
760 filter
.flagmask
|= IFA_F_SECONDARY
;
761 } else if (strcmp(*argv
, "primary") == 0) {
762 filter
.flags
&= ~IFA_F_SECONDARY
;
763 filter
.flagmask
|= IFA_F_SECONDARY
;
764 } else if (strcmp(*argv
, "tentative") == 0) {
765 filter
.flags
|= IFA_F_TENTATIVE
;
766 filter
.flagmask
|= IFA_F_TENTATIVE
;
767 } else if (strcmp(*argv
, "deprecated") == 0) {
768 filter
.flags
|= IFA_F_DEPRECATED
;
769 filter
.flagmask
|= IFA_F_DEPRECATED
;
770 } else if (strcmp(*argv
, "home") == 0) {
771 filter
.flags
|= IFA_F_HOMEADDRESS
;
772 filter
.flagmask
|= IFA_F_HOMEADDRESS
;
773 } else if (strcmp(*argv
, "nodad") == 0) {
774 filter
.flags
|= IFA_F_NODAD
;
775 filter
.flagmask
|= IFA_F_NODAD
;
776 } else if (strcmp(*argv
, "dadfailed") == 0) {
777 filter
.flags
|= IFA_F_DADFAILED
;
778 filter
.flagmask
|= IFA_F_DADFAILED
;
779 } else if (strcmp(*argv
, "label") == 0) {
781 filter
.label
= *argv
;
783 if (strcmp(*argv
, "dev") == 0) {
786 if (matches(*argv
, "help") == 0)
789 duparg2("dev", *argv
);
795 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETLINK
) < 0) {
796 perror("Cannot send dump request");
800 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
, NULL
, NULL
) < 0) {
801 fprintf(stderr
, "Dump terminated\n");
806 filter
.ifindex
= ll_name_to_index(filter_dev
);
807 if (filter
.ifindex
<= 0) {
808 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
815 char flushb
[4096-512];
817 filter
.flushb
= flushb
;
819 filter
.flushe
= sizeof(flushb
);
821 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
822 const struct rtnl_dump_filter_arg a
[3] = {
824 .filter
= print_addrinfo_secondary
,
830 .filter
= print_addrinfo_primary
,
842 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
843 perror("Cannot send dump request");
847 if (rtnl_dump_filter_l(&rth
, a
) < 0) {
848 fprintf(stderr
, "Flush terminated\n");
851 if (filter
.flushed
== 0) {
855 printf("Nothing to flush.\n");
857 printf("*** Flush is complete after %d round%s ***\n", round
, round
>1?"s":"");
863 if (flush_update() < 0)
867 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
871 /* If we are flushing, and specifying primary, then we
872 * want to flush only a single round. Otherwise, we'll
873 * start flushing secondaries that were promoted to
876 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
879 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
884 if (filter
.family
!= AF_PACKET
) {
885 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
886 perror("Cannot send dump request");
890 if (rtnl_dump_filter(&rth
, store_nlmsg
, &ainfo
, NULL
, NULL
) < 0) {
891 fprintf(stderr
, "Dump terminated\n");
897 if (filter
.family
&& filter
.family
!= AF_PACKET
) {
898 struct nlmsg_list
**lp
;
904 while ((l
=*lp
)!=NULL
) {
906 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
907 struct nlmsg_list
*a
;
909 for (a
=ainfo
; a
; a
=a
->next
) {
910 struct nlmsghdr
*n
= &a
->h
;
911 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
913 if (ifa
->ifa_index
!= ifi
->ifi_index
||
914 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
916 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
918 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
920 if (filter
.pfx
.family
|| filter
.label
) {
921 struct rtattr
*tb
[IFA_MAX
+1];
922 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
924 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
926 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
928 memset(&dst
, 0, sizeof(dst
));
929 dst
.family
= ifa
->ifa_family
;
930 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
931 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
938 label
= RTA_DATA(tb
[IFA_LABEL
]);
940 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
941 if (fnmatch(filter
.label
, label
, 0) != 0)
956 for (l
=linfo
; l
; l
= n
) {
958 if (no_link
|| print_linkinfo(NULL
, &l
->h
, stdout
) == 0) {
959 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
960 if (filter
.family
!= AF_PACKET
)
961 print_selected_addrinfo(ifi
->ifi_index
, ainfo
, stdout
);
970 int ipaddr_list_link(int argc
, char **argv
)
972 preferred_family
= AF_PACKET
;
974 return ipaddr_list_or_flush(argc
, argv
, 0);
977 void ipaddr_reset_filter(int oneline
)
979 memset(&filter
, 0, sizeof(filter
));
980 filter
.oneline
= oneline
;
983 static int default_scope(inet_prefix
*lcl
)
985 if (lcl
->family
== AF_INET
) {
986 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
987 return RT_SCOPE_HOST
;
992 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
996 struct ifaddrmsg ifa
;
1001 char *lcl_arg
= NULL
;
1002 char *valid_lftp
= NULL
;
1003 char *preferred_lftp
= NULL
;
1011 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
1012 __u32 valid_lft
= INFINITY_LIFE_TIME
;
1013 struct ifa_cacheinfo cinfo
;
1015 memset(&req
, 0, sizeof(req
));
1017 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1018 req
.n
.nlmsg_flags
= NLM_F_REQUEST
| flags
;
1019 req
.n
.nlmsg_type
= cmd
;
1020 req
.ifa
.ifa_family
= preferred_family
;
1023 if (strcmp(*argv
, "peer") == 0 ||
1024 strcmp(*argv
, "remote") == 0) {
1028 duparg("peer", *argv
);
1029 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
1030 peer_len
= peer
.bytelen
;
1031 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1032 req
.ifa
.ifa_family
= peer
.family
;
1033 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
1034 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
1035 } else if (matches(*argv
, "broadcast") == 0 ||
1036 strcmp(*argv
, "brd") == 0) {
1040 duparg("broadcast", *argv
);
1041 if (strcmp(*argv
, "+") == 0)
1043 else if (strcmp(*argv
, "-") == 0)
1046 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1047 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1048 req
.ifa
.ifa_family
= addr
.family
;
1049 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
1050 brd_len
= addr
.bytelen
;
1052 } else if (strcmp(*argv
, "anycast") == 0) {
1056 duparg("anycast", *argv
);
1057 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1058 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1059 req
.ifa
.ifa_family
= addr
.family
;
1060 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
1061 any_len
= addr
.bytelen
;
1062 } else if (strcmp(*argv
, "scope") == 0) {
1065 if (rtnl_rtscope_a2n(&scope
, *argv
))
1066 invarg(*argv
, "invalid scope value.");
1067 req
.ifa
.ifa_scope
= scope
;
1069 } else if (strcmp(*argv
, "dev") == 0) {
1072 } else if (strcmp(*argv
, "label") == 0) {
1075 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
1076 } else if (matches(*argv
, "valid_lft") == 0) {
1078 duparg("valid_lft", *argv
);
1081 if (set_lifetime(&valid_lft
, *argv
))
1082 invarg("valid_lft value", *argv
);
1083 } else if (matches(*argv
, "preferred_lft") == 0) {
1085 duparg("preferred_lft", *argv
);
1087 preferred_lftp
= *argv
;
1088 if (set_lifetime(&preferred_lft
, *argv
))
1089 invarg("preferred_lft value", *argv
);
1090 } else if (strcmp(*argv
, "home") == 0) {
1091 req
.ifa
.ifa_flags
|= IFA_F_HOMEADDRESS
;
1092 } else if (strcmp(*argv
, "nodad") == 0) {
1093 req
.ifa
.ifa_flags
|= IFA_F_NODAD
;
1095 if (strcmp(*argv
, "local") == 0) {
1098 if (matches(*argv
, "help") == 0)
1101 duparg2("local", *argv
);
1103 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
1104 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1105 req
.ifa
.ifa_family
= lcl
.family
;
1106 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
1107 local_len
= lcl
.bytelen
;
1112 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
1115 if (l
&& matches(d
, l
) != 0) {
1116 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
1120 if (peer_len
== 0 && local_len
) {
1121 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
1123 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1124 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1125 " This special behaviour is likely to disappear in further releases,\n" \
1126 " fix your scripts!\n", lcl_arg
, local_len
*8);
1129 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
1132 if (req
.ifa
.ifa_prefixlen
== 0)
1133 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
1135 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
1138 if (req
.ifa
.ifa_family
!= AF_INET
) {
1139 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
1143 if (brd
.bitlen
<= 30) {
1144 for (i
=31; i
>=brd
.bitlen
; i
--) {
1146 brd
.data
[0] |= htonl(1<<(31-i
));
1148 brd
.data
[0] &= ~htonl(1<<(31-i
));
1150 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
1151 brd_len
= brd
.bytelen
;
1154 if (!scoped
&& cmd
!= RTM_DELADDR
)
1155 req
.ifa
.ifa_scope
= default_scope(&lcl
);
1159 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
1160 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
1164 if (valid_lftp
|| preferred_lftp
) {
1166 fprintf(stderr
, "valid_lft is zero\n");
1169 if (valid_lft
< preferred_lft
) {
1170 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
1174 memset(&cinfo
, 0, sizeof(cinfo
));
1175 cinfo
.ifa_prefered
= preferred_lft
;
1176 cinfo
.ifa_valid
= valid_lft
;
1177 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
1181 if (rtnl_talk(&rth
, &req
.n
, 0, 0, NULL
, NULL
, NULL
) < 0)
1187 int do_ipaddr(int argc
, char **argv
)
1190 return ipaddr_list_or_flush(0, NULL
, 0);
1191 if (matches(*argv
, "add") == 0)
1192 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
1193 if (matches(*argv
, "change") == 0 ||
1194 strcmp(*argv
, "chg") == 0)
1195 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
1196 if (matches(*argv
, "replace") == 0)
1197 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
1198 if (matches(*argv
, "delete") == 0)
1199 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
1200 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
1201 || matches(*argv
, "lst") == 0)
1202 return ipaddr_list_or_flush(argc
-1, argv
+1, 0);
1203 if (matches(*argv
, "flush") == 0)
1204 return ipaddr_list_or_flush(argc
-1, argv
+1, 1);
1205 if (matches(*argv
, "help") == 0)
1207 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv
);