br_vlan_options.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright (c) 2020, Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
  3. #include <linux/kernel.h>
  4. #include <linux/netdevice.h>
  5. #include <linux/rtnetlink.h>
  6. #include <linux/slab.h>
  7. #include <net/ip_tunnels.h>
  8. #include "br_private.h"
  9. #include "br_private_tunnel.h"
  10. static bool __vlan_tun_put(struct sk_buff *skb, const struct net_bridge_vlan *v)
  11. {
  12. __be32 tid = tunnel_id_to_key32(v->tinfo.tunnel_id);
  13. struct nlattr *nest;
  14. if (!v->tinfo.tunnel_dst)
  15. return true;
  16. nest = nla_nest_start(skb, BRIDGE_VLANDB_ENTRY_TUNNEL_INFO);
  17. if (!nest)
  18. return false;
  19. if (nla_put_u32(skb, BRIDGE_VLANDB_TINFO_ID, be32_to_cpu(tid))) {
  20. nla_nest_cancel(skb, nest);
  21. return false;
  22. }
  23. nla_nest_end(skb, nest);
  24. return true;
  25. }
  26. static bool __vlan_tun_can_enter_range(const struct net_bridge_vlan *v_curr,
  27. const struct net_bridge_vlan *range_end)
  28. {
  29. return (!v_curr->tinfo.tunnel_dst && !range_end->tinfo.tunnel_dst) ||
  30. vlan_tunid_inrange(v_curr, range_end);
  31. }
  32. /* check if the options' state of v_curr allow it to enter the range */
  33. bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr,
  34. const struct net_bridge_vlan *range_end)
  35. {
  36. u8 range_mc_rtr = br_vlan_multicast_router(range_end);
  37. u8 curr_mc_rtr = br_vlan_multicast_router(v_curr);
  38. return v_curr->state == range_end->state &&
  39. __vlan_tun_can_enter_range(v_curr, range_end) &&
  40. curr_mc_rtr == range_mc_rtr;
  41. }
  42. bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v,
  43. const struct net_bridge_port *p)
  44. {
  45. if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_STATE, br_vlan_get_state(v)) ||
  46. !__vlan_tun_put(skb, v) ||
  47. nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS,
  48. !!(v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED)))
  49. return false;
  50. #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
  51. if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
  52. br_vlan_multicast_router(v)))
  53. return false;
  54. if (p && !br_multicast_port_ctx_vlan_disabled(&v->port_mcast_ctx) &&
  55. (nla_put_u32(skb, BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS,
  56. br_multicast_ngroups_get(&v->port_mcast_ctx)) ||
  57. nla_put_u32(skb, BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS,
  58. br_multicast_ngroups_get_max(&v->port_mcast_ctx))))
  59. return false;
  60. #endif
  61. return true;
  62. }
  63. size_t br_vlan_opts_nl_size(void)
  64. {
  65. return nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_STATE */
  66. + nla_total_size(0) /* BRIDGE_VLANDB_ENTRY_TUNNEL_INFO */
  67. + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_TINFO_ID */
  68. #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
  69. + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_MCAST_ROUTER */
  70. + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS */
  71. + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS */
  72. #endif
  73. + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS */
  74. + 0;
  75. }
  76. static int br_vlan_modify_state(struct net_bridge_vlan_group *vg,
  77. struct net_bridge_vlan *v,
  78. u8 state,
  79. bool *changed,
  80. struct netlink_ext_ack *extack)
  81. {
  82. struct net_bridge *br;
  83. ASSERT_RTNL();
  84. if (state > BR_STATE_BLOCKING) {
  85. NL_SET_ERR_MSG_MOD(extack, "Invalid vlan state");
  86. return -EINVAL;
  87. }
  88. if (br_vlan_is_brentry(v))
  89. br = v->br;
  90. else
  91. br = v->port->br;
  92. if (br->stp_enabled == BR_KERNEL_STP) {
  93. NL_SET_ERR_MSG_MOD(extack, "Can't modify vlan state when using kernel STP");
  94. return -EBUSY;
  95. }
  96. if (br_opt_get(br, BROPT_MST_ENABLED)) {
  97. NL_SET_ERR_MSG_MOD(extack, "Can't modify vlan state directly when MST is enabled");
  98. return -EBUSY;
  99. }
  100. if (v->state == state)
  101. return 0;
  102. if (v->vid == br_get_pvid(vg))
  103. br_vlan_set_pvid_state(vg, state);
  104. br_vlan_set_state(v, state);
  105. *changed = true;
  106. return 0;
  107. }
  108. static const struct nla_policy br_vlandb_tinfo_pol[BRIDGE_VLANDB_TINFO_MAX + 1] = {
  109. [BRIDGE_VLANDB_TINFO_ID] = { .type = NLA_U32 },
  110. [BRIDGE_VLANDB_TINFO_CMD] = { .type = NLA_U32 },
  111. };
  112. static int br_vlan_modify_tunnel(const struct net_bridge_port *p,
  113. struct net_bridge_vlan *v,
  114. struct nlattr **tb,
  115. bool *changed,
  116. struct netlink_ext_ack *extack)
  117. {
  118. struct nlattr *tun_tb[BRIDGE_VLANDB_TINFO_MAX + 1], *attr;
  119. struct bridge_vlan_info *vinfo;
  120. u32 tun_id = 0;
  121. int cmd, err;
  122. if (!p) {
  123. NL_SET_ERR_MSG_MOD(extack, "Can't modify tunnel mapping of non-port vlans");
  124. return -EINVAL;
  125. }
  126. if (!(p->flags & BR_VLAN_TUNNEL)) {
  127. NL_SET_ERR_MSG_MOD(extack, "Port doesn't have tunnel flag set");
  128. return -EINVAL;
  129. }
  130. attr = tb[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO];
  131. err = nla_parse_nested(tun_tb, BRIDGE_VLANDB_TINFO_MAX, attr,
  132. br_vlandb_tinfo_pol, extack);
  133. if (err)
  134. return err;
  135. if (!tun_tb[BRIDGE_VLANDB_TINFO_CMD]) {
  136. NL_SET_ERR_MSG_MOD(extack, "Missing tunnel command attribute");
  137. return -ENOENT;
  138. }
  139. cmd = nla_get_u32(tun_tb[BRIDGE_VLANDB_TINFO_CMD]);
  140. switch (cmd) {
  141. case RTM_SETLINK:
  142. if (!tun_tb[BRIDGE_VLANDB_TINFO_ID]) {
  143. NL_SET_ERR_MSG_MOD(extack, "Missing tunnel id attribute");
  144. return -ENOENT;
  145. }
  146. /* when working on vlan ranges this is the starting tunnel id */
  147. tun_id = nla_get_u32(tun_tb[BRIDGE_VLANDB_TINFO_ID]);
  148. /* vlan info attr is guaranteed by br_vlan_rtm_process_one */
  149. vinfo = nla_data(tb[BRIDGE_VLANDB_ENTRY_INFO]);
  150. /* tunnel ids are mapped to each vlan in increasing order,
  151. * the starting vlan is in BRIDGE_VLANDB_ENTRY_INFO and v is the
  152. * current vlan, so we compute: tun_id + v - vinfo->vid
  153. */
  154. tun_id += v->vid - vinfo->vid;
  155. break;
  156. case RTM_DELLINK:
  157. break;
  158. default:
  159. NL_SET_ERR_MSG_MOD(extack, "Unsupported tunnel command");
  160. return -EINVAL;
  161. }
  162. return br_vlan_tunnel_info(p, cmd, v->vid, tun_id, changed);
  163. }
  164. static int br_vlan_process_one_opts(const struct net_bridge *br,
  165. const struct net_bridge_port *p,
  166. struct net_bridge_vlan_group *vg,
  167. struct net_bridge_vlan *v,
  168. struct nlattr **tb,
  169. bool *changed,
  170. struct netlink_ext_ack *extack)
  171. {
  172. int err;
  173. *changed = false;
  174. if (tb[BRIDGE_VLANDB_ENTRY_STATE]) {
  175. u8 state = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_STATE]);
  176. err = br_vlan_modify_state(vg, v, state, changed, extack);
  177. if (err)
  178. return err;
  179. }
  180. if (tb[BRIDGE_VLANDB_ENTRY_TUNNEL_INFO]) {
  181. err = br_vlan_modify_tunnel(p, v, tb, changed, extack);
  182. if (err)
  183. return err;
  184. }
  185. #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
  186. if (tb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]) {
  187. u8 val;
  188. val = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]);
  189. err = br_multicast_set_vlan_router(v, val);
  190. if (err)
  191. return err;
  192. *changed = true;
  193. }
  194. if (tb[BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS]) {
  195. u32 val;
  196. if (!p) {
  197. NL_SET_ERR_MSG_MOD(extack, "Can't set mcast_max_groups for non-port vlans");
  198. return -EINVAL;
  199. }
  200. if (br_multicast_port_ctx_vlan_disabled(&v->port_mcast_ctx)) {
  201. NL_SET_ERR_MSG_MOD(extack, "Multicast snooping disabled on this VLAN");
  202. return -EINVAL;
  203. }
  204. val = nla_get_u32(tb[BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS]);
  205. br_multicast_ngroups_set_max(&v->port_mcast_ctx, val);
  206. *changed = true;
  207. }
  208. #endif
  209. if (tb[BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS]) {
  210. bool enabled = v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED;
  211. bool val = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS]);
  212. if (!p) {
  213. NL_SET_ERR_MSG_MOD(extack, "Can't set neigh_suppress for non-port vlans");
  214. return -EINVAL;
  215. }
  216. if (val != enabled) {
  217. v->priv_flags ^= BR_VLFLAG_NEIGH_SUPPRESS_ENABLED;
  218. *changed = true;
  219. }
  220. }
  221. return 0;
  222. }
  223. int br_vlan_process_options(const struct net_bridge *br,
  224. const struct net_bridge_port *p,
  225. struct net_bridge_vlan *range_start,
  226. struct net_bridge_vlan *range_end,
  227. struct nlattr **tb,
  228. struct netlink_ext_ack *extack)
  229. {
  230. struct net_bridge_vlan *v, *curr_start = NULL, *curr_end = NULL;
  231. struct net_bridge_vlan_group *vg;
  232. int vid, err = 0;
  233. u16 pvid;
  234. if (p)
  235. vg = nbp_vlan_group(p);
  236. else
  237. vg = br_vlan_group(br);
  238. if (!range_start || !br_vlan_should_use(range_start)) {
  239. NL_SET_ERR_MSG_MOD(extack, "Vlan range start doesn't exist, can't process options");
  240. return -ENOENT;
  241. }
  242. if (!range_end || !br_vlan_should_use(range_end)) {
  243. NL_SET_ERR_MSG_MOD(extack, "Vlan range end doesn't exist, can't process options");
  244. return -ENOENT;
  245. }
  246. pvid = br_get_pvid(vg);
  247. for (vid = range_start->vid; vid <= range_end->vid; vid++) {
  248. bool changed = false;
  249. v = br_vlan_find(vg, vid);
  250. if (!v || !br_vlan_should_use(v)) {
  251. NL_SET_ERR_MSG_MOD(extack, "Vlan in range doesn't exist, can't process options");
  252. err = -ENOENT;
  253. break;
  254. }
  255. err = br_vlan_process_one_opts(br, p, vg, v, tb, &changed,
  256. extack);
  257. if (err)
  258. break;
  259. if (changed) {
  260. /* vlan options changed, check for range */
  261. if (!curr_start) {
  262. curr_start = v;
  263. curr_end = v;
  264. continue;
  265. }
  266. if (v->vid == pvid ||
  267. !br_vlan_can_enter_range(v, curr_end)) {
  268. br_vlan_notify(br, p, curr_start->vid,
  269. curr_end->vid, RTM_NEWVLAN);
  270. curr_start = v;
  271. }
  272. curr_end = v;
  273. } else {
  274. /* nothing changed and nothing to notify yet */
  275. if (!curr_start)
  276. continue;
  277. br_vlan_notify(br, p, curr_start->vid, curr_end->vid,
  278. RTM_NEWVLAN);
  279. curr_start = NULL;
  280. curr_end = NULL;
  281. }
  282. }
  283. if (curr_start)
  284. br_vlan_notify(br, p, curr_start->vid, curr_end->vid,
  285. RTM_NEWVLAN);
  286. return err;
  287. }
  288. bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
  289. const struct net_bridge_vlan *r_end)
  290. {
  291. return v_curr->vid - r_end->vid == 1 &&
  292. v_curr->msti == r_end->msti &&
  293. ((v_curr->priv_flags ^ r_end->priv_flags) &
  294. BR_VLFLAG_GLOBAL_MCAST_ENABLED) == 0 &&
  295. br_multicast_ctx_options_equal(&v_curr->br_mcast_ctx,
  296. &r_end->br_mcast_ctx);
  297. }
  298. bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
  299. const struct net_bridge_vlan *v_opts)
  300. {
  301. struct nlattr *nest2 __maybe_unused;
  302. u64 clockval __maybe_unused;
  303. struct nlattr *nest;
  304. nest = nla_nest_start(skb, BRIDGE_VLANDB_GLOBAL_OPTIONS);
  305. if (!nest)
  306. return false;
  307. if (nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_ID, vid))
  308. goto out_err;
  309. if (vid_range && vid < vid_range &&
  310. nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_RANGE, vid_range))
  311. goto out_err;
  312. #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
  313. if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING,
  314. !!(v_opts->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED)) ||
  315. nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION,
  316. v_opts->br_mcast_ctx.multicast_igmp_version) ||
  317. nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
  318. v_opts->br_mcast_ctx.multicast_last_member_count) ||
  319. nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
  320. v_opts->br_mcast_ctx.multicast_startup_query_count) ||
  321. nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
  322. v_opts->br_mcast_ctx.multicast_querier) ||
  323. br_multicast_dump_querier_state(skb, &v_opts->br_mcast_ctx,
  324. BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE))
  325. goto out_err;
  326. clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_last_member_interval);
  327. if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL,
  328. clockval, BRIDGE_VLANDB_GOPTS_PAD))
  329. goto out_err;
  330. clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_membership_interval);
  331. if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL,
  332. clockval, BRIDGE_VLANDB_GOPTS_PAD))
  333. goto out_err;
  334. clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_querier_interval);
  335. if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL,
  336. clockval, BRIDGE_VLANDB_GOPTS_PAD))
  337. goto out_err;
  338. clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_query_interval);
  339. if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
  340. clockval, BRIDGE_VLANDB_GOPTS_PAD))
  341. goto out_err;
  342. clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_query_response_interval);
  343. if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
  344. clockval, BRIDGE_VLANDB_GOPTS_PAD))
  345. goto out_err;
  346. clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_startup_query_interval);
  347. if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
  348. clockval, BRIDGE_VLANDB_GOPTS_PAD))
  349. goto out_err;
  350. if (br_rports_have_mc_router(&v_opts->br_mcast_ctx)) {
  351. nest2 = nla_nest_start(skb,
  352. BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS);
  353. if (!nest2)
  354. goto out_err;
  355. rcu_read_lock();
  356. if (br_rports_fill_info(skb, &v_opts->br_mcast_ctx)) {
  357. rcu_read_unlock();
  358. nla_nest_cancel(skb, nest2);
  359. goto out_err;
  360. }
  361. rcu_read_unlock();
  362. nla_nest_end(skb, nest2);
  363. }
  364. #if IS_ENABLED(CONFIG_IPV6)
  365. if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION,
  366. v_opts->br_mcast_ctx.multicast_mld_version))
  367. goto out_err;
  368. #endif
  369. #endif
  370. if (nla_put_u16(skb, BRIDGE_VLANDB_GOPTS_MSTI, v_opts->msti))
  371. goto out_err;
  372. nla_nest_end(skb, nest);
  373. return true;
  374. out_err:
  375. nla_nest_cancel(skb, nest);
  376. return false;
  377. }
  378. static size_t rtnl_vlan_global_opts_nlmsg_size(const struct net_bridge_vlan *v)
  379. {
  380. return NLMSG_ALIGN(sizeof(struct br_vlan_msg))
  381. + nla_total_size(0) /* BRIDGE_VLANDB_GLOBAL_OPTIONS */
  382. + nla_total_size(sizeof(u16)) /* BRIDGE_VLANDB_GOPTS_ID */
  383. #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
  384. + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING */
  385. + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION */
  386. + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION */
  387. + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT */
  388. + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT */
  389. + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL */
  390. + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL */
  391. + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL */
  392. + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL */
  393. + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL */
  394. + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL */
  395. + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER */
  396. + br_multicast_querier_state_size() /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE */
  397. + nla_total_size(0) /* BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS */
  398. + br_rports_size(&v->br_mcast_ctx) /* BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS */
  399. #endif
  400. + nla_total_size(sizeof(u16)) /* BRIDGE_VLANDB_GOPTS_MSTI */
  401. + nla_total_size(sizeof(u16)); /* BRIDGE_VLANDB_GOPTS_RANGE */
  402. }
  403. static void br_vlan_global_opts_notify(const struct net_bridge *br,
  404. u16 vid, u16 vid_range)
  405. {
  406. struct net_bridge_vlan *v;
  407. struct br_vlan_msg *bvm;
  408. struct nlmsghdr *nlh;
  409. struct sk_buff *skb;
  410. int err = -ENOBUFS;
  411. /* right now notifications are done only with rtnl held */
  412. ASSERT_RTNL();
  413. /* need to find the vlan due to flags/options */
  414. v = br_vlan_find(br_vlan_group(br), vid);
  415. if (!v)
  416. return;
  417. skb = nlmsg_new(rtnl_vlan_global_opts_nlmsg_size(v), GFP_KERNEL);
  418. if (!skb)
  419. goto out_err;
  420. err = -EMSGSIZE;
  421. nlh = nlmsg_put(skb, 0, 0, RTM_NEWVLAN, sizeof(*bvm), 0);
  422. if (!nlh)
  423. goto out_err;
  424. bvm = nlmsg_data(nlh);
  425. memset(bvm, 0, sizeof(*bvm));
  426. bvm->family = AF_BRIDGE;
  427. bvm->ifindex = br->dev->ifindex;
  428. if (!br_vlan_global_opts_fill(skb, vid, vid_range, v))
  429. goto out_err;
  430. nlmsg_end(skb, nlh);
  431. rtnl_notify(skb, dev_net(br->dev), 0, RTNLGRP_BRVLAN, NULL, GFP_KERNEL);
  432. return;
  433. out_err:
  434. rtnl_set_sk_err(dev_net(br->dev), RTNLGRP_BRVLAN, err);
  435. kfree_skb(skb);
  436. }
  437. static int br_vlan_process_global_one_opts(const struct net_bridge *br,
  438. struct net_bridge_vlan_group *vg,
  439. struct net_bridge_vlan *v,
  440. struct nlattr **tb,
  441. bool *changed,
  442. struct netlink_ext_ack *extack)
  443. {
  444. int err __maybe_unused;
  445. *changed = false;
  446. #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
  447. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]) {
  448. u8 mc_snooping;
  449. mc_snooping = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]);
  450. if (br_multicast_toggle_global_vlan(v, !!mc_snooping))
  451. *changed = true;
  452. }
  453. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]) {
  454. u8 ver;
  455. ver = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]);
  456. err = br_multicast_set_igmp_version(&v->br_mcast_ctx, ver);
  457. if (err)
  458. return err;
  459. *changed = true;
  460. }
  461. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]) {
  462. u32 cnt;
  463. cnt = nla_get_u32(tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]);
  464. v->br_mcast_ctx.multicast_last_member_count = cnt;
  465. *changed = true;
  466. }
  467. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]) {
  468. u32 cnt;
  469. cnt = nla_get_u32(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]);
  470. v->br_mcast_ctx.multicast_startup_query_count = cnt;
  471. *changed = true;
  472. }
  473. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]) {
  474. u64 val;
  475. val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]);
  476. v->br_mcast_ctx.multicast_last_member_interval = clock_t_to_jiffies(val);
  477. *changed = true;
  478. }
  479. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]) {
  480. u64 val;
  481. val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]);
  482. v->br_mcast_ctx.multicast_membership_interval = clock_t_to_jiffies(val);
  483. *changed = true;
  484. }
  485. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]) {
  486. u64 val;
  487. val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]);
  488. v->br_mcast_ctx.multicast_querier_interval = clock_t_to_jiffies(val);
  489. *changed = true;
  490. }
  491. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]) {
  492. u64 val;
  493. val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL]);
  494. br_multicast_set_query_intvl(&v->br_mcast_ctx, val);
  495. *changed = true;
  496. }
  497. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]) {
  498. u64 val;
  499. val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL]);
  500. v->br_mcast_ctx.multicast_query_response_interval = clock_t_to_jiffies(val);
  501. *changed = true;
  502. }
  503. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]) {
  504. u64 val;
  505. val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]);
  506. br_multicast_set_startup_query_intvl(&v->br_mcast_ctx, val);
  507. *changed = true;
  508. }
  509. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) {
  510. u8 val;
  511. val = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]);
  512. err = br_multicast_set_querier(&v->br_mcast_ctx, val);
  513. if (err)
  514. return err;
  515. *changed = true;
  516. }
  517. #if IS_ENABLED(CONFIG_IPV6)
  518. if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
  519. u8 ver;
  520. ver = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]);
  521. err = br_multicast_set_mld_version(&v->br_mcast_ctx, ver);
  522. if (err)
  523. return err;
  524. *changed = true;
  525. }
  526. #endif
  527. #endif
  528. if (tb[BRIDGE_VLANDB_GOPTS_MSTI]) {
  529. u16 msti;
  530. msti = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_MSTI]);
  531. err = br_mst_vlan_set_msti(v, msti);
  532. if (err)
  533. return err;
  534. *changed = true;
  535. }
  536. return 0;
  537. }
  538. static const struct nla_policy br_vlan_db_gpol[BRIDGE_VLANDB_GOPTS_MAX + 1] = {
  539. [BRIDGE_VLANDB_GOPTS_ID] = { .type = NLA_U16 },
  540. [BRIDGE_VLANDB_GOPTS_RANGE] = { .type = NLA_U16 },
  541. [BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING] = { .type = NLA_U8 },
  542. [BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION] = { .type = NLA_U8 },
  543. [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL] = { .type = NLA_U64 },
  544. [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER] = { .type = NLA_U8 },
  545. [BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION] = { .type = NLA_U8 },
  546. [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT] = { .type = NLA_U32 },
  547. [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT] = { .type = NLA_U32 },
  548. [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL] = { .type = NLA_U64 },
  549. [BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL] = { .type = NLA_U64 },
  550. [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL] = { .type = NLA_U64 },
  551. [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL] = { .type = NLA_U64 },
  552. [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL] = { .type = NLA_U64 },
  553. [BRIDGE_VLANDB_GOPTS_MSTI] = NLA_POLICY_MAX(NLA_U16, VLAN_N_VID - 1),
  554. };
  555. int br_vlan_rtm_process_global_options(struct net_device *dev,
  556. const struct nlattr *attr,
  557. int cmd,
  558. struct netlink_ext_ack *extack)
  559. {
  560. struct net_bridge_vlan *v, *curr_start = NULL, *curr_end = NULL;
  561. struct nlattr *tb[BRIDGE_VLANDB_GOPTS_MAX + 1];
  562. struct net_bridge_vlan_group *vg;
  563. u16 vid, vid_range = 0;
  564. struct net_bridge *br;
  565. int err = 0;
  566. if (cmd != RTM_NEWVLAN) {
  567. NL_SET_ERR_MSG_MOD(extack, "Global vlan options support only set operation");
  568. return -EINVAL;
  569. }
  570. if (!netif_is_bridge_master(dev)) {
  571. NL_SET_ERR_MSG_MOD(extack, "Global vlan options can only be set on bridge device");
  572. return -EINVAL;
  573. }
  574. br = netdev_priv(dev);
  575. vg = br_vlan_group(br);
  576. if (WARN_ON(!vg))
  577. return -ENODEV;
  578. err = nla_parse_nested(tb, BRIDGE_VLANDB_GOPTS_MAX, attr,
  579. br_vlan_db_gpol, extack);
  580. if (err)
  581. return err;
  582. if (!tb[BRIDGE_VLANDB_GOPTS_ID]) {
  583. NL_SET_ERR_MSG_MOD(extack, "Missing vlan entry id");
  584. return -EINVAL;
  585. }
  586. vid = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_ID]);
  587. if (!br_vlan_valid_id(vid, extack))
  588. return -EINVAL;
  589. if (tb[BRIDGE_VLANDB_GOPTS_RANGE]) {
  590. vid_range = nla_get_u16(tb[BRIDGE_VLANDB_GOPTS_RANGE]);
  591. if (!br_vlan_valid_id(vid_range, extack))
  592. return -EINVAL;
  593. if (vid >= vid_range) {
  594. NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id");
  595. return -EINVAL;
  596. }
  597. } else {
  598. vid_range = vid;
  599. }
  600. for (; vid <= vid_range; vid++) {
  601. bool changed = false;
  602. v = br_vlan_find(vg, vid);
  603. if (!v) {
  604. NL_SET_ERR_MSG_MOD(extack, "Vlan in range doesn't exist, can't process global options");
  605. err = -ENOENT;
  606. break;
  607. }
  608. err = br_vlan_process_global_one_opts(br, vg, v, tb, &changed,
  609. extack);
  610. if (err)
  611. break;
  612. if (changed) {
  613. /* vlan options changed, check for range */
  614. if (!curr_start) {
  615. curr_start = v;
  616. curr_end = v;
  617. continue;
  618. }
  619. if (!br_vlan_global_opts_can_enter_range(v, curr_end)) {
  620. br_vlan_global_opts_notify(br, curr_start->vid,
  621. curr_end->vid);
  622. curr_start = v;
  623. }
  624. curr_end = v;
  625. } else {
  626. /* nothing changed and nothing to notify yet */
  627. if (!curr_start)
  628. continue;
  629. br_vlan_global_opts_notify(br, curr_start->vid,
  630. curr_end->vid);
  631. curr_start = NULL;
  632. curr_end = NULL;
  633. }
  634. }
  635. if (curr_start)
  636. br_vlan_global_opts_notify(br, curr_start->vid, curr_end->vid);
  637. return err;
  638. }