144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 2535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf * src/nl-route-add.c Route addition utility 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 98808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 128808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/utils.h> 138808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/route.h> 148808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/link.h> 15535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf 16a948e082ea1d9457057296f65e5d72708cd5e768Thomas Grafstatic int quiet = 0; 17535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafstatic struct nl_cache *link_cache, *route_cache; 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf 1944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void print_usage(void) 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf printf( 22a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf "Usage: nl-route-add [OPTION]... [ROUTE]\n" 23a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf "\n" 24a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf "Options\n" 25a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " -q, --quiet Do not print informal notifications\n" 26a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " -h, --help Show this help\n" 27a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " -v, --version Show versioning information\n" 28535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf "\n" 29a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf "Route Options\n" 30535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf " -d, --dst=ADDR destination prefix, e.g. 10.10.0.0/16\n" 31a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " -n, --nexthop=NH nexthop configuration:\n" 32535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf " dev=DEV route via device\n" 33535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf " weight=WEIGHT weight of nexthop\n" 34535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf " flags=FLAGS\n" 35535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf " via=GATEWAY route via other node\n" 36535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf " realms=REALMS\n" 37535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf " e.g. dev=eth0,via=192.168.1.12\n" 38a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " -t, --table=TABLE Routing table\n" 39a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --family=FAMILY Address family\n" 40a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --src=ADDR Source prefix\n" 41a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --iif=DEV Incomming interface\n" 42a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --pref-src=ADDR Preferred source address\n" 43a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --metrics=OPTS Metrics configurations\n" 44a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --priority=NUM Priotity\n" 45a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --scope=SCOPE Scope\n" 46a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --protocol=PROTO Protocol\n" 47a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf " --type=TYPE { unicast | local | broadcast | multicast }\n" 48a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ); 49a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf exit(0); 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf 5244d362409d5469aed47d19e7908d19bd194493aThomas Grafint main(int argc, char *argv[]) 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 54b624b9ed936f4c23bc4f30d8dce34da49775dd15Thomas Graf struct nl_sock *sock; 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_route *route; 56a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf struct nl_dump_params dp = { 57d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf .dp_type = NL_DUMP_LINE, 58a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf .dp_fd = stdout, 59a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf }; 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf int err = 1; 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf 628808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf sock = nl_cli_alloc_socket(); 638808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_cli_connect(sock, NETLINK_ROUTE); 648808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf link_cache = nl_cli_link_alloc_cache(sock); 658808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf route_cache = nl_cli_route_alloc_cache(sock, 0); 668808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf route = nl_cli_route_alloc(); 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf 68535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf for (;;) { 69535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf int c, optidx = 0; 70a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf enum { 71a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_FAMILY = 257, 72a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_SRC = 258, 73a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_IIF, 74a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_PREF_SRC, 75a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_METRICS, 76a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_PRIORITY, 77a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_SCOPE, 78a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_PROTOCOL, 79a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf ARG_TYPE, 80a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf }; 81535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf static struct option long_opts[] = { 82a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "quiet", 0, 0, 'q' }, 83a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "help", 0, 0, 'h' }, 84a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "version", 0, 0, 'v' }, 85535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf { "dst", 1, 0, 'd' }, 86a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "nexthop", 1, 0, 'n' }, 87535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf { "table", 1, 0, 't' }, 88a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "family", 1, 0, ARG_FAMILY }, 89a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "src", 1, 0, ARG_SRC }, 90a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "iif", 1, 0, ARG_IIF }, 91a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "pref-src", 1, 0, ARG_PREF_SRC }, 92a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "metrics", 1, 0, ARG_METRICS }, 93a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "priority", 1, 0, ARG_PRIORITY }, 94a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "scope", 1, 0, ARG_SCOPE }, 95a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "protocol", 1, 0, ARG_PROTOCOL }, 96a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf { "type", 1, 0, ARG_TYPE }, 97535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf { 0, 0, 0, 0 } 98535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf }; 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf 100a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf c = getopt_long(argc, argv, "qhvd:n:t:", long_opts, &optidx); 101535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf if (c == -1) 102535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf break; 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf 104535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf switch (c) { 105a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf case 'q': quiet = 1; break; 106a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf case 'h': print_usage(); break; 1078808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case 'v': nl_cli_print_version(); break; 1088808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case 'd': nl_cli_route_parse_dst(route, optarg); break; 1098808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case 'n': nl_cli_route_parse_nexthop(route, optarg, link_cache); break; 1108808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case 't': nl_cli_route_parse_table(route, optarg); break; 1118808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_FAMILY: nl_cli_route_parse_family(route, optarg); break; 1128808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_SRC: nl_cli_route_parse_src(route, optarg); break; 1138808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_IIF: nl_cli_route_parse_iif(route, optarg, link_cache); break; 1148808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_PREF_SRC: nl_cli_route_parse_pref_src(route, optarg); break; 1158808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_METRICS: nl_cli_route_parse_metric(route, optarg); break; 1168808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_PRIORITY: nl_cli_route_parse_prio(route, optarg); break; 1178808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_SCOPE: nl_cli_route_parse_scope(route, optarg); break; 1188808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_PROTOCOL: nl_cli_route_parse_protocol(route, optarg); break; 1198808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf case ARG_TYPE: nl_cli_route_parse_type(route, optarg); break; 120535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf } 121535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf } 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf 12310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf if ((err = rtnl_route_add(sock, route, 0)) < 0) 1248808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_cli_fatal(err, "Unable to add route: %s", nl_geterror(err)); 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf 126a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf if (!quiet) { 127a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf printf("Added "); 128a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf nl_object_dump(OBJ_CAST(route), &dp); 129a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf } 130a948e082ea1d9457057296f65e5d72708cd5e768Thomas Graf 13110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf return 0; 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 133