aboutsummaryrefslogtreecommitdiff
path: root/networking/libiproute/iproute.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/libiproute/iproute.c')
-rw-r--r--networking/libiproute/iproute.c170
1 files changed, 167 insertions, 3 deletions
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 0f2b89682..62fa6efd3 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -325,13 +325,14 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
325/* Return value becomes exitcode. It's okay to not return at all */ 325/* Return value becomes exitcode. It's okay to not return at all */
326static int iproute_modify(int cmd, unsigned flags, char **argv) 326static int iproute_modify(int cmd, unsigned flags, char **argv)
327{ 327{
328 /* If you add stuff here, update iproute_full_usage */
328 static const char keywords[] ALIGN1 = 329 static const char keywords[] ALIGN1 =
329 "src\0""via\0""mtu\0""lock\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") 330 "src\0""via\0""mtu\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0")
330 "dev\0""oif\0""to\0""metric\0""onlink\0"; 331 "dev\0""oif\0""to\0""metric\0""onlink\0";
331 enum { 332 enum {
332 ARG_src, 333 ARG_src,
333 ARG_via, 334 ARG_via,
334 ARG_mtu, PARM_lock, 335 ARG_mtu,
335 ARG_scope, 336 ARG_scope,
336 ARG_protocol, 337 ARG_protocol,
337IF_FEATURE_IP_RULE(ARG_table,) 338IF_FEATURE_IP_RULE(ARG_table,)
@@ -404,7 +405,7 @@ IF_FEATURE_IP_RULE(ARG_table,)
404 } else if (arg == ARG_mtu) { 405 } else if (arg == ARG_mtu) {
405 unsigned mtu; 406 unsigned mtu;
406 NEXT_ARG(); 407 NEXT_ARG();
407 if (index_in_strings(keywords, *argv) == PARM_lock) { 408 if (strcmp(*argv, "lock") == 0) {
408 mxlock |= (1 << RTAX_MTU); 409 mxlock |= (1 << RTAX_MTU);
409 NEXT_ARG(); 410 NEXT_ARG();
410 } 411 }
@@ -441,6 +442,7 @@ IF_FEATURE_IP_RULE(ARG_table,)
441 NEXT_ARG(); 442 NEXT_ARG();
442 d = *argv; 443 d = *argv;
443 } else if (arg == ARG_metric) { 444 } else if (arg == ARG_metric) {
445//TODO: "metric", "priority" and "preference" are synonyms
444 uint32_t metric; 446 uint32_t metric;
445 NEXT_ARG(); 447 NEXT_ARG();
446 metric = get_u32(*argv, "metric"); 448 metric = get_u32(*argv, "metric");
@@ -475,6 +477,168 @@ IF_FEATURE_IP_RULE(ARG_table,)
475 addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); 477 addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen);
476 } 478 }
477 } 479 }
480/* Other keywords recognized by iproute2-3.19.0: */
481#if 0
482 } else if (strcmp(*argv, "from") == 0) {
483 inet_prefix addr;
484 NEXT_ARG();
485 get_prefix(&addr, *argv, req.r.rtm_family);
486 if (req.r.rtm_family == AF_UNSPEC)
487 req.r.rtm_family = addr.family;
488 if (addr.bytelen)
489 addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen);
490 req.r.rtm_src_len = addr.bitlen;
491 } else if (strcmp(*argv, "tos") == 0 ||
492 matches(*argv, "dsfield") == 0) {
493 __u32 tos;
494 NEXT_ARG();
495 if (rtnl_dsfield_a2n(&tos, *argv))
496 invarg("\"tos\" value is invalid\n", *argv);
497 req.r.rtm_tos = tos;
498 } else if (strcmp(*argv, "hoplimit") == 0) {
499 unsigned hoplimit;
500 NEXT_ARG();
501 if (strcmp(*argv, "lock") == 0) {
502 mxlock |= (1<<RTAX_HOPLIMIT);
503 NEXT_ARG();
504 }
505 if (get_unsigned(&hoplimit, *argv, 0))
506 invarg("\"hoplimit\" value is invalid\n", *argv);
507 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_HOPLIMIT, hoplimit);
508 } else if (strcmp(*argv, "advmss") == 0) {
509 unsigned mss;
510 NEXT_ARG();
511 if (strcmp(*argv, "lock") == 0) {
512 mxlock |= (1<<RTAX_ADVMSS);
513 NEXT_ARG();
514 }
515 if (get_unsigned(&mss, *argv, 0))
516 invarg("\"mss\" value is invalid\n", *argv);
517 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_ADVMSS, mss);
518 } else if (matches(*argv, "reordering") == 0) {
519 unsigned reord;
520 NEXT_ARG();
521 if (strcmp(*argv, "lock") == 0) {
522 mxlock |= (1<<RTAX_REORDERING);
523 NEXT_ARG();
524 }
525 if (get_unsigned(&reord, *argv, 0))
526 invarg("\"reordering\" value is invalid\n", *argv);
527 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_REORDERING, reord);
528 } else if (strcmp(*argv, "rtt") == 0) {
529 unsigned rtt;
530 NEXT_ARG();
531 if (strcmp(*argv, "lock") == 0) {
532 mxlock |= (1<<RTAX_RTT);
533 NEXT_ARG();
534 }
535 if (get_time_rtt(&rtt, *argv, &raw))
536 invarg("\"rtt\" value is invalid\n", *argv);
537 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTT,
538 (raw) ? rtt : rtt * 8);
539 } else if (strcmp(*argv, "rto_min") == 0) {
540 unsigned rto_min;
541 NEXT_ARG();
542 mxlock |= (1<<RTAX_RTO_MIN);
543 if (get_time_rtt(&rto_min, *argv, &raw))
544 invarg("\"rto_min\" value is invalid\n",
545 *argv);
546 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTO_MIN,
547 rto_min);
548 } else if (matches(*argv, "window") == 0) {
549 unsigned win;
550 NEXT_ARG();
551 if (strcmp(*argv, "lock") == 0) {
552 mxlock |= (1<<RTAX_WINDOW);
553 NEXT_ARG();
554 }
555 if (get_unsigned(&win, *argv, 0))
556 invarg("\"window\" value is invalid\n", *argv);
557 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_WINDOW, win);
558 } else if (matches(*argv, "cwnd") == 0) {
559 unsigned win;
560 NEXT_ARG();
561 if (strcmp(*argv, "lock") == 0) {
562 mxlock |= (1<<RTAX_CWND);
563 NEXT_ARG();
564 }
565 if (get_unsigned(&win, *argv, 0))
566 invarg("\"cwnd\" value is invalid\n", *argv);
567 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_CWND, win);
568 } else if (matches(*argv, "initcwnd") == 0) {
569 unsigned win;
570 NEXT_ARG();
571 if (strcmp(*argv, "lock") == 0) {
572 mxlock |= (1<<RTAX_INITCWND);
573 NEXT_ARG();
574 }
575 if (get_unsigned(&win, *argv, 0))
576 invarg("\"initcwnd\" value is invalid\n", *argv);
577 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITCWND, win);
578 } else if (matches(*argv, "initrwnd") == 0) {
579 unsigned win;
580 NEXT_ARG();
581 if (strcmp(*argv, "lock") == 0) {
582 mxlock |= (1<<RTAX_INITRWND);
583 NEXT_ARG();
584 }
585 if (get_unsigned(&win, *argv, 0))
586 invarg("\"initrwnd\" value is invalid\n", *argv);
587 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITRWND, win);
588 } else if (matches(*argv, "features") == 0) {
589 unsigned int features = 0;
590
591 while (argc > 0) {
592 NEXT_ARG();
593
594 if (strcmp(*argv, "ecn") == 0)
595 features |= RTAX_FEATURE_ECN;
596 else
597 invarg("\"features\" value not valid\n", *argv);
598 break;
599 }
600
601 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_FEATURES, features);
602 } else if (matches(*argv, "quickack") == 0) {
603 unsigned quickack;
604 NEXT_ARG();
605 if (get_unsigned(&quickack, *argv, 0))
606 invarg("\"quickack\" value is invalid\n", *argv);
607 if (quickack != 1 && quickack != 0)
608 invarg("\"quickack\" value should be 0 or 1\n", *argv);
609 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_QUICKACK, quickack);
610 } else if (matches(*argv, "rttvar") == 0) {
611 unsigned win;
612 NEXT_ARG();
613 if (strcmp(*argv, "lock") == 0) {
614 mxlock |= (1<<RTAX_RTTVAR);
615 NEXT_ARG();
616 }
617 if (get_time_rtt(&win, *argv, &raw))
618 invarg("\"rttvar\" value is invalid\n", *argv);
619 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTTVAR,
620 (raw) ? win : win * 4);
621 } else if (matches(*argv, "ssthresh") == 0) {
622 unsigned win;
623 NEXT_ARG();
624 if (strcmp(*argv, "lock") == 0) {
625 mxlock |= (1<<RTAX_SSTHRESH);
626 NEXT_ARG();
627 }
628 if (get_unsigned(&win, *argv, 0))
629 invarg("\"ssthresh\" value is invalid\n", *argv);
630 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_SSTHRESH, win);
631 } else if (matches(*argv, "realms") == 0) {
632 __u32 realm;
633 NEXT_ARG();
634 if (get_rt_realms(&realm, *argv))
635 invarg("\"realm\" value is invalid\n", *argv);
636 addattr32(&req.n, sizeof(req), RTA_FLOW, realm);
637 } else if (strcmp(*argv, "nexthop") == 0) {
638 nhs_ok = 1;
639 break;
640 }
641#endif
478 argv++; 642 argv++;
479 } 643 }
480 644