libnl
3.2.3
|
00001 /* 00002 * lib/genl/family.c Generic Netlink Family 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 genl 00014 * @defgroup genl_family Generic Netlink Family 00015 * @brief 00016 * 00017 * @{ 00018 */ 00019 00020 #include <netlink-generic.h> 00021 #include <netlink/netlink.h> 00022 #include <netlink/genl/genl.h> 00023 #include <netlink/genl/family.h> 00024 #include <netlink/utils.h> 00025 00026 /** @cond SKIP */ 00027 #define FAMILY_ATTR_ID 0x01 00028 #define FAMILY_ATTR_NAME 0x02 00029 #define FAMILY_ATTR_VERSION 0x04 00030 #define FAMILY_ATTR_HDRSIZE 0x08 00031 #define FAMILY_ATTR_MAXATTR 0x10 00032 #define FAMILY_ATTR_OPS 0x20 00033 00034 struct nl_object_ops genl_family_ops; 00035 /** @endcond */ 00036 00037 static void family_constructor(struct nl_object *c) 00038 { 00039 struct genl_family *family = (struct genl_family *) c; 00040 00041 nl_init_list_head(&family->gf_ops); 00042 nl_init_list_head(&family->gf_mc_grps); 00043 } 00044 00045 static void family_free_data(struct nl_object *c) 00046 { 00047 struct genl_family *family = (struct genl_family *) c; 00048 struct genl_family_op *ops, *tmp; 00049 struct genl_family_grp *grp, *t_grp; 00050 00051 if (family == NULL) 00052 return; 00053 00054 nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) { 00055 nl_list_del(&ops->o_list); 00056 free(ops); 00057 } 00058 00059 nl_list_for_each_entry_safe(grp, t_grp, &family->gf_mc_grps, list) { 00060 nl_list_del(&grp->list); 00061 free(grp); 00062 } 00063 00064 } 00065 00066 static int family_clone(struct nl_object *_dst, struct nl_object *_src) 00067 { 00068 struct genl_family *dst = nl_object_priv(_dst); 00069 struct genl_family *src = nl_object_priv(_src); 00070 struct genl_family_op *ops; 00071 struct genl_family_grp *grp; 00072 int err; 00073 00074 nl_list_for_each_entry(ops, &src->gf_ops, o_list) { 00075 err = genl_family_add_op(dst, ops->o_id, ops->o_flags); 00076 if (err < 0) 00077 return err; 00078 } 00079 00080 nl_list_for_each_entry(grp, &src->gf_mc_grps, list) { 00081 err = genl_family_add_grp(dst, grp->id, grp->name); 00082 if (err < 0) 00083 return err; 00084 } 00085 00086 00087 return 0; 00088 } 00089 00090 static void family_dump_line(struct nl_object *obj, struct nl_dump_params *p) 00091 { 00092 struct genl_family *family = (struct genl_family *) obj; 00093 00094 nl_dump(p, "0x%04x %s version %u\n", 00095 family->gf_id, family->gf_name, family->gf_version); 00096 } 00097 00098 static const struct trans_tbl ops_flags[] = { 00099 __ADD(GENL_ADMIN_PERM, admin-perm) 00100 __ADD(GENL_CMD_CAP_DO, has-doit) 00101 __ADD(GENL_CMD_CAP_DUMP, has-dump) 00102 __ADD(GENL_CMD_CAP_HASPOL, has-policy) 00103 }; 00104 00105 static char *ops_flags2str(int flags, char *buf, size_t len) 00106 { 00107 return __flags2str(flags, buf, len, ops_flags, ARRAY_SIZE(ops_flags)); 00108 } 00109 00110 static void family_dump_details(struct nl_object *obj, struct nl_dump_params *p) 00111 { 00112 struct genl_family_grp *grp; 00113 struct genl_family *family = (struct genl_family *) obj; 00114 00115 family_dump_line(obj, p); 00116 nl_dump_line(p, " hdrsize %u maxattr %u\n", 00117 family->gf_hdrsize, family->gf_maxattr); 00118 00119 if (family->ce_mask & FAMILY_ATTR_OPS) { 00120 struct genl_family_op *op; 00121 char buf[64]; 00122 00123 nl_list_for_each_entry(op, &family->gf_ops, o_list) { 00124 ops_flags2str(op->o_flags, buf, sizeof(buf)); 00125 00126 genl_op2name(family->gf_id, op->o_id, buf, sizeof(buf)); 00127 00128 nl_dump_line(p, " op %s (0x%02x)", buf, op->o_id); 00129 00130 if (op->o_flags) 00131 nl_dump(p, " <%s>", 00132 ops_flags2str(op->o_flags, buf, 00133 sizeof(buf))); 00134 00135 nl_dump(p, "\n"); 00136 } 00137 } 00138 00139 nl_list_for_each_entry(grp, &family->gf_mc_grps, list) { 00140 nl_dump_line(p, " grp %s (0x%02x)\n", grp->name, grp->id); 00141 } 00142 00143 } 00144 00145 static void family_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 00146 { 00147 family_dump_details(obj, p); 00148 } 00149 00150 static int family_compare(struct nl_object *_a, struct nl_object *_b, 00151 uint32_t attrs, int flags) 00152 { 00153 struct genl_family *a = (struct genl_family *) _a; 00154 struct genl_family *b = (struct genl_family *) _b; 00155 int diff = 0; 00156 00157 #define FAM_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, FAMILY_ATTR_##ATTR, a, b, EXPR) 00158 00159 diff |= FAM_DIFF(ID, a->gf_id != b->gf_id); 00160 diff |= FAM_DIFF(VERSION, a->gf_version != b->gf_version); 00161 diff |= FAM_DIFF(HDRSIZE, a->gf_hdrsize != b->gf_hdrsize); 00162 diff |= FAM_DIFF(MAXATTR, a->gf_maxattr != b->gf_maxattr); 00163 diff |= FAM_DIFF(NAME, strcmp(a->gf_name, b->gf_name)); 00164 00165 #undef FAM_DIFF 00166 00167 return diff; 00168 } 00169 00170 00171 /** 00172 * @name Family Object 00173 * @{ 00174 */ 00175 00176 struct genl_family *genl_family_alloc(void) 00177 { 00178 return (struct genl_family *) nl_object_alloc(&genl_family_ops); 00179 } 00180 00181 void genl_family_put(struct genl_family *family) 00182 { 00183 nl_object_put((struct nl_object *) family); 00184 } 00185 00186 /** @} */ 00187 00188 /** 00189 * @name Attributes 00190 * @{ 00191 */ 00192 00193 unsigned int genl_family_get_id(struct genl_family *family) 00194 { 00195 if (family->ce_mask & FAMILY_ATTR_ID) 00196 return family->gf_id; 00197 else 00198 return GENL_ID_GENERATE; 00199 } 00200 00201 void genl_family_set_id(struct genl_family *family, unsigned int id) 00202 { 00203 family->gf_id = id; 00204 family->ce_mask |= FAMILY_ATTR_ID; 00205 } 00206 00207 char *genl_family_get_name(struct genl_family *family) 00208 { 00209 if (family->ce_mask & FAMILY_ATTR_NAME) 00210 return family->gf_name; 00211 else 00212 return NULL; 00213 } 00214 00215 void genl_family_set_name(struct genl_family *family, const char *name) 00216 { 00217 strncpy(family->gf_name, name, GENL_NAMSIZ-1); 00218 family->ce_mask |= FAMILY_ATTR_NAME; 00219 } 00220 00221 uint8_t genl_family_get_version(struct genl_family *family) 00222 { 00223 if (family->ce_mask & FAMILY_ATTR_VERSION) 00224 return family->gf_version; 00225 else 00226 return 0; 00227 } 00228 00229 void genl_family_set_version(struct genl_family *family, uint8_t version) 00230 { 00231 family->gf_version = version; 00232 family->ce_mask |= FAMILY_ATTR_VERSION; 00233 } 00234 00235 uint32_t genl_family_get_hdrsize(struct genl_family *family) 00236 { 00237 if (family->ce_mask & FAMILY_ATTR_HDRSIZE) 00238 return family->gf_hdrsize; 00239 else 00240 return 0; 00241 } 00242 00243 void genl_family_set_hdrsize(struct genl_family *family, uint32_t hdrsize) 00244 { 00245 family->gf_hdrsize = hdrsize; 00246 family->ce_mask |= FAMILY_ATTR_HDRSIZE; 00247 } 00248 00249 uint32_t genl_family_get_maxattr(struct genl_family *family) 00250 { 00251 if (family->ce_mask & FAMILY_ATTR_MAXATTR) 00252 return family->gf_maxattr; 00253 else 00254 return family->gf_maxattr; 00255 } 00256 00257 void genl_family_set_maxattr(struct genl_family *family, uint32_t maxattr) 00258 { 00259 family->gf_maxattr = maxattr; 00260 family->ce_mask |= FAMILY_ATTR_MAXATTR; 00261 } 00262 00263 int genl_family_add_op(struct genl_family *family, int id, int flags) 00264 { 00265 struct genl_family_op *op; 00266 00267 op = calloc(1, sizeof(*op)); 00268 if (op == NULL) 00269 return -NLE_NOMEM; 00270 00271 op->o_id = id; 00272 op->o_flags = flags; 00273 00274 nl_list_add_tail(&op->o_list, &family->gf_ops); 00275 family->ce_mask |= FAMILY_ATTR_OPS; 00276 00277 return 0; 00278 } 00279 00280 int genl_family_add_grp(struct genl_family *family, uint32_t id, 00281 const char *name) 00282 { 00283 struct genl_family_grp *grp; 00284 00285 grp = calloc(1, sizeof(*grp)); 00286 if (grp == NULL) 00287 return -NLE_NOMEM; 00288 00289 grp->id = id; 00290 strncpy(grp->name, name, GENL_NAMSIZ - 1); 00291 00292 nl_list_add_tail(&grp->list, &family->gf_mc_grps); 00293 00294 return 0; 00295 } 00296 00297 /** @} */ 00298 00299 /** @cond SKIP */ 00300 struct nl_object_ops genl_family_ops = { 00301 .oo_name = "genl/family", 00302 .oo_size = sizeof(struct genl_family), 00303 .oo_constructor = family_constructor, 00304 .oo_free_data = family_free_data, 00305 .oo_clone = family_clone, 00306 .oo_dump = { 00307 [NL_DUMP_LINE] = family_dump_line, 00308 [NL_DUMP_DETAILS] = family_dump_details, 00309 [NL_DUMP_STATS] = family_dump_stats, 00310 }, 00311 .oo_compare = family_compare, 00312 .oo_id_attrs = FAMILY_ATTR_ID, 00313 }; 00314 /** @endcond */ 00315 00316 /** @} */