macvlan.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * netifd - network interface daemon
  3. * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
  4. * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2
  8. * as published by the Free Software Foundation
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <assert.h>
  19. #include <errno.h>
  20. #include "netifd.h"
  21. #include "device.h"
  22. #include "interface.h"
  23. #include "system.h"
  24. enum {
  25. MACVLAN_ATTR_IFNAME,
  26. MACVLAN_ATTR_MACADDR,
  27. MACVLAN_ATTR_MODE,
  28. __MACVLAN_ATTR_MAX
  29. };
  30. static const struct blobmsg_policy macvlan_attrs[__MACVLAN_ATTR_MAX] = {
  31. [MACVLAN_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_STRING },
  32. [MACVLAN_ATTR_MACADDR] = { "macaddr", BLOBMSG_TYPE_STRING },
  33. [MACVLAN_ATTR_MODE] = { "mode", BLOBMSG_TYPE_STRING },
  34. };
  35. static const struct uci_blob_param_list macvlan_attr_list = {
  36. .n_params = __MACVLAN_ATTR_MAX,
  37. .params = macvlan_attrs,
  38. .n_next = 1,
  39. .next = { &device_attr_list },
  40. };
  41. struct macvlan_device {
  42. struct device dev;
  43. struct device_user parent;
  44. device_state_cb set_state;
  45. struct blob_attr *config_data;
  46. struct blob_attr *ifname;
  47. struct macvlan_config config;
  48. };
  49. static void
  50. macvlan_base_cb(struct device_user *dev, enum device_event ev)
  51. {
  52. struct macvlan_device *mvdev = container_of(dev, struct macvlan_device, parent);
  53. switch (ev) {
  54. case DEV_EVENT_ADD:
  55. device_set_present(&mvdev->dev, true);
  56. break;
  57. case DEV_EVENT_REMOVE:
  58. device_set_present(&mvdev->dev, false);
  59. break;
  60. default:
  61. return;
  62. }
  63. }
  64. static int
  65. macvlan_set_down(struct macvlan_device *mvdev)
  66. {
  67. mvdev->set_state(&mvdev->dev, false);
  68. system_macvlan_del(&mvdev->dev);
  69. device_release(&mvdev->parent);
  70. return 0;
  71. }
  72. static int
  73. macvlan_set_up(struct macvlan_device *mvdev)
  74. {
  75. int ret;
  76. ret = device_claim(&mvdev->parent);
  77. if (ret < 0)
  78. return ret;
  79. ret = system_macvlan_add(&mvdev->dev, mvdev->parent.dev, &mvdev->config);
  80. if (ret < 0)
  81. goto release;
  82. ret = mvdev->set_state(&mvdev->dev, true);
  83. if (ret)
  84. goto delete;
  85. return 0;
  86. delete:
  87. system_macvlan_del(&mvdev->dev);
  88. release:
  89. device_release(&mvdev->parent);
  90. return ret;
  91. }
  92. static int
  93. macvlan_set_state(struct device *dev, bool up)
  94. {
  95. struct macvlan_device *mvdev;
  96. D(SYSTEM, "macvlan_set_state(%s, %u)", dev->ifname, up);
  97. mvdev = container_of(dev, struct macvlan_device, dev);
  98. if (up)
  99. return macvlan_set_up(mvdev);
  100. else
  101. return macvlan_set_down(mvdev);
  102. }
  103. static void
  104. macvlan_free(struct device *dev)
  105. {
  106. struct macvlan_device *mvdev;
  107. mvdev = container_of(dev, struct macvlan_device, dev);
  108. device_remove_user(&mvdev->parent);
  109. free(mvdev->config_data);
  110. free(mvdev);
  111. }
  112. static void
  113. macvlan_dump_info(struct device *dev, struct blob_buf *b)
  114. {
  115. struct macvlan_device *mvdev;
  116. mvdev = container_of(dev, struct macvlan_device, dev);
  117. blobmsg_add_string(b, "parent", mvdev->parent.dev->ifname);
  118. system_if_dump_info(dev, b);
  119. }
  120. static void
  121. macvlan_config_init(struct device *dev)
  122. {
  123. struct macvlan_device *mvdev;
  124. struct device *basedev = NULL;
  125. mvdev = container_of(dev, struct macvlan_device, dev);
  126. if (mvdev->ifname)
  127. basedev = device_get(blobmsg_data(mvdev->ifname), true);
  128. device_add_user(&mvdev->parent, basedev);
  129. }
  130. static void
  131. macvlan_apply_settings(struct macvlan_device *mvdev, struct blob_attr **tb)
  132. {
  133. struct macvlan_config *cfg = &mvdev->config;
  134. struct blob_attr *cur;
  135. struct ether_addr *ea;
  136. cfg->flags = 0;
  137. cfg->mode = NULL;
  138. if ((cur = tb[MACVLAN_ATTR_MACADDR])) {
  139. ea = ether_aton(blobmsg_data(cur));
  140. if (ea) {
  141. memcpy(cfg->macaddr, ea, 6);
  142. cfg->flags |= MACVLAN_OPT_MACADDR;
  143. }
  144. }
  145. if ((cur = tb[MACVLAN_ATTR_MODE]))
  146. cfg->mode = blobmsg_data(cur);
  147. }
  148. static enum dev_change_type
  149. macvlan_reload(struct device *dev, struct blob_attr *attr)
  150. {
  151. struct blob_attr *tb_dev[__DEV_ATTR_MAX];
  152. struct blob_attr *tb_mv[__MACVLAN_ATTR_MAX];
  153. enum dev_change_type ret = DEV_CONFIG_APPLIED;
  154. struct macvlan_device *mvdev;
  155. mvdev = container_of(dev, struct macvlan_device, dev);
  156. attr = blob_memdup(attr);
  157. blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev,
  158. blob_data(attr), blob_len(attr));
  159. blobmsg_parse(macvlan_attrs, __MACVLAN_ATTR_MAX, tb_mv,
  160. blob_data(attr), blob_len(attr));
  161. device_init_settings(dev, tb_dev);
  162. macvlan_apply_settings(mvdev, tb_mv);
  163. mvdev->ifname = tb_mv[MACVLAN_ATTR_IFNAME];
  164. if (mvdev->config_data) {
  165. struct blob_attr *otb_dev[__DEV_ATTR_MAX];
  166. struct blob_attr *otb_mv[__MACVLAN_ATTR_MAX];
  167. blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev,
  168. blob_data(mvdev->config_data), blob_len(mvdev->config_data));
  169. if (uci_blob_diff(tb_dev, otb_dev, &device_attr_list, NULL))
  170. ret = DEV_CONFIG_RESTART;
  171. blobmsg_parse(macvlan_attrs, __MACVLAN_ATTR_MAX, otb_mv,
  172. blob_data(mvdev->config_data), blob_len(mvdev->config_data));
  173. if (uci_blob_diff(tb_mv, otb_mv, &macvlan_attr_list, NULL))
  174. ret = DEV_CONFIG_RESTART;
  175. macvlan_config_init(dev);
  176. }
  177. free(mvdev->config_data);
  178. mvdev->config_data = attr;
  179. return ret;
  180. }
  181. static struct device *
  182. macvlan_create(const char *name, struct device_type *devtype,
  183. struct blob_attr *attr)
  184. {
  185. struct macvlan_device *mvdev;
  186. struct device *dev = NULL;
  187. mvdev = calloc(1, sizeof(*mvdev));
  188. if (!mvdev)
  189. return NULL;
  190. dev = &mvdev->dev;
  191. if (device_init(dev, devtype, name) < 0) {
  192. device_cleanup(dev);
  193. free(mvdev);
  194. return NULL;
  195. }
  196. dev->config_pending = true;
  197. mvdev->set_state = dev->set_state;
  198. dev->set_state = macvlan_set_state;
  199. dev->hotplug_ops = NULL;
  200. mvdev->parent.cb = macvlan_base_cb;
  201. macvlan_reload(dev, attr);
  202. return dev;
  203. }
  204. static struct device_type macvlan_device_type = {
  205. .name = "macvlan",
  206. .config_params = &macvlan_attr_list,
  207. .create = macvlan_create,
  208. .config_init = macvlan_config_init,
  209. .reload = macvlan_reload,
  210. .free = macvlan_free,
  211. .dump_info = macvlan_dump_info,
  212. };
  213. static void __init macvlan_device_type_init(void)
  214. {
  215. device_type_add(&macvlan_device_type);
  216. }