netlink_snl_generic.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*-
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2022 Alexander V. Chernikov <melifaro@FreeBSD.org>
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. * SUCH DAMAGE.
  26. */
  27. #ifndef _NETLINK_NETLINK_SNL_GENERIC_H_
  28. #define _NETLINK_NETLINK_SNL_GENERIC_H_
  29. #include <netlink/netlink.h>
  30. #include <netlink/netlink_generic.h>
  31. #include <netlink/netlink_snl.h>
  32. /* Genetlink helpers */
  33. static inline struct nlmsghdr *
  34. snl_create_genl_msg_request(struct snl_writer *nw, int genl_family, uint8_t genl_cmd)
  35. {
  36. assert(nw->hdr == NULL);
  37. struct nlmsghdr *hdr = snl_reserve_msg_object(nw, struct nlmsghdr);
  38. hdr->nlmsg_type = genl_family;
  39. hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
  40. nw->hdr = hdr;
  41. struct genlmsghdr *ghdr = snl_reserve_msg_object(nw, struct genlmsghdr);
  42. ghdr->cmd = genl_cmd;
  43. return (hdr);
  44. }
  45. static struct snl_field_parser snl_fp_genl[] = {};
  46. #define SNL_DECLARE_GENL_PARSER(_name, _np) SNL_DECLARE_PARSER(_name,\
  47. struct genlmsghdr, snl_fp_genl, _np)
  48. struct snl_genl_ctrl_mcast_group {
  49. uint32_t mcast_grp_id;
  50. char *mcast_grp_name;
  51. };
  52. struct snl_genl_ctrl_mcast_groups {
  53. uint32_t num_groups;
  54. struct snl_genl_ctrl_mcast_group **groups;
  55. };
  56. #define _OUT(_field) offsetof(struct snl_genl_ctrl_mcast_group, _field)
  57. static struct snl_attr_parser _nla_p_getmc[] = {
  58. { .type = CTRL_ATTR_MCAST_GRP_NAME, .off = _OUT(mcast_grp_name), .cb = snl_attr_get_string },
  59. { .type = CTRL_ATTR_MCAST_GRP_ID, .off = _OUT(mcast_grp_id), .cb = snl_attr_get_uint32 },
  60. };
  61. #undef _OUT
  62. SNL_DECLARE_ATTR_PARSER_EXT(_genl_ctrl_mc_parser,
  63. sizeof(struct snl_genl_ctrl_mcast_group),
  64. _nla_p_getmc, NULL);
  65. struct _getfamily_attrs {
  66. uint16_t family_id;
  67. char *family_name;
  68. struct snl_genl_ctrl_mcast_groups mcast_groups;
  69. };
  70. #define _IN(_field) offsetof(struct genlmsghdr, _field)
  71. #define _OUT(_field) offsetof(struct _getfamily_attrs, _field)
  72. static struct snl_attr_parser _nla_p_getfam[] = {
  73. { .type = CTRL_ATTR_FAMILY_ID , .off = _OUT(family_id), .cb = snl_attr_get_uint16 },
  74. { .type = CTRL_ATTR_FAMILY_NAME, .off = _OUT(family_name), .cb = snl_attr_get_string },
  75. {
  76. .type = CTRL_ATTR_MCAST_GROUPS,
  77. .off = _OUT(mcast_groups),
  78. .cb = snl_attr_get_parray,
  79. .arg = &_genl_ctrl_mc_parser,
  80. },
  81. };
  82. #undef _IN
  83. #undef _OUT
  84. SNL_DECLARE_GENL_PARSER(_genl_ctrl_getfam_parser, _nla_p_getfam);
  85. static bool
  86. snl_get_genl_family_info(struct snl_state *ss, const char *family_name,
  87. struct _getfamily_attrs *attrs)
  88. {
  89. struct snl_writer nw;
  90. struct nlmsghdr *hdr;
  91. memset(attrs, 0, sizeof(*attrs));
  92. snl_init_writer(ss, &nw);
  93. hdr = snl_create_genl_msg_request(&nw, GENL_ID_CTRL, CTRL_CMD_GETFAMILY);
  94. snl_add_msg_attr_string(&nw, CTRL_ATTR_FAMILY_NAME, family_name);
  95. if ((hdr = snl_finalize_msg(&nw)) == NULL || !snl_send_message(ss, hdr))
  96. return (false);
  97. hdr = snl_read_reply(ss, hdr->nlmsg_seq);
  98. if (hdr != NULL && hdr->nlmsg_type != NLMSG_ERROR) {
  99. if (snl_parse_nlmsg(ss, hdr, &_genl_ctrl_getfam_parser, attrs))
  100. return (true);
  101. }
  102. return (false);
  103. }
  104. static inline uint16_t
  105. snl_get_genl_family(struct snl_state *ss, const char *family_name)
  106. {
  107. struct _getfamily_attrs attrs = {};
  108. snl_get_genl_family_info(ss, family_name, &attrs);
  109. return (attrs.family_id);
  110. }
  111. static const struct snl_hdr_parser *snl_all_genl_parsers[] = {
  112. &_genl_ctrl_getfam_parser, &_genl_ctrl_mc_parser,
  113. };
  114. #endif