libnl
3.2.3
|
00001 /* 00002 * src/lib/tc.c CLI Traffic Control Helpers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2010 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 #include <netlink/cli/utils.h> 00013 #include <netlink/cli/tc.h> 00014 #include <netlink/route/tc-api.h> 00015 00016 /** 00017 * @ingroup cli 00018 * @defgroup cli_tc Traffic Control 00019 * @{ 00020 */ 00021 void nl_cli_tc_parse_dev(struct rtnl_tc *tc, struct nl_cache *link_cache, char *name) 00022 { 00023 struct rtnl_link *link; 00024 00025 link = rtnl_link_get_by_name(link_cache, name); 00026 if (!link) 00027 nl_cli_fatal(ENOENT, "Link \"%s\" does not exist.", name); 00028 00029 rtnl_tc_set_link(tc, link); 00030 rtnl_link_put(link); 00031 } 00032 00033 void nl_cli_tc_parse_parent(struct rtnl_tc *tc, char *arg) 00034 { 00035 uint32_t parent; 00036 int err; 00037 00038 if ((err = rtnl_tc_str2handle(arg, &parent)) < 0) 00039 nl_cli_fatal(err, "Unable to parse handle \"%s\": %s", 00040 arg, nl_geterror(err)); 00041 00042 rtnl_tc_set_parent(tc, parent); 00043 } 00044 00045 void nl_cli_tc_parse_handle(struct rtnl_tc *tc, char *arg, int create) 00046 { 00047 uint32_t handle, parent; 00048 int err; 00049 00050 parent = rtnl_tc_get_parent(tc); 00051 00052 if ((err = rtnl_tc_str2handle(arg, &handle)) < 0) { 00053 if (err == -NLE_OBJ_NOTFOUND && create) 00054 err = rtnl_classid_generate(arg, &handle, parent); 00055 00056 if (err < 0) 00057 nl_cli_fatal(err, "Unable to parse handle \"%s\": %s", 00058 arg, nl_geterror(err)); 00059 } 00060 00061 rtnl_tc_set_handle(tc, handle); 00062 } 00063 00064 void nl_cli_tc_parse_mtu(struct rtnl_tc *tc, char *arg) 00065 { 00066 rtnl_tc_set_mtu(tc, nl_cli_parse_u32(arg)); 00067 } 00068 00069 void nl_cli_tc_parse_mpu(struct rtnl_tc *tc, char *arg) 00070 { 00071 rtnl_tc_set_mpu(tc, nl_cli_parse_u32(arg)); 00072 } 00073 00074 void nl_cli_tc_parse_overhead(struct rtnl_tc *tc, char *arg) 00075 { 00076 rtnl_tc_set_overhead(tc, nl_cli_parse_u32(arg)); 00077 } 00078 00079 void nl_cli_tc_parse_kind(struct rtnl_tc *tc, char *arg) 00080 { 00081 rtnl_tc_set_kind(tc, arg); 00082 } 00083 00084 void nl_cli_tc_parse_linktype(struct rtnl_tc *tc, char *arg) 00085 { 00086 int type; 00087 00088 if ((type = nl_str2llproto(arg)) < 0) 00089 nl_cli_fatal(type, "Unable to parse linktype \"%s\": %s", 00090 arg, nl_geterror(type)); 00091 00092 rtnl_tc_set_linktype(tc, type); 00093 } 00094 00095 static NL_LIST_HEAD(tc_modules); 00096 00097 static struct nl_cli_tc_module *__nl_cli_tc_lookup(struct rtnl_tc_ops *ops) 00098 { 00099 struct nl_cli_tc_module *tm; 00100 00101 nl_list_for_each_entry(tm, &tc_modules, tm_list) 00102 if (tm->tm_ops == ops) 00103 return tm; 00104 00105 return NULL; 00106 } 00107 00108 struct nl_cli_tc_module *nl_cli_tc_lookup(struct rtnl_tc_ops *ops) 00109 { 00110 struct nl_cli_tc_module *tm; 00111 00112 if ((tm = __nl_cli_tc_lookup(ops))) 00113 return tm; 00114 00115 switch (ops->to_type) { 00116 case RTNL_TC_TYPE_QDISC: 00117 case RTNL_TC_TYPE_CLASS: 00118 nl_cli_load_module("cli/qdisc", ops->to_kind); 00119 break; 00120 00121 case RTNL_TC_TYPE_CLS: 00122 nl_cli_load_module("cli/cls", ops->to_kind); 00123 break; 00124 00125 default: 00126 nl_cli_fatal(EINVAL, "BUG: unhandled TC object type %d", 00127 ops->to_type); 00128 } 00129 00130 if (!(tm = __nl_cli_tc_lookup(ops))) { 00131 nl_cli_fatal(EINVAL, "Application bug: The shared library for " 00132 "the tc object \"%s\" was successfully loaded but it " 00133 "seems that module did not register itself", 00134 ops->to_kind); 00135 } 00136 00137 return tm; 00138 } 00139 00140 void nl_cli_tc_register(struct nl_cli_tc_module *tm) 00141 { 00142 struct rtnl_tc_ops *ops; 00143 00144 if (!(ops = rtnl_tc_lookup_ops(tm->tm_type, tm->tm_name))) { 00145 nl_cli_fatal(ENOENT, "Unable to register CLI TC module " 00146 "\"%s\": No matching libnl TC module found.", tm->tm_name); 00147 } 00148 00149 if (__nl_cli_tc_lookup(ops)) { 00150 nl_cli_fatal(EEXIST, "Unable to register CLI TC module " 00151 "\"%s\": Module already registered.", tm->tm_name); 00152 } 00153 00154 tm->tm_ops = ops; 00155 00156 nl_list_add_tail(&tm->tm_list, &tc_modules); 00157 } 00158 00159 void nl_cli_tc_unregister(struct nl_cli_tc_module *tm) 00160 { 00161 nl_list_del(&tm->tm_list); 00162 } 00163 00164 00165 /** @} */