From 2a09497fa43699320346a224829e764448406537 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 30 Apr 2008 18:48:49 +0200 Subject: Improved nl-route-delete featuring an interactive deletion mode --- src/nl-route-delete.c | 168 +++++++++++++++++++++++++++++++++++++------------- src/utils.h | 1 + 2 files changed, 125 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/nl-route-delete.c b/src/nl-route-delete.c index 1c97817..e0e2c1c 100644 --- a/src/nl-route-delete.c +++ b/src/nl-route-delete.c @@ -11,41 +11,94 @@ #include "route-utils.h" +static int interactive = 0, default_yes = 0, quiet = 0; +static int deleted = 0; +static struct nl_handle *nlh; + +static void print_version(void) +{ + fprintf(stderr, "%s\n", LIBNL_STRING); + exit(0); +} + static void print_usage(void) { printf( - "Usage: nl-route-delete [OPTION]...\n" + "Usage: nl-route-delete [OPTION]... [ROUTE]\n" "\n" "Options\n" - " -f, --family=FAMILY address family\n" + " -i, --interactive Run interactively\n" + " --yes Set default answer to yes\n" + " -q, --quiet Do not print informal notifications\n" + " -h, --help Show this help\n" + " -v, --version Show versioning information\n" + "\n" + "Route Options\n" " -d, --dst=ADDR destination prefix, e.g. 10.10.0.0/16\n" - " -n, --nh=NEXTHOP nexthop configuration:\n" + " -n, --nexthop=NH nexthop configuration:\n" " dev=DEV route via device\n" " weight=WEIGHT weight of nexthop\n" " flags=FLAGS\n" " via=GATEWAY route via other node\n" " realms=REALMS\n" " e.g. dev=eth0,via=192.168.1.12\n" - " -s, --src=ADDR source prefix\n" - " -i, --iif=DEV incomming interface\n" - " -P, --pref-src=ADDR preferred source address\n" - " -t, --table=TABLE routing table\n" - " -m, --metric=OPTS metrics\n" - " -p, --prio=NUM priotity\n" - " -S, --scope=SCOPE scope\n" - " -x, --proto=PROTO protocol\n" - " -T, --type=TYPE routing type\n" - " -D, --dumptype=TYPE { brief | detailed | stats | env }\n" - " -h, --help show this help\n"); - exit(1); + " -t, --table=TABLE Routing table\n" + " --family=FAMILY Address family\n" + " --src=ADDR Source prefix\n" + " --iif=DEV Incomming interface\n" + " --pref-src=ADDR Preferred source address\n" + " --metrics=OPTS Metrics configurations\n" + " --priority=NUM Priotity\n" + " --scope=SCOPE Scope\n" + " --protocol=PROTO Protocol\n" + " --type=TYPE { unicast | local | broadcast | multicast }\n" + ); + exit(0); +} + +static void delete_cb(struct nl_object *obj, void *arg) +{ + struct rtnl_route *route = (struct rtnl_route *) obj; + struct nl_dump_params dp = { + .dp_type = NL_DUMP_ONELINE, + .dp_fd = stdout, + }; + int err; + + if (interactive) { + int answer; + + nl_object_dump(obj, &dp); + printf("Delete? (%c/%c) ", + default_yes ? 'Y' : 'y', + default_yes ? 'n' : 'N'); + + do { + answer = tolower(getchar()); + if (answer == '\n') + answer = default_yes ? 'y' : 'n'; + } while (answer != 'y' && answer != 'n'); + + if (answer == 'n') + return; + } + + if ((err = rtnl_route_delete(nlh, route, 0)) < 0) + fatal(err, "rtnl_route_del failed: %s\n", nl_geterror()); + + if (!quiet) { + printf("Deleted "); + nl_object_dump(obj, &dp); + } + + deleted++; } int main(int argc, char *argv[]) { - struct nl_handle *nlh; struct nl_cache *link_cache, *route_cache; struct rtnl_route *route; - int err = 1; + int err = 1, nf = 0; nlh = nltool_alloc_handle(); nltool_connect(nlh, NETLINK_ROUTE); @@ -58,47 +111,74 @@ int main(int argc, char *argv[]) for (;;) { int c, optidx = 0; + enum { + ARG_FAMILY = 257, + ARG_SRC = 258, + ARG_IIF, + ARG_PREF_SRC, + ARG_METRICS, + ARG_PRIORITY, + ARG_SCOPE, + ARG_PROTOCOL, + ARG_TYPE, + ARG_YES, + }; static struct option long_opts[] = { - { "family", 1, 0, 'f' }, + { "interactive", 0, 0, 'i' }, + { "yes", 0, 0, ARG_YES }, + { "quiet", 0, 0, 'q' }, + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'v' }, { "dst", 1, 0, 'd' }, - { "src", 1, 0, 's' }, - { "iif", 1, 0, 'i' }, - { "nh", 1, 0, 'n' }, - { "pref-src", 1, 0, 'P' }, + { "nexthop", 1, 0, 'n' }, { "table", 1, 0, 't' }, - { "metric", 1, 0, 'm' }, - { "prio", 1, 0, 'p' }, - { "scope", 1, 0, 'S' }, - { "proto", 1, 0, 'x' }, - { "type", 1, 0, 'T' }, - { "help", 0, 0, 'h' }, + { "family", 1, 0, ARG_FAMILY }, + { "src", 1, 0, ARG_SRC }, + { "iif", 1, 0, ARG_IIF }, + { "pref-src", 1, 0, ARG_PREF_SRC }, + { "metrics", 1, 0, ARG_METRICS }, + { "priority", 1, 0, ARG_PRIORITY }, + { "scope", 1, 0, ARG_SCOPE }, + { "protocol", 1, 0, ARG_PROTOCOL }, + { "type", 1, 0, ARG_TYPE }, { 0, 0, 0, 0 } }; - c = getopt_long(argc, argv, "f:d:s:i:n:P:t:m:p:S:x:T:h", - long_opts, &optidx); + c = getopt_long(argc, argv, "iqhvd:n:t:", long_opts, &optidx); if (c == -1) break; switch (c) { - case 'f': parse_family(route, optarg); break; - case 'd': parse_dst(route, optarg); break; - case 's': parse_src(route, optarg); break; - case 'i': parse_iif(route, optarg, link_cache); break; - case 'n': parse_nexthop(route, optarg, link_cache); break; - case 'P': parse_pref_src(route, optarg); break; - case 't': parse_table(route, optarg); break; - case 'm': parse_metric(route, optarg); break; - case 'p': parse_prio(route, optarg); break; - case 'S': parse_scope(route, optarg); break; - case 'x': parse_protocol(route, optarg); break; - case 'T': parse_type(route, optarg); break; + case 'i': interactive = 1; break; + case ARG_YES: default_yes = 1; break; + case 'q': quiet = 1; break; case 'h': print_usage(); break; + case 'v': print_version(); break; + case 'd': nf++; parse_dst(route, optarg); break; + case 'n': nf++; parse_nexthop(route, optarg, link_cache); break; + case 't': nf++; parse_table(route, optarg); break; + case ARG_FAMILY: nf++; parse_family(route, optarg); break; + case ARG_SRC: nf++; parse_src(route, optarg); break; + case ARG_IIF: nf++; parse_iif(route, optarg, link_cache); break; + case ARG_PREF_SRC: nf++; parse_pref_src(route, optarg); break; + case ARG_METRICS: nf++; parse_metric(route, optarg); break; + case ARG_PRIORITY: nf++; parse_prio(route, optarg); break; + case ARG_SCOPE: nf++; parse_scope(route, optarg); break; + case ARG_PROTOCOL: nf++; parse_protocol(route, optarg); break; + case ARG_TYPE: nf++; parse_type(route, optarg); break; } } - if ((err = rtnl_route_delete(nlh, route, 0)) < 0) - fatal(err, "rtnl_route_del failed: %s\n", nl_geterror()); + if (nf == 0 && !interactive && !default_yes) { + fprintf(stderr, "You attempted to delete all routes in " + "non-interactive mode, aborting.\n"); + exit(0); + } + + nl_cache_foreach_filter(route_cache, OBJ_CAST(route), delete_cb, NULL); + + if (!quiet) + printf("Deleted %d routes\n", deleted); err = 0; diff --git a/src/utils.h b/src/utils.h index 7d85e15..1e0bcb4 100644 --- a/src/utils.h +++ b/src/utils.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3