aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-03-01 17:38:41 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2014-03-01 17:38:41 +0100
commitecd8c3affcbf39de2bdbfe347ae014abb709ab5d (patch)
tree028ec639dccb6b62e092587cfd9be0cf32873c05
parent81071e6872eeb9e47b938d5d6fd82056aaebdd2e (diff)
downloadbusybox-w32-ecd8c3affcbf39de2bdbfe347ae014abb709ab5d.tar.gz
busybox-w32-ecd8c3affcbf39de2bdbfe347ae014abb709ab5d.tar.bz2
busybox-w32-ecd8c3affcbf39de2bdbfe347ae014abb709ab5d.zip
ip link: add support for "address ETHADDR". Closes 4862
function old new delta do_iplink 2175 2289 +114 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/libiproute/iplink.c190
1 files changed, 188 insertions, 2 deletions
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 506fb3c7e..5c27c2de3 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -46,6 +46,12 @@ struct ifla_vlan_flags {
46/* taken from linux/sockios.h */ 46/* taken from linux/sockios.h */
47#define SIOCSIFNAME 0x8923 /* set interface name */ 47#define SIOCSIFNAME 0x8923 /* set interface name */
48 48
49#if 0
50# define dbg(...) bb_error_msg(__VA_ARGS__)
51#else
52# define dbg(...) ((void)0)
53#endif
54
49/* Exits on error */ 55/* Exits on error */
50static int get_ctl_fd(void) 56static int get_ctl_fd(void)
51{ 57{
@@ -401,12 +407,13 @@ static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size)
401static int do_add_or_delete(char **argv, const unsigned rtm) 407static int do_add_or_delete(char **argv, const unsigned rtm)
402{ 408{
403 static const char keywords[] ALIGN1 = 409 static const char keywords[] ALIGN1 =
404 "link\0""name\0""type\0""dev\0"; 410 "link\0""name\0""type\0""dev\0""address\0";
405 enum { 411 enum {
406 ARG_link, 412 ARG_link,
407 ARG_name, 413 ARG_name,
408 ARG_type, 414 ARG_type,
409 ARG_dev, 415 ARG_dev,
416 ARG_address,
410 }; 417 };
411 struct rtnl_handle rth; 418 struct rtnl_handle rth;
412 struct { 419 struct {
@@ -415,7 +422,11 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
415 char buf[1024]; 422 char buf[1024];
416 } req; 423 } req;
417 smalluint arg; 424 smalluint arg;
418 char *name_str = NULL, *link_str = NULL, *type_str = NULL, *dev_str = NULL; 425 char *name_str = NULL;
426 char *link_str = NULL;
427 char *type_str = NULL;
428 char *dev_str = NULL;
429 char *address_str = NULL;
419 430
420 memset(&req, 0, sizeof(req)); 431 memset(&req, 0, sizeof(req));
421 432
@@ -431,14 +442,21 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
431 if (arg == ARG_type) { 442 if (arg == ARG_type) {
432 NEXT_ARG(); 443 NEXT_ARG();
433 type_str = *argv++; 444 type_str = *argv++;
445 dbg("type_str:'%s'", type_str);
434 break; 446 break;
435 } 447 }
436 if (arg == ARG_link) { 448 if (arg == ARG_link) {
437 NEXT_ARG(); 449 NEXT_ARG();
438 link_str = *argv; 450 link_str = *argv;
451 dbg("link_str:'%s'", link_str);
439 } else if (arg == ARG_name) { 452 } else if (arg == ARG_name) {
440 NEXT_ARG(); 453 NEXT_ARG();
441 name_str = *argv; 454 name_str = *argv;
455 dbg("name_str:'%s'", name_str);
456 } else if (arg == ARG_address) {
457 NEXT_ARG();
458 address_str = *argv;
459 dbg("address_str:'%s'", name_str);
442 } else { 460 } else {
443 if (arg == ARG_dev) { 461 if (arg == ARG_dev) {
444 if (dev_str) 462 if (dev_str)
@@ -446,6 +464,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
446 NEXT_ARG(); 464 NEXT_ARG();
447 } 465 }
448 dev_str = *argv; 466 dev_str = *argv;
467 dbg("dev_str:'%s'", dev_str);
449 } 468 }
450 argv++; 469 argv++;
451 } 470 }
@@ -481,6 +500,14 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
481 int idx = xll_name_to_index(link_str); 500 int idx = xll_name_to_index(link_str);
482 addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4); 501 addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4);
483 } 502 }
503 if (address_str) {
504 unsigned char abuf[32];
505 int len = ll_addr_a2n(abuf, sizeof(abuf), address_str);
506 dbg("address len:%d", len);
507 if (len < 0)
508 return -1;
509 addattr_l(&req.n, sizeof(req), IFLA_ADDRESS, abuf, len);
510 }
484 } 511 }
485 if (name_str) { 512 if (name_str) {
486 const size_t name_len = strlen(name_str) + 1; 513 const size_t name_len = strlen(name_str) + 1;
@@ -493,6 +520,165 @@ static int do_add_or_delete(char **argv, const unsigned rtm)
493 return 0; 520 return 0;
494} 521}
495 522
523/* Other keywords recognized by iproute2-3.12.0: */
524#if 0
525 } else if (matches(*argv, "broadcast") == 0 ||
526 strcmp(*argv, "brd") == 0) {
527 NEXT_ARG();
528 len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
529 if (len < 0)
530 return -1;
531 addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len);
532 } else if (matches(*argv, "txqueuelen") == 0 ||
533 strcmp(*argv, "qlen") == 0 ||
534 matches(*argv, "txqlen") == 0) {
535 NEXT_ARG();
536 if (qlen != -1)
537 duparg("txqueuelen", *argv);
538 if (get_integer(&qlen, *argv, 0))
539 invarg("Invalid \"txqueuelen\" value\n", *argv);
540 addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4);
541 } else if (strcmp(*argv, "mtu") == 0) {
542 NEXT_ARG();
543 if (mtu != -1)
544 duparg("mtu", *argv);
545 if (get_integer(&mtu, *argv, 0))
546 invarg("Invalid \"mtu\" value\n", *argv);
547 addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
548 } else if (strcmp(*argv, "netns") == 0) {
549 NEXT_ARG();
550 if (netns != -1)
551 duparg("netns", *argv);
552 if ((netns = get_netns_fd(*argv)) >= 0)
553 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4);
554 else if (get_integer(&netns, *argv, 0) == 0)
555 addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4);
556 else
557 invarg("Invalid \"netns\" value\n", *argv);
558 } else if (strcmp(*argv, "multicast") == 0) {
559 NEXT_ARG();
560 req->i.ifi_change |= IFF_MULTICAST;
561 if (strcmp(*argv, "on") == 0) {
562 req->i.ifi_flags |= IFF_MULTICAST;
563 } else if (strcmp(*argv, "off") == 0) {
564 req->i.ifi_flags &= ~IFF_MULTICAST;
565 } else
566 return on_off("multicast", *argv);
567 } else if (strcmp(*argv, "allmulticast") == 0) {
568 NEXT_ARG();
569 req->i.ifi_change |= IFF_ALLMULTI;
570 if (strcmp(*argv, "on") == 0) {
571 req->i.ifi_flags |= IFF_ALLMULTI;
572 } else if (strcmp(*argv, "off") == 0) {
573 req->i.ifi_flags &= ~IFF_ALLMULTI;
574 } else
575 return on_off("allmulticast", *argv);
576 } else if (strcmp(*argv, "promisc") == 0) {
577 NEXT_ARG();
578 req->i.ifi_change |= IFF_PROMISC;
579 if (strcmp(*argv, "on") == 0) {
580 req->i.ifi_flags |= IFF_PROMISC;
581 } else if (strcmp(*argv, "off") == 0) {
582 req->i.ifi_flags &= ~IFF_PROMISC;
583 } else
584 return on_off("promisc", *argv);
585 } else if (strcmp(*argv, "trailers") == 0) {
586 NEXT_ARG();
587 req->i.ifi_change |= IFF_NOTRAILERS;
588 if (strcmp(*argv, "off") == 0) {
589 req->i.ifi_flags |= IFF_NOTRAILERS;
590 } else if (strcmp(*argv, "on") == 0) {
591 req->i.ifi_flags &= ~IFF_NOTRAILERS;
592 } else
593 return on_off("trailers", *argv);
594 } else if (strcmp(*argv, "arp") == 0) {
595 NEXT_ARG();
596 req->i.ifi_change |= IFF_NOARP;
597 if (strcmp(*argv, "on") == 0) {
598 req->i.ifi_flags &= ~IFF_NOARP;
599 } else if (strcmp(*argv, "off") == 0) {
600 req->i.ifi_flags |= IFF_NOARP;
601 } else
602 return on_off("noarp", *argv);
603 } else if (strcmp(*argv, "vf") == 0) {
604 struct rtattr *vflist;
605 NEXT_ARG();
606 if (get_integer(&vf, *argv, 0)) {
607 invarg("Invalid \"vf\" value\n", *argv);
608 }
609 vflist = addattr_nest(&req->n, sizeof(*req),
610 IFLA_VFINFO_LIST);
611 len = iplink_parse_vf(vf, &argc, &argv, req);
612 if (len < 0)
613 return -1;
614 addattr_nest_end(&req->n, vflist);
615 } else if (matches(*argv, "master") == 0) {
616 int ifindex;
617 NEXT_ARG();
618 ifindex = ll_name_to_index(*argv);
619 if (!ifindex)
620 invarg("Device does not exist\n", *argv);
621 addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
622 &ifindex, 4);
623 } else if (matches(*argv, "nomaster") == 0) {
624 int ifindex = 0;
625 addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
626 &ifindex, 4);
627 } else if (matches(*argv, "dynamic") == 0) {
628 NEXT_ARG();
629 req->i.ifi_change |= IFF_DYNAMIC;
630 if (strcmp(*argv, "on") == 0) {
631 req->i.ifi_flags |= IFF_DYNAMIC;
632 } else if (strcmp(*argv, "off") == 0) {
633 req->i.ifi_flags &= ~IFF_DYNAMIC;
634 } else
635 return on_off("dynamic", *argv);
636 } else if (matches(*argv, "alias") == 0) {
637 NEXT_ARG();
638 addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS,
639 *argv, strlen(*argv));
640 argc--; argv++;
641 break;
642 } else if (strcmp(*argv, "group") == 0) {
643 NEXT_ARG();
644 if (*group != -1)
645 duparg("group", *argv);
646 if (rtnl_group_a2n(group, *argv))
647 invarg("Invalid \"group\" value\n", *argv);
648 } else if (strcmp(*argv, "mode") == 0) {
649 int mode;
650 NEXT_ARG();
651 mode = get_link_mode(*argv);
652 if (mode < 0)
653 invarg("Invalid link mode\n", *argv);
654 addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
655 } else if (strcmp(*argv, "state") == 0) {
656 int state;
657 NEXT_ARG();
658 state = get_operstate(*argv);
659 if (state < 0)
660 invarg("Invalid operstate\n", *argv);
661
662 addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);
663 } else if (matches(*argv, "numtxqueues") == 0) {
664 NEXT_ARG();
665 if (numtxqueues != -1)
666 duparg("numtxqueues", *argv);
667 if (get_integer(&numtxqueues, *argv, 0))
668 invarg("Invalid \"numtxqueues\" value\n", *argv);
669 addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES,
670 &numtxqueues, 4);
671 } else if (matches(*argv, "numrxqueues") == 0) {
672 NEXT_ARG();
673 if (numrxqueues != -1)
674 duparg("numrxqueues", *argv);
675 if (get_integer(&numrxqueues, *argv, 0))
676 invarg("Invalid \"numrxqueues\" value\n", *argv);
677 addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES,
678 &numrxqueues, 4);
679 }
680#endif
681
496/* Return value becomes exitcode. It's okay to not return at all */ 682/* Return value becomes exitcode. It's okay to not return at all */
497int FAST_FUNC do_iplink(char **argv) 683int FAST_FUNC do_iplink(char **argv)
498{ 684{