libnl 1.1
|
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 00044 static int cls_clone(struct nl_object *_dst, struct nl_object *_src) 00045 { 00046 struct rtnl_cls *dst = nl_object_priv(_dst); 00047 struct rtnl_cls *src = nl_object_priv(_src); 00048 struct rtnl_cls_ops *cops; 00049 int err; 00050 00051 err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src); 00052 if (err < 0) 00053 goto errout; 00054 00055 cops = rtnl_cls_lookup_ops(src); 00056 if (cops && cops->co_clone) 00057 err = cops->co_clone(dst, src); 00058 errout: 00059 return err; 00060 } 00061 00062 static int cls_dump_brief(struct nl_object *obj, struct nl_dump_params *p) 00063 { 00064 char buf[32]; 00065 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 00066 struct rtnl_cls_ops *cops; 00067 int line; 00068 00069 line = tca_dump_brief((struct rtnl_tca *) cls, "cls", p, 0); 00070 00071 dp_dump(p, " prio %u protocol %s", cls->c_prio, 00072 nl_ether_proto2str(cls->c_protocol, buf, sizeof(buf))); 00073 00074 cops = rtnl_cls_lookup_ops(cls); 00075 if (cops && cops->co_dump[NL_DUMP_BRIEF]) 00076 line = cops->co_dump[NL_DUMP_BRIEF](cls, p, line); 00077 dp_dump(p, "\n"); 00078 00079 return line; 00080 } 00081 00082 static int cls_dump_full(struct nl_object *obj, struct nl_dump_params *p) 00083 { 00084 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 00085 struct rtnl_cls_ops *cops; 00086 int line; 00087 00088 line = cls_dump_brief(obj, p); 00089 line = tca_dump_full((struct rtnl_tca *) cls, p, line); 00090 00091 cops = rtnl_cls_lookup_ops(cls); 00092 if (cops && cops->co_dump[NL_DUMP_FULL]) 00093 line = cops->co_dump[NL_DUMP_FULL](cls, p, line); 00094 else 00095 dp_dump(p, "no options\n"); 00096 00097 return line; 00098 } 00099 00100 static int cls_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 00101 { 00102 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 00103 struct rtnl_cls_ops *cops; 00104 int line; 00105 00106 line = cls_dump_full(obj, p); 00107 line = tca_dump_stats((struct rtnl_tca *) cls, p, line); 00108 dp_dump(p, "\n"); 00109 00110 cops = rtnl_cls_lookup_ops(cls); 00111 if (cops && cops->co_dump[NL_DUMP_STATS]) 00112 line = cops->co_dump[NL_DUMP_STATS](cls, p, line); 00113 00114 return line; 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 void rtnl_cls_set_handle(struct rtnl_cls *f, uint32_t handle) 00146 { 00147 tca_set_handle((struct rtnl_tca *) f, handle); 00148 } 00149 00150 void rtnl_cls_set_parent(struct rtnl_cls *f, uint32_t parent) 00151 { 00152 tca_set_parent((struct rtnl_tca *) f, parent); 00153 } 00154 00155 void rtnl_cls_set_kind(struct rtnl_cls *f, const char *kind) 00156 { 00157 tca_set_kind((struct rtnl_tca *) f, kind); 00158 f->c_ops = __rtnl_cls_lookup_ops(kind); 00159 } 00160 00161 void rtnl_cls_set_prio(struct rtnl_cls *cls, int prio) 00162 { 00163 cls->c_prio = prio; 00164 cls->ce_mask |= CLS_ATTR_PRIO; 00165 } 00166 00167 int rtnl_cls_get_prio(struct rtnl_cls *cls) 00168 { 00169 if (cls->ce_mask & CLS_ATTR_PRIO) 00170 return cls->c_prio; 00171 else 00172 return 0; 00173 } 00174 00175 void rtnl_cls_set_protocol(struct rtnl_cls *cls, int protocol) 00176 { 00177 cls->c_protocol = protocol; 00178 cls->ce_mask |= CLS_ATTR_PROTOCOL; 00179 } 00180 00181 int rtnl_cls_get_protocol(struct rtnl_cls *cls) 00182 { 00183 if (cls->ce_mask & CLS_ATTR_PROTOCOL) 00184 return cls->c_protocol; 00185 else 00186 return ETH_P_ALL; 00187 } 00188 00189 /** @} */ 00190 00191 struct nl_object_ops cls_obj_ops = { 00192 .oo_name = "route/cls", 00193 .oo_size = sizeof(struct rtnl_cls), 00194 .oo_free_data = cls_free_data, 00195 .oo_clone = cls_clone, 00196 .oo_dump[NL_DUMP_BRIEF] = cls_dump_brief, 00197 .oo_dump[NL_DUMP_FULL] = cls_dump_full, 00198 .oo_dump[NL_DUMP_STATS] = cls_dump_stats, 00199 .oo_compare = tca_compare, 00200 .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE), 00201 }; 00202 00203 /** @} */