vlan_util.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * hostapd / VLAN netlink api
  3. * Copyright (c) 2012, Michael Braun <michael-dev@fami-braun.de>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "utils/includes.h"
  9. #include <netlink/route/link.h>
  10. #include <netlink/route/link/vlan.h>
  11. #include "utils/common.h"
  12. #include "vlan_util.h"
  13. /*
  14. * Add a vlan interface with name 'vlan_if_name', VLAN ID 'vid' and
  15. * tagged interface 'if_name'.
  16. *
  17. * returns -1 on error
  18. * returns 1 if the interface already exists
  19. * returns 0 otherwise
  20. */
  21. int vlan_add(const char *if_name, int vid, const char *vlan_if_name)
  22. {
  23. int err, ret = -1;
  24. struct nl_sock *handle = NULL;
  25. struct rtnl_link *rlink = NULL;
  26. int if_idx = 0;
  27. wpa_printf(MSG_DEBUG, "VLAN: vlan_add(if_name=%s, vid=%d, "
  28. "vlan_if_name=%s)", if_name, vid, vlan_if_name);
  29. if ((os_strlen(if_name) + 1) > IFNAMSIZ) {
  30. wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'",
  31. if_name);
  32. return -1;
  33. }
  34. if ((os_strlen(vlan_if_name) + 1) > IFNAMSIZ) {
  35. wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'",
  36. vlan_if_name);
  37. return -1;
  38. }
  39. handle = nl_socket_alloc();
  40. if (!handle) {
  41. wpa_printf(MSG_ERROR, "VLAN: failed to open netlink socket");
  42. goto vlan_add_error;
  43. }
  44. err = nl_connect(handle, NETLINK_ROUTE);
  45. if (err < 0) {
  46. wpa_printf(MSG_ERROR, "VLAN: failed to connect to netlink: %s",
  47. nl_geterror(err));
  48. goto vlan_add_error;
  49. }
  50. err = rtnl_link_get_kernel(handle, 0, if_name, &rlink);
  51. if (err < 0) {
  52. /* link does not exist */
  53. wpa_printf(MSG_ERROR, "VLAN: interface %s does not exist",
  54. if_name);
  55. goto vlan_add_error;
  56. }
  57. if_idx = rtnl_link_get_ifindex(rlink);
  58. rtnl_link_put(rlink);
  59. rlink = NULL;
  60. err = rtnl_link_get_kernel(handle, 0, vlan_if_name, &rlink);
  61. if (err >= 0) {
  62. /* link does exist */
  63. rtnl_link_put(rlink);
  64. rlink = NULL;
  65. wpa_printf(MSG_ERROR, "VLAN: interface %s already exists",
  66. vlan_if_name);
  67. ret = 1;
  68. goto vlan_add_error;
  69. }
  70. rlink = rtnl_link_alloc();
  71. if (!rlink) {
  72. wpa_printf(MSG_ERROR, "VLAN: failed to allocate new link");
  73. goto vlan_add_error;
  74. }
  75. err = rtnl_link_set_type(rlink, "vlan");
  76. if (err < 0) {
  77. wpa_printf(MSG_ERROR, "VLAN: failed to set link type: %s",
  78. nl_geterror(err));
  79. goto vlan_add_error;
  80. }
  81. rtnl_link_set_link(rlink, if_idx);
  82. rtnl_link_set_name(rlink, vlan_if_name);
  83. err = rtnl_link_vlan_set_id(rlink, vid);
  84. if (err < 0) {
  85. wpa_printf(MSG_ERROR, "VLAN: failed to set link vlan id: %s",
  86. nl_geterror(err));
  87. goto vlan_add_error;
  88. }
  89. err = rtnl_link_add(handle, rlink, NLM_F_CREATE);
  90. if (err < 0) {
  91. wpa_printf(MSG_ERROR, "VLAN: failed to create link %s for "
  92. "vlan %d on %s (%d): %s",
  93. vlan_if_name, vid, if_name, if_idx,
  94. nl_geterror(err));
  95. goto vlan_add_error;
  96. }
  97. ret = 0;
  98. vlan_add_error:
  99. if (rlink)
  100. rtnl_link_put(rlink);
  101. if (handle)
  102. nl_socket_free(handle);
  103. return ret;
  104. }
  105. int vlan_rem(const char *if_name)
  106. {
  107. int err, ret = -1;
  108. struct nl_sock *handle = NULL;
  109. struct rtnl_link *rlink = NULL;
  110. wpa_printf(MSG_DEBUG, "VLAN: vlan_rem(if_name=%s)", if_name);
  111. handle = nl_socket_alloc();
  112. if (!handle) {
  113. wpa_printf(MSG_ERROR, "VLAN: failed to open netlink socket");
  114. goto vlan_rem_error;
  115. }
  116. err = nl_connect(handle, NETLINK_ROUTE);
  117. if (err < 0) {
  118. wpa_printf(MSG_ERROR, "VLAN: failed to connect to netlink: %s",
  119. nl_geterror(err));
  120. goto vlan_rem_error;
  121. }
  122. err = rtnl_link_get_kernel(handle, 0, if_name, &rlink);
  123. if (err < 0) {
  124. /* link does not exist */
  125. wpa_printf(MSG_ERROR, "VLAN: interface %s does not exists",
  126. if_name);
  127. goto vlan_rem_error;
  128. }
  129. err = rtnl_link_delete(handle, rlink);
  130. if (err < 0) {
  131. wpa_printf(MSG_ERROR, "VLAN: failed to remove link %s: %s",
  132. if_name, nl_geterror(err));
  133. goto vlan_rem_error;
  134. }
  135. ret = 0;
  136. vlan_rem_error:
  137. if (rlink)
  138. rtnl_link_put(rlink);
  139. if (handle)
  140. nl_socket_free(handle);
  141. return ret;
  142. }
  143. int vlan_set_name_type(unsigned int name_type)
  144. {
  145. return 0;
  146. }