diff options
author | Thomas Graf <tgraf@suug.ch> | 2011-03-21 14:51:52 (GMT) |
---|---|---|
committer | Thomas Graf <tgraf@suug.ch> | 2011-03-21 14:51:52 (GMT) |
commit | 8eb5b5532eae985a5f0911dccf2db8cb4e0a5de4 (patch) | |
tree | 0fec48d114edbb535bd234f2684acccf81447d13 /src/lib/tc.c | |
parent | 5dc897d5de9f54078221b241e0122713207f5e0c (diff) | |
download | libnl-8eb5b5532eae985a5f0911dccf2db8cb4e0a5de4.zip libnl-8eb5b5532eae985a5f0911dccf2db8cb4e0a5de4.tar.gz libnl-8eb5b5532eae985a5f0911dccf2db8cb4e0a5de4.tar.bz2 |
Unified TC API
Finally got rid of all the qdisc/class/cls code duplication in
the tc module API. The API takes care of allocation/freeing the
tc object specific data.
I hope I got it right this time.
Diffstat (limited to 'src/lib/tc.c')
-rw-r--r-- | src/lib/tc.c | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/src/lib/tc.c b/src/lib/tc.c index 72407cf..8d013f9 100644 --- a/src/lib/tc.c +++ b/src/lib/tc.c @@ -11,7 +11,7 @@ #include <netlink/cli/utils.h> #include <netlink/cli/tc.h> -#include <netlink/route/tc.h> +#include <netlink/route/tc-api.h> /** * @ingroup cli @@ -76,6 +76,11 @@ void nl_cli_tc_parse_overhead(struct rtnl_tc *tc, char *arg) rtnl_tc_set_overhead(tc, nl_cli_parse_u32(arg)); } +void nl_cli_tc_parse_kind(struct rtnl_tc *tc, char *arg) +{ + rtnl_tc_set_kind(tc, arg); +} + void nl_cli_tc_parse_linktype(struct rtnl_tc *tc, char *arg) { int type; @@ -87,4 +92,74 @@ void nl_cli_tc_parse_linktype(struct rtnl_tc *tc, char *arg) rtnl_tc_set_linktype(tc, type); } +static NL_LIST_HEAD(tc_modules); + +struct nl_cli_tc_module *__nl_cli_tc_lookup(struct rtnl_tc_ops *ops) +{ + struct nl_cli_tc_module *tm; + + nl_list_for_each_entry(tm, &tc_modules, tm_list) + if (tm->tm_ops == ops) + return tm; + + return NULL; +} + +struct nl_cli_tc_module *nl_cli_tc_lookup(struct rtnl_tc_ops *ops) +{ + struct nl_cli_tc_module *tm; + + if ((tm = __nl_cli_tc_lookup(ops))) + return tm; + + switch (ops->to_type) { + case RTNL_TC_TYPE_QDISC: + case RTNL_TC_TYPE_CLASS: + nl_cli_load_module("cli/qdisc", ops->to_kind); + break; + + case RTNL_TC_TYPE_CLS: + nl_cli_load_module("cli/cls", ops->to_kind); + break; + + default: + nl_cli_fatal(EINVAL, "BUG: unhandled TC object type %d", + ops->to_type); + } + + if (!(tm = __nl_cli_tc_lookup(ops))) { + nl_cli_fatal(EINVAL, "Application bug: The shared library for " + "the tc object \"%s\" was successfully loaded but it " + "seems that module did not register itself", + ops->to_kind); + } + + return tm; +} + +void nl_cli_tc_register(struct nl_cli_tc_module *tm) +{ + struct rtnl_tc_ops *ops; + + if (!(ops = rtnl_tc_lookup_ops(tm->tm_type, tm->tm_name))) { + nl_cli_fatal(ENOENT, "Unable to register CLI TC module " + "\"%s\": No matching libnl TC module found.", tm->tm_name); + } + + if (__nl_cli_tc_lookup(ops)) { + nl_cli_fatal(EEXIST, "Unable to register CLI TC module " + "\"%s\": Module already registered.", tm->tm_name); + } + + tm->tm_ops = ops; + + nl_list_add_tail(&tm->tm_list, &tc_modules); +} + +void nl_cli_tc_unregister(struct nl_cli_tc_module *tm) +{ + nl_list_del(&tm->tm_list); +} + + /** @} */ |