aboutsummaryrefslogtreecommitdiffstats
path: root/package/libnl-tiny/src/genl_family.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/libnl-tiny/src/genl_family.c')
-rw-r--r--package/libnl-tiny/src/genl_family.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/package/libnl-tiny/src/genl_family.c b/package/libnl-tiny/src/genl_family.c
new file mode 100644
index 0000000000..88aaad9b77
--- /dev/null
+++ b/package/libnl-tiny/src/genl_family.c
@@ -0,0 +1,136 @@
+/*
+ * lib/genl/family.c Generic Netlink Family
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
+ */
+
+/**
+ * @ingroup genl
+ * @defgroup genl_family Generic Netlink Family
+ * @brief
+ *
+ * @{
+ */
+
+#include <netlink-generic.h>
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/utils.h>
+
+struct nl_object_ops genl_family_ops;
+/** @endcond */
+
+static void family_constructor(struct nl_object *c)
+{
+ struct genl_family *family = (struct genl_family *) c;
+
+ nl_init_list_head(&family->gf_ops);
+}
+
+static void family_free_data(struct nl_object *c)
+{
+ struct genl_family *family = (struct genl_family *) c;
+ struct genl_family_op *ops, *tmp;
+
+ if (family == NULL)
+ return;
+
+ nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) {
+ nl_list_del(&ops->o_list);
+ free(ops);
+ }
+}
+
+static int family_clone(struct nl_object *_dst, struct nl_object *_src)
+{
+ struct genl_family *dst = nl_object_priv(_dst);
+ struct genl_family *src = nl_object_priv(_src);
+ struct genl_family_op *ops;
+ int err;
+
+ nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
+ err = genl_family_add_op(dst, ops->o_id, ops->o_flags);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int family_compare(struct nl_object *_a, struct nl_object *_b,
+ uint32_t attrs, int flags)
+{
+ struct genl_family *a = (struct genl_family *) _a;
+ struct genl_family *b = (struct genl_family *) _b;
+ int diff = 0;
+
+#define FAM_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, FAMILY_ATTR_##ATTR, a, b, EXPR)
+
+ diff |= FAM_DIFF(ID, a->gf_id != b->gf_id);
+ diff |= FAM_DIFF(VERSION, a->gf_version != b->gf_version);
+ diff |= FAM_DIFF(HDRSIZE, a->gf_hdrsize != b->gf_hdrsize);
+ diff |= FAM_DIFF(MAXATTR, a->gf_maxattr != b->gf_maxattr);
+ diff |= FAM_DIFF(NAME, strcmp(a->gf_name, b->gf_name));
+
+#undef FAM_DIFF
+
+ return diff;
+}
+
+
+/**
+ * @name Family Object
+ * @{
+ */
+
+struct genl_family *genl_family_alloc(void)
+{
+ return (struct genl_family *) nl_object_alloc(&genl_family_ops);
+}
+
+void genl_family_put(struct genl_family *family)
+{
+ nl_object_put((struct nl_object *) family);
+}
+
+/** @} */
+
+
+int genl_family_add_op(struct genl_family *family, int id, int flags)
+{
+ struct genl_family_op *op;
+
+ op = calloc(1, sizeof(*op));
+ if (op == NULL)
+ return -NLE_NOMEM;
+
+ op->o_id = id;
+ op->o_flags = flags;
+
+ nl_list_add_tail(&op->o_list, &family->gf_ops);
+ family->ce_mask |= FAMILY_ATTR_OPS;
+
+ return 0;
+}
+
+/** @} */
+
+/** @cond SKIP */
+struct nl_object_ops genl_family_ops = {
+ .oo_name = "genl/family",
+ .oo_size = sizeof(struct genl_family),
+ .oo_constructor = family_constructor,
+ .oo_free_data = family_free_data,
+ .oo_clone = family_clone,
+ .oo_compare = family_compare,
+ .oo_id_attrs = FAMILY_ATTR_ID,
+};
+/** @endcond */
+
+/** @} */