1/* 2 * ipaddress.c "ip address". 3 * 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. 8 * 9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10 * 11 */ 12 13#include <stdio.h> 14#include <stdlib.h> 15#include <unistd.h> 16#include <syslog.h> 17#include <inttypes.h> 18#include <fcntl.h> 19#include <sys/ioctl.h> 20#include <sys/socket.h> 21#include <sys/param.h> 22#include <errno.h> 23#include <netinet/in.h> 24#include <arpa/inet.h> 25#include <string.h> 26#include <fnmatch.h> 27 28#include <linux/netdevice.h> 29#include <linux/if_arp.h> 30#include <linux/sockios.h> 31#include <linux/net_namespace.h> 32 33#include "utils.h" 34#include "rt_names.h" 35#include "utils.h" 36#include "ll_map.h" 37#include "ip_common.h" 38#include "xdp.h" 39#include "color.h" 40 41enum { 42 IPADD_LIST, 43 IPADD_FLUSH, 44 IPADD_SAVE, 45}; 46 47static struct link_filter filter; 48static int do_link; 49 50static void usage(void) __attribute__((noreturn)); 51 52static void usage(void) 53{ 54 if (do_link) { 55 iplink_usage(); 56 } 57 fprintf(stderr, "Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]\n"); 58 fprintf(stderr, " [ CONFFLAG-LIST ]\n"); 59 fprintf(stderr, " ip address del IFADDR dev IFNAME [mngtmpaddr]\n"); 60 fprintf(stderr, " ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]\n"); 61 fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n"); 62 fprintf(stderr, " ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n"); 63 fprintf(stderr, " [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n"); 64 fprintf(stderr, " [ label LABEL ] [up] [ vrf NAME ] ]\n"); 65 fprintf(stderr, " ip address {showdump|restore}\n"); 66 fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n"); 67 fprintf(stderr, " [ broadcast ADDR ] [ anycast ADDR ]\n"); 68 fprintf(stderr, " [ label IFNAME ] [ scope SCOPE-ID ]\n"); 69 fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n"); 70 fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); 71 fprintf(stderr, "FLAG := [ permanent | dynamic | secondary | primary |\n"); 72 fprintf(stderr, " [-]tentative | [-]deprecated | [-]dadfailed | temporary |\n"); 73 fprintf(stderr, " CONFFLAG-LIST ]\n"); 74 fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n"); 75 fprintf(stderr, "CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n"); 76 fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n"); 77 fprintf(stderr, "LFT := forever | SECONDS\n"); 78 fprintf(stderr, "TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |\n"); 79 fprintf(stderr, " bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |\n"); 80 fprintf(stderr, " gre | gretap | erspan | ip6gre | ip6gretap | vti | nlmon | can |\n"); 81 fprintf(stderr, " bond_slave | ipvlan | geneve | bridge_slave | vrf | hsr | macsec }\n"); 82 83 exit(-1); 84} 85 86static void print_link_flags(FILE *fp, unsigned int flags, unsigned int mdown) 87{ 88 open_json_array(PRINT_ANY, is_json_context() ? "flags" : "<"); 89 if (flags & IFF_UP && !(flags & IFF_RUNNING)) 90 print_string(PRINT_ANY, NULL, 91 flags ? "%s," : "%s", "NO-CARRIER"); 92 flags &= ~IFF_RUNNING; 93#define _PF(f) if (flags&IFF_##f) { \ 94 flags &= ~IFF_##f ; \ 95 print_string(PRINT_ANY, NULL, flags ? "%s," : "%s", #f); } 96 _PF(LOOPBACK); 97 _PF(BROADCAST); 98 _PF(POINTOPOINT); 99 _PF(MULTICAST); 100 _PF(NOARP); 101 _PF(ALLMULTI); 102 _PF(PROMISC); 103 _PF(MASTER); 104 _PF(SLAVE); 105 _PF(DEBUG); 106 _PF(DYNAMIC); 107 _PF(AUTOMEDIA); 108 _PF(PORTSEL); 109 _PF(NOTRAILERS); 110 _PF(UP); 111 _PF(LOWER_UP); 112 _PF(DORMANT); 113 _PF(ECHO); 114#undef _PF 115 if (flags) 116 print_hex(PRINT_ANY, NULL, "%x", flags); 117 if (mdown) 118 print_string(PRINT_ANY, NULL, ",%s", "M-DOWN"); 119 close_json_array(PRINT_ANY, "> "); 120} 121 122static const char *oper_states[] = { 123 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN", 124 "TESTING", "DORMANT", "UP" 125}; 126 127static void print_operstate(FILE *f, __u8 state) 128{ 129 if (state >= ARRAY_SIZE(oper_states)) { 130 if (is_json_context()) 131 print_uint(PRINT_JSON, "operstate_index", NULL, state); 132 else 133 print_0xhex(PRINT_FP, NULL, "state %#x", state); 134 } else if (brief) { 135 print_color_string(PRINT_ANY, 136 oper_state_color(state), 137 "operstate", 138 "%-14s ", 139 oper_states[state]); 140 } else { 141 if (is_json_context()) 142 print_string(PRINT_JSON, 143 "operstate", 144 NULL, oper_states[state]); 145 else { 146 fprintf(f, "state "); 147 color_fprintf(f, oper_state_color(state), 148 "%s ", oper_states[state]); 149 } 150 } 151} 152 153int get_operstate(const char *name) 154{ 155 int i; 156 157 for (i = 0; i < ARRAY_SIZE(oper_states); i++) 158 if (strcasecmp(name, oper_states[i]) == 0) 159 return i; 160 return -1; 161} 162 163static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1]) 164{ 165 int qlen; 166 167 if (tb[IFLA_TXQLEN]) 168 qlen = rta_getattr_u32(tb[IFLA_TXQLEN]); 169 else { 170 struct ifreq ifr = {}; 171 int s = socket(AF_INET, SOCK_STREAM, 0); 172 173 if (s < 0) 174 return; 175 176 strcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME])); 177 if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { 178 fprintf(f, "ioctl(SIOCGIFTXQLEN) failed: %s\n", strerror(errno)); 179 close(s); 180 return; 181 } 182 close(s); 183 qlen = ifr.ifr_qlen; 184 } 185 if (qlen) 186 print_int(PRINT_ANY, "txqlen", "qlen %d", qlen); 187} 188 189static const char *link_modes[] = { 190 "DEFAULT", "DORMANT" 191}; 192 193static void print_linkmode(FILE *f, struct rtattr *tb) 194{ 195 unsigned int mode = rta_getattr_u8(tb); 196 197 if (mode >= ARRAY_SIZE(link_modes)) 198 print_int(PRINT_ANY, 199 "linkmode_index", 200 "mode %d ", 201 mode); 202 else 203 print_string(PRINT_ANY, 204 "linkmode", 205 "mode %s " 206 , link_modes[mode]); 207} 208 209static char *parse_link_kind(struct rtattr *tb, bool slave) 210{ 211 struct rtattr *linkinfo[IFLA_INFO_MAX+1]; 212 int attr = slave ? IFLA_INFO_SLAVE_KIND : IFLA_INFO_KIND; 213 214 parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb); 215 216 if (linkinfo[attr]) 217 return RTA_DATA(linkinfo[attr]); 218 219 return ""; 220} 221 222static int match_link_kind(struct rtattr **tb, const char *kind, bool slave) 223{ 224 if (!tb[IFLA_LINKINFO]) 225 return -1; 226 227 return strcmp(parse_link_kind(tb[IFLA_LINKINFO], slave), kind); 228} 229 230static void print_linktype(FILE *fp, struct rtattr *tb) 231{ 232 struct rtattr *linkinfo[IFLA_INFO_MAX+1]; 233 struct link_util *lu; 234 struct link_util *slave_lu; 235 char slave[32]; 236 237 parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb); 238 open_json_object("linkinfo"); 239 240 if (linkinfo[IFLA_INFO_KIND]) { 241 const char *kind 242 = rta_getattr_str(linkinfo[IFLA_INFO_KIND]); 243 244 print_string(PRINT_FP, NULL, "%s", _SL_); 245 print_string(PRINT_ANY, "info_kind", " %s ", kind); 246 247 lu = get_link_kind(kind); 248 if (lu && lu->print_opt) { 249 struct rtattr *attr[lu->maxattr+1], **data = NULL; 250 251 if (linkinfo[IFLA_INFO_DATA]) { 252 parse_rtattr_nested(attr, lu->maxattr, 253 linkinfo[IFLA_INFO_DATA]); 254 data = attr; 255 } 256 open_json_object("info_data"); 257 lu->print_opt(lu, fp, data); 258 close_json_object(); 259 260 if (linkinfo[IFLA_INFO_XSTATS] && show_stats && 261 lu->print_xstats) { 262 open_json_object("info_xstats"); 263 lu->print_xstats(lu, fp, linkinfo[IFLA_INFO_XSTATS]); 264 close_json_object(); 265 } 266 } 267 } 268 269 if (linkinfo[IFLA_INFO_SLAVE_KIND]) { 270 const char *slave_kind 271 = rta_getattr_str(linkinfo[IFLA_INFO_SLAVE_KIND]); 272 273 print_string(PRINT_FP, NULL, "%s", _SL_); 274 print_string(PRINT_ANY, 275 "info_slave_kind", 276 " %s_slave ", 277 slave_kind); 278 279 snprintf(slave, sizeof(slave), "%s_slave", slave_kind); 280 281 slave_lu = get_link_kind(slave); 282 if (slave_lu && slave_lu->print_opt) { 283 struct rtattr *attr[slave_lu->maxattr+1], **data = NULL; 284 285 if (linkinfo[IFLA_INFO_SLAVE_DATA]) { 286 parse_rtattr_nested(attr, slave_lu->maxattr, 287 linkinfo[IFLA_INFO_SLAVE_DATA]); 288 data = attr; 289 } 290 open_json_object("info_slave_data"); 291 slave_lu->print_opt(slave_lu, fp, data); 292 close_json_object(); 293 } 294 } 295 close_json_object(); 296} 297 298static void print_af_spec(FILE *fp, struct rtattr *af_spec_attr) 299{ 300 struct rtattr *inet6_attr; 301 struct rtattr *tb[IFLA_INET6_MAX + 1]; 302 303 inet6_attr = parse_rtattr_one_nested(AF_INET6, af_spec_attr); 304 if (!inet6_attr) 305 return; 306 307 parse_rtattr_nested(tb, IFLA_INET6_MAX, inet6_attr); 308 309 if (tb[IFLA_INET6_ADDR_GEN_MODE]) { 310 __u8 mode = rta_getattr_u8(tb[IFLA_INET6_ADDR_GEN_MODE]); 311 SPRINT_BUF(b1); 312 313 switch (mode) { 314 case IN6_ADDR_GEN_MODE_EUI64: 315 print_string(PRINT_ANY, 316 "inet6_addr_gen_mode", 317 "addrgenmode %s ", 318 "eui64"); 319 break; 320 case IN6_ADDR_GEN_MODE_NONE: 321 print_string(PRINT_ANY, 322 "inet6_addr_gen_mode", 323 "addrgenmode %s ", 324 "none"); 325 break; 326 case IN6_ADDR_GEN_MODE_STABLE_PRIVACY: 327 print_string(PRINT_ANY, 328 "inet6_addr_gen_mode", 329 "addrgenmode %s ", 330 "stable_secret"); 331 break; 332 case IN6_ADDR_GEN_MODE_RANDOM: 333 print_string(PRINT_ANY, 334 "inet6_addr_gen_mode", 335 "addrgenmode %s ", 336 "random"); 337 break; 338 default: 339 snprintf(b1, sizeof(b1), "%#.2hhx", mode); 340 print_string(PRINT_ANY, 341 "inet6_addr_gen_mode", 342 "addrgenmode %s ", 343 b1); 344 break; 345 } 346 } 347} 348 349static void print_vf_stats64(FILE *fp, struct rtattr *vfstats); 350 351static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) 352{ 353 struct ifla_vf_mac *vf_mac; 354 struct ifla_vf_tx_rate *vf_tx_rate; 355 struct rtattr *vf[IFLA_VF_MAX + 1] = {}; 356 357 SPRINT_BUF(b1); 358 359 if (vfinfo->rta_type != IFLA_VF_INFO) { 360 fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type); 361 return; 362 } 363 364 parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo); 365 366 vf_mac = RTA_DATA(vf[IFLA_VF_MAC]); 367 vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]); 368 369 print_string(PRINT_FP, NULL, "%s ", _SL_); 370 print_int(PRINT_ANY, "vf", "vf %d ", vf_mac->vf); 371 print_string(PRINT_ANY, "mac", "MAC %s", 372 ll_addr_n2a((unsigned char *) &vf_mac->mac, 373 ETH_ALEN, 0, b1, sizeof(b1))); 374 375 if (vf[IFLA_VF_VLAN_LIST]) { 376 struct rtattr *i, *vfvlanlist = vf[IFLA_VF_VLAN_LIST]; 377 int rem = RTA_PAYLOAD(vfvlanlist); 378 379 open_json_array(PRINT_JSON, "vlan_list"); 380 for (i = RTA_DATA(vfvlanlist); 381 RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { 382 struct ifla_vf_vlan_info *vf_vlan_info = RTA_DATA(i); 383 SPRINT_BUF(b2); 384 385 open_json_object(NULL); 386 if (vf_vlan_info->vlan) 387 print_int(PRINT_ANY, 388 "vlan", 389 ", vlan %d", 390 vf_vlan_info->vlan); 391 if (vf_vlan_info->qos) 392 print_int(PRINT_ANY, 393 "qos", 394 ", qos %d", 395 vf_vlan_info->qos); 396 if (vf_vlan_info->vlan_proto && 397 vf_vlan_info->vlan_proto != htons(ETH_P_8021Q)) 398 print_string(PRINT_ANY, 399 "protocol", 400 ", vlan protocol %s", 401 ll_proto_n2a( 402 vf_vlan_info->vlan_proto, 403 b2, sizeof(b2))); 404 close_json_object(); 405 } 406 close_json_array(PRINT_JSON, NULL); 407 } else { 408 struct ifla_vf_vlan *vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]); 409 410 if (vf_vlan->vlan) 411 print_int(PRINT_ANY, 412 "vlan", 413 ", vlan %d", 414 vf_vlan->vlan); 415 if (vf_vlan->qos) 416 print_int(PRINT_ANY, "qos", ", qos %d", vf_vlan->qos); 417 } 418 419 if (vf_tx_rate->rate) 420 print_int(PRINT_ANY, 421 "tx_rate", 422 ", tx rate %d (Mbps)", 423 vf_tx_rate->rate); 424 425 if (vf[IFLA_VF_RATE]) { 426 struct ifla_vf_rate *vf_rate = RTA_DATA(vf[IFLA_VF_RATE]); 427 int max_tx = vf_rate->max_tx_rate; 428 int min_tx = vf_rate->min_tx_rate; 429 430 if (is_json_context()) { 431 open_json_object("rate"); 432 print_int(PRINT_JSON, "max_tx", NULL, max_tx); 433 print_int(PRINT_ANY, "min_tx", NULL, min_tx); 434 close_json_object(); 435 } else { 436 if (max_tx) 437 fprintf(fp, ", max_tx_rate %dMbps", max_tx); 438 if (min_tx) 439 fprintf(fp, ", min_tx_rate %dMbps", min_tx); 440 } 441 } 442 443 if (vf[IFLA_VF_SPOOFCHK]) { 444 struct ifla_vf_spoofchk *vf_spoofchk = 445 RTA_DATA(vf[IFLA_VF_SPOOFCHK]); 446 447 if (vf_spoofchk->setting != -1) 448 print_bool(PRINT_ANY, 449 "spoofchk", 450 vf_spoofchk->setting ? 451 ", spoof checking on" : ", spoof checking off", 452 vf_spoofchk->setting); 453 } 454 455 if (vf[IFLA_VF_LINK_STATE]) { 456 struct ifla_vf_link_state *vf_linkstate = 457 RTA_DATA(vf[IFLA_VF_LINK_STATE]); 458 459 if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_AUTO) 460 print_string(PRINT_ANY, 461 "link_state", 462 ", link-state %s", 463 "auto"); 464 else if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_ENABLE) 465 print_string(PRINT_ANY, 466 "link_state", 467 ", link-state %s", 468 "enable"); 469 else 470 print_string(PRINT_ANY, 471 "link_state", 472 ", link-state %s", 473 "disable"); 474 } 475 476 if (vf[IFLA_VF_TRUST]) { 477 struct ifla_vf_trust *vf_trust = RTA_DATA(vf[IFLA_VF_TRUST]); 478 479 if (vf_trust->setting != -1) 480 print_bool(PRINT_ANY, 481 "trust", 482 vf_trust->setting ? ", trust on" : ", trust off", 483 vf_trust->setting); 484 } 485 486 if (vf[IFLA_VF_RSS_QUERY_EN]) { 487 struct ifla_vf_rss_query_en *rss_query = 488 RTA_DATA(vf[IFLA_VF_RSS_QUERY_EN]); 489 490 if (rss_query->setting != -1) 491 print_bool(PRINT_ANY, 492 "query_rss_en", 493 rss_query->setting ? ", query_rss on" 494 : ", query_rss off", 495 rss_query->setting); 496 } 497 498 if (vf[IFLA_VF_STATS] && show_stats) 499 print_vf_stats64(fp, vf[IFLA_VF_STATS]); 500} 501 502void print_num(FILE *fp, unsigned int width, uint64_t count) 503{ 504 const char *prefix = "kMGTPE"; 505 const unsigned int base = use_iec ? 1024 : 1000; 506 uint64_t powi = 1; 507 uint16_t powj = 1; 508 uint8_t precision = 2; 509 char buf[64]; 510 511 if (!human_readable || count < base) { 512 fprintf(fp, "%-*"PRIu64" ", width, count); 513 return; 514 } 515 516 /* increase value by a factor of 1000/1024 and print 517 * if result is something a human can read 518 */ 519 for (;;) { 520 powi *= base; 521 if (count / base < powi) 522 break; 523 524 if (!prefix[1]) 525 break; 526 ++prefix; 527 } 528 529 /* try to guess a good number of digits for precision */ 530 for (; precision > 0; precision--) { 531 powj *= 10; 532 if (count / powi < powj) 533 break; 534 } 535 536 snprintf(buf, sizeof(buf), "%.*f%c%s", precision, 537 (double) count / powi, *prefix, use_iec ? "i" : ""); 538 539 fprintf(fp, "%-*s ", width, buf); 540} 541 542static void print_vf_stats64(FILE *fp, struct rtattr *vfstats) 543{ 544 struct rtattr *vf[IFLA_VF_STATS_MAX + 1]; 545 546 if (vfstats->rta_type != IFLA_VF_STATS) { 547 fprintf(stderr, "BUG: rta type is %d\n", vfstats->rta_type); 548 return; 549 } 550 551 parse_rtattr_nested(vf, IFLA_VF_MAX, vfstats); 552 553 if (is_json_context()) { 554 open_json_object("stats"); 555 556 /* RX stats */ 557 open_json_object("rx"); 558 print_uint(PRINT_JSON, "bytes", NULL, 559 rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES])); 560 print_uint(PRINT_JSON, "packets", NULL, 561 rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS])); 562 print_uint(PRINT_JSON, "multicast", NULL, 563 rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST])); 564 print_uint(PRINT_JSON, "broadcast", NULL, 565 rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST])); 566 close_json_object(); 567 568 /* TX stats */ 569 open_json_object("tx"); 570 print_uint(PRINT_JSON, "tx_bytes", NULL, 571 rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES])); 572 print_uint(PRINT_JSON, "tx_packets", NULL, 573 rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS])); 574 close_json_object(); 575 close_json_object(); 576 } else { 577 /* RX stats */ 578 fprintf(fp, "%s", _SL_); 579 fprintf(fp, " RX: bytes packets mcast bcast %s", _SL_); 580 fprintf(fp, " "); 581 582 print_num(fp, 10, rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES])); 583 print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS])); 584 print_num(fp, 7, rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST])); 585 print_num(fp, 7, rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST])); 586 587 /* TX stats */ 588 fprintf(fp, "%s", _SL_); 589 fprintf(fp, " TX: bytes packets %s", _SL_); 590 fprintf(fp, " "); 591 592 print_num(fp, 10, rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES])); 593 print_num(fp, 8, rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS])); 594 } 595} 596 597static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s, 598 const struct rtattr *carrier_changes) 599{ 600 if (is_json_context()) { 601 open_json_object("stats644"); 602 603 /* RX stats */ 604 open_json_object("rx"); 605 print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes); 606 print_uint(PRINT_JSON, "packets", NULL, s->rx_packets); 607 print_uint(PRINT_JSON, "errors", NULL, s->rx_errors); 608 print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped); 609 print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors); 610 print_uint(PRINT_JSON, "multicast", NULL, s->multicast); 611 if (s->rx_compressed) 612 print_uint(PRINT_JSON, 613 "compressed", 614 NULL, s->rx_compressed); 615 616 /* RX error stats */ 617 if (show_stats > 1) { 618 print_uint(PRINT_JSON, 619 "length_errors", 620 NULL, s->rx_length_errors); 621 print_uint(PRINT_JSON, 622 "crc_errors", 623 NULL, s->rx_crc_errors); 624 print_uint(PRINT_JSON, 625 "frame_errors", 626 NULL, s->rx_frame_errors); 627 print_uint(PRINT_JSON, 628 "fifo_errors", 629 NULL, s->rx_fifo_errors); 630 print_uint(PRINT_JSON, 631 "missed_errors", 632 NULL, s->rx_missed_errors); 633 if (s->rx_nohandler) 634 print_uint(PRINT_JSON, 635 "nohandler", NULL, s->rx_nohandler); 636 } 637 close_json_object(); 638 639 /* TX stats */ 640 open_json_object("tx"); 641 print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes); 642 print_uint(PRINT_JSON, "packets", NULL, s->tx_packets); 643 print_uint(PRINT_JSON, "errors", NULL, s->tx_errors); 644 print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped); 645 print_uint(PRINT_JSON, 646 "carrier_errors", 647 NULL, s->tx_carrier_errors); 648 print_uint(PRINT_JSON, "collisions", NULL, s->collisions); 649 if (s->tx_compressed) 650 print_uint(PRINT_JSON, 651 "compressed", 652 NULL, s->tx_compressed); 653 654 /* TX error stats */ 655 if (show_stats > 1) { 656 print_uint(PRINT_JSON, 657 "aborted_errors", 658 NULL, s->tx_aborted_errors); 659 print_uint(PRINT_JSON, 660 "fifo_errors", 661 NULL, s->tx_fifo_errors); 662 print_uint(PRINT_JSON, 663 "window_errors", 664 NULL, s->tx_window_errors); 665 print_uint(PRINT_JSON, 666 "heartbeat_errors", 667 NULL, s->tx_heartbeat_errors); 668 if (carrier_changes) 669 print_uint(PRINT_JSON, "carrier_changes", NULL, 670 rta_getattr_u32(carrier_changes)); 671 } 672 close_json_object(); 673 close_json_object(); 674 675 } else { 676 /* RX stats */ 677 fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", 678 s->rx_compressed ? "compressed" : "", _SL_); 679 680 fprintf(fp, " "); 681 print_num(fp, 10, s->rx_bytes); 682 print_num(fp, 8, s->rx_packets); 683 print_num(fp, 7, s->rx_errors); 684 print_num(fp, 7, s->rx_dropped); 685 print_num(fp, 7, s->rx_over_errors); 686 print_num(fp, 7, s->multicast); 687 if (s->rx_compressed) 688 print_num(fp, 7, s->rx_compressed); 689 690 /* RX error stats */ 691 if (show_stats > 1) { 692 fprintf(fp, "%s", _SL_); 693 fprintf(fp, " RX errors: length crc frame fifo missed%s%s", 694 s->rx_nohandler ? " nohandler" : "", _SL_); 695 696 fprintf(fp, " "); 697 print_num(fp, 8, s->rx_length_errors); 698 print_num(fp, 7, s->rx_crc_errors); 699 print_num(fp, 7, s->rx_frame_errors); 700 print_num(fp, 7, s->rx_fifo_errors); 701 print_num(fp, 7, s->rx_missed_errors); 702 if (s->rx_nohandler) 703 print_num(fp, 7, s->rx_nohandler); 704 705 } 706 fprintf(fp, "%s", _SL_); 707 708 /* TX stats */ 709 fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", 710 s->tx_compressed ? "compressed" : "", _SL_); 711 712 fprintf(fp, " "); 713 print_num(fp, 10, s->tx_bytes); 714 print_num(fp, 8, s->tx_packets); 715 print_num(fp, 7, s->tx_errors); 716 print_num(fp, 7, s->tx_dropped); 717 print_num(fp, 7, s->tx_carrier_errors); 718 print_num(fp, 7, s->collisions); 719 if (s->tx_compressed) 720 print_num(fp, 7, s->tx_compressed); 721 722 /* TX error stats */ 723 if (show_stats > 1) { 724 fprintf(fp, "%s", _SL_); 725 fprintf(fp, " TX errors: aborted fifo window heartbeat"); 726 if (carrier_changes) 727 fprintf(fp, " transns"); 728 fprintf(fp, "%s", _SL_); 729 730 fprintf(fp, " "); 731 print_num(fp, 8, s->tx_aborted_errors); 732 print_num(fp, 7, s->tx_fifo_errors); 733 print_num(fp, 7, s->tx_window_errors); 734 print_num(fp, 7, s->tx_heartbeat_errors); 735 if (carrier_changes) 736 print_num(fp, 7, 737 rta_getattr_u32(carrier_changes)); 738 } 739 } 740} 741 742static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s, 743 const struct rtattr *carrier_changes) 744{ 745 if (is_json_context()) { 746 open_json_object("stats"); 747 748 /* RX stats */ 749 open_json_object("rx"); 750 print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes); 751 print_uint(PRINT_JSON, "packets", NULL, s->rx_packets); 752 print_uint(PRINT_JSON, "errors", NULL, s->rx_errors); 753 print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped); 754 print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors); 755 print_uint(PRINT_JSON, "multicast", NULL, s->multicast); 756 if (s->rx_compressed) 757 print_int(PRINT_JSON, 758 "compressed", 759 NULL, s->rx_compressed); 760 761 /* RX error stats */ 762 if (show_stats > 1) { 763 print_uint(PRINT_JSON, 764 "length_errors", 765 NULL, s->rx_length_errors); 766 print_uint(PRINT_JSON, 767 "crc_errors", 768 NULL, s->rx_crc_errors); 769 print_uint(PRINT_JSON, 770 "frame_errors", 771 NULL, s->rx_frame_errors); 772 print_uint(PRINT_JSON, 773 "fifo_errors", 774 NULL, s->rx_fifo_errors); 775 print_uint(PRINT_JSON, 776 "missed_errors", 777 NULL, s->rx_missed_errors); 778 if (s->rx_nohandler) 779 print_int(PRINT_JSON, 780 "nohandler", 781 NULL, s->rx_nohandler); 782 } 783 close_json_object(); 784 785 /* TX stats */ 786 open_json_object("tx"); 787 print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes); 788 print_uint(PRINT_JSON, "packets", NULL, s->tx_packets); 789 print_uint(PRINT_JSON, "errors", NULL, s->tx_errors); 790 print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped); 791 print_uint(PRINT_JSON, 792 "carrier_errors", 793 NULL, s->tx_carrier_errors); 794 print_uint(PRINT_JSON, "collisions", NULL, s->collisions); 795 if (s->tx_compressed) 796 print_int(PRINT_JSON, 797 "compressed", 798 NULL, s->tx_compressed); 799 800 /* TX error stats */ 801 if (show_stats > 1) { 802 print_uint(PRINT_JSON, 803 "aborted_errors", 804 NULL, s->tx_aborted_errors); 805 print_uint(PRINT_JSON, 806 "fifo_errors", 807 NULL, s->tx_fifo_errors); 808 print_uint(PRINT_JSON, 809 "window_errors", 810 NULL, s->tx_window_errors); 811 print_uint(PRINT_JSON, 812 "heartbeat_errors", 813 NULL, s->tx_heartbeat_errors); 814 if (carrier_changes) 815 print_uint(PRINT_JSON, 816 "carrier_changes", 817 NULL, 818 rta_getattr_u32(carrier_changes)); 819 } 820 821 close_json_object(); 822 close_json_object(); 823 } else { 824 /* RX stats */ 825 fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", 826 s->rx_compressed ? "compressed" : "", _SL_); 827 828 829 fprintf(fp, " "); 830 print_num(fp, 10, s->rx_bytes); 831 print_num(fp, 8, s->rx_packets); 832 print_num(fp, 7, s->rx_errors); 833 print_num(fp, 7, s->rx_dropped); 834 print_num(fp, 7, s->rx_over_errors); 835 print_num(fp, 7, s->multicast); 836 if (s->rx_compressed) 837 print_num(fp, 7, s->rx_compressed); 838 839 /* RX error stats */ 840 if (show_stats > 1) { 841 fprintf(fp, "%s", _SL_); 842 fprintf(fp, " RX errors: length crc frame fifo missed%s%s", 843 s->rx_nohandler ? " nohandler" : "", _SL_); 844 fprintf(fp, " "); 845 print_num(fp, 8, s->rx_length_errors); 846 print_num(fp, 7, s->rx_crc_errors); 847 print_num(fp, 7, s->rx_frame_errors); 848 print_num(fp, 7, s->rx_fifo_errors); 849 print_num(fp, 7, s->rx_missed_errors); 850 if (s->rx_nohandler) 851 print_num(fp, 7, s->rx_nohandler); 852 } 853 fprintf(fp, "%s", _SL_); 854 855 /* TX stats */ 856 fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", 857 s->tx_compressed ? "compressed" : "", _SL_); 858 859 fprintf(fp, " "); 860 print_num(fp, 10, s->tx_bytes); 861 print_num(fp, 8, s->tx_packets); 862 print_num(fp, 7, s->tx_errors); 863 print_num(fp, 7, s->tx_dropped); 864 print_num(fp, 7, s->tx_carrier_errors); 865 print_num(fp, 7, s->collisions); 866 if (s->tx_compressed) 867 print_num(fp, 7, s->tx_compressed); 868 869 /* TX error stats */ 870 if (show_stats > 1) { 871 fprintf(fp, "%s", _SL_); 872 fprintf(fp, " TX errors: aborted fifo window heartbeat"); 873 if (carrier_changes) 874 fprintf(fp, " transns"); 875 fprintf(fp, "%s", _SL_); 876 877 fprintf(fp, " "); 878 print_num(fp, 8, s->tx_aborted_errors); 879 print_num(fp, 7, s->tx_fifo_errors); 880 print_num(fp, 7, s->tx_window_errors); 881 print_num(fp, 7, s->tx_heartbeat_errors); 882 if (carrier_changes) 883 print_num(fp, 7, 884 rta_getattr_u32(carrier_changes)); 885 } 886 } 887} 888 889static void __print_link_stats(FILE *fp, struct rtattr **tb) 890{ 891 const struct rtattr *carrier_changes = tb[IFLA_CARRIER_CHANGES]; 892 893 if (tb[IFLA_STATS64]) { 894 struct rtnl_link_stats64 stats = { 0 }; 895 896 memcpy(&stats, RTA_DATA(tb[IFLA_STATS64]), 897 MIN(RTA_PAYLOAD(tb[IFLA_STATS64]), sizeof(stats))); 898 899 print_link_stats64(fp, &stats, carrier_changes); 900 } else if (tb[IFLA_STATS]) { 901 struct rtnl_link_stats stats = { 0 }; 902 903 memcpy(&stats, RTA_DATA(tb[IFLA_STATS]), 904 MIN(RTA_PAYLOAD(tb[IFLA_STATS]), sizeof(stats))); 905 906 print_link_stats32(fp, &stats, carrier_changes); 907 } 908} 909 910static void print_link_stats(FILE *fp, struct nlmsghdr *n) 911{ 912 struct ifinfomsg *ifi = NLMSG_DATA(n); 913 struct rtattr *tb[IFLA_MAX+1]; 914 915 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), 916 n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi))); 917 __print_link_stats(fp, tb); 918 fprintf(fp, "%s", _SL_); 919} 920 921int print_linkinfo_brief(const struct sockaddr_nl *who, 922 struct nlmsghdr *n, void *arg, 923 struct link_filter *pfilter) 924{ 925 FILE *fp = (FILE *)arg; 926 struct ifinfomsg *ifi = NLMSG_DATA(n); 927 struct rtattr *tb[IFLA_MAX+1]; 928 int len = n->nlmsg_len; 929 const char *name; 930 char buf[32] = { 0, }; 931 unsigned int m_flag = 0; 932 933 if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) 934 return -1; 935 936 len -= NLMSG_LENGTH(sizeof(*ifi)); 937 if (len < 0) 938 return -1; 939 940 if (!pfilter) 941 pfilter = &filter; 942 943 if (pfilter->ifindex && ifi->ifi_index != pfilter->ifindex) 944 return -1; 945 if (pfilter->up && !(ifi->ifi_flags&IFF_UP)) 946 return -1; 947 948 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 949 if (tb[IFLA_IFNAME] == NULL) { 950 fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); 951 name = "<nil>"; 952 } else { 953 name = rta_getattr_str(tb[IFLA_IFNAME]); 954 } 955 956 if (pfilter->label && 957 (!pfilter->family || pfilter->family == AF_PACKET) && 958 fnmatch(pfilter->label, RTA_DATA(tb[IFLA_IFNAME]), 0)) 959 return -1; 960 961 if (tb[IFLA_GROUP]) { 962 int group = rta_getattr_u32(tb[IFLA_GROUP]); 963 964 if (pfilter->group != -1 && group != pfilter->group) 965 return -1; 966 } 967 968 if (tb[IFLA_MASTER]) { 969 int master = rta_getattr_u32(tb[IFLA_MASTER]); 970 971 if (pfilter->master > 0 && master != pfilter->master) 972 return -1; 973 } else if (pfilter->master > 0) 974 return -1; 975 976 if (pfilter->kind && match_link_kind(tb, pfilter->kind, 0)) 977 return -1; 978 979 if (pfilter->slave_kind && match_link_kind(tb, pfilter->slave_kind, 1)) 980 return -1; 981 982 if (n->nlmsg_type == RTM_DELLINK) 983 print_bool(PRINT_ANY, "deleted", "Deleted ", true); 984 985 if (tb[IFLA_LINK]) { 986 SPRINT_BUF(b1); 987 int iflink = rta_getattr_u32(tb[IFLA_LINK]); 988 989 if (iflink == 0) { 990 snprintf(buf, sizeof(buf), "%s@NONE", name); 991 print_null(PRINT_JSON, "link", NULL, NULL); 992 } else { 993 const char *link = ll_idx_n2a(iflink, b1); 994 995 print_string(PRINT_JSON, "link", NULL, link); 996 snprintf(buf, sizeof(buf), "%s@%s", name, link); 997 m_flag = ll_index_to_flags(iflink); 998 m_flag = !(m_flag & IFF_UP); 999 } 1000 } else 1001 snprintf(buf, sizeof(buf), "%s", name); 1002 1003 print_string(PRINT_FP, NULL, "%-16s ", buf); 1004 print_string(PRINT_JSON, "ifname", NULL, name); 1005 1006 if (tb[IFLA_OPERSTATE]) 1007 print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE])); 1008 1009 if (pfilter->family == AF_PACKET) { 1010 SPRINT_BUF(b1); 1011 1012 if (tb[IFLA_ADDRESS]) { 1013 print_color_string(PRINT_ANY, COLOR_MAC, 1014 "address", "%s ", 1015 ll_addr_n2a( 1016 RTA_DATA(tb[IFLA_ADDRESS]), 1017 RTA_PAYLOAD(tb[IFLA_ADDRESS]), 1018 ifi->ifi_type, 1019 b1, sizeof(b1))); 1020 } 1021 } 1022 1023 if (pfilter->family == AF_PACKET) { 1024 print_link_flags(fp, ifi->ifi_flags, m_flag); 1025 print_string(PRINT_FP, NULL, "%s", "\n"); 1026 } 1027 fflush(fp); 1028 return 0; 1029} 1030 1031static const char *link_events[] = { 1032 [IFLA_EVENT_NONE] = "NONE", 1033 [IFLA_EVENT_REBOOT] = "REBOOT", 1034 [IFLA_EVENT_FEATURES] = "FEATURE CHANGE", 1035 [IFLA_EVENT_BONDING_FAILOVER] = "BONDING FAILOVER", 1036 [IFLA_EVENT_NOTIFY_PEERS] = "NOTIFY PEERS", 1037 [IFLA_EVENT_IGMP_RESEND] = "RESEND IGMP", 1038 [IFLA_EVENT_BONDING_OPTIONS] = "BONDING OPTION" 1039}; 1040 1041static void print_link_event(FILE *f, __u32 event) 1042{ 1043 if (event >= ARRAY_SIZE(link_events)) 1044 print_int(PRINT_ANY, "event", "event %d ", event); 1045 else { 1046 if (event) 1047 print_string(PRINT_ANY, 1048 "event", "event %s ", 1049 link_events[event]); 1050 } 1051} 1052 1053int print_linkinfo(const struct sockaddr_nl *who, 1054 struct nlmsghdr *n, void *arg) 1055{ 1056 FILE *fp = (FILE *)arg; 1057 struct ifinfomsg *ifi = NLMSG_DATA(n); 1058 struct rtattr *tb[IFLA_MAX+1]; 1059 int len = n->nlmsg_len; 1060 unsigned int m_flag = 0; 1061 1062 if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) 1063 return 0; 1064 1065 len -= NLMSG_LENGTH(sizeof(*ifi)); 1066 if (len < 0) 1067 return -1; 1068 1069 if (filter.ifindex && ifi->ifi_index != filter.ifindex) 1070 return 0; 1071 if (filter.up && !(ifi->ifi_flags&IFF_UP)) 1072 return 0; 1073 1074 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 1075 if (tb[IFLA_IFNAME] == NULL) 1076 fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); 1077 1078 if (filter.label && 1079 (!filter.family || filter.family == AF_PACKET) && 1080 fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) 1081 return 0; 1082 1083 if (tb[IFLA_GROUP]) { 1084 int group = rta_getattr_u32(tb[IFLA_GROUP]); 1085 1086 if (filter.group != -1 && group != filter.group) 1087 return -1; 1088 } 1089 1090 if (tb[IFLA_MASTER]) { 1091 int master = rta_getattr_u32(tb[IFLA_MASTER]); 1092 1093 if (filter.master > 0 && master != filter.master) 1094 return -1; 1095 } else if (filter.master > 0) 1096 return -1; 1097 1098 if (filter.kind && match_link_kind(tb, filter.kind, 0)) 1099 return -1; 1100 1101 if (filter.slave_kind && match_link_kind(tb, filter.slave_kind, 1)) 1102 return -1; 1103 1104 if (n->nlmsg_type == RTM_DELLINK) 1105 print_bool(PRINT_ANY, "deleted", "Deleted ", true); 1106 1107 print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index); 1108 if (tb[IFLA_IFNAME]) { 1109 print_color_string(PRINT_ANY, 1110 COLOR_IFNAME, 1111 "ifname", "%s", 1112 rta_getattr_str(tb[IFLA_IFNAME])); 1113 } else { 1114 print_null(PRINT_JSON, "ifname", NULL, NULL); 1115 print_color_null(PRINT_FP, COLOR_IFNAME, 1116 "ifname", "%s", "<nil>"); 1117 } 1118 1119 if (tb[IFLA_LINK]) { 1120 int iflink = rta_getattr_u32(tb[IFLA_LINK]); 1121 1122 if (iflink == 0) 1123 print_null(PRINT_ANY, "link", "@%s: ", "NONE"); 1124 else { 1125 if (tb[IFLA_LINK_NETNSID]) 1126 print_int(PRINT_ANY, 1127 "link_index", "@if%d: ", iflink); 1128 else { 1129 SPRINT_BUF(b1); 1130 1131 print_string(PRINT_ANY, 1132 "link", 1133 "@%s: ", 1134 ll_idx_n2a(iflink, b1)); 1135 m_flag = ll_index_to_flags(iflink); 1136 m_flag = !(m_flag & IFF_UP); 1137 } 1138 } 1139 } else { 1140 print_string(PRINT_FP, NULL, ": ", NULL); 1141 } 1142 print_link_flags(fp, ifi->ifi_flags, m_flag); 1143 1144 if (tb[IFLA_MTU]) 1145 print_int(PRINT_ANY, 1146 "mtu", "mtu %u ", 1147 rta_getattr_u32(tb[IFLA_MTU])); 1148 if (tb[IFLA_XDP]) 1149 xdp_dump(fp, tb[IFLA_XDP], do_link, false); 1150 if (tb[IFLA_QDISC]) 1151 print_string(PRINT_ANY, 1152 "qdisc", 1153 "qdisc %s ", 1154 rta_getattr_str(tb[IFLA_QDISC])); 1155 if (tb[IFLA_MASTER]) { 1156 SPRINT_BUF(b1); 1157 1158 print_string(PRINT_ANY, 1159 "master", 1160 "master %s ", 1161 ll_idx_n2a(rta_getattr_u32(tb[IFLA_MASTER]), b1)); 1162 } 1163 1164 if (tb[IFLA_OPERSTATE]) 1165 print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE])); 1166 1167 if (do_link && tb[IFLA_LINKMODE]) 1168 print_linkmode(fp, tb[IFLA_LINKMODE]); 1169 1170 if (tb[IFLA_GROUP]) { 1171 SPRINT_BUF(b1); 1172 int group = rta_getattr_u32(tb[IFLA_GROUP]); 1173 1174 print_string(PRINT_ANY, 1175 "group", 1176 "group %s ", 1177 rtnl_group_n2a(group, b1, sizeof(b1))); 1178 } 1179 1180 if (filter.showqueue) 1181 print_queuelen(fp, tb); 1182 1183 if (tb[IFLA_EVENT]) 1184 print_link_event(fp, rta_getattr_u32(tb[IFLA_EVENT])); 1185 1186 if (!filter.family || filter.family == AF_PACKET || show_details) { 1187 SPRINT_BUF(b1); 1188 1189 print_string(PRINT_FP, NULL, "%s", _SL_); 1190 print_string(PRINT_ANY, 1191 "link_type", 1192 " link/%s ", 1193 ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); 1194 if (tb[IFLA_ADDRESS]) { 1195 print_color_string(PRINT_ANY, 1196 COLOR_MAC, 1197 "address", 1198 "%s", 1199 ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), 1200 RTA_PAYLOAD(tb[IFLA_ADDRESS]), 1201 ifi->ifi_type, 1202 b1, sizeof(b1))); 1203 } 1204 if (tb[IFLA_BROADCAST]) { 1205 if (ifi->ifi_flags&IFF_POINTOPOINT) { 1206 print_string(PRINT_FP, NULL, " peer ", NULL); 1207 print_bool(PRINT_JSON, 1208 "link_pointtopoint", NULL, true); 1209 } else { 1210 print_string(PRINT_FP, NULL, " brd ", NULL); 1211 } 1212 print_color_string(PRINT_ANY, 1213 COLOR_MAC, 1214 "broadcast", 1215 "%s", 1216 ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), 1217 RTA_PAYLOAD(tb[IFLA_BROADCAST]), 1218 ifi->ifi_type, 1219 b1, sizeof(b1))); 1220 } 1221 } 1222 1223 if (tb[IFLA_LINK_NETNSID]) { 1224 int id = rta_getattr_u32(tb[IFLA_LINK_NETNSID]); 1225 1226 if (is_json_context()) { 1227 print_int(PRINT_JSON, "link_netnsid", NULL, id); 1228 } else { 1229 if (id >= 0) 1230 print_int(PRINT_FP, NULL, 1231 " link-netnsid %d", id); 1232 else 1233 print_string(PRINT_FP, NULL, 1234 " link-netnsid %s", "unknown"); 1235 } 1236 } 1237 1238 if (tb[IFLA_PROTO_DOWN]) { 1239 if (rta_getattr_u8(tb[IFLA_PROTO_DOWN])) 1240 print_bool(PRINT_ANY, 1241 "proto_down", " protodown on ", true); 1242 } 1243 1244 if (show_details) { 1245 if (tb[IFLA_PROMISCUITY]) 1246 print_uint(PRINT_ANY, 1247 "promiscuity", 1248 " promiscuity %u ", 1249 rta_getattr_u32(tb[IFLA_PROMISCUITY])); 1250 1251 if (tb[IFLA_LINKINFO]) 1252 print_linktype(fp, tb[IFLA_LINKINFO]); 1253 1254 if (do_link && tb[IFLA_AF_SPEC]) 1255 print_af_spec(fp, tb[IFLA_AF_SPEC]); 1256 1257 if (tb[IFLA_NUM_TX_QUEUES]) 1258 print_uint(PRINT_ANY, 1259 "num_tx_queues", 1260 "numtxqueues %u ", 1261 rta_getattr_u32(tb[IFLA_NUM_TX_QUEUES])); 1262 1263 if (tb[IFLA_NUM_RX_QUEUES]) 1264 print_uint(PRINT_ANY, 1265 "num_rx_queues", 1266 "numrxqueues %u ", 1267 rta_getattr_u32(tb[IFLA_NUM_RX_QUEUES])); 1268 1269 if (tb[IFLA_GSO_MAX_SIZE]) 1270 print_uint(PRINT_ANY, 1271 "gso_max_size", 1272 "gso_max_size %u ", 1273 rta_getattr_u32(tb[IFLA_GSO_MAX_SIZE])); 1274 1275 if (tb[IFLA_GSO_MAX_SEGS]) 1276 print_uint(PRINT_ANY, 1277 "gso_max_segs", 1278 "gso_max_segs %u ", 1279 rta_getattr_u32(tb[IFLA_GSO_MAX_SEGS])); 1280 1281 if (tb[IFLA_PHYS_PORT_NAME]) 1282 print_string(PRINT_ANY, 1283 "phys_port_name", 1284 "portname %s ", 1285 rta_getattr_str(tb[IFLA_PHYS_PORT_NAME])); 1286 1287 if (tb[IFLA_PHYS_PORT_ID]) { 1288 SPRINT_BUF(b1); 1289 print_string(PRINT_ANY, 1290 "phys_port_id", 1291 "portid %s ", 1292 hexstring_n2a( 1293 RTA_DATA(tb[IFLA_PHYS_PORT_ID]), 1294 RTA_PAYLOAD(tb[IFLA_PHYS_PORT_ID]), 1295 b1, sizeof(b1))); 1296 } 1297 1298 if (tb[IFLA_PHYS_SWITCH_ID]) { 1299 SPRINT_BUF(b1); 1300 print_string(PRINT_ANY, 1301 "phys_switch_id", 1302 "switchid %s ", 1303 hexstring_n2a(RTA_DATA(tb[IFLA_PHYS_SWITCH_ID]), 1304 RTA_PAYLOAD(tb[IFLA_PHYS_SWITCH_ID]), 1305 b1, sizeof(b1))); 1306 } 1307 } 1308 1309 if ((do_link || show_details) && tb[IFLA_IFALIAS]) { 1310 print_string(PRINT_FP, NULL, "%s ", _SL_); 1311 print_string(PRINT_ANY, 1312 "ifalias", 1313 "alias %s", 1314 rta_getattr_str(tb[IFLA_IFALIAS])); 1315 } 1316 1317 if ((do_link || show_details) && tb[IFLA_XDP]) 1318 xdp_dump(fp, tb[IFLA_XDP], true, true); 1319 1320 if (do_link && show_stats) { 1321 print_string(PRINT_FP, NULL, "%s", _SL_); 1322 __print_link_stats(fp, tb); 1323 } 1324 1325 if ((do_link || show_details) && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) { 1326 struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST]; 1327 int rem = RTA_PAYLOAD(vflist); 1328 1329 open_json_array(PRINT_JSON, "vfinfo_list"); 1330 for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { 1331 open_json_object(NULL); 1332 print_vfinfo(fp, i); 1333 close_json_object(); 1334 } 1335 close_json_array(PRINT_JSON, NULL); 1336 } 1337 1338 print_string(PRINT_FP, NULL, "\n", NULL); 1339 fflush(fp); 1340 return 1; 1341} 1342 1343static int flush_update(void) 1344{ 1345 1346 /* 1347 * Note that the kernel may delete multiple addresses for one 1348 * delete request (e.g. if ipv4 address promotion is disabled). 1349 * Since a flush operation is really a series of delete requests 1350 * its possible that we may request an address delete that has 1351 * already been done by the kernel. Therefore, ignore EADDRNOTAVAIL 1352 * errors returned from a flush request 1353 */ 1354 if ((rtnl_send_check(&rth, filter.flushb, filter.flushp) < 0) && 1355 (errno != EADDRNOTAVAIL)) { 1356 perror("Failed to send flush request"); 1357 return -1; 1358 } 1359 filter.flushp = 0; 1360 return 0; 1361} 1362 1363static int set_lifetime(unsigned int *lifetime, char *argv) 1364{ 1365 if (strcmp(argv, "forever") == 0) 1366 *lifetime = INFINITY_LIFE_TIME; 1367 else if (get_u32(lifetime, argv, 0)) 1368 return -1; 1369 1370 return 0; 1371} 1372 1373static unsigned int get_ifa_flags(struct ifaddrmsg *ifa, 1374 struct rtattr *ifa_flags_attr) 1375{ 1376 return ifa_flags_attr ? rta_getattr_u32(ifa_flags_attr) : 1377 ifa->ifa_flags; 1378} 1379 1380/* Mapping from argument to address flag mask */ 1381struct { 1382 const char *name; 1383 unsigned long value; 1384} ifa_flag_names[] = { 1385 { "secondary", IFA_F_SECONDARY }, 1386 { "temporary", IFA_F_SECONDARY }, 1387 { "nodad", IFA_F_NODAD }, 1388 { "optimistic", IFA_F_OPTIMISTIC }, 1389 { "dadfailed", IFA_F_DADFAILED }, 1390 { "home", IFA_F_HOMEADDRESS }, 1391 { "deprecated", IFA_F_DEPRECATED }, 1392 { "tentative", IFA_F_TENTATIVE }, 1393 { "permanent", IFA_F_PERMANENT }, 1394 { "mngtmpaddr", IFA_F_MANAGETEMPADDR }, 1395 { "noprefixroute", IFA_F_NOPREFIXROUTE }, 1396 { "autojoin", IFA_F_MCAUTOJOIN }, 1397 { "stable-privacy", IFA_F_STABLE_PRIVACY }, 1398}; 1399 1400static void print_ifa_flags(FILE *fp, const struct ifaddrmsg *ifa, 1401 unsigned int flags) 1402{ 1403 unsigned int i; 1404 1405 for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) { 1406 unsigned long mask = ifa_flag_names[i].value; 1407 1408 if (mask == IFA_F_PERMANENT) { 1409 if (!(flags & mask)) 1410 print_bool(PRINT_ANY, 1411 "dynamic", "dynamic ", true); 1412 } else if (flags & mask) { 1413 if (mask == IFA_F_SECONDARY && 1414 ifa->ifa_family == AF_INET6) { 1415 print_bool(PRINT_ANY, 1416 "temporary", "temporary ", true); 1417 } else { 1418 print_string(PRINT_FP, NULL, 1419 "%s ", ifa_flag_names[i].name); 1420 print_bool(PRINT_JSON, 1421 ifa_flag_names[i].name, NULL, true); 1422 } 1423 } 1424 1425 flags &= ~mask; 1426 } 1427 1428 if (flags) { 1429 if (is_json_context()) { 1430 SPRINT_BUF(b1); 1431 1432 snprintf(b1, sizeof(b1), "%02x", flags); 1433 print_string(PRINT_JSON, "ifa_flags", NULL, b1); 1434 } else { 1435 fprintf(fp, "flags %02x ", flags); 1436 } 1437 } 1438 1439} 1440 1441static int get_filter(const char *arg) 1442{ 1443 unsigned int i; 1444 1445 /* Special cases */ 1446 if (strcmp(arg, "dynamic") == 0) { 1447 filter.flags &= ~IFA_F_PERMANENT; 1448 filter.flagmask |= IFA_F_PERMANENT; 1449 } else if (strcmp(arg, "primary") == 0) { 1450 filter.flags &= ~IFA_F_SECONDARY; 1451 filter.flagmask |= IFA_F_SECONDARY; 1452 } else if (*arg == '-') { 1453 for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) { 1454 if (strcmp(arg + 1, ifa_flag_names[i].name)) 1455 continue; 1456 1457 filter.flags &= ifa_flag_names[i].value; 1458 filter.flagmask |= ifa_flag_names[i].value; 1459 return 0; 1460 } 1461 1462 return -1; 1463 } else { 1464 for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) { 1465 if (strcmp(arg, ifa_flag_names[i].name)) 1466 continue; 1467 filter.flags |= ifa_flag_names[i].value; 1468 filter.flagmask |= ifa_flag_names[i].value; 1469 return 0; 1470 } 1471 return -1; 1472 } 1473 1474 return 0; 1475} 1476 1477int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, 1478 void *arg) 1479{ 1480 FILE *fp = arg; 1481 struct ifaddrmsg *ifa = NLMSG_DATA(n); 1482 int len = n->nlmsg_len; 1483 unsigned int ifa_flags; 1484 struct rtattr *rta_tb[IFA_MAX+1]; 1485 1486 SPRINT_BUF(b1); 1487 1488 if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) 1489 return 0; 1490 len -= NLMSG_LENGTH(sizeof(*ifa)); 1491 if (len < 0) { 1492 fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); 1493 return -1; 1494 } 1495 1496 if (filter.flushb && n->nlmsg_type != RTM_NEWADDR) 1497 return 0; 1498 1499 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), 1500 n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); 1501 1502 ifa_flags = get_ifa_flags(ifa, rta_tb[IFA_FLAGS]); 1503 1504 if (!rta_tb[IFA_LOCAL]) 1505 rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; 1506 if (!rta_tb[IFA_ADDRESS]) 1507 rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL]; 1508 1509 if (filter.ifindex && filter.ifindex != ifa->ifa_index) 1510 return 0; 1511 if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 1512 return 0; 1513 if ((filter.flags ^ ifa_flags) & filter.flagmask) 1514 return 0; 1515 if (filter.label) { 1516 SPRINT_BUF(b1); 1517 const char *label; 1518 1519 if (rta_tb[IFA_LABEL]) 1520 label = RTA_DATA(rta_tb[IFA_LABEL]); 1521 else 1522 label = ll_idx_n2a(ifa->ifa_index, b1); 1523 if (fnmatch(filter.label, label, 0) != 0) 1524 return 0; 1525 } 1526 if (filter.pfx.family) { 1527 if (rta_tb[IFA_LOCAL]) { 1528 inet_prefix dst = { .family = ifa->ifa_family }; 1529 1530 memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL])); 1531 if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 1532 return 0; 1533 } 1534 } 1535 1536 if (filter.family && filter.family != ifa->ifa_family) 1537 return 0; 1538 1539 if (filter.flushb) { 1540 struct nlmsghdr *fn; 1541 1542 if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { 1543 if (flush_update()) 1544 return -1; 1545 } 1546 fn = (struct nlmsghdr *)(filter.flushb + NLMSG_ALIGN(filter.flushp)); 1547 memcpy(fn, n, n->nlmsg_len); 1548 fn->nlmsg_type = RTM_DELADDR; 1549 fn->nlmsg_flags = NLM_F_REQUEST; 1550 fn->nlmsg_seq = ++rth.seq; 1551 filter.flushp = (((char *)fn) + n->nlmsg_len) - filter.flushb; 1552 filter.flushed++; 1553 if (show_stats < 2) 1554 return 0; 1555 } 1556 1557 if (n->nlmsg_type == RTM_DELADDR) 1558 print_bool(PRINT_ANY, "deleted", "Deleted ", true); 1559 1560 if (!brief) { 1561 if (filter.oneline || filter.flushb) { 1562 const char *dev = ll_index_to_name(ifa->ifa_index); 1563 1564 if (is_json_context()) { 1565 print_int(PRINT_JSON, 1566 "index", NULL, ifa->ifa_index); 1567 print_string(PRINT_JSON, "dev", NULL, dev); 1568 } else { 1569 fprintf(fp, "%u: %s", ifa->ifa_index, dev); 1570 } 1571 } 1572 1573 int family = ifa->ifa_family; 1574 1575 if (ifa->ifa_family == AF_INET) 1576 print_string(PRINT_ANY, "family", " %s ", "inet"); 1577 else if (ifa->ifa_family == AF_INET6) 1578 print_string(PRINT_ANY, "family", " %s ", "inet6"); 1579 else if (ifa->ifa_family == AF_DECnet) 1580 print_string(PRINT_ANY, "family", " %s ", "dnet"); 1581 else if (ifa->ifa_family == AF_IPX) 1582 print_string(PRINT_ANY, "family", " %s ", "ipx"); 1583 else 1584 print_int(PRINT_ANY, 1585 "family_index", 1586 " family %d ", family); 1587 } 1588 1589 if (rta_tb[IFA_LOCAL]) { 1590 print_color_string(PRINT_ANY, 1591 ifa_family_color(ifa->ifa_family), 1592 "local", "%s", 1593 format_host_rta(ifa->ifa_family, 1594 rta_tb[IFA_LOCAL])); 1595 if (rta_tb[IFA_ADDRESS] && 1596 memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), 1597 RTA_DATA(rta_tb[IFA_LOCAL]), 1598 ifa->ifa_family == AF_INET ? 4 : 16)) { 1599 print_string(PRINT_FP, NULL, " %s ", "peer"); 1600 print_color_string(PRINT_ANY, 1601 ifa_family_color(ifa->ifa_family), 1602 "address", 1603 "%s", 1604 format_host_rta(ifa->ifa_family, 1605 rta_tb[IFA_ADDRESS])); 1606 } 1607 print_int(PRINT_ANY, "prefixlen", "/%d ", ifa->ifa_prefixlen); 1608 } 1609 1610 if (brief) 1611 goto brief_exit; 1612 1613 if (rta_tb[IFA_BROADCAST]) { 1614 print_string(PRINT_FP, NULL, "%s ", "brd"); 1615 print_color_string(PRINT_ANY, 1616 ifa_family_color(ifa->ifa_family), 1617 "broadcast", 1618 "%s ", 1619 format_host_rta(ifa->ifa_family, 1620 rta_tb[IFA_BROADCAST])); 1621 } 1622 1623 if (rta_tb[IFA_ANYCAST]) { 1624 print_string(PRINT_FP, NULL, "%s ", "any"); 1625 print_color_string(PRINT_ANY, 1626 ifa_family_color(ifa->ifa_family), 1627 "anycast", 1628 "%s ", 1629 format_host_rta(ifa->ifa_family, 1630 rta_tb[IFA_ANYCAST])); 1631 } 1632 1633 print_string(PRINT_ANY, 1634 "scope", 1635 "scope %s ", 1636 rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1))); 1637 1638 print_ifa_flags(fp, ifa, ifa_flags); 1639 1640 if (rta_tb[IFA_LABEL]) 1641 print_string(PRINT_ANY, 1642 "label", 1643 "%s", 1644 rta_getattr_str(rta_tb[IFA_LABEL])); 1645 1646 if (rta_tb[IFA_CACHEINFO]) { 1647 struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]); 1648 1649 print_string(PRINT_FP, NULL, "%s", _SL_); 1650 print_string(PRINT_FP, NULL, " valid_lft ", NULL); 1651 1652 if (ci->ifa_valid == INFINITY_LIFE_TIME) { 1653 print_uint(PRINT_JSON, 1654 "valid_life_time", 1655 NULL, INFINITY_LIFE_TIME); 1656 print_string(PRINT_FP, NULL, "%s", "forever"); 1657 } else { 1658 print_uint(PRINT_ANY, 1659 "valid_life_time", "%usec", ci->ifa_valid); 1660 } 1661 1662 print_string(PRINT_FP, NULL, " preferred_lft ", NULL); 1663 if (ci->ifa_prefered == INFINITY_LIFE_TIME) { 1664 print_uint(PRINT_JSON, 1665 "preferred_life_time", 1666 NULL, INFINITY_LIFE_TIME); 1667 print_string(PRINT_FP, NULL, "%s", "forever"); 1668 } else { 1669 if (ifa_flags & IFA_F_DEPRECATED) 1670 print_int(PRINT_ANY, 1671 "preferred_life_time", 1672 "%dsec", 1673 ci->ifa_prefered); 1674 else 1675 print_uint(PRINT_ANY, 1676 "preferred_life_time", 1677 "%usec", 1678 ci->ifa_prefered); 1679 } 1680 } 1681 print_string(PRINT_FP, NULL, "%s", "\n"); 1682brief_exit: 1683 fflush(fp); 1684 return 0; 1685} 1686 1687static int print_selected_addrinfo(struct ifinfomsg *ifi, 1688 struct nlmsg_list *ainfo, FILE *fp) 1689{ 1690 open_json_array(PRINT_JSON, "addr_info"); 1691 for ( ; ainfo ; ainfo = ainfo->next) { 1692 struct nlmsghdr *n = &ainfo->h; 1693 struct ifaddrmsg *ifa = NLMSG_DATA(n); 1694 1695 if (n->nlmsg_type != RTM_NEWADDR) 1696 continue; 1697 1698 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*ifa))) 1699 return -1; 1700 1701 if (ifa->ifa_index != ifi->ifi_index || 1702 (filter.family && filter.family != ifa->ifa_family)) 1703 continue; 1704 1705 if (filter.up && !(ifi->ifi_flags&IFF_UP)) 1706 continue; 1707 1708 open_json_object(NULL); 1709 print_addrinfo(NULL, n, fp); 1710 close_json_object(); 1711 } 1712 close_json_array(PRINT_JSON, NULL); 1713 1714 if (brief) { 1715 print_string(PRINT_FP, NULL, "%s", "\n"); 1716 fflush(fp); 1717 } 1718 return 0; 1719} 1720 1721 1722static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, 1723 void *arg) 1724{ 1725 struct nlmsg_chain *lchain = (struct nlmsg_chain *)arg; 1726 struct nlmsg_list *h; 1727 1728 h = malloc(n->nlmsg_len+sizeof(void *)); 1729 if (h == NULL) 1730 return -1; 1731 1732 memcpy(&h->h, n, n->nlmsg_len); 1733 h->next = NULL; 1734 1735 if (lchain->tail) 1736 lchain->tail->next = h; 1737 else 1738 lchain->head = h; 1739 lchain->tail = h; 1740 1741 ll_remember_index(who, n, NULL); 1742 return 0; 1743} 1744 1745static __u32 ipadd_dump_magic = 0x47361222; 1746 1747static int ipadd_save_prep(void) 1748{ 1749 int ret; 1750 1751 if (isatty(STDOUT_FILENO)) { 1752 fprintf(stderr, "Not sending a binary stream to stdout\n"); 1753 return -1; 1754 } 1755 1756 ret = write(STDOUT_FILENO, &ipadd_dump_magic, sizeof(ipadd_dump_magic)); 1757 if (ret != sizeof(ipadd_dump_magic)) { 1758 fprintf(stderr, "Can't write magic to dump file\n"); 1759 return -1; 1760 } 1761 1762 return 0; 1763} 1764 1765static int ipadd_dump_check_magic(void) 1766{ 1767 int ret; 1768 __u32 magic = 0; 1769 1770 if (isatty(STDIN_FILENO)) { 1771 fprintf(stderr, "Can't restore address dump from a terminal\n"); 1772 return -1; 1773 } 1774 1775 ret = fread(&magic, sizeof(magic), 1, stdin); 1776 if (magic != ipadd_dump_magic) { 1777 fprintf(stderr, "Magic mismatch (%d elems, %x magic)\n", ret, magic); 1778 return -1; 1779 } 1780 1781 return 0; 1782} 1783 1784static int save_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, 1785 void *arg) 1786{ 1787 int ret; 1788 1789 ret = write(STDOUT_FILENO, n, n->nlmsg_len); 1790 if ((ret > 0) && (ret != n->nlmsg_len)) { 1791 fprintf(stderr, "Short write while saving nlmsg\n"); 1792 ret = -EIO; 1793 } 1794 1795 return ret == n->nlmsg_len ? 0 : ret; 1796} 1797 1798static int show_handler(const struct sockaddr_nl *nl, 1799 struct rtnl_ctrl_data *ctrl, 1800 struct nlmsghdr *n, void *arg) 1801{ 1802 struct ifaddrmsg *ifa = NLMSG_DATA(n); 1803 1804 open_json_object(NULL); 1805 print_int(PRINT_ANY, "index", "if%d:\n", ifa->ifa_index); 1806 print_addrinfo(NULL, n, stdout); 1807 close_json_object(); 1808 return 0; 1809} 1810 1811static int ipaddr_showdump(void) 1812{ 1813 int err; 1814 1815 if (ipadd_dump_check_magic()) 1816 exit(-1); 1817 1818 new_json_obj(json); 1819 open_json_object(NULL); 1820 open_json_array(PRINT_JSON, "addr_info"); 1821 1822 err = rtnl_from_file(stdin, &show_handler, NULL); 1823 1824 close_json_array(PRINT_JSON, NULL); 1825 close_json_object(); 1826 delete_json_obj(); 1827 1828 exit(err); 1829} 1830 1831static int restore_handler(const struct sockaddr_nl *nl, 1832 struct rtnl_ctrl_data *ctrl, 1833 struct nlmsghdr *n, void *arg) 1834{ 1835 int ret; 1836 1837 n->nlmsg_flags |= NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK; 1838 1839 ll_init_map(&rth); 1840 1841 ret = rtnl_talk(&rth, n, n, sizeof(*n)); 1842 if ((ret < 0) && (errno == EEXIST)) 1843 ret = 0; 1844 1845 return ret; 1846} 1847 1848static int ipaddr_restore(void) 1849{ 1850 if (ipadd_dump_check_magic()) 1851 exit(-1); 1852 1853 exit(rtnl_from_file(stdin, &restore_handler, NULL)); 1854} 1855 1856void free_nlmsg_chain(struct nlmsg_chain *info) 1857{ 1858 struct nlmsg_list *l, *n; 1859 1860 for (l = info->head; l; l = n) { 1861 n = l->next; 1862 free(l); 1863 } 1864} 1865 1866static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo) 1867{ 1868 struct nlmsg_list *l, **lp; 1869 1870 lp = &linfo->head; 1871 while ((l = *lp) != NULL) { 1872 int ok = 0; 1873 int missing_net_address = 1; 1874 struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 1875 struct nlmsg_list *a; 1876 1877 for (a = ainfo->head; a; a = a->next) { 1878 struct nlmsghdr *n = &a->h; 1879 struct ifaddrmsg *ifa = NLMSG_DATA(n); 1880 struct rtattr *tb[IFA_MAX + 1]; 1881 unsigned int ifa_flags; 1882 1883 if (ifa->ifa_index != ifi->ifi_index) 1884 continue; 1885 missing_net_address = 0; 1886 if (filter.family && filter.family != ifa->ifa_family) 1887 continue; 1888 if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 1889 continue; 1890 1891 parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n)); 1892 ifa_flags = get_ifa_flags(ifa, tb[IFA_FLAGS]); 1893 1894 if ((filter.flags ^ ifa_flags) & filter.flagmask) 1895 continue; 1896 if (filter.pfx.family || filter.label) { 1897 if (!tb[IFA_LOCAL]) 1898 tb[IFA_LOCAL] = tb[IFA_ADDRESS]; 1899 1900 if (filter.pfx.family && tb[IFA_LOCAL]) { 1901 inet_prefix dst = { 1902 .family = ifa->ifa_family 1903 }; 1904 1905 memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL])); 1906 if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 1907 continue; 1908 } 1909 if (filter.label) { 1910 SPRINT_BUF(b1); 1911 const char *label; 1912 1913 if (tb[IFA_LABEL]) 1914 label = RTA_DATA(tb[IFA_LABEL]); 1915 else 1916 label = ll_idx_n2a(ifa->ifa_index, b1); 1917 if (fnmatch(filter.label, label, 0) != 0) 1918 continue; 1919 } 1920 } 1921 1922 ok = 1; 1923 break; 1924 } 1925 if (missing_net_address && 1926 (filter.family == AF_UNSPEC || filter.family == AF_PACKET)) 1927 ok = 1; 1928 if (!ok) { 1929 *lp = l->next; 1930 free(l); 1931 } else 1932 lp = &l->next; 1933 } 1934} 1935 1936static int ipaddr_flush(void) 1937{ 1938 int round = 0; 1939 char flushb[4096-512]; 1940 1941 filter.flushb = flushb; 1942 filter.flushp = 0; 1943 filter.flushe = sizeof(flushb); 1944 1945 while ((max_flush_loops == 0) || (round < max_flush_loops)) { 1946 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 1947 perror("Cannot send dump request"); 1948 exit(1); 1949 } 1950 filter.flushed = 0; 1951 if (rtnl_dump_filter_nc(&rth, print_addrinfo, 1952 stdout, NLM_F_DUMP_INTR) < 0) { 1953 fprintf(stderr, "Flush terminated\n"); 1954 exit(1); 1955 } 1956 if (filter.flushed == 0) { 1957 flush_done: 1958 if (show_stats) { 1959 if (round == 0) 1960 printf("Nothing to flush.\n"); 1961 else 1962 printf("*** Flush is complete after %d round%s ***\n", round, round > 1?"s":""); 1963 } 1964 fflush(stdout); 1965 return 0; 1966 } 1967 round++; 1968 if (flush_update() < 0) 1969 return 1; 1970 1971 if (show_stats) { 1972 printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed); 1973 fflush(stdout); 1974 } 1975 1976 /* If we are flushing, and specifying primary, then we 1977 * want to flush only a single round. Otherwise, we'll 1978 * start flushing secondaries that were promoted to 1979 * primaries. 1980 */ 1981 if (!(filter.flags & IFA_F_SECONDARY) && (filter.flagmask & IFA_F_SECONDARY)) 1982 goto flush_done; 1983 } 1984 fprintf(stderr, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops); 1985 fflush(stderr); 1986 return 1; 1987} 1988 1989static int iplink_filter_req(struct nlmsghdr *nlh, int reqlen) 1990{ 1991 int err; 1992 1993 err = addattr32(nlh, reqlen, IFLA_EXT_MASK, RTEXT_FILTER_VF); 1994 if (err) 1995 return err; 1996 1997 if (filter.master) { 1998 err = addattr32(nlh, reqlen, IFLA_MASTER, filter.master); 1999 if (err) 2000 return err; 2001 } 2002 2003 if (filter.kind) { 2004 struct rtattr *linkinfo; 2005 2006 linkinfo = addattr_nest(nlh, reqlen, IFLA_LINKINFO); 2007 2008 err = addattr_l(nlh, reqlen, IFLA_INFO_KIND, filter.kind, 2009 strlen(filter.kind)); 2010 if (err) 2011 return err; 2012 2013 addattr_nest_end(nlh, linkinfo); 2014 } 2015 2016 return 0; 2017} 2018 2019/* fills in linfo with link data and optionally ainfo with address info 2020 * caller can walk lists as desired and must call free_nlmsg_chain for 2021 * both when done 2022 */ 2023int ip_linkaddr_list(int family, req_filter_fn_t filter_fn, 2024 struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo) 2025{ 2026 if (rtnl_wilddump_req_filter_fn(&rth, preferred_family, RTM_GETLINK, 2027 filter_fn) < 0) { 2028 perror("Cannot send dump request"); 2029 return 1; 2030 } 2031 2032 if (rtnl_dump_filter(&rth, store_nlmsg, linfo) < 0) { 2033 fprintf(stderr, "Dump terminated\n"); 2034 return 1; 2035 } 2036 2037 if (ainfo) { 2038 if (rtnl_wilddump_request(&rth, family, RTM_GETADDR) < 0) { 2039 perror("Cannot send dump request"); 2040 return 1; 2041 } 2042 2043 if (rtnl_dump_filter(&rth, store_nlmsg, ainfo) < 0) { 2044 fprintf(stderr, "Dump terminated\n"); 2045 return 1; 2046 } 2047 } 2048 2049 return 0; 2050} 2051 2052static int ipaddr_list_flush_or_save(int argc, char **argv, int action) 2053{ 2054 struct nlmsg_chain linfo = { NULL, NULL}; 2055 struct nlmsg_chain _ainfo = { NULL, NULL}, *ainfo = NULL; 2056 struct nlmsg_list *l; 2057 char *filter_dev = NULL; 2058 int no_link = 0; 2059 2060 ipaddr_reset_filter(oneline, 0); 2061 filter.showqueue = 1; 2062 filter.family = preferred_family; 2063 filter.group = -1; 2064 2065 if (action == IPADD_FLUSH) { 2066 if (argc <= 0) { 2067 fprintf(stderr, "Flush requires arguments.\n"); 2068 2069 return -1; 2070 } 2071 if (filter.family == AF_PACKET) { 2072 fprintf(stderr, "Cannot flush link addresses.\n"); 2073 return -1; 2074 } 2075 } 2076 2077 while (argc > 0) { 2078 if (strcmp(*argv, "to") == 0) { 2079 NEXT_ARG(); 2080 get_prefix(&filter.pfx, *argv, filter.family); 2081 if (filter.family == AF_UNSPEC) 2082 filter.family = filter.pfx.family; 2083 } else if (strcmp(*argv, "scope") == 0) { 2084 unsigned int scope = 0; 2085 2086 NEXT_ARG(); 2087 filter.scopemask = -1; 2088 if (rtnl_rtscope_a2n(&scope, *argv)) { 2089 if (strcmp(*argv, "all") != 0) 2090 invarg("invalid \"scope\"\n", *argv); 2091 scope = RT_SCOPE_NOWHERE; 2092 filter.scopemask = 0; 2093 } 2094 filter.scope = scope; 2095 } else if (strcmp(*argv, "up") == 0) { 2096 filter.up = 1; 2097 } else if (get_filter(*argv) == 0) { 2098 2099 } else if (strcmp(*argv, "label") == 0) { 2100 NEXT_ARG(); 2101 filter.label = *argv; 2102 } else if (strcmp(*argv, "group") == 0) { 2103 NEXT_ARG(); 2104 if (rtnl_group_a2n(&filter.group, *argv)) 2105 invarg("Invalid \"group\" value\n", *argv); 2106 } else if (strcmp(*argv, "master") == 0) { 2107 int ifindex; 2108 2109 NEXT_ARG(); 2110 ifindex = ll_name_to_index(*argv); 2111 if (!ifindex) 2112 invarg("Device does not exist\n", *argv); 2113 filter.master = ifindex; 2114 } else if (strcmp(*argv, "vrf") == 0) { 2115 int ifindex; 2116 2117 NEXT_ARG(); 2118 ifindex = ll_name_to_index(*argv); 2119 if (!ifindex) 2120 invarg("Not a valid VRF name\n", *argv); 2121 if (!name_is_vrf(*argv)) 2122 invarg("Not a valid VRF name\n", *argv); 2123 filter.master = ifindex; 2124 } else if (strcmp(*argv, "type") == 0) { 2125 int soff; 2126 2127 NEXT_ARG(); 2128 soff = strlen(*argv) - strlen("_slave"); 2129 if (!strcmp(*argv + soff, "_slave")) { 2130 (*argv)[soff] = '\0'; 2131 filter.slave_kind = *argv; 2132 } else { 2133 filter.kind = *argv; 2134 } 2135 } else { 2136 if (strcmp(*argv, "dev") == 0) 2137 NEXT_ARG(); 2138 else if (matches(*argv, "help") == 0) 2139 usage(); 2140 if (filter_dev) 2141 duparg2("dev", *argv); 2142 filter_dev = *argv; 2143 } 2144 argv++; argc--; 2145 } 2146 2147 if (filter_dev) { 2148 filter.ifindex = ll_name_to_index(filter_dev); 2149 if (filter.ifindex <= 0) { 2150 fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev); 2151 return -1; 2152 } 2153 } 2154 2155 if (action == IPADD_FLUSH) 2156 return ipaddr_flush(); 2157 2158 if (action == IPADD_SAVE) { 2159 if (ipadd_save_prep()) 2160 exit(1); 2161 2162 if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETADDR) < 0) { 2163 perror("Cannot send dump request"); 2164 exit(1); 2165 } 2166 2167 if (rtnl_dump_filter(&rth, save_nlmsg, stdout) < 0) { 2168 fprintf(stderr, "Save terminated\n"); 2169 exit(1); 2170 } 2171 2172 exit(0); 2173 } 2174 2175 /* 2176 * Initialize a json_writer and open an array object 2177 * if -json was specified. 2178 */ 2179 new_json_obj(json); 2180 2181 /* 2182 * If only filter_dev present and none of the other 2183 * link filters are present, use RTM_GETLINK to get 2184 * the link device 2185 */ 2186 if (filter_dev && filter.group == -1 && do_link == 1) { 2187 if (iplink_get(0, filter_dev, RTEXT_FILTER_VF) < 0) { 2188 perror("Cannot send link get request"); 2189 delete_json_obj(); 2190 exit(1); 2191 } 2192 delete_json_obj(); 2193 exit(0); 2194 } 2195 2196 if (filter.family != AF_PACKET) { 2197 ainfo = &_ainfo; 2198 2199 if (filter.oneline) 2200 no_link = 1; 2201 } 2202 2203 if (ip_linkaddr_list(filter.family, iplink_filter_req, 2204 &linfo, ainfo) != 0) 2205 goto out; 2206 2207 if (filter.family != AF_PACKET) 2208 ipaddr_filter(&linfo, ainfo); 2209 2210 for (l = linfo.head; l; l = l->next) { 2211 int res = 0; 2212 struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 2213 2214 open_json_object(NULL); 2215 if (brief) { 2216 if (print_linkinfo_brief(NULL, &l->h, 2217 stdout, NULL) == 0) 2218 if (filter.family != AF_PACKET) 2219 print_selected_addrinfo(ifi, 2220 ainfo->head, 2221 stdout); 2222 } else if (no_link || 2223 (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) { 2224 if (filter.family != AF_PACKET) 2225 print_selected_addrinfo(ifi, 2226 ainfo->head, stdout); 2227 if (res > 0 && !do_link && show_stats) 2228 print_link_stats(stdout, &l->h); 2229 } 2230 close_json_object(); 2231 } 2232 fflush(stdout); 2233 2234out: 2235 if (ainfo) 2236 free_nlmsg_chain(ainfo); 2237 free_nlmsg_chain(&linfo); 2238 delete_json_obj(); 2239 return 0; 2240} 2241 2242static void 2243ipaddr_loop_each_vf(struct rtattr *tb[], int vfnum, int *min, int *max) 2244{ 2245 struct rtattr *vflist = tb[IFLA_VFINFO_LIST]; 2246 struct rtattr *i, *vf[IFLA_VF_MAX+1]; 2247 struct ifla_vf_rate *vf_rate; 2248 int rem; 2249 2250 rem = RTA_PAYLOAD(vflist); 2251 2252 for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { 2253 parse_rtattr_nested(vf, IFLA_VF_MAX, i); 2254 vf_rate = RTA_DATA(vf[IFLA_VF_RATE]); 2255 if (vf_rate->vf == vfnum) { 2256 *min = vf_rate->min_tx_rate; 2257 *max = vf_rate->max_tx_rate; 2258 return; 2259 } 2260 } 2261 fprintf(stderr, "Cannot find VF %d\n", vfnum); 2262 exit(1); 2263} 2264 2265void ipaddr_get_vf_rate(int vfnum, int *min, int *max, int idx) 2266{ 2267 struct nlmsg_chain linfo = { NULL, NULL}; 2268 struct rtattr *tb[IFLA_MAX+1]; 2269 struct ifinfomsg *ifi; 2270 struct nlmsg_list *l; 2271 struct nlmsghdr *n; 2272 int len; 2273 2274 if (rtnl_wilddump_request(&rth, AF_UNSPEC, RTM_GETLINK) < 0) { 2275 perror("Cannot send dump request"); 2276 exit(1); 2277 } 2278 if (rtnl_dump_filter(&rth, store_nlmsg, &linfo) < 0) { 2279 fprintf(stderr, "Dump terminated\n"); 2280 exit(1); 2281 } 2282 for (l = linfo.head; l; l = l->next) { 2283 n = &l->h; 2284 ifi = NLMSG_DATA(n); 2285 2286 len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)); 2287 if (len < 0 || (idx && idx != ifi->ifi_index)) 2288 continue; 2289 2290 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 2291 2292 if ((tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF])) { 2293 ipaddr_loop_each_vf(tb, vfnum, min, max); 2294 return; 2295 } 2296 } 2297} 2298 2299int ipaddr_list_link(int argc, char **argv) 2300{ 2301 preferred_family = AF_PACKET; 2302 do_link = 1; 2303 return ipaddr_list_flush_or_save(argc, argv, IPADD_LIST); 2304} 2305 2306void ipaddr_reset_filter(int oneline, int ifindex) 2307{ 2308 memset(&filter, 0, sizeof(filter)); 2309 filter.oneline = oneline; 2310 filter.ifindex = ifindex; 2311} 2312 2313static int default_scope(inet_prefix *lcl) 2314{ 2315 if (lcl->family == AF_INET) { 2316 if (lcl->bytelen >= 1 && *(__u8 *)&lcl->data == 127) 2317 return RT_SCOPE_HOST; 2318 } 2319 return 0; 2320} 2321 2322static bool ipaddr_is_multicast(inet_prefix *a) 2323{ 2324 if (a->family == AF_INET) 2325 return IN_MULTICAST(ntohl(a->data[0])); 2326 else if (a->family == AF_INET6) 2327 return IN6_IS_ADDR_MULTICAST(a->data); 2328 else 2329 return false; 2330} 2331 2332static int ipaddr_modify(int cmd, int flags, int argc, char **argv) 2333{ 2334 struct { 2335 struct nlmsghdr n; 2336 struct ifaddrmsg ifa; 2337 char buf[256]; 2338 } req = { 2339 .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), 2340 .n.nlmsg_flags = NLM_F_REQUEST | flags, 2341 .n.nlmsg_type = cmd, 2342 .ifa.ifa_family = preferred_family, 2343 }; 2344 char *d = NULL; 2345 char *l = NULL; 2346 char *lcl_arg = NULL; 2347 char *valid_lftp = NULL; 2348 char *preferred_lftp = NULL; 2349 inet_prefix lcl = {}; 2350 inet_prefix peer; 2351 int local_len = 0; 2352 int peer_len = 0; 2353 int brd_len = 0; 2354 int any_len = 0; 2355 int scoped = 0; 2356 __u32 preferred_lft = INFINITY_LIFE_TIME; 2357 __u32 valid_lft = INFINITY_LIFE_TIME; 2358 unsigned int ifa_flags = 0; 2359 2360 while (argc > 0) { 2361 if (strcmp(*argv, "peer") == 0 || 2362 strcmp(*argv, "remote") == 0) { 2363 NEXT_ARG(); 2364 2365 if (peer_len) 2366 duparg("peer", *argv); 2367 get_prefix(&peer, *argv, req.ifa.ifa_family); 2368 peer_len = peer.bytelen; 2369 if (req.ifa.ifa_family == AF_UNSPEC) 2370 req.ifa.ifa_family = peer.family; 2371 addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); 2372 req.ifa.ifa_prefixlen = peer.bitlen; 2373 } else if (matches(*argv, "broadcast") == 0 || 2374 strcmp(*argv, "brd") == 0) { 2375 inet_prefix addr; 2376 2377 NEXT_ARG(); 2378 if (brd_len) 2379 duparg("broadcast", *argv); 2380 if (strcmp(*argv, "+") == 0) 2381 brd_len = -1; 2382 else if (strcmp(*argv, "-") == 0) 2383 brd_len = -2; 2384 else { 2385 get_addr(&addr, *argv, req.ifa.ifa_family); 2386 if (req.ifa.ifa_family == AF_UNSPEC) 2387 req.ifa.ifa_family = addr.family; 2388 addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); 2389 brd_len = addr.bytelen; 2390 } 2391 } else if (strcmp(*argv, "anycast") == 0) { 2392 inet_prefix addr; 2393 2394 NEXT_ARG(); 2395 if (any_len) 2396 duparg("anycast", *argv); 2397 get_addr(&addr, *argv, req.ifa.ifa_family); 2398 if (req.ifa.ifa_family == AF_UNSPEC) 2399 req.ifa.ifa_family = addr.family; 2400 addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); 2401 any_len = addr.bytelen; 2402 } else if (strcmp(*argv, "scope") == 0) { 2403 unsigned int scope = 0; 2404 2405 NEXT_ARG(); 2406 if (rtnl_rtscope_a2n(&scope, *argv)) 2407 invarg("invalid scope value.", *argv); 2408 req.ifa.ifa_scope = scope; 2409 scoped = 1; 2410 } else if (strcmp(*argv, "dev") == 0) { 2411 NEXT_ARG(); 2412 d = *argv; 2413 } else if (strcmp(*argv, "label") == 0) { 2414 NEXT_ARG(); 2415 l = *argv; 2416 addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1); 2417 } else if (matches(*argv, "valid_lft") == 0) { 2418 if (valid_lftp) 2419 duparg("valid_lft", *argv); 2420 NEXT_ARG(); 2421 valid_lftp = *argv; 2422 if (set_lifetime(&valid_lft, *argv)) 2423 invarg("valid_lft value", *argv); 2424 } else if (matches(*argv, "preferred_lft") == 0) { 2425 if (preferred_lftp) 2426 duparg("preferred_lft", *argv); 2427 NEXT_ARG(); 2428 preferred_lftp = *argv; 2429 if (set_lifetime(&preferred_lft, *argv)) 2430 invarg("preferred_lft value", *argv); 2431 } else if (strcmp(*argv, "home") == 0) { 2432 ifa_flags |= IFA_F_HOMEADDRESS; 2433 } else if (strcmp(*argv, "nodad") == 0) { 2434 ifa_flags |= IFA_F_NODAD; 2435 } else if (strcmp(*argv, "mngtmpaddr") == 0) { 2436 ifa_flags |= IFA_F_MANAGETEMPADDR; 2437 } else if (strcmp(*argv, "noprefixroute") == 0) { 2438 ifa_flags |= IFA_F_NOPREFIXROUTE; 2439 } else if (strcmp(*argv, "autojoin") == 0) { 2440 ifa_flags |= IFA_F_MCAUTOJOIN; 2441 } else { 2442 if (strcmp(*argv, "local") == 0) 2443 NEXT_ARG(); 2444 if (matches(*argv, "help") == 0) 2445 usage(); 2446 if (local_len) 2447 duparg2("local", *argv); 2448 lcl_arg = *argv; 2449 get_prefix(&lcl, *argv, req.ifa.ifa_family); 2450 if (req.ifa.ifa_family == AF_UNSPEC) 2451 req.ifa.ifa_family = lcl.family; 2452 addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); 2453 local_len = lcl.bytelen; 2454 } 2455 argc--; argv++; 2456 } 2457 if (ifa_flags <= 0xff) 2458 req.ifa.ifa_flags = ifa_flags; 2459 else 2460 addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags); 2461 2462 if (d == NULL) { 2463 fprintf(stderr, "Not enough information: \"dev\" argument is required.\n"); 2464 return -1; 2465 } 2466 if (l && matches(d, l) != 0) { 2467 fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l); 2468 return -1; 2469 } 2470 2471 if (peer_len == 0 && local_len) { 2472 if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) { 2473 fprintf(stderr, 2474 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" 2475 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" 2476 " This special behaviour is likely to disappear in further releases,\n" 2477 " fix your scripts!\n", lcl_arg, local_len*8); 2478 } else { 2479 peer = lcl; 2480 addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen); 2481 } 2482 } 2483 if (req.ifa.ifa_prefixlen == 0) 2484 req.ifa.ifa_prefixlen = lcl.bitlen; 2485 2486 if (brd_len < 0 && cmd != RTM_DELADDR) { 2487 inet_prefix brd; 2488 int i; 2489 2490 if (req.ifa.ifa_family != AF_INET) { 2491 fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n"); 2492 return -1; 2493 } 2494 brd = peer; 2495 if (brd.bitlen <= 30) { 2496 for (i = 31; i >= brd.bitlen; i--) { 2497 if (brd_len == -1) 2498 brd.data[0] |= htonl(1<<(31-i)); 2499 else 2500 brd.data[0] &= ~htonl(1<<(31-i)); 2501 } 2502 addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen); 2503 brd_len = brd.bytelen; 2504 } 2505 } 2506 if (!scoped && cmd != RTM_DELADDR) 2507 req.ifa.ifa_scope = default_scope(&lcl); 2508 2509 if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) { 2510 fprintf(stderr, "Cannot find device \"%s\"\n", d); 2511 return -1; 2512 } 2513 2514 if (valid_lftp || preferred_lftp) { 2515 struct ifa_cacheinfo cinfo = {}; 2516 2517 if (!valid_lft) { 2518 fprintf(stderr, "valid_lft is zero\n"); 2519 return -1; 2520 } 2521 if (valid_lft < preferred_lft) { 2522 fprintf(stderr, "preferred_lft is greater than valid_lft\n"); 2523 return -1; 2524 } 2525 2526 cinfo.ifa_prefered = preferred_lft; 2527 cinfo.ifa_valid = valid_lft; 2528 addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo, 2529 sizeof(cinfo)); 2530 } 2531 2532 if ((ifa_flags & IFA_F_MCAUTOJOIN) && !ipaddr_is_multicast(&lcl)) { 2533 fprintf(stderr, "autojoin needs multicast address\n"); 2534 return -1; 2535 } 2536 2537 if (rtnl_talk(&rth, &req.n, NULL, 0) < 0) 2538 return -2; 2539 2540 return 0; 2541} 2542 2543int do_ipaddr(int argc, char **argv) 2544{ 2545 if (argc < 1) 2546 return ipaddr_list_flush_or_save(0, NULL, IPADD_LIST); 2547 if (matches(*argv, "add") == 0) 2548 return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1); 2549 if (matches(*argv, "change") == 0 || 2550 strcmp(*argv, "chg") == 0) 2551 return ipaddr_modify(RTM_NEWADDR, NLM_F_REPLACE, argc-1, argv+1); 2552 if (matches(*argv, "replace") == 0) 2553 return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1); 2554 if (matches(*argv, "delete") == 0) 2555 return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1); 2556 if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 2557 || matches(*argv, "lst") == 0) 2558 return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_LIST); 2559 if (matches(*argv, "flush") == 0) 2560 return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_FLUSH); 2561 if (matches(*argv, "save") == 0) 2562 return ipaddr_list_flush_or_save(argc-1, argv+1, IPADD_SAVE); 2563 if (matches(*argv, "showdump") == 0) 2564 return ipaddr_showdump(); 2565 if (matches(*argv, "restore") == 0) 2566 return ipaddr_restore(); 2567 if (matches(*argv, "help") == 0) 2568 usage(); 2569 fprintf(stderr, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv); 2570 exit(-1); 2571} 2572