netlink_snl_route.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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_ROUTE_H_
  28. #define _NETLINK_NETLINK_SNL_ROUTE_H_
  29. #include <netlink/netlink_snl.h>
  30. #include <netlink/netlink_route.h>
  31. #include <netinet/in.h>
  32. /*
  33. * Simple Netlink Library - NETLINK_ROUTE helpers
  34. */
  35. static inline struct sockaddr *
  36. parse_rta_ip4(struct snl_state *ss, void *rta_data, int *perror)
  37. {
  38. struct sockaddr_in *sin;
  39. sin = (struct sockaddr_in *)snl_allocz(ss, sizeof(struct sockaddr_in));
  40. if (sin == NULL) {
  41. *perror = ENOBUFS;
  42. return (NULL);
  43. }
  44. sin->sin_len = sizeof(struct sockaddr_in);
  45. sin->sin_family = AF_INET;
  46. memcpy(&sin->sin_addr, rta_data, sizeof(struct in_addr));
  47. return ((struct sockaddr *)sin);
  48. }
  49. static inline struct sockaddr *
  50. parse_rta_ip6(struct snl_state *ss, void *rta_data, int *perror)
  51. {
  52. struct sockaddr_in6 *sin6;
  53. sin6 = (struct sockaddr_in6 *)snl_allocz(ss, sizeof(struct sockaddr_in6));
  54. if (sin6 == NULL) {
  55. *perror = ENOBUFS;
  56. return (NULL);
  57. }
  58. sin6->sin6_len = sizeof(struct sockaddr_in6);
  59. sin6->sin6_family = AF_INET6;
  60. memcpy(&sin6->sin6_addr, rta_data, sizeof(struct in6_addr));
  61. return ((struct sockaddr *)sin6);
  62. }
  63. static inline struct sockaddr *
  64. parse_rta_ip(struct snl_state *ss, struct rtattr *rta, int *perror)
  65. {
  66. void *rta_data = NL_RTA_DATA(rta);
  67. int rta_len = NL_RTA_DATA_LEN(rta);
  68. if (rta_len == sizeof(struct in_addr)) {
  69. return (parse_rta_ip4(ss, rta_data, perror));
  70. } else if (rta_len == sizeof(struct in6_addr)) {
  71. return (parse_rta_ip6(ss, rta_data, perror));
  72. } else {
  73. *perror = ENOTSUP;
  74. return (NULL);
  75. }
  76. return (NULL);
  77. }
  78. static inline bool
  79. snl_attr_get_ip(struct snl_state *ss, struct nlattr *nla,
  80. const void *arg __unused, void *target)
  81. {
  82. int error = 0;
  83. struct sockaddr *sa = parse_rta_ip(ss, (struct rtattr *)nla, &error);
  84. if (error == 0) {
  85. *((struct sockaddr **)target) = sa;
  86. return (true);
  87. }
  88. return (false);
  89. }
  90. static inline struct sockaddr *
  91. parse_rta_via(struct snl_state *ss, struct rtattr *rta, int *perror)
  92. {
  93. struct rtvia *via = (struct rtvia *)NL_RTA_DATA(rta);
  94. switch (via->rtvia_family) {
  95. case AF_INET:
  96. return (parse_rta_ip4(ss, via->rtvia_addr, perror));
  97. case AF_INET6:
  98. return (parse_rta_ip6(ss, via->rtvia_addr, perror));
  99. default:
  100. *perror = ENOTSUP;
  101. return (NULL);
  102. }
  103. }
  104. static inline bool
  105. snl_attr_get_ipvia(struct snl_state *ss, struct nlattr *nla,
  106. const void *arg __unused, void *target)
  107. {
  108. int error = 0;
  109. struct sockaddr *sa = parse_rta_via(ss, (struct rtattr *)nla, &error);
  110. if (error == 0) {
  111. *((struct sockaddr **)target) = sa;
  112. return (true);
  113. }
  114. return (false);
  115. }
  116. static inline bool
  117. snl_add_msg_attr_ip4(struct snl_writer *nw, int attrtype, const struct in_addr *addr)
  118. {
  119. return (snl_add_msg_attr(nw, attrtype, 4, addr));
  120. }
  121. static inline bool
  122. snl_add_msg_attr_ip6(struct snl_writer *nw, int attrtype, const struct in6_addr *addr)
  123. {
  124. return (snl_add_msg_attr(nw, attrtype, 16, addr));
  125. }
  126. static inline bool
  127. snl_add_msg_attr_ip(struct snl_writer *nw, int attrtype, const struct sockaddr *sa)
  128. {
  129. const void *addr;
  130. switch (sa->sa_family) {
  131. case AF_INET:
  132. addr = &((const struct sockaddr_in *)(const void *)sa)->sin_addr;
  133. return (snl_add_msg_attr(nw, attrtype, 4, addr));
  134. case AF_INET6:
  135. addr = &((const struct sockaddr_in6 *)(const void *)sa)->sin6_addr;
  136. return (snl_add_msg_attr(nw, attrtype, 16, addr));
  137. }
  138. return (false);
  139. }
  140. static inline bool
  141. snl_add_msg_attr_ipvia(struct snl_writer *nw, int attrtype, const struct sockaddr *sa)
  142. {
  143. char buf[17];
  144. buf[0] = sa->sa_family;
  145. switch (sa->sa_family) {
  146. case AF_INET:
  147. memcpy(&buf[1], &((const struct sockaddr_in *)(const void *)sa)->sin_addr, 4);
  148. return (snl_add_msg_attr(nw, attrtype, 5, buf));
  149. case AF_INET6:
  150. memcpy(&buf[1], &((const struct sockaddr_in6 *)(const void *)sa)->sin6_addr, 16);
  151. return (snl_add_msg_attr(nw, attrtype, 17, buf));
  152. }
  153. return (false);
  154. }
  155. static inline bool
  156. snl_attr_get_in_addr(struct snl_state *ss __unused, struct nlattr *nla,
  157. const void *arg __unused, void *target)
  158. {
  159. if (NLA_DATA_LEN(nla) != sizeof(struct in_addr))
  160. return (false);
  161. memcpy(target, NLA_DATA_CONST(nla), sizeof(struct in_addr));
  162. return (true);
  163. }
  164. static inline bool
  165. snl_attr_get_in6_addr(struct snl_state *ss __unused, struct nlattr *nla,
  166. const void *arg __unused, void *target)
  167. {
  168. if (NLA_DATA_LEN(nla) != sizeof(struct in6_addr))
  169. return (false);
  170. memcpy(target, NLA_DATA_CONST(nla), sizeof(struct in6_addr));
  171. return (true);
  172. }
  173. #endif