interface-ip.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <arpa/inet.h>
  6. #include "netifd.h"
  7. #include "device.h"
  8. #include "interface.h"
  9. #include "interface-ip.h"
  10. #include "proto.h"
  11. #include "ubus.h"
  12. #include "system.h"
  13. enum {
  14. ROUTE_INTERFACE,
  15. ROUTE_TARGET,
  16. ROUTE_MASK,
  17. ROUTE_GATEWAY,
  18. ROUTE_METRIC,
  19. ROUTE_MTU,
  20. __ROUTE_MAX
  21. };
  22. static const struct blobmsg_policy route_attr[__ROUTE_MAX] = {
  23. [ROUTE_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
  24. [ROUTE_TARGET] = { .name = "target", .type = BLOBMSG_TYPE_STRING },
  25. [ROUTE_MASK] = { .name = "netmask", .type = BLOBMSG_TYPE_STRING },
  26. [ROUTE_GATEWAY] = { .name = "gateway", .type = BLOBMSG_TYPE_STRING },
  27. [ROUTE_METRIC] = { .name = "metric", .type = BLOBMSG_TYPE_INT32 },
  28. [ROUTE_MTU] = { .name = "mtu", .type = BLOBMSG_TYPE_INT32 },
  29. };
  30. const struct config_param_list route_attr_list = {
  31. .n_params = __ROUTE_MAX,
  32. .params = route_attr,
  33. };
  34. void
  35. interface_ip_add_route(struct interface *iface, struct blob_attr *attr, bool v6)
  36. {
  37. struct interface_ip_settings *ip;
  38. struct blob_attr *tb[__ROUTE_MAX], *cur;
  39. struct device_route *route;
  40. int af = v6 ? AF_INET6 : AF_INET;
  41. blobmsg_parse(route_attr, __ROUTE_MAX, tb, blobmsg_data(attr), blobmsg_data_len(attr));
  42. if (!iface) {
  43. if ((cur = tb[ROUTE_INTERFACE]) == NULL)
  44. return;
  45. iface = vlist_find(&interfaces, blobmsg_data(cur), iface, node);
  46. if (!iface)
  47. return;
  48. ip = &iface->config_ip;
  49. } else {
  50. ip = &iface->proto_ip;
  51. }
  52. route = calloc(1, sizeof(*route));
  53. if (!route)
  54. return;
  55. route->mask = v6 ? 128 : 32;
  56. if ((cur = tb[ROUTE_MASK]) != NULL) {
  57. route->mask = parse_netmask_string(blobmsg_data(cur), v6);
  58. if (route->mask > (v6 ? 128 : 32))
  59. goto error;
  60. }
  61. if ((cur = tb[ROUTE_TARGET]) != NULL) {
  62. if (!inet_pton(af, blobmsg_data(cur), &route->addr)) {
  63. DPRINTF("Failed to parse route target: %s\n", (char *) blobmsg_data(cur));
  64. goto error;
  65. }
  66. }
  67. if ((cur = tb[ROUTE_GATEWAY]) != NULL) {
  68. if (!inet_pton(af, blobmsg_data(cur), &route->nexthop)) {
  69. DPRINTF("Failed to parse route gateway: %s\n", (char *) blobmsg_data(cur));
  70. goto error;
  71. }
  72. }
  73. if ((cur = tb[ROUTE_METRIC]) != NULL)
  74. route->metric = blobmsg_get_u32(cur);
  75. if ((cur = tb[ROUTE_MTU]) != NULL)
  76. route->mtu = blobmsg_get_u32(cur);
  77. vlist_add(&ip->route, &route->node, &route->mask);
  78. return;
  79. error:
  80. free(route);
  81. }
  82. static int
  83. addr_cmp(const void *k1, const void *k2, void *ptr)
  84. {
  85. return memcmp(k1, k2, sizeof(struct device_addr) -
  86. offsetof(struct device_addr, mask));
  87. }
  88. static int
  89. route_cmp(const void *k1, const void *k2, void *ptr)
  90. {
  91. return memcmp(k1, k2, sizeof(struct device_route) -
  92. offsetof(struct device_route, mask));
  93. }
  94. static void
  95. interface_update_proto_addr(struct vlist_tree *tree,
  96. struct vlist_node *node_new,
  97. struct vlist_node *node_old)
  98. {
  99. struct interface_ip_settings *ip;
  100. struct interface *iface;
  101. struct device *dev;
  102. struct device_addr *a_new = NULL, *a_old = NULL;
  103. bool keep = false;
  104. ip = container_of(tree, struct interface_ip_settings, addr);
  105. iface = ip->iface;
  106. dev = iface->l3_dev->dev;
  107. if (node_new) {
  108. a_new = container_of(node_new, struct device_addr, node);
  109. if ((a_new->flags & DEVADDR_FAMILY) == DEVADDR_INET4 &&
  110. !a_new->broadcast) {
  111. uint32_t mask = ~0;
  112. uint32_t *a = (uint32_t *) &a_new->addr;
  113. mask >>= a_new->mask;
  114. a_new->broadcast = *a | mask;
  115. }
  116. }
  117. if (node_old)
  118. a_old = container_of(node_old, struct device_addr, node);
  119. if (a_new && a_old) {
  120. keep = true;
  121. if (a_old->flags != a_new->flags)
  122. keep = false;
  123. if ((a_new->flags & DEVADDR_FAMILY) == DEVADDR_INET4 &&
  124. a_new->broadcast != a_old->broadcast)
  125. keep = false;
  126. }
  127. if (node_old) {
  128. if (!(a_old->flags & DEVADDR_EXTERNAL) && a_old->enabled && !keep)
  129. system_del_address(dev, a_old);
  130. free(a_old);
  131. }
  132. if (node_new) {
  133. if (!(a_new->flags & DEVADDR_EXTERNAL) && !keep)
  134. system_add_address(dev, a_new);
  135. a_new->enabled = true;
  136. }
  137. }
  138. static bool
  139. enable_route(struct interface_ip_settings *ip, struct device_route *route)
  140. {
  141. if (ip->no_defaultroute && !route->mask)
  142. return false;
  143. return true;
  144. }
  145. static void
  146. interface_update_proto_route(struct vlist_tree *tree,
  147. struct vlist_node *node_new,
  148. struct vlist_node *node_old)
  149. {
  150. struct interface_ip_settings *ip;
  151. struct interface *iface;
  152. struct device *dev;
  153. struct device_route *route_old, *route_new;
  154. bool keep = false;
  155. ip = container_of(tree, struct interface_ip_settings, route);
  156. iface = ip->iface;
  157. dev = iface->l3_dev->dev;
  158. route_old = container_of(node_old, struct device_route, node);
  159. route_new = container_of(node_new, struct device_route, node);
  160. if (node_old && node_new)
  161. keep = !memcmp(&route_old->nexthop, &route_new->nexthop, sizeof(route_old->nexthop));
  162. if (node_old) {
  163. if (!(route_old->flags & DEVADDR_EXTERNAL) && route_old->enabled && !keep)
  164. system_del_route(dev, route_old);
  165. free(route_old);
  166. }
  167. if (node_new) {
  168. bool _enabled = enable_route(ip, route_new);
  169. if (!(route_new->flags & DEVADDR_EXTERNAL) && !keep && _enabled)
  170. system_add_route(dev, route_new);
  171. route_new->enabled = _enabled;
  172. }
  173. }
  174. void
  175. interface_add_dns_server(struct interface_ip_settings *ip, const char *str)
  176. {
  177. struct dns_server *s;
  178. s = calloc(1, sizeof(*s));
  179. s->af = AF_INET;
  180. if (inet_pton(s->af, str, &s->addr.in))
  181. goto add;
  182. s->af = AF_INET6;
  183. if (inet_pton(s->af, str, &s->addr.in))
  184. goto add;
  185. free(s);
  186. return;
  187. add:
  188. D(INTERFACE, "Add IPv%c DNS server: %s\n",
  189. s->af == AF_INET6 ? '6' : '4', str);
  190. vlist_simple_add(&ip->dns_servers, &s->node);
  191. }
  192. void
  193. interface_add_dns_server_list(struct interface_ip_settings *ip, struct blob_attr *list)
  194. {
  195. struct blob_attr *cur;
  196. int rem;
  197. blobmsg_for_each_attr(cur, list, rem) {
  198. if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
  199. continue;
  200. if (!blobmsg_check_attr(cur, NULL))
  201. continue;
  202. interface_add_dns_server(ip, blobmsg_data(cur));
  203. }
  204. }
  205. static void
  206. interface_add_dns_search_domain(struct interface_ip_settings *ip, const char *str)
  207. {
  208. struct dns_search_domain *s;
  209. int len = strlen(str);
  210. s = calloc(1, sizeof(*s) + len + 1);
  211. if (!s)
  212. return;
  213. D(INTERFACE, "Add DNS search domain: %s\n", str);
  214. memcpy(s->name, str, len);
  215. vlist_simple_add(&ip->dns_search, &s->node);
  216. }
  217. void
  218. interface_add_dns_search_list(struct interface_ip_settings *ip, struct blob_attr *list)
  219. {
  220. struct blob_attr *cur;
  221. int rem;
  222. blobmsg_for_each_attr(cur, list, rem) {
  223. if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
  224. continue;
  225. if (!blobmsg_check_attr(cur, NULL))
  226. continue;
  227. interface_add_dns_search_domain(ip, blobmsg_data(cur));
  228. }
  229. }
  230. static void
  231. write_resolv_conf_entries(FILE *f, struct interface_ip_settings *ip)
  232. {
  233. struct dns_server *s;
  234. struct dns_search_domain *d;
  235. const char *str;
  236. char buf[32];
  237. vlist_simple_for_each_element(&ip->dns_servers, s, node) {
  238. str = inet_ntop(s->af, &s->addr, buf, sizeof(buf));
  239. if (!str)
  240. continue;
  241. fprintf(f, "nameserver %s\n", str);
  242. }
  243. vlist_simple_for_each_element(&ip->dns_search, d, node) {
  244. fprintf(f, "search %s\n", d->name);
  245. }
  246. }
  247. void
  248. interface_write_resolv_conf(void)
  249. {
  250. struct interface *iface;
  251. char *path = alloca(strlen(resolv_conf) + 5);
  252. FILE *f;
  253. sprintf(path, "%s.tmp", resolv_conf);
  254. unlink(path);
  255. f = fopen(path, "w");
  256. if (!f) {
  257. D(INTERFACE, "Failed to open %s for writing\n", path);
  258. return;
  259. }
  260. vlist_for_each_element(&interfaces, iface, node) {
  261. if (iface->state != IFS_UP)
  262. continue;
  263. if (vlist_simple_empty(&iface->proto_ip.dns_search) &&
  264. vlist_simple_empty(&iface->proto_ip.dns_servers) &&
  265. vlist_simple_empty(&iface->config_ip.dns_search) &&
  266. vlist_simple_empty(&iface->config_ip.dns_servers))
  267. continue;
  268. fprintf(f, "# Interface %s\n", iface->name);
  269. write_resolv_conf_entries(f, &iface->config_ip);
  270. write_resolv_conf_entries(f, &iface->proto_ip);
  271. }
  272. fclose(f);
  273. if (rename(path, resolv_conf) < 0) {
  274. D(INTERFACE, "Failed to replace %s\n", resolv_conf);
  275. unlink(path);
  276. }
  277. }
  278. void interface_ip_set_enabled(struct interface_ip_settings *ip, bool enabled)
  279. {
  280. struct device_addr *addr;
  281. struct device_route *route;
  282. struct device *dev;
  283. ip->enabled = enabled;
  284. dev = ip->iface->l3_dev->dev;
  285. if (!dev)
  286. return;
  287. vlist_for_each_element(&ip->addr, addr, node) {
  288. if (addr->enabled == enabled)
  289. continue;
  290. if (enabled)
  291. system_add_address(dev, addr);
  292. else
  293. system_del_address(dev, addr);
  294. addr->enabled = enabled;
  295. }
  296. vlist_for_each_element(&ip->route, route, node) {
  297. bool _enabled = enabled;
  298. if (!enable_route(ip, route))
  299. _enabled = false;
  300. if (route->enabled == _enabled)
  301. continue;
  302. if (_enabled)
  303. system_add_route(dev, route);
  304. else
  305. system_del_route(dev, route);
  306. route->enabled = _enabled;
  307. }
  308. }
  309. void
  310. interface_ip_update_start(struct interface_ip_settings *ip)
  311. {
  312. vlist_simple_update(&ip->dns_servers);
  313. vlist_simple_update(&ip->dns_search);
  314. vlist_update(&ip->route);
  315. vlist_update(&ip->addr);
  316. }
  317. void
  318. interface_ip_update_complete(struct interface_ip_settings *ip)
  319. {
  320. vlist_simple_flush(&ip->dns_servers);
  321. vlist_simple_flush(&ip->dns_search);
  322. vlist_flush(&ip->route);
  323. vlist_flush(&ip->addr);
  324. }
  325. void
  326. interface_ip_flush(struct interface_ip_settings *ip)
  327. {
  328. vlist_simple_flush_all(&ip->dns_servers);
  329. vlist_simple_flush_all(&ip->dns_search);
  330. vlist_flush_all(&ip->route);
  331. vlist_flush_all(&ip->addr);
  332. }
  333. void
  334. interface_ip_init(struct interface_ip_settings *ip, struct interface *iface)
  335. {
  336. ip->iface = iface;
  337. ip->enabled = true;
  338. vlist_simple_init(&ip->dns_search, struct dns_search_domain, node);
  339. vlist_simple_init(&ip->dns_servers, struct dns_server, node);
  340. vlist_init(&ip->route, route_cmp, interface_update_proto_route);
  341. vlist_init(&ip->addr, addr_cmp, interface_update_proto_addr);
  342. }