libnl 2.0
|
00001 /* 00002 * lib/route/cls_api.c Classifier Object 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-2006 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup cls 00014 * @defgroup cls_obj Classifier Object 00015 * @{ 00016 */ 00017 00018 #include <netlink-local.h> 00019 #include <netlink-tc.h> 00020 #include <netlink/netlink.h> 00021 #include <netlink/utils.h> 00022 #include <netlink/route/tc.h> 00023 #include <netlink/route/classifier.h> 00024 #include <netlink/route/classifier-modules.h> 00025 #include <netlink/route/link.h> 00026 00027 /** @cond SKIP */ 00028 #define CLS_ATTR_PRIO (TCA_ATTR_MAX << 1) 00029 #define CLS_ATTR_PROTOCOL (TCA_ATTR_MAX << 2) 00030 /** @endcond */ 00031 00032 static void cls_free_data(struct nl_object *obj) 00033 { 00034 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 00035 struct rtnl_cls_ops *cops; 00036 00037 tca_free_data((struct rtnl_tca *) cls); 00038 00039 cops = rtnl_cls_lookup_ops(cls); 00040 if (cops && cops->co_free_data) 00041 cops->co_free_data(cls); 00042 00043 nl_data_free(cls->c_subdata); 00044 } 00045 00046 static int cls_clone(struct nl_object *_dst, struct nl_object *_src) 00047 { 00048 struct rtnl_cls *dst = nl_object_priv(_dst); 00049 struct rtnl_cls *src = nl_object_priv(_src); 00050 struct rtnl_cls_ops *cops; 00051 int err; 00052 00053 err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src); 00054 if (err < 0) 00055 goto errout; 00056 00057 if (src->c_subdata) { 00058 if (!(dst->c_subdata = nl_data_clone(src->c_subdata))) { 00059 err = -NLE_NOMEM; 00060 goto errout; 00061 } 00062 } 00063 00064 cops = rtnl_cls_lookup_ops(src); 00065 if (cops && cops->co_clone) 00066 err = cops->co_clone(dst, src); 00067 errout: 00068 return err; 00069 } 00070 00071 static void cls_dump_line(struct nl_object *obj, struct nl_dump_params *p) 00072 { 00073 char buf[32]; 00074 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 00075 struct rtnl_cls_ops *cops; 00076 00077 tca_dump_line((struct rtnl_tca *) cls, "cls", p); 00078 00079 nl_dump(p, " prio %u protocol %s", cls->c_prio, 00080 nl_ether_proto2str(cls->c_protocol, buf, sizeof(buf))); 00081 00082 cops = rtnl_cls_lookup_ops(cls); 00083 if (cops && cops->co_dump[NL_DUMP_LINE]) 00084 cops->co_dump[NL_DUMP_LINE](cls, p); 00085 nl_dump(p, "\n"); 00086 } 00087 00088 static void cls_dump_details(struct nl_object *obj, struct nl_dump_params *p) 00089 { 00090 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 00091 struct rtnl_cls_ops *cops; 00092 00093 cls_dump_line(obj, p); 00094 tca_dump_details((struct rtnl_tca *) cls, p); 00095 00096 cops = rtnl_cls_lookup_ops(cls); 00097 if (cops && cops->co_dump[NL_DUMP_DETAILS]) 00098 cops->co_dump[NL_DUMP_DETAILS](cls, p); 00099 else 00100 nl_dump(p, "no options\n"); 00101 } 00102 00103 static void cls_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 00104 { 00105 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 00106 struct rtnl_cls_ops *cops; 00107 00108 cls_dump_details(obj, p); 00109 tca_dump_stats((struct rtnl_tca *) cls, p); 00110 nl_dump(p, "\n"); 00111 00112 cops = rtnl_cls_lookup_ops(cls); 00113 if (cops && cops->co_dump[NL_DUMP_STATS]) 00114 cops->co_dump[NL_DUMP_STATS](cls, p); 00115 } 00116 00117 /** 00118 * @name Allocation/Freeing 00119 * @{ 00120 */ 00121 00122 struct rtnl_cls *rtnl_cls_alloc(void) 00123 { 00124 return (struct rtnl_cls *) nl_object_alloc(&cls_obj_ops); 00125 } 00126 00127 void rtnl_cls_put(struct rtnl_cls *cls) 00128 { 00129 nl_object_put((struct nl_object *) cls); 00130 } 00131 00132 /** @} */ 00133 00134 00135 /** 00136 * @name Attributes 00137 * @{ 00138 */ 00139 00140 void rtnl_cls_set_ifindex(struct rtnl_cls *f, int ifindex) 00141 { 00142 tca_set_ifindex((struct rtnl_tca *) f, ifindex); 00143 } 00144 00145 int rtnl_cls_get_ifindex(struct rtnl_cls *cls) 00146 { 00147 return cls->c_ifindex; 00148 } 00149 00150 void rtnl_cls_set_handle(struct rtnl_cls *f, uint32_t handle) 00151 { 00152 tca_set_handle((struct rtnl_tca *) f, handle); 00153 } 00154 00155 void rtnl_cls_set_parent(struct rtnl_cls *f, uint32_t parent) 00156 { 00157 tca_set_parent((struct rtnl_tca *) f, parent); 00158 } 00159 00160 uint32_t rtnl_cls_get_parent(struct rtnl_cls *cls) 00161 { 00162 return cls->c_parent; 00163 } 00164 00165 int rtnl_cls_set_kind(struct rtnl_cls *cls, const char *kind) 00166 { 00167 if (cls->ce_mask & TCA_ATTR_KIND) 00168 return -NLE_EXIST; 00169 00170 tca_set_kind((struct rtnl_tca *) cls, kind); 00171 00172 /* Force allocation of data */ 00173 rtnl_cls_data(cls); 00174 00175 return 0; 00176 } 00177 00178 struct rtnl_cls_ops *rtnl_cls_get_ops(struct rtnl_cls *cls) 00179 { 00180 return cls->c_ops; 00181 } 00182 00183 void rtnl_cls_set_prio(struct rtnl_cls *cls, uint16_t prio) 00184 { 00185 cls->c_prio = prio; 00186 cls->ce_mask |= CLS_ATTR_PRIO; 00187 } 00188 00189 uint16_t rtnl_cls_get_prio(struct rtnl_cls *cls) 00190 { 00191 if (cls->ce_mask & CLS_ATTR_PRIO) 00192 return cls->c_prio; 00193 else 00194 return 0; 00195 } 00196 00197 void rtnl_cls_set_protocol(struct rtnl_cls *cls, uint16_t protocol) 00198 { 00199 cls->c_protocol = protocol; 00200 cls->ce_mask |= CLS_ATTR_PROTOCOL; 00201 } 00202 00203 uint16_t rtnl_cls_get_protocol(struct rtnl_cls *cls) 00204 { 00205 if (cls->ce_mask & CLS_ATTR_PROTOCOL) 00206 return cls->c_protocol; 00207 else 00208 return ETH_P_ALL; 00209 } 00210 00211 void *rtnl_cls_data(struct rtnl_cls *cls) 00212 { 00213 if (!cls->c_subdata) { 00214 struct rtnl_cls_ops *ops = cls->c_ops; 00215 00216 if (!ops) { 00217 if (!cls->c_kind[0]) 00218 BUG(); 00219 00220 ops = __rtnl_cls_lookup_ops(cls->c_kind); 00221 if (ops == NULL) 00222 return NULL; 00223 00224 cls->c_ops = ops; 00225 } 00226 00227 if (!ops->co_size) 00228 BUG(); 00229 00230 if (!(cls->c_subdata = nl_data_alloc(NULL, ops->co_size))) 00231 return NULL; 00232 } 00233 00234 return nl_data_get(cls->c_subdata); 00235 } 00236 00237 /** @} */ 00238 00239 struct nl_object_ops cls_obj_ops = { 00240 .oo_name = "route/cls", 00241 .oo_size = sizeof(struct rtnl_cls), 00242 .oo_free_data = cls_free_data, 00243 .oo_clone = cls_clone, 00244 .oo_dump = { 00245 [NL_DUMP_LINE] = cls_dump_line, 00246 [NL_DUMP_DETAILS] = cls_dump_details, 00247 [NL_DUMP_STATS] = cls_dump_stats, 00248 }, 00249 .oo_compare = tca_compare, 00250 .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE), 00251 }; 00252 00253 /** @} */