bridge.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /*
  2. * netifd - network interface daemon
  3. * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2
  7. * as published by the Free Software Foundation
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <assert.h>
  18. #include <errno.h>
  19. #include "netifd.h"
  20. #include "device.h"
  21. #include "interface.h"
  22. #include "system.h"
  23. enum {
  24. BRIDGE_ATTR_IFNAME,
  25. BRIDGE_ATTR_STP,
  26. BRIDGE_ATTR_FORWARD_DELAY,
  27. BRIDGE_ATTR_PRIORITY,
  28. BRIDGE_ATTR_IGMP_SNOOP,
  29. BRIDGE_ATTR_AGEING_TIME,
  30. BRIDGE_ATTR_HELLO_TIME,
  31. BRIDGE_ATTR_MAX_AGE,
  32. BRIDGE_ATTR_BRIDGE_EMPTY,
  33. BRIDGE_ATTR_MULTICAST_QUERIER,
  34. BRIDGE_ATTR_HASH_MAX,
  35. BRIDGE_ATTR_ROBUSTNESS,
  36. BRIDGE_ATTR_QUERY_INTERVAL,
  37. BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL,
  38. BRIDGE_ATTR_LAST_MEMBER_INTERVAL,
  39. __BRIDGE_ATTR_MAX
  40. };
  41. static const struct blobmsg_policy bridge_attrs[__BRIDGE_ATTR_MAX] = {
  42. [BRIDGE_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_ARRAY },
  43. [BRIDGE_ATTR_STP] = { "stp", BLOBMSG_TYPE_BOOL },
  44. [BRIDGE_ATTR_FORWARD_DELAY] = { "forward_delay", BLOBMSG_TYPE_INT32 },
  45. [BRIDGE_ATTR_PRIORITY] = { "priority", BLOBMSG_TYPE_INT32 },
  46. [BRIDGE_ATTR_AGEING_TIME] = { "ageing_time", BLOBMSG_TYPE_INT32 },
  47. [BRIDGE_ATTR_HELLO_TIME] = { "hello_time", BLOBMSG_TYPE_INT32 },
  48. [BRIDGE_ATTR_MAX_AGE] = { "max_age", BLOBMSG_TYPE_INT32 },
  49. [BRIDGE_ATTR_IGMP_SNOOP] = { "igmp_snooping", BLOBMSG_TYPE_BOOL },
  50. [BRIDGE_ATTR_BRIDGE_EMPTY] = { "bridge_empty", BLOBMSG_TYPE_BOOL },
  51. [BRIDGE_ATTR_MULTICAST_QUERIER] = { "multicast_querier", BLOBMSG_TYPE_BOOL },
  52. [BRIDGE_ATTR_HASH_MAX] = { "hash_max", BLOBMSG_TYPE_INT32 },
  53. [BRIDGE_ATTR_ROBUSTNESS] = { "robustness", BLOBMSG_TYPE_INT32 },
  54. [BRIDGE_ATTR_QUERY_INTERVAL] = { "query_interval", BLOBMSG_TYPE_INT32 },
  55. [BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL] = { "query_response_interval", BLOBMSG_TYPE_INT32 },
  56. [BRIDGE_ATTR_LAST_MEMBER_INTERVAL] = { "last_member_interval", BLOBMSG_TYPE_INT32 },
  57. };
  58. static const struct uci_blob_param_info bridge_attr_info[__BRIDGE_ATTR_MAX] = {
  59. [BRIDGE_ATTR_IFNAME] = { .type = BLOBMSG_TYPE_STRING },
  60. };
  61. static const struct uci_blob_param_list bridge_attr_list = {
  62. .n_params = __BRIDGE_ATTR_MAX,
  63. .params = bridge_attrs,
  64. .info = bridge_attr_info,
  65. .n_next = 1,
  66. .next = { &device_attr_list },
  67. };
  68. static struct device *bridge_create(const char *name, struct device_type *devtype,
  69. struct blob_attr *attr);
  70. static void bridge_config_init(struct device *dev);
  71. static void bridge_free(struct device *dev);
  72. static void bridge_dump_info(struct device *dev, struct blob_buf *b);
  73. static enum dev_change_type
  74. bridge_reload(struct device *dev, struct blob_attr *attr);
  75. static struct device_type bridge_device_type = {
  76. .name = "bridge",
  77. .config_params = &bridge_attr_list,
  78. .bridge_capability = true,
  79. .name_prefix = "br",
  80. .create = bridge_create,
  81. .config_init = bridge_config_init,
  82. .reload = bridge_reload,
  83. .free = bridge_free,
  84. .dump_info = bridge_dump_info,
  85. };
  86. struct bridge_state {
  87. struct device dev;
  88. device_state_cb set_state;
  89. struct blob_attr *config_data;
  90. struct bridge_config config;
  91. struct blob_attr *ifnames;
  92. bool active;
  93. bool force_active;
  94. struct uloop_timeout retry;
  95. struct bridge_member *primary_port;
  96. struct vlist_tree members;
  97. int n_present;
  98. int n_failed;
  99. };
  100. struct bridge_member {
  101. struct vlist_node node;
  102. struct bridge_state *bst;
  103. struct device_user dev;
  104. bool present;
  105. char name[];
  106. };
  107. static void
  108. bridge_reset_primary(struct bridge_state *bst)
  109. {
  110. struct bridge_member *bm;
  111. if (!bst->primary_port &&
  112. (bst->dev.settings.flags & DEV_OPT_MACADDR))
  113. return;
  114. bst->primary_port = NULL;
  115. bst->dev.settings.flags &= ~DEV_OPT_MACADDR;
  116. vlist_for_each_element(&bst->members, bm, node) {
  117. uint8_t *macaddr;
  118. if (!bm->present)
  119. continue;
  120. bst->primary_port = bm;
  121. if (bm->dev.dev->settings.flags & DEV_OPT_MACADDR)
  122. macaddr = bm->dev.dev->settings.macaddr;
  123. else
  124. macaddr = bm->dev.dev->orig_settings.macaddr;
  125. memcpy(bst->dev.settings.macaddr, macaddr, 6);
  126. bst->dev.settings.flags |= DEV_OPT_MACADDR;
  127. return;
  128. }
  129. }
  130. static int
  131. bridge_disable_member(struct bridge_member *bm)
  132. {
  133. struct bridge_state *bst = bm->bst;
  134. if (!bm->present)
  135. return 0;
  136. system_bridge_delif(&bst->dev, bm->dev.dev);
  137. device_release(&bm->dev);
  138. device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
  139. return 0;
  140. }
  141. static int
  142. bridge_enable_interface(struct bridge_state *bst)
  143. {
  144. int ret;
  145. if (bst->active)
  146. return 0;
  147. ret = system_bridge_addbr(&bst->dev, &bst->config);
  148. if (ret < 0)
  149. return ret;
  150. bst->active = true;
  151. return 0;
  152. }
  153. static void
  154. bridge_disable_interface(struct bridge_state *bst)
  155. {
  156. if (!bst->active)
  157. return;
  158. system_bridge_delbr(&bst->dev);
  159. bst->active = false;
  160. }
  161. static int
  162. bridge_enable_member(struct bridge_member *bm)
  163. {
  164. struct bridge_state *bst = bm->bst;
  165. int ret;
  166. if (!bm->present)
  167. return 0;
  168. ret = bridge_enable_interface(bst);
  169. if (ret)
  170. goto error;
  171. /* Disable IPv6 for bridge members */
  172. if (!(bm->dev.dev->settings.flags & DEV_OPT_IPV6)) {
  173. bm->dev.dev->settings.ipv6 = 0;
  174. bm->dev.dev->settings.flags |= DEV_OPT_IPV6;
  175. }
  176. ret = device_claim(&bm->dev);
  177. if (ret < 0)
  178. goto error;
  179. ret = system_bridge_addif(&bst->dev, bm->dev.dev);
  180. if (ret < 0) {
  181. D(DEVICE, "Bridge device %s could not be added\n", bm->dev.dev->ifname);
  182. goto error;
  183. }
  184. device_set_present(&bst->dev, true);
  185. device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
  186. return 0;
  187. error:
  188. bst->n_failed++;
  189. bm->present = false;
  190. bst->n_present--;
  191. device_release(&bm->dev);
  192. return ret;
  193. }
  194. static void
  195. bridge_remove_member(struct bridge_member *bm)
  196. {
  197. struct bridge_state *bst = bm->bst;
  198. if (!bm->present)
  199. return;
  200. if (bst->dev.active)
  201. bridge_disable_member(bm);
  202. bm->present = false;
  203. bm->bst->n_present--;
  204. if (bm == bst->primary_port)
  205. bridge_reset_primary(bst);
  206. if (bst->config.bridge_empty)
  207. return;
  208. bst->force_active = false;
  209. if (bst->n_present == 0)
  210. device_set_present(&bst->dev, false);
  211. }
  212. static void
  213. bridge_free_member(struct bridge_member *bm)
  214. {
  215. struct device *dev = bm->dev.dev;
  216. bridge_remove_member(bm);
  217. device_remove_user(&bm->dev);
  218. /*
  219. * When reloading the config and moving a device from one bridge to
  220. * another, the other bridge may have tried to claim this device
  221. * before it was removed here.
  222. * Ensure that claiming the device is retried by toggling its present
  223. * state
  224. */
  225. if (dev->present) {
  226. device_set_present(dev, false);
  227. device_set_present(dev, true);
  228. }
  229. free(bm);
  230. }
  231. static void
  232. bridge_check_retry(struct bridge_state *bst)
  233. {
  234. if (!bst->n_failed)
  235. return;
  236. uloop_timeout_set(&bst->retry, 100);
  237. }
  238. static void
  239. bridge_member_cb(struct device_user *dev, enum device_event ev)
  240. {
  241. struct bridge_member *bm = container_of(dev, struct bridge_member, dev);
  242. struct bridge_state *bst = bm->bst;
  243. switch (ev) {
  244. case DEV_EVENT_ADD:
  245. assert(!bm->present);
  246. bm->present = true;
  247. bst->n_present++;
  248. if (bst->n_present == 1)
  249. device_set_present(&bst->dev, true);
  250. if (bst->dev.active && !bridge_enable_member(bm)) {
  251. /*
  252. * Adding a bridge member can overwrite the bridge mtu
  253. * in the kernel, apply the bridge settings in case the
  254. * bridge mtu is set
  255. */
  256. system_if_apply_settings(&bst->dev, &bst->dev.settings,
  257. DEV_OPT_MTU | DEV_OPT_MTU6);
  258. }
  259. break;
  260. case DEV_EVENT_REMOVE:
  261. if (dev->hotplug) {
  262. vlist_delete(&bst->members, &bm->node);
  263. return;
  264. }
  265. if (bm->present)
  266. bridge_remove_member(bm);
  267. break;
  268. default:
  269. return;
  270. }
  271. }
  272. static int
  273. bridge_set_down(struct bridge_state *bst)
  274. {
  275. struct bridge_member *bm;
  276. bst->set_state(&bst->dev, false);
  277. vlist_for_each_element(&bst->members, bm, node)
  278. bridge_disable_member(bm);
  279. bridge_disable_interface(bst);
  280. return 0;
  281. }
  282. static int
  283. bridge_set_up(struct bridge_state *bst)
  284. {
  285. struct bridge_member *bm;
  286. int ret;
  287. if (!bst->n_present) {
  288. if (!bst->force_active)
  289. return -ENOENT;
  290. ret = bridge_enable_interface(bst);
  291. if (ret)
  292. return ret;
  293. }
  294. bst->n_failed = 0;
  295. vlist_for_each_element(&bst->members, bm, node)
  296. bridge_enable_member(bm);
  297. bridge_check_retry(bst);
  298. if (!bst->force_active && !bst->n_present) {
  299. /* initialization of all member interfaces failed */
  300. bridge_disable_interface(bst);
  301. device_set_present(&bst->dev, false);
  302. return -ENOENT;
  303. }
  304. bridge_reset_primary(bst);
  305. ret = bst->set_state(&bst->dev, true);
  306. if (ret < 0)
  307. bridge_set_down(bst);
  308. return ret;
  309. }
  310. static int
  311. bridge_set_state(struct device *dev, bool up)
  312. {
  313. struct bridge_state *bst;
  314. bst = container_of(dev, struct bridge_state, dev);
  315. if (up)
  316. return bridge_set_up(bst);
  317. else
  318. return bridge_set_down(bst);
  319. }
  320. static struct bridge_member *
  321. bridge_create_member(struct bridge_state *bst, const char *name,
  322. struct device *dev, bool hotplug)
  323. {
  324. struct bridge_member *bm;
  325. bm = calloc(1, sizeof(*bm) + strlen(name) + 1);
  326. if (!bm)
  327. return NULL;
  328. bm->bst = bst;
  329. bm->dev.cb = bridge_member_cb;
  330. bm->dev.hotplug = hotplug;
  331. strcpy(bm->name, name);
  332. bm->dev.dev = dev;
  333. vlist_add(&bst->members, &bm->node, bm->name);
  334. /*
  335. * Need to look up the bridge member again as the above
  336. * created pointer will be freed in case the bridge member
  337. * already existed
  338. */
  339. bm = vlist_find(&bst->members, name, bm, node);
  340. if (hotplug && bm)
  341. bm->node.version = -1;
  342. return bm;
  343. }
  344. static void
  345. bridge_member_update(struct vlist_tree *tree, struct vlist_node *node_new,
  346. struct vlist_node *node_old)
  347. {
  348. struct bridge_member *bm;
  349. struct device *dev;
  350. if (node_new) {
  351. bm = container_of(node_new, struct bridge_member, node);
  352. if (node_old) {
  353. free(bm);
  354. return;
  355. }
  356. dev = bm->dev.dev;
  357. bm->dev.dev = NULL;
  358. device_add_user(&bm->dev, dev);
  359. }
  360. if (node_old) {
  361. bm = container_of(node_old, struct bridge_member, node);
  362. bridge_free_member(bm);
  363. }
  364. }
  365. static void
  366. bridge_add_member(struct bridge_state *bst, const char *name)
  367. {
  368. struct device *dev;
  369. dev = device_get(name, true);
  370. if (!dev)
  371. return;
  372. bridge_create_member(bst, name, dev, false);
  373. }
  374. static int
  375. bridge_hotplug_add(struct device *dev, struct device *member)
  376. {
  377. struct bridge_state *bst = container_of(dev, struct bridge_state, dev);
  378. bridge_create_member(bst, member->ifname, member, true);
  379. return 0;
  380. }
  381. static int
  382. bridge_hotplug_del(struct device *dev, struct device *member)
  383. {
  384. struct bridge_state *bst = container_of(dev, struct bridge_state, dev);
  385. struct bridge_member *bm;
  386. bm = vlist_find(&bst->members, member->ifname, bm, node);
  387. if (!bm)
  388. return UBUS_STATUS_NOT_FOUND;
  389. vlist_delete(&bst->members, &bm->node);
  390. return 0;
  391. }
  392. static int
  393. bridge_hotplug_prepare(struct device *dev)
  394. {
  395. struct bridge_state *bst;
  396. bst = container_of(dev, struct bridge_state, dev);
  397. bst->force_active = true;
  398. device_set_present(&bst->dev, true);
  399. return 0;
  400. }
  401. static const struct device_hotplug_ops bridge_ops = {
  402. .prepare = bridge_hotplug_prepare,
  403. .add = bridge_hotplug_add,
  404. .del = bridge_hotplug_del
  405. };
  406. static void
  407. bridge_free(struct device *dev)
  408. {
  409. struct bridge_state *bst;
  410. bst = container_of(dev, struct bridge_state, dev);
  411. vlist_flush_all(&bst->members);
  412. free(bst->config_data);
  413. free(bst);
  414. }
  415. static void
  416. bridge_dump_info(struct device *dev, struct blob_buf *b)
  417. {
  418. struct bridge_state *bst;
  419. struct bridge_member *bm;
  420. void *list;
  421. bst = container_of(dev, struct bridge_state, dev);
  422. system_if_dump_info(dev, b);
  423. list = blobmsg_open_array(b, "bridge-members");
  424. vlist_for_each_element(&bst->members, bm, node) {
  425. if (bm->dev.dev->hidden)
  426. continue;
  427. blobmsg_add_string(b, NULL, bm->dev.dev->ifname);
  428. }
  429. blobmsg_close_array(b, list);
  430. }
  431. static void
  432. bridge_config_init(struct device *dev)
  433. {
  434. struct bridge_state *bst;
  435. struct blob_attr *cur;
  436. int rem;
  437. bst = container_of(dev, struct bridge_state, dev);
  438. if (bst->config.bridge_empty) {
  439. bst->force_active = true;
  440. device_set_present(&bst->dev, true);
  441. }
  442. bst->n_failed = 0;
  443. vlist_update(&bst->members);
  444. if (bst->ifnames) {
  445. blobmsg_for_each_attr(cur, bst->ifnames, rem) {
  446. bridge_add_member(bst, blobmsg_data(cur));
  447. }
  448. }
  449. vlist_flush(&bst->members);
  450. bridge_check_retry(bst);
  451. }
  452. static void
  453. bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb)
  454. {
  455. struct bridge_config *cfg = &bst->config;
  456. struct blob_attr *cur;
  457. /* defaults */
  458. cfg->stp = false;
  459. cfg->forward_delay = 2;
  460. cfg->robustness = 2;
  461. cfg->query_interval = 12500;
  462. cfg->query_response_interval = 1000;
  463. cfg->last_member_interval = 100;
  464. cfg->hash_max = 512;
  465. cfg->bridge_empty = false;
  466. cfg->priority = 0x7FFF;
  467. if ((cur = tb[BRIDGE_ATTR_STP]))
  468. cfg->stp = blobmsg_get_bool(cur);
  469. if ((cur = tb[BRIDGE_ATTR_FORWARD_DELAY]))
  470. cfg->forward_delay = blobmsg_get_u32(cur);
  471. if ((cur = tb[BRIDGE_ATTR_PRIORITY]))
  472. cfg->priority = blobmsg_get_u32(cur);
  473. if ((cur = tb[BRIDGE_ATTR_IGMP_SNOOP]))
  474. cfg->multicast_querier = cfg->igmp_snoop = blobmsg_get_bool(cur);
  475. if ((cur = tb[BRIDGE_ATTR_MULTICAST_QUERIER]))
  476. cfg->multicast_querier = blobmsg_get_bool(cur);
  477. if ((cur = tb[BRIDGE_ATTR_HASH_MAX]))
  478. cfg->hash_max = blobmsg_get_u32(cur);
  479. if ((cur = tb[BRIDGE_ATTR_ROBUSTNESS])) {
  480. cfg->robustness = blobmsg_get_u32(cur);
  481. cfg->flags |= BRIDGE_OPT_ROBUSTNESS;
  482. }
  483. if ((cur = tb[BRIDGE_ATTR_QUERY_INTERVAL])) {
  484. cfg->query_interval = blobmsg_get_u32(cur);
  485. cfg->flags |= BRIDGE_OPT_QUERY_INTERVAL;
  486. }
  487. if ((cur = tb[BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL])) {
  488. cfg->query_response_interval = blobmsg_get_u32(cur);
  489. cfg->flags |= BRIDGE_OPT_QUERY_RESPONSE_INTERVAL;
  490. }
  491. if ((cur = tb[BRIDGE_ATTR_LAST_MEMBER_INTERVAL])) {
  492. cfg->last_member_interval = blobmsg_get_u32(cur);
  493. cfg->flags |= BRIDGE_OPT_LAST_MEMBER_INTERVAL;
  494. }
  495. if ((cur = tb[BRIDGE_ATTR_AGEING_TIME])) {
  496. cfg->ageing_time = blobmsg_get_u32(cur);
  497. cfg->flags |= BRIDGE_OPT_AGEING_TIME;
  498. }
  499. if ((cur = tb[BRIDGE_ATTR_HELLO_TIME])) {
  500. cfg->hello_time = blobmsg_get_u32(cur);
  501. cfg->flags |= BRIDGE_OPT_HELLO_TIME;
  502. }
  503. if ((cur = tb[BRIDGE_ATTR_MAX_AGE])) {
  504. cfg->max_age = blobmsg_get_u32(cur);
  505. cfg->flags |= BRIDGE_OPT_MAX_AGE;
  506. }
  507. if ((cur = tb[BRIDGE_ATTR_BRIDGE_EMPTY]))
  508. cfg->bridge_empty = blobmsg_get_bool(cur);
  509. }
  510. static enum dev_change_type
  511. bridge_reload(struct device *dev, struct blob_attr *attr)
  512. {
  513. struct blob_attr *tb_dev[__DEV_ATTR_MAX];
  514. struct blob_attr *tb_br[__BRIDGE_ATTR_MAX];
  515. enum dev_change_type ret = DEV_CONFIG_APPLIED;
  516. unsigned long diff;
  517. struct bridge_state *bst;
  518. BUILD_BUG_ON(sizeof(diff) < __BRIDGE_ATTR_MAX / 8);
  519. BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / 8);
  520. bst = container_of(dev, struct bridge_state, dev);
  521. attr = blob_memdup(attr);
  522. blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev,
  523. blob_data(attr), blob_len(attr));
  524. blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, tb_br,
  525. blob_data(attr), blob_len(attr));
  526. if (tb_dev[DEV_ATTR_MACADDR])
  527. bst->primary_port = NULL;
  528. bst->ifnames = tb_br[BRIDGE_ATTR_IFNAME];
  529. device_init_settings(dev, tb_dev);
  530. bridge_apply_settings(bst, tb_br);
  531. if (bst->config_data) {
  532. struct blob_attr *otb_dev[__DEV_ATTR_MAX];
  533. struct blob_attr *otb_br[__BRIDGE_ATTR_MAX];
  534. blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev,
  535. blob_data(bst->config_data), blob_len(bst->config_data));
  536. diff = 0;
  537. uci_blob_diff(tb_dev, otb_dev, &device_attr_list, &diff);
  538. if (diff)
  539. ret = DEV_CONFIG_RESTART;
  540. blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, otb_br,
  541. blob_data(bst->config_data), blob_len(bst->config_data));
  542. diff = 0;
  543. uci_blob_diff(tb_br, otb_br, &bridge_attr_list, &diff);
  544. if (diff & ~(1 << BRIDGE_ATTR_IFNAME))
  545. ret = DEV_CONFIG_RESTART;
  546. bridge_config_init(dev);
  547. }
  548. free(bst->config_data);
  549. bst->config_data = attr;
  550. return ret;
  551. }
  552. static void
  553. bridge_retry_members(struct uloop_timeout *timeout)
  554. {
  555. struct bridge_state *bst = container_of(timeout, struct bridge_state, retry);
  556. struct bridge_member *bm;
  557. bst->n_failed = 0;
  558. vlist_for_each_element(&bst->members, bm, node) {
  559. if (bm->present)
  560. continue;
  561. if (!bm->dev.dev->present)
  562. continue;
  563. bm->present = true;
  564. bst->n_present++;
  565. bridge_enable_member(bm);
  566. }
  567. }
  568. static struct device *
  569. bridge_create(const char *name, struct device_type *devtype,
  570. struct blob_attr *attr)
  571. {
  572. struct bridge_state *bst;
  573. struct device *dev = NULL;
  574. bst = calloc(1, sizeof(*bst));
  575. if (!bst)
  576. return NULL;
  577. dev = &bst->dev;
  578. if (device_init(dev, devtype, name) < 0) {
  579. device_cleanup(dev);
  580. free(bst);
  581. return NULL;
  582. }
  583. dev->config_pending = true;
  584. bst->retry.cb = bridge_retry_members;
  585. bst->set_state = dev->set_state;
  586. dev->set_state = bridge_set_state;
  587. dev->hotplug_ops = &bridge_ops;
  588. vlist_init(&bst->members, avl_strcmp, bridge_member_update);
  589. bst->members.keep_old = true;
  590. bridge_reload(dev, attr);
  591. return dev;
  592. }
  593. static void __init bridge_device_type_init(void)
  594. {
  595. device_type_add(&bridge_device_type);
  596. }