diff options
author | Thomas Graf <tgraf@suug.ch> | 2010-10-19 11:06:42 (GMT) |
---|---|---|
committer | Thomas Graf <tgraf@suug.ch> | 2010-10-19 11:06:42 (GMT) |
commit | c0cd587dfc46ca8e8e5f9da51e878e0678950f23 (patch) | |
tree | 10aaa6c61ac3416f2fd579c3d05c9210c7d4ef83 /src/lib | |
parent | 3229b32e39363c439f0d042b561417e7b48aa786 (diff) | |
download | libnl-c0cd587dfc46ca8e8e5f9da51e878e0678950f23.zip libnl-c0cd587dfc46ca8e8e5f9da51e878e0678950f23.tar.gz libnl-c0cd587dfc46ca8e8e5f9da51e878e0678950f23.tar.bz2 |
nl-qdisc-add tool
Adds a cli based tool to add/update/replace qdiscs. This tool requires
each qdisc to be supported via a dynamic loadable module in
pkglibdir/cli/qdisc/$name.so.
So far HTB and blackhole have been implemented.
Syntax:
nl-qdisc-add --dev eth2 --parent root --id 1: htb --r2q=5
nl-qdisc-add --update-only --dev eth2 --id 1: htb --r2q=10
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/qdisc.c | 57 | ||||
-rw-r--r-- | src/lib/utils.c | 38 |
2 files changed, 92 insertions, 3 deletions
diff --git a/src/lib/qdisc.c b/src/lib/qdisc.c index bc7ff92..52b7a6a 100644 --- a/src/lib/qdisc.c +++ b/src/lib/qdisc.c @@ -6,13 +6,12 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch> */ /** * @ingroup cli * @defgroup cli_qdisc Queueing Disciplines - * * @{ */ @@ -69,4 +68,58 @@ void nl_cli_qdisc_parse_kind(struct rtnl_qdisc *qdisc, char *arg) rtnl_qdisc_set_kind(qdisc, arg); } +static NL_LIST_HEAD(qdisc_modules); + +struct nl_cli_qdisc_module *__nl_cli_qdisc_lookup(struct rtnl_qdisc_ops *ops) +{ + struct nl_cli_qdisc_module *qm; + + nl_list_for_each_entry(qm, &qdisc_modules, qm_list) + if (qm->qm_ops == ops) + return qm; + + return NULL; +} + +struct nl_cli_qdisc_module *nl_cli_qdisc_lookup(struct rtnl_qdisc_ops *ops) +{ + struct nl_cli_qdisc_module *qm; + + if ((qm = __nl_cli_qdisc_lookup(ops))) + return qm; + + nl_cli_load_module("cli/qdisc", ops->qo_kind); + + if (!(qm = __nl_cli_qdisc_lookup(ops))) { + nl_cli_fatal(EINVAL, "Application bug: The shared library for " + "the qdisc \"%s\" was successfully loaded but it " + "seems that module did not register itself"); + } + + return qm; +} + +void nl_cli_qdisc_register(struct nl_cli_qdisc_module *qm) +{ + struct rtnl_qdisc_ops *ops; + + if (!(ops = __rtnl_qdisc_lookup_ops(qm->qm_name))) { + nl_cli_fatal(ENOENT, "Unable to register CLI qdisc module " + "\"%s\": No matching libnl qdisc module found.", qm->qm_name); + } + + if (__nl_cli_qdisc_lookup(ops)) { + nl_cli_fatal(EEXIST, "Unable to register CLI qdisc module " + "\"%s\": Module already registered.", qm->qm_name); + } + + qm->qm_ops = ops; + nl_list_add_tail(&qm->qm_list, &qdisc_modules); +} + +void nl_cli_qdisc_unregister(struct nl_cli_qdisc_module *qm) +{ + nl_list_del(&qm->qm_list); +} + /** @} */ diff --git a/src/lib/utils.c b/src/lib/utils.c index 02a7be1..9375bfc 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -13,10 +13,25 @@ * @defgroup cli Command Line Interface API * * @{ + * + * These modules provide an interface for text based applications. The + * functions provided are wrappers for their libnl equivalent with + * added error handling. The functions check for allocation failures, + * invalid input, and unknown types and will print error messages + * accordingly via nl_cli_fatal(). */ #include <netlink/cli/utils.h> +/** + * Parse a text based 32 bit unsigned integer argument + * @arg arg Integer in text form. + * + * Tries to convert the number provided in arg to a uint32_t. Will call + * nl_cli_fatal() if the conversion fails. + * + * @return 32bit unsigned integer. + */ uint32_t nl_cli_parse_u32(const char *arg) { unsigned long lval; @@ -34,7 +49,7 @@ void nl_cli_print_version(void) { printf("libnl tools version %s\n", LIBNL_VERSION); printf( - "Copyright (C) 2003-2009 Thomas Graf <tgraf@redhat.com>\n" + "Copyright (C) 2003-2010 Thomas Graf <tgraf@redhat.com>\n" "\n" "This program comes with ABSOLUTELY NO WARRANTY. This is free \n" "software, and you are welcome to redistribute it under certain\n" @@ -44,6 +59,14 @@ void nl_cli_print_version(void) exit(0); } +/** + * Print error message and quit application + * @arg err Error code. + * @arg fmt Error message. + * + * Prints the formatted error message to stderr and quits the application + * using the provided error code. + */ void nl_cli_fatal(int err, const char *fmt, ...) { va_list ap; @@ -144,4 +167,17 @@ struct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name, return cache; } +void nl_cli_load_module(const char *prefix, const char *name) +{ + char path[FILENAME_MAX+1]; + void *handle; + + snprintf(path, sizeof(path), "%s/%s/%s.so", + PKGLIBDIR, prefix, name); + + if (!(handle = dlopen(path, RTLD_NOW))) + nl_cli_fatal(ENOENT, "Unable to load module \"%s\": %s\n", + path, dlerror()); +} + /** @} */ |