libnl
3.2.3
|
00001 /* 00002 * lib/route/qdisc/dsmark.c DSMARK 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) 2003-2011 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup qdisc 00014 * @ingroup class 00015 * @defgroup qdisc_dsmark Differentiated Services Marker (DSMARK) 00016 * @{ 00017 */ 00018 00019 #include <netlink-local.h> 00020 #include <netlink-tc.h> 00021 #include <netlink/netlink.h> 00022 #include <netlink/utils.h> 00023 #include <netlink/route/qdisc.h> 00024 #include <netlink/route/tc-api.h> 00025 #include <netlink/route/class.h> 00026 #include <netlink/route/qdisc/dsmark.h> 00027 00028 /** @cond SKIP */ 00029 #define SCH_DSMARK_ATTR_INDICES 0x1 00030 #define SCH_DSMARK_ATTR_DEFAULT_INDEX 0x2 00031 #define SCH_DSMARK_ATTR_SET_TC_INDEX 0x4 00032 00033 #define SCH_DSMARK_ATTR_MASK 0x1 00034 #define SCH_DSMARK_ATTR_VALUE 0x2 00035 /** @endcond */ 00036 00037 static struct nla_policy dsmark_policy[TCA_DSMARK_MAX+1] = { 00038 [TCA_DSMARK_INDICES] = { .type = NLA_U16 }, 00039 [TCA_DSMARK_DEFAULT_INDEX] = { .type = NLA_U16 }, 00040 [TCA_DSMARK_SET_TC_INDEX] = { .type = NLA_FLAG }, 00041 [TCA_DSMARK_VALUE] = { .type = NLA_U8 }, 00042 [TCA_DSMARK_MASK] = { .type = NLA_U8 }, 00043 }; 00044 00045 static int dsmark_qdisc_msg_parser(struct rtnl_tc *tc, void *data) 00046 { 00047 struct rtnl_dsmark_qdisc *dsmark = data; 00048 struct nlattr *tb[TCA_DSMARK_MAX + 1]; 00049 int err; 00050 00051 err = tca_parse(tb, TCA_DSMARK_MAX, tc, dsmark_policy); 00052 if (err < 0) 00053 return err; 00054 00055 if (tb[TCA_DSMARK_INDICES]) { 00056 dsmark->qdm_indices = nla_get_u16(tb[TCA_DSMARK_INDICES]); 00057 dsmark->qdm_mask |= SCH_DSMARK_ATTR_INDICES; 00058 } 00059 00060 if (tb[TCA_DSMARK_DEFAULT_INDEX]) { 00061 dsmark->qdm_default_index = 00062 nla_get_u16(tb[TCA_DSMARK_DEFAULT_INDEX]); 00063 dsmark->qdm_mask |= SCH_DSMARK_ATTR_DEFAULT_INDEX; 00064 } 00065 00066 if (tb[TCA_DSMARK_SET_TC_INDEX]) { 00067 dsmark->qdm_set_tc_index = 1; 00068 dsmark->qdm_mask |= SCH_DSMARK_ATTR_SET_TC_INDEX; 00069 } 00070 00071 return 0; 00072 } 00073 00074 static int dsmark_class_msg_parser(struct rtnl_tc *tc, void *data) 00075 { 00076 struct rtnl_dsmark_class *dsmark = data; 00077 struct nlattr *tb[TCA_DSMARK_MAX + 1]; 00078 int err; 00079 00080 err = tca_parse(tb, TCA_DSMARK_MAX, tc, dsmark_policy); 00081 if (err < 0) 00082 return err; 00083 00084 if (tb[TCA_DSMARK_MASK]) { 00085 dsmark->cdm_bmask = nla_get_u8(tb[TCA_DSMARK_MASK]); 00086 dsmark->cdm_mask |= SCH_DSMARK_ATTR_MASK; 00087 } 00088 00089 if (tb[TCA_DSMARK_VALUE]) { 00090 dsmark->cdm_value = nla_get_u8(tb[TCA_DSMARK_VALUE]); 00091 dsmark->cdm_mask |= SCH_DSMARK_ATTR_VALUE; 00092 } 00093 00094 return 0; 00095 } 00096 00097 static void dsmark_qdisc_dump_line(struct rtnl_tc *tc, void *data, 00098 struct nl_dump_params *p) 00099 { 00100 struct rtnl_dsmark_qdisc *dsmark = data; 00101 00102 if (dsmark && (dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES)) 00103 nl_dump(p, " indices 0x%04x", dsmark->qdm_indices); 00104 } 00105 00106 static void dsmark_qdisc_dump_details(struct rtnl_tc *tc, void *data, 00107 struct nl_dump_params *p) 00108 { 00109 struct rtnl_dsmark_qdisc *dsmark = data; 00110 00111 if (!dsmark) 00112 return; 00113 00114 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX) 00115 nl_dump(p, " default index 0x%04x", dsmark->qdm_default_index); 00116 00117 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX) 00118 nl_dump(p, " set-tc-index"); 00119 } 00120 00121 static void dsmark_class_dump_line(struct rtnl_tc *tc, void *data, 00122 struct nl_dump_params *p) 00123 { 00124 struct rtnl_dsmark_class *dsmark = data; 00125 00126 if (!dsmark) 00127 return; 00128 00129 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE) 00130 nl_dump(p, " value 0x%02x", dsmark->cdm_value); 00131 00132 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK) 00133 nl_dump(p, " mask 0x%02x", dsmark->cdm_bmask); 00134 } 00135 00136 static int dsmark_qdisc_msg_fill(struct rtnl_tc *tc, void *data, 00137 struct nl_msg *msg) 00138 { 00139 struct rtnl_dsmark_qdisc *dsmark = data; 00140 00141 if (!dsmark) 00142 return 0; 00143 00144 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES) 00145 NLA_PUT_U16(msg, TCA_DSMARK_INDICES, dsmark->qdm_indices); 00146 00147 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX) 00148 NLA_PUT_U16(msg, TCA_DSMARK_DEFAULT_INDEX, 00149 dsmark->qdm_default_index); 00150 00151 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX) 00152 NLA_PUT_FLAG(msg, TCA_DSMARK_SET_TC_INDEX); 00153 00154 return 0; 00155 00156 nla_put_failure: 00157 return -NLE_MSGSIZE; 00158 } 00159 00160 static int dsmark_class_msg_fill(struct rtnl_tc *tc, void *data, 00161 struct nl_msg *msg) 00162 { 00163 struct rtnl_dsmark_class *dsmark = data; 00164 00165 if (!dsmark) 00166 return 0; 00167 00168 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK) 00169 NLA_PUT_U8(msg, TCA_DSMARK_MASK, dsmark->cdm_bmask); 00170 00171 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE) 00172 NLA_PUT_U8(msg, TCA_DSMARK_VALUE, dsmark->cdm_value); 00173 00174 return 0; 00175 00176 nla_put_failure: 00177 return -NLE_MSGSIZE; 00178 } 00179 00180 /** 00181 * @name Class Attribute Access 00182 * @{ 00183 */ 00184 00185 /** 00186 * Set bitmask of DSMARK class. 00187 * @arg class DSMARK class to be modified. 00188 * @arg mask New bitmask. 00189 * @return 0 on success or a negative error code. 00190 */ 00191 int rtnl_class_dsmark_set_bitmask(struct rtnl_class *class, uint8_t mask) 00192 { 00193 struct rtnl_dsmark_class *dsmark; 00194 00195 if (!(dsmark = rtnl_tc_data(TC_CAST(class)))) 00196 return -NLE_NOMEM; 00197 00198 dsmark->cdm_bmask = mask; 00199 dsmark->cdm_mask |= SCH_DSMARK_ATTR_MASK; 00200 00201 return 0; 00202 } 00203 00204 /** 00205 * Get bitmask of DSMARK class. 00206 * @arg class DSMARK class. 00207 * @return Bitmask or a negative error code. 00208 */ 00209 int rtnl_class_dsmark_get_bitmask(struct rtnl_class *class) 00210 { 00211 struct rtnl_dsmark_class *dsmark; 00212 00213 if (!(dsmark = rtnl_tc_data(TC_CAST(class)))) 00214 return -NLE_NOMEM; 00215 00216 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_MASK) 00217 return dsmark->cdm_bmask; 00218 else 00219 return -NLE_NOATTR; 00220 } 00221 00222 /** 00223 * Set value of DSMARK class. 00224 * @arg class DSMARK class to be modified. 00225 * @arg value New value. 00226 * @return 0 on success or a negative errror code. 00227 */ 00228 int rtnl_class_dsmark_set_value(struct rtnl_class *class, uint8_t value) 00229 { 00230 struct rtnl_dsmark_class *dsmark; 00231 00232 if (!(dsmark = rtnl_tc_data(TC_CAST(class)))) 00233 return -NLE_NOMEM; 00234 00235 dsmark->cdm_value = value; 00236 dsmark->cdm_mask |= SCH_DSMARK_ATTR_VALUE; 00237 00238 return 0; 00239 } 00240 00241 /** 00242 * Get value of DSMARK class. 00243 * @arg class DSMARK class. 00244 * @return Value or a negative error code. 00245 */ 00246 int rtnl_class_dsmark_get_value(struct rtnl_class *class) 00247 { 00248 struct rtnl_dsmark_class *dsmark; 00249 00250 if (!(dsmark = rtnl_tc_data(TC_CAST(class)))) 00251 return -NLE_NOMEM; 00252 00253 if (dsmark->cdm_mask & SCH_DSMARK_ATTR_VALUE) 00254 return dsmark->cdm_value; 00255 else 00256 return -NLE_NOATTR; 00257 } 00258 00259 /** @} */ 00260 00261 /** 00262 * @name Qdisc Attribute Access 00263 * @{ 00264 */ 00265 00266 /** 00267 * Set indices of DSMARK qdisc. 00268 * @arg qdisc DSMARK qdisc to be modified. 00269 * @arg indices New indices. 00270 */ 00271 int rtnl_qdisc_dsmark_set_indices(struct rtnl_qdisc *qdisc, uint16_t indices) 00272 { 00273 struct rtnl_dsmark_qdisc *dsmark; 00274 00275 if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) 00276 return -NLE_NOMEM; 00277 00278 dsmark->qdm_indices = indices; 00279 dsmark->qdm_mask |= SCH_DSMARK_ATTR_INDICES; 00280 00281 return 0; 00282 } 00283 00284 /** 00285 * Get indices of DSMARK qdisc. 00286 * @arg qdisc DSMARK qdisc. 00287 * @return Indices or a negative error code. 00288 */ 00289 int rtnl_qdisc_dsmark_get_indices(struct rtnl_qdisc *qdisc) 00290 { 00291 struct rtnl_dsmark_qdisc *dsmark; 00292 00293 if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) 00294 return -NLE_NOMEM; 00295 00296 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_INDICES) 00297 return dsmark->qdm_indices; 00298 else 00299 return -NLE_NOATTR; 00300 } 00301 00302 /** 00303 * Set default index of DSMARK qdisc. 00304 * @arg qdisc DSMARK qdisc to be modified. 00305 * @arg default_index New default index. 00306 * @return 0 on success or a negative error code. 00307 */ 00308 int rtnl_qdisc_dsmark_set_default_index(struct rtnl_qdisc *qdisc, 00309 uint16_t default_index) 00310 { 00311 struct rtnl_dsmark_qdisc *dsmark; 00312 00313 if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) 00314 return -NLE_NOMEM; 00315 00316 dsmark->qdm_default_index = default_index; 00317 dsmark->qdm_mask |= SCH_DSMARK_ATTR_DEFAULT_INDEX; 00318 00319 return 0; 00320 } 00321 00322 /** 00323 * Get default index of DSMARK qdisc. 00324 * @arg qdisc DSMARK qdisc. 00325 * @return Default index or a negative error code. 00326 */ 00327 int rtnl_qdisc_dsmark_get_default_index(struct rtnl_qdisc *qdisc) 00328 { 00329 struct rtnl_dsmark_qdisc *dsmark; 00330 00331 if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) 00332 return -NLE_NOMEM; 00333 00334 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_DEFAULT_INDEX) 00335 return dsmark->qdm_default_index; 00336 else 00337 return -NLE_NOATTR; 00338 } 00339 00340 /** 00341 * Set set-tc-index flag of DSMARK qdisc. 00342 * @arg qdisc DSMARK qdisc to be modified. 00343 * @arg flag Flag indicating whether to enable or disable. 00344 * @return 0 on success or a negative error code. 00345 */ 00346 int rtnl_qdisc_dsmark_set_set_tc_index(struct rtnl_qdisc *qdisc, int flag) 00347 { 00348 struct rtnl_dsmark_qdisc *dsmark; 00349 00350 if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) 00351 return -NLE_NOMEM; 00352 00353 dsmark->qdm_set_tc_index = !!flag; 00354 dsmark->qdm_mask |= SCH_DSMARK_ATTR_SET_TC_INDEX; 00355 00356 return 0; 00357 } 00358 00359 /** 00360 * Get set-tc-index flag of DSMARK qdisc. 00361 * @arg qdisc DSMARK qdisc to be modified. 00362 * @return 1 or 0 to indicate wehther the flag is enabled or a negative 00363 * error code. 00364 */ 00365 int rtnl_qdisc_dsmark_get_set_tc_index(struct rtnl_qdisc *qdisc) 00366 { 00367 struct rtnl_dsmark_qdisc *dsmark; 00368 00369 if (!(dsmark = rtnl_tc_data(TC_CAST(qdisc)))) 00370 return -NLE_NOMEM; 00371 00372 if (dsmark->qdm_mask & SCH_DSMARK_ATTR_SET_TC_INDEX) 00373 return dsmark->qdm_set_tc_index; 00374 else 00375 return -NLE_NOATTR; 00376 } 00377 00378 /** @} */ 00379 00380 static struct rtnl_tc_ops dsmark_qdisc_ops = { 00381 .to_kind = "dsmark", 00382 .to_type = RTNL_TC_TYPE_QDISC, 00383 .to_size = sizeof(struct rtnl_dsmark_qdisc), 00384 .to_msg_parser = dsmark_qdisc_msg_parser, 00385 .to_dump = { 00386 [NL_DUMP_LINE] = dsmark_qdisc_dump_line, 00387 [NL_DUMP_DETAILS] = dsmark_qdisc_dump_details, 00388 }, 00389 .to_msg_fill = dsmark_qdisc_msg_fill, 00390 }; 00391 00392 static struct rtnl_tc_ops dsmark_class_ops = { 00393 .to_kind = "dsmark", 00394 .to_type = RTNL_TC_TYPE_CLASS, 00395 .to_size = sizeof(struct rtnl_dsmark_class), 00396 .to_msg_parser = dsmark_class_msg_parser, 00397 .to_dump[NL_DUMP_LINE] = dsmark_class_dump_line, 00398 .to_msg_fill = dsmark_class_msg_fill, 00399 }; 00400 00401 static void __init dsmark_init(void) 00402 { 00403 rtnl_tc_register(&dsmark_qdisc_ops); 00404 rtnl_tc_register(&dsmark_class_ops); 00405 } 00406 00407 static void __exit dsmark_exit(void) 00408 { 00409 rtnl_tc_unregister(&dsmark_qdisc_ops); 00410 rtnl_tc_unregister(&dsmark_class_ops); 00411 } 00412 00413 /** @} */