cls_obj.c revision 5d92f9c03d85cefee5afe7f40d7ea69dfde4cf77
1/* 2 * lib/route/cls_api.c Classifier Object 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation version 2.1 7 * of the License. 8 * 9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 10 */ 11 12/** 13 * @ingroup cls 14 * @defgroup cls_obj Classifier Object 15 * @{ 16 */ 17 18#include <netlink-local.h> 19#include <netlink-tc.h> 20#include <netlink/netlink.h> 21#include <netlink/utils.h> 22#include <netlink/route/tc.h> 23#include <netlink/route/classifier.h> 24#include <netlink/route/classifier-modules.h> 25#include <netlink/route/link.h> 26 27/** @cond SKIP */ 28#define CLS_ATTR_PRIO (TCA_ATTR_MAX << 1) 29#define CLS_ATTR_PROTOCOL (TCA_ATTR_MAX << 2) 30/** @endcond */ 31 32static void cls_free_data(struct nl_object *obj) 33{ 34 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 35 struct rtnl_cls_ops *cops; 36 37 tca_free_data((struct rtnl_tca *) cls); 38 39 cops = rtnl_cls_lookup_ops(cls); 40 if (cops && cops->co_free_data) 41 cops->co_free_data(cls); 42} 43 44static int cls_clone(struct nl_object *_dst, struct nl_object *_src) 45{ 46 struct rtnl_cls *dst = nl_object_priv(_dst); 47 struct rtnl_cls *src = nl_object_priv(_src); 48 struct rtnl_cls_ops *cops; 49 int err; 50 51 err = tca_clone((struct rtnl_tca *) dst, (struct rtnl_tca *) src); 52 if (err < 0) 53 goto errout; 54 55 cops = rtnl_cls_lookup_ops(src); 56 if (cops && cops->co_clone) 57 err = cops->co_clone(dst, src); 58errout: 59 return err; 60} 61 62static void cls_dump_line(struct nl_object *obj, struct nl_dump_params *p) 63{ 64 char buf[32]; 65 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 66 struct rtnl_cls_ops *cops; 67 68 tca_dump_line((struct rtnl_tca *) cls, "cls", p); 69 70 nl_dump(p, " prio %u protocol %s", cls->c_prio, 71 nl_ether_proto2str(cls->c_protocol, buf, sizeof(buf))); 72 73 cops = rtnl_cls_lookup_ops(cls); 74 if (cops && cops->co_dump[NL_DUMP_LINE]) 75 cops->co_dump[NL_DUMP_LINE](cls, p); 76 nl_dump(p, "\n"); 77} 78 79static void cls_dump_details(struct nl_object *obj, struct nl_dump_params *p) 80{ 81 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 82 struct rtnl_cls_ops *cops; 83 84 cls_dump_line(obj, p); 85 tca_dump_details((struct rtnl_tca *) cls, p); 86 87 cops = rtnl_cls_lookup_ops(cls); 88 if (cops && cops->co_dump[NL_DUMP_DETAILS]) 89 cops->co_dump[NL_DUMP_DETAILS](cls, p); 90 else 91 nl_dump(p, "no options\n"); 92} 93 94static void cls_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 95{ 96 struct rtnl_cls *cls = (struct rtnl_cls *) obj; 97 struct rtnl_cls_ops *cops; 98 99 cls_dump_details(obj, p); 100 tca_dump_stats((struct rtnl_tca *) cls, p); 101 nl_dump(p, "\n"); 102 103 cops = rtnl_cls_lookup_ops(cls); 104 if (cops && cops->co_dump[NL_DUMP_STATS]) 105 cops->co_dump[NL_DUMP_STATS](cls, p); 106} 107 108/** 109 * @name Allocation/Freeing 110 * @{ 111 */ 112 113struct rtnl_cls *rtnl_cls_alloc(void) 114{ 115 return (struct rtnl_cls *) nl_object_alloc(&cls_obj_ops); 116} 117 118void rtnl_cls_put(struct rtnl_cls *cls) 119{ 120 nl_object_put((struct nl_object *) cls); 121} 122 123/** @} */ 124 125 126/** 127 * @name Attributes 128 * @{ 129 */ 130 131void rtnl_cls_set_ifindex(struct rtnl_cls *f, int ifindex) 132{ 133 tca_set_ifindex((struct rtnl_tca *) f, ifindex); 134} 135 136void rtnl_cls_set_handle(struct rtnl_cls *f, uint32_t handle) 137{ 138 tca_set_handle((struct rtnl_tca *) f, handle); 139} 140 141void rtnl_cls_set_parent(struct rtnl_cls *f, uint32_t parent) 142{ 143 tca_set_parent((struct rtnl_tca *) f, parent); 144} 145 146void rtnl_cls_set_kind(struct rtnl_cls *f, const char *kind) 147{ 148 tca_set_kind((struct rtnl_tca *) f, kind); 149 f->c_ops = __rtnl_cls_lookup_ops(kind); 150} 151 152void rtnl_cls_set_prio(struct rtnl_cls *cls, uint16_t prio) 153{ 154 cls->c_prio = prio; 155 cls->ce_mask |= CLS_ATTR_PRIO; 156} 157 158uint16_t rtnl_cls_get_prio(struct rtnl_cls *cls) 159{ 160 if (cls->ce_mask & CLS_ATTR_PRIO) 161 return cls->c_prio; 162 else 163 return 0; 164} 165 166void rtnl_cls_set_protocol(struct rtnl_cls *cls, uint16_t protocol) 167{ 168 cls->c_protocol = protocol; 169 cls->ce_mask |= CLS_ATTR_PROTOCOL; 170} 171 172uint16_t rtnl_cls_get_protocol(struct rtnl_cls *cls) 173{ 174 if (cls->ce_mask & CLS_ATTR_PROTOCOL) 175 return cls->c_protocol; 176 else 177 return ETH_P_ALL; 178} 179 180/** @} */ 181 182struct nl_object_ops cls_obj_ops = { 183 .oo_name = "route/cls", 184 .oo_size = sizeof(struct rtnl_cls), 185 .oo_free_data = cls_free_data, 186 .oo_clone = cls_clone, 187 .oo_dump = { 188 [NL_DUMP_LINE] = cls_dump_line, 189 [NL_DUMP_DETAILS] = cls_dump_details, 190 [NL_DUMP_STATS] = cls_dump_stats, 191 }, 192 .oo_compare = tca_compare, 193 .oo_id_attrs = (TCA_ATTR_IFINDEX | TCA_ATTR_HANDLE), 194}; 195 196/** @} */ 197