genl_family.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * lib/genl/family.c Generic Netlink Family
  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. * @ingroup genl
  13. * @defgroup genl_family Generic Netlink Family
  14. * @brief
  15. *
  16. * @{
  17. */
  18. #include <netlink-generic.h>
  19. #include <netlink/netlink.h>
  20. #include <netlink/genl/genl.h>
  21. #include <netlink/genl/family.h>
  22. #include <netlink/utils.h>
  23. struct nl_object_ops genl_family_ops;
  24. /** @endcond */
  25. static void family_constructor(struct nl_object *c)
  26. {
  27. struct genl_family *family = (struct genl_family *) c;
  28. nl_init_list_head(&family->gf_ops);
  29. nl_init_list_head(&family->gf_mc_grps);
  30. }
  31. static void family_free_data(struct nl_object *c)
  32. {
  33. struct genl_family *family = (struct genl_family *) c;
  34. struct genl_family_op *ops, *tmp;
  35. struct genl_family_grp *grp, *t_grp;
  36. if (family == NULL)
  37. return;
  38. nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) {
  39. nl_list_del(&ops->o_list);
  40. free(ops);
  41. }
  42. nl_list_for_each_entry_safe(grp, t_grp, &family->gf_mc_grps, list) {
  43. nl_list_del(&grp->list);
  44. free(grp);
  45. }
  46. }
  47. static int family_clone(struct nl_object *_dst, struct nl_object *_src)
  48. {
  49. struct genl_family *dst = nl_object_priv(_dst);
  50. struct genl_family *src = nl_object_priv(_src);
  51. struct genl_family_op *ops;
  52. struct genl_family_grp *grp;
  53. int err;
  54. nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
  55. err = genl_family_add_op(dst, ops->o_id, ops->o_flags);
  56. if (err < 0)
  57. return err;
  58. }
  59. nl_list_for_each_entry(grp, &src->gf_mc_grps, list) {
  60. err = genl_family_add_grp(dst, grp->id, grp->name);
  61. if (err < 0)
  62. return err;
  63. }
  64. return 0;
  65. }
  66. static int family_compare(struct nl_object *_a, struct nl_object *_b,
  67. uint32_t attrs, int flags)
  68. {
  69. struct genl_family *a = (struct genl_family *) _a;
  70. struct genl_family *b = (struct genl_family *) _b;
  71. int diff = 0;
  72. #define FAM_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, FAMILY_ATTR_##ATTR, a, b, EXPR)
  73. diff |= FAM_DIFF(ID, a->gf_id != b->gf_id);
  74. diff |= FAM_DIFF(VERSION, a->gf_version != b->gf_version);
  75. diff |= FAM_DIFF(HDRSIZE, a->gf_hdrsize != b->gf_hdrsize);
  76. diff |= FAM_DIFF(MAXATTR, a->gf_maxattr != b->gf_maxattr);
  77. diff |= FAM_DIFF(NAME, strcmp(a->gf_name, b->gf_name));
  78. #undef FAM_DIFF
  79. return diff;
  80. }
  81. /**
  82. * @name Family Object
  83. * @{
  84. */
  85. struct genl_family *genl_family_alloc(void)
  86. {
  87. return (struct genl_family *) nl_object_alloc(&genl_family_ops);
  88. }
  89. void genl_family_put(struct genl_family *family)
  90. {
  91. nl_object_put((struct nl_object *) family);
  92. }
  93. /** @} */
  94. int genl_family_add_op(struct genl_family *family, int id, int flags)
  95. {
  96. struct genl_family_op *op;
  97. op = calloc(1, sizeof(*op));
  98. if (op == NULL)
  99. return -NLE_NOMEM;
  100. op->o_id = id;
  101. op->o_flags = flags;
  102. nl_list_add_tail(&op->o_list, &family->gf_ops);
  103. family->ce_mask |= FAMILY_ATTR_OPS;
  104. return 0;
  105. }
  106. int genl_family_add_grp(struct genl_family *family, uint32_t id,
  107. const char *name)
  108. {
  109. struct genl_family_grp *grp;
  110. grp = calloc(1, sizeof(*grp));
  111. if (grp == NULL)
  112. return -NLE_NOMEM;
  113. grp->id = id;
  114. strncpy(grp->name, name, GENL_NAMSIZ - 1);
  115. grp->name[GENL_NAMSIZ - 1] = '\0';
  116. nl_list_add_tail(&grp->list, &family->gf_mc_grps);
  117. return 0;
  118. }
  119. /** @} */
  120. /** @cond SKIP */
  121. struct nl_object_ops genl_family_ops = {
  122. .oo_name = "genl/family",
  123. .oo_size = sizeof(struct genl_family),
  124. .oo_constructor = family_constructor,
  125. .oo_free_data = family_free_data,
  126. .oo_clone = family_clone,
  127. .oo_compare = family_compare,
  128. .oo_id_attrs = FAMILY_ATTR_ID,
  129. };
  130. /** @endcond */
  131. /** @} */