00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <netlink-local.h>
00019 #include <netlink/netlink.h>
00020 #include <netlink/cache.h>
00021 #include <netlink/object.h>
00022 #include <netlink/utils.h>
00023
00024 static inline struct nl_cache_ops *obj_ops(struct nl_object *obj)
00025 {
00026 if (!obj->ce_ops)
00027 BUG();
00028
00029 return obj->ce_ops;
00030 }
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 struct nl_object *nl_object_alloc(size_t size)
00043 {
00044 struct nl_object *new;
00045
00046 if (size < sizeof(*new))
00047 BUG();
00048
00049 new = calloc(1, size);
00050 if (!new) {
00051 nl_errno(ENOMEM);
00052 return NULL;
00053 }
00054
00055 new->ce_refcnt = 1;
00056 nl_init_list_head(&new->ce_list);
00057
00058 return new;
00059 }
00060
00061
00062
00063
00064
00065
00066 struct nl_object *nl_object_alloc_from_ops(struct nl_cache_ops *ops)
00067 {
00068 struct nl_object *new;
00069
00070 new = nl_object_alloc(ops->co_size);
00071 if (new) {
00072 new->ce_ops = ops;
00073 if (ops->co_constructor)
00074 ops->co_constructor(new);
00075 }
00076
00077 return new;
00078 }
00079
00080
00081
00082
00083
00084
00085 struct nl_object *nl_object_alloc_name(const char *kind)
00086 {
00087 struct nl_cache_ops *ops;
00088
00089 ops = nl_cache_mngt_lookup(kind);
00090 if (!ops) {
00091 nl_error(ENOENT, "Unable to lookup cache kind \"%s\"", kind);
00092 return NULL;
00093 }
00094
00095 return nl_object_alloc_from_ops(ops);
00096 }
00097
00098 struct nl_derived_object {
00099 NLHDR_COMMON
00100 char data;
00101 };
00102
00103
00104
00105
00106
00107
00108 struct nl_object *nl_object_clone(struct nl_object *obj)
00109 {
00110 struct nl_object *new;
00111 struct nl_cache_ops *ops = obj_ops(obj);
00112 int doff = offsetof(struct nl_derived_object, data);
00113 int size;
00114
00115 new = nl_object_alloc(ops->co_size);
00116 if (!new)
00117 return NULL;
00118
00119 size = ops->co_size - doff;
00120 if (size < 0)
00121 BUG();
00122
00123 new->ce_cache = obj->ce_cache;
00124 new->ce_ops = obj->ce_ops;
00125 new->ce_msgtype = obj->ce_msgtype;
00126 if (ops->co_free_data) {
00127 new->ce_dataref = obj;
00128 nl_object_get(obj);
00129 }
00130
00131 if (size)
00132 memcpy((void *)new + doff, (void *)obj + doff, size);
00133
00134 return new;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 void nl_object_free(struct nl_object *obj)
00144 {
00145 struct nl_cache_ops *ops = obj_ops(obj);
00146
00147 if (obj->ce_refcnt > 0)
00148 NL_DBG(1, "Warning: Freeing object in used...\n");
00149
00150 if (obj->ce_dataref)
00151 nl_object_put(obj->ce_dataref);
00152 else if (ops->co_free_data)
00153 ops->co_free_data(obj);
00154
00155 free(obj);
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 void nl_object_get(struct nl_object *obj)
00170 {
00171 obj->ce_refcnt++;
00172 }
00173
00174
00175
00176
00177
00178 void nl_object_put(struct nl_object *obj)
00179 {
00180 if (!obj)
00181 return;
00182
00183 obj->ce_refcnt--;
00184
00185 if (obj->ce_refcnt < 0)
00186 BUG();
00187
00188 if (obj->ce_refcnt <= 0)
00189 nl_object_free(obj);
00190 }
00191
00192
00193
00194
00195
00196
00197 int nl_object_shared(struct nl_object *obj)
00198 {
00199 return obj->ce_refcnt > 1;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 void nl_object_dump(struct nl_object *obj, struct nl_dump_params *params)
00215 {
00216 dump_from_ops(obj, params);
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 int nl_object_match(struct nl_object *obj, struct nl_object *filter)
00229 {
00230 struct nl_cache_ops *ops = obj->ce_ops;
00231
00232 if (ops == filter->ce_ops &&
00233 ops->co_filter && !ops->co_filter(obj, filter))
00234 return 1;
00235 else
00236 return 0;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 int nl_object_get_refcnt(struct nl_object *obj)
00251 {
00252 return obj->ce_refcnt;
00253 }
00254
00255
00256
00257
00258
00259 struct nl_cache_ops *nl_object_get_ops(struct nl_object *obj)
00260 {
00261 return obj->ce_ops;
00262 }
00263
00264
00265
00266
00267
00268
00269 struct nl_cache *nl_object_get_cache(struct nl_object *obj)
00270 {
00271 return obj->ce_cache;
00272 }
00273
00274
00275
00276
00277
00278 inline void *nl_object_priv(struct nl_object *obj)
00279 {
00280 return obj;
00281 }
00282
00283
00284
00285