diff options
Diffstat (limited to 'networking/libiproute/iproute.c')
-rw-r--r-- | networking/libiproute/iproute.c | 170 |
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 */ |
326 | static int iproute_modify(int cmd, unsigned flags, char **argv) | 326 | static 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, |
337 | IF_FEATURE_IP_RULE(ARG_table,) | 338 | IF_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 | ||