mrp.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  1. /*
  2. * IEEE 802.1Q Multiple Registration Protocol (MRP)
  3. *
  4. * Copyright (c) 2012 Massachusetts Institute of Technology
  5. *
  6. * Adapted from code in net/802/garp.c
  7. * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * version 2 as published by the Free Software Foundation.
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/timer.h>
  15. #include <linux/skbuff.h>
  16. #include <linux/netdevice.h>
  17. #include <linux/etherdevice.h>
  18. #include <linux/rtnetlink.h>
  19. #include <linux/slab.h>
  20. #include <linux/module.h>
  21. #include <net/mrp.h>
  22. #include <asm/unaligned.h>
  23. static unsigned int mrp_join_time __read_mostly = 200;
  24. module_param(mrp_join_time, uint, 0644);
  25. MODULE_PARM_DESC(mrp_join_time, "Join time in ms (default 200ms)");
  26. static unsigned int mrp_periodic_time __read_mostly = 1000;
  27. module_param(mrp_periodic_time, uint, 0644);
  28. MODULE_PARM_DESC(mrp_periodic_time, "Periodic time in ms (default 1s)");
  29. MODULE_LICENSE("GPL");
  30. static const u8
  31. mrp_applicant_state_table[MRP_APPLICANT_MAX + 1][MRP_EVENT_MAX + 1] = {
  32. [MRP_APPLICANT_VO] = {
  33. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  34. [MRP_EVENT_JOIN] = MRP_APPLICANT_VP,
  35. [MRP_EVENT_LV] = MRP_APPLICANT_VO,
  36. [MRP_EVENT_TX] = MRP_APPLICANT_VO,
  37. [MRP_EVENT_R_NEW] = MRP_APPLICANT_VO,
  38. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_AO,
  39. [MRP_EVENT_R_IN] = MRP_APPLICANT_VO,
  40. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_VO,
  41. [MRP_EVENT_R_MT] = MRP_APPLICANT_VO,
  42. [MRP_EVENT_R_LV] = MRP_APPLICANT_VO,
  43. [MRP_EVENT_R_LA] = MRP_APPLICANT_VO,
  44. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VO,
  45. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_VO,
  46. },
  47. [MRP_APPLICANT_VP] = {
  48. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  49. [MRP_EVENT_JOIN] = MRP_APPLICANT_VP,
  50. [MRP_EVENT_LV] = MRP_APPLICANT_VO,
  51. [MRP_EVENT_TX] = MRP_APPLICANT_AA,
  52. [MRP_EVENT_R_NEW] = MRP_APPLICANT_VP,
  53. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_AP,
  54. [MRP_EVENT_R_IN] = MRP_APPLICANT_VP,
  55. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_VP,
  56. [MRP_EVENT_R_MT] = MRP_APPLICANT_VP,
  57. [MRP_EVENT_R_LV] = MRP_APPLICANT_VP,
  58. [MRP_EVENT_R_LA] = MRP_APPLICANT_VP,
  59. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VP,
  60. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_VP,
  61. },
  62. [MRP_APPLICANT_VN] = {
  63. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  64. [MRP_EVENT_JOIN] = MRP_APPLICANT_VN,
  65. [MRP_EVENT_LV] = MRP_APPLICANT_LA,
  66. [MRP_EVENT_TX] = MRP_APPLICANT_AN,
  67. [MRP_EVENT_R_NEW] = MRP_APPLICANT_VN,
  68. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_VN,
  69. [MRP_EVENT_R_IN] = MRP_APPLICANT_VN,
  70. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_VN,
  71. [MRP_EVENT_R_MT] = MRP_APPLICANT_VN,
  72. [MRP_EVENT_R_LV] = MRP_APPLICANT_VN,
  73. [MRP_EVENT_R_LA] = MRP_APPLICANT_VN,
  74. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VN,
  75. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_VN,
  76. },
  77. [MRP_APPLICANT_AN] = {
  78. [MRP_EVENT_NEW] = MRP_APPLICANT_AN,
  79. [MRP_EVENT_JOIN] = MRP_APPLICANT_AN,
  80. [MRP_EVENT_LV] = MRP_APPLICANT_LA,
  81. [MRP_EVENT_TX] = MRP_APPLICANT_QA,
  82. [MRP_EVENT_R_NEW] = MRP_APPLICANT_AN,
  83. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_AN,
  84. [MRP_EVENT_R_IN] = MRP_APPLICANT_AN,
  85. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_AN,
  86. [MRP_EVENT_R_MT] = MRP_APPLICANT_AN,
  87. [MRP_EVENT_R_LV] = MRP_APPLICANT_VN,
  88. [MRP_EVENT_R_LA] = MRP_APPLICANT_VN,
  89. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VN,
  90. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_AN,
  91. },
  92. [MRP_APPLICANT_AA] = {
  93. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  94. [MRP_EVENT_JOIN] = MRP_APPLICANT_AA,
  95. [MRP_EVENT_LV] = MRP_APPLICANT_LA,
  96. [MRP_EVENT_TX] = MRP_APPLICANT_QA,
  97. [MRP_EVENT_R_NEW] = MRP_APPLICANT_AA,
  98. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_QA,
  99. [MRP_EVENT_R_IN] = MRP_APPLICANT_AA,
  100. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_AA,
  101. [MRP_EVENT_R_MT] = MRP_APPLICANT_AA,
  102. [MRP_EVENT_R_LV] = MRP_APPLICANT_VP,
  103. [MRP_EVENT_R_LA] = MRP_APPLICANT_VP,
  104. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VP,
  105. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_AA,
  106. },
  107. [MRP_APPLICANT_QA] = {
  108. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  109. [MRP_EVENT_JOIN] = MRP_APPLICANT_QA,
  110. [MRP_EVENT_LV] = MRP_APPLICANT_LA,
  111. [MRP_EVENT_TX] = MRP_APPLICANT_QA,
  112. [MRP_EVENT_R_NEW] = MRP_APPLICANT_QA,
  113. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_QA,
  114. [MRP_EVENT_R_IN] = MRP_APPLICANT_QA,
  115. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_AA,
  116. [MRP_EVENT_R_MT] = MRP_APPLICANT_AA,
  117. [MRP_EVENT_R_LV] = MRP_APPLICANT_VP,
  118. [MRP_EVENT_R_LA] = MRP_APPLICANT_VP,
  119. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VP,
  120. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_AA,
  121. },
  122. [MRP_APPLICANT_LA] = {
  123. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  124. [MRP_EVENT_JOIN] = MRP_APPLICANT_AA,
  125. [MRP_EVENT_LV] = MRP_APPLICANT_LA,
  126. [MRP_EVENT_TX] = MRP_APPLICANT_VO,
  127. [MRP_EVENT_R_NEW] = MRP_APPLICANT_LA,
  128. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_LA,
  129. [MRP_EVENT_R_IN] = MRP_APPLICANT_LA,
  130. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_LA,
  131. [MRP_EVENT_R_MT] = MRP_APPLICANT_LA,
  132. [MRP_EVENT_R_LV] = MRP_APPLICANT_LA,
  133. [MRP_EVENT_R_LA] = MRP_APPLICANT_LA,
  134. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_LA,
  135. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_LA,
  136. },
  137. [MRP_APPLICANT_AO] = {
  138. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  139. [MRP_EVENT_JOIN] = MRP_APPLICANT_AP,
  140. [MRP_EVENT_LV] = MRP_APPLICANT_AO,
  141. [MRP_EVENT_TX] = MRP_APPLICANT_AO,
  142. [MRP_EVENT_R_NEW] = MRP_APPLICANT_AO,
  143. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_QO,
  144. [MRP_EVENT_R_IN] = MRP_APPLICANT_AO,
  145. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_AO,
  146. [MRP_EVENT_R_MT] = MRP_APPLICANT_AO,
  147. [MRP_EVENT_R_LV] = MRP_APPLICANT_VO,
  148. [MRP_EVENT_R_LA] = MRP_APPLICANT_VO,
  149. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VO,
  150. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_AO,
  151. },
  152. [MRP_APPLICANT_QO] = {
  153. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  154. [MRP_EVENT_JOIN] = MRP_APPLICANT_QP,
  155. [MRP_EVENT_LV] = MRP_APPLICANT_QO,
  156. [MRP_EVENT_TX] = MRP_APPLICANT_QO,
  157. [MRP_EVENT_R_NEW] = MRP_APPLICANT_QO,
  158. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_QO,
  159. [MRP_EVENT_R_IN] = MRP_APPLICANT_QO,
  160. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_AO,
  161. [MRP_EVENT_R_MT] = MRP_APPLICANT_AO,
  162. [MRP_EVENT_R_LV] = MRP_APPLICANT_VO,
  163. [MRP_EVENT_R_LA] = MRP_APPLICANT_VO,
  164. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VO,
  165. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_QO,
  166. },
  167. [MRP_APPLICANT_AP] = {
  168. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  169. [MRP_EVENT_JOIN] = MRP_APPLICANT_AP,
  170. [MRP_EVENT_LV] = MRP_APPLICANT_AO,
  171. [MRP_EVENT_TX] = MRP_APPLICANT_QA,
  172. [MRP_EVENT_R_NEW] = MRP_APPLICANT_AP,
  173. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_QP,
  174. [MRP_EVENT_R_IN] = MRP_APPLICANT_AP,
  175. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_AP,
  176. [MRP_EVENT_R_MT] = MRP_APPLICANT_AP,
  177. [MRP_EVENT_R_LV] = MRP_APPLICANT_VP,
  178. [MRP_EVENT_R_LA] = MRP_APPLICANT_VP,
  179. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VP,
  180. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_AP,
  181. },
  182. [MRP_APPLICANT_QP] = {
  183. [MRP_EVENT_NEW] = MRP_APPLICANT_VN,
  184. [MRP_EVENT_JOIN] = MRP_APPLICANT_QP,
  185. [MRP_EVENT_LV] = MRP_APPLICANT_QO,
  186. [MRP_EVENT_TX] = MRP_APPLICANT_QP,
  187. [MRP_EVENT_R_NEW] = MRP_APPLICANT_QP,
  188. [MRP_EVENT_R_JOIN_IN] = MRP_APPLICANT_QP,
  189. [MRP_EVENT_R_IN] = MRP_APPLICANT_QP,
  190. [MRP_EVENT_R_JOIN_MT] = MRP_APPLICANT_AP,
  191. [MRP_EVENT_R_MT] = MRP_APPLICANT_AP,
  192. [MRP_EVENT_R_LV] = MRP_APPLICANT_VP,
  193. [MRP_EVENT_R_LA] = MRP_APPLICANT_VP,
  194. [MRP_EVENT_REDECLARE] = MRP_APPLICANT_VP,
  195. [MRP_EVENT_PERIODIC] = MRP_APPLICANT_AP,
  196. },
  197. };
  198. static const u8
  199. mrp_tx_action_table[MRP_APPLICANT_MAX + 1] = {
  200. [MRP_APPLICANT_VO] = MRP_TX_ACTION_S_IN_OPTIONAL,
  201. [MRP_APPLICANT_VP] = MRP_TX_ACTION_S_JOIN_IN,
  202. [MRP_APPLICANT_VN] = MRP_TX_ACTION_S_NEW,
  203. [MRP_APPLICANT_AN] = MRP_TX_ACTION_S_NEW,
  204. [MRP_APPLICANT_AA] = MRP_TX_ACTION_S_JOIN_IN,
  205. [MRP_APPLICANT_QA] = MRP_TX_ACTION_S_JOIN_IN_OPTIONAL,
  206. [MRP_APPLICANT_LA] = MRP_TX_ACTION_S_LV,
  207. [MRP_APPLICANT_AO] = MRP_TX_ACTION_S_IN_OPTIONAL,
  208. [MRP_APPLICANT_QO] = MRP_TX_ACTION_S_IN_OPTIONAL,
  209. [MRP_APPLICANT_AP] = MRP_TX_ACTION_S_JOIN_IN,
  210. [MRP_APPLICANT_QP] = MRP_TX_ACTION_S_IN_OPTIONAL,
  211. };
  212. static void mrp_attrvalue_inc(void *value, u8 len)
  213. {
  214. u8 *v = (u8 *)value;
  215. /* Add 1 to the last byte. If it becomes zero,
  216. * go to the previous byte and repeat.
  217. */
  218. while (len > 0 && !++v[--len])
  219. ;
  220. }
  221. static int mrp_attr_cmp(const struct mrp_attr *attr,
  222. const void *value, u8 len, u8 type)
  223. {
  224. if (attr->type != type)
  225. return attr->type - type;
  226. if (attr->len != len)
  227. return attr->len - len;
  228. return memcmp(attr->value, value, len);
  229. }
  230. static struct mrp_attr *mrp_attr_lookup(const struct mrp_applicant *app,
  231. const void *value, u8 len, u8 type)
  232. {
  233. struct rb_node *parent = app->mad.rb_node;
  234. struct mrp_attr *attr;
  235. int d;
  236. while (parent) {
  237. attr = rb_entry(parent, struct mrp_attr, node);
  238. d = mrp_attr_cmp(attr, value, len, type);
  239. if (d > 0)
  240. parent = parent->rb_left;
  241. else if (d < 0)
  242. parent = parent->rb_right;
  243. else
  244. return attr;
  245. }
  246. return NULL;
  247. }
  248. static struct mrp_attr *mrp_attr_create(struct mrp_applicant *app,
  249. const void *value, u8 len, u8 type)
  250. {
  251. struct rb_node *parent = NULL, **p = &app->mad.rb_node;
  252. struct mrp_attr *attr;
  253. int d;
  254. while (*p) {
  255. parent = *p;
  256. attr = rb_entry(parent, struct mrp_attr, node);
  257. d = mrp_attr_cmp(attr, value, len, type);
  258. if (d > 0)
  259. p = &parent->rb_left;
  260. else if (d < 0)
  261. p = &parent->rb_right;
  262. else {
  263. /* The attribute already exists; re-use it. */
  264. return attr;
  265. }
  266. }
  267. attr = kmalloc(sizeof(*attr) + len, GFP_ATOMIC);
  268. if (!attr)
  269. return attr;
  270. attr->state = MRP_APPLICANT_VO;
  271. attr->type = type;
  272. attr->len = len;
  273. memcpy(attr->value, value, len);
  274. rb_link_node(&attr->node, parent, p);
  275. rb_insert_color(&attr->node, &app->mad);
  276. return attr;
  277. }
  278. static void mrp_attr_destroy(struct mrp_applicant *app, struct mrp_attr *attr)
  279. {
  280. rb_erase(&attr->node, &app->mad);
  281. kfree(attr);
  282. }
  283. static int mrp_pdu_init(struct mrp_applicant *app)
  284. {
  285. struct sk_buff *skb;
  286. struct mrp_pdu_hdr *ph;
  287. skb = alloc_skb(app->dev->mtu + LL_RESERVED_SPACE(app->dev),
  288. GFP_ATOMIC);
  289. if (!skb)
  290. return -ENOMEM;
  291. skb->dev = app->dev;
  292. skb->protocol = app->app->pkttype.type;
  293. skb_reserve(skb, LL_RESERVED_SPACE(app->dev));
  294. skb_reset_network_header(skb);
  295. skb_reset_transport_header(skb);
  296. ph = (struct mrp_pdu_hdr *)__skb_put(skb, sizeof(*ph));
  297. ph->version = app->app->version;
  298. app->pdu = skb;
  299. return 0;
  300. }
  301. static int mrp_pdu_append_end_mark(struct mrp_applicant *app)
  302. {
  303. __be16 *endmark;
  304. if (skb_tailroom(app->pdu) < sizeof(*endmark))
  305. return -1;
  306. endmark = (__be16 *)__skb_put(app->pdu, sizeof(*endmark));
  307. put_unaligned(MRP_END_MARK, endmark);
  308. return 0;
  309. }
  310. static void mrp_pdu_queue(struct mrp_applicant *app)
  311. {
  312. if (!app->pdu)
  313. return;
  314. if (mrp_cb(app->pdu)->mh)
  315. mrp_pdu_append_end_mark(app);
  316. mrp_pdu_append_end_mark(app);
  317. dev_hard_header(app->pdu, app->dev, ntohs(app->app->pkttype.type),
  318. app->app->group_address, app->dev->dev_addr,
  319. app->pdu->len);
  320. skb_queue_tail(&app->queue, app->pdu);
  321. app->pdu = NULL;
  322. }
  323. static void mrp_queue_xmit(struct mrp_applicant *app)
  324. {
  325. struct sk_buff *skb;
  326. while ((skb = skb_dequeue(&app->queue)))
  327. dev_queue_xmit(skb);
  328. }
  329. static int mrp_pdu_append_msg_hdr(struct mrp_applicant *app,
  330. u8 attrtype, u8 attrlen)
  331. {
  332. struct mrp_msg_hdr *mh;
  333. if (mrp_cb(app->pdu)->mh) {
  334. if (mrp_pdu_append_end_mark(app) < 0)
  335. return -1;
  336. mrp_cb(app->pdu)->mh = NULL;
  337. mrp_cb(app->pdu)->vah = NULL;
  338. }
  339. if (skb_tailroom(app->pdu) < sizeof(*mh))
  340. return -1;
  341. mh = (struct mrp_msg_hdr *)__skb_put(app->pdu, sizeof(*mh));
  342. mh->attrtype = attrtype;
  343. mh->attrlen = attrlen;
  344. mrp_cb(app->pdu)->mh = mh;
  345. return 0;
  346. }
  347. static int mrp_pdu_append_vecattr_hdr(struct mrp_applicant *app,
  348. const void *firstattrvalue, u8 attrlen)
  349. {
  350. struct mrp_vecattr_hdr *vah;
  351. if (skb_tailroom(app->pdu) < sizeof(*vah) + attrlen)
  352. return -1;
  353. vah = (struct mrp_vecattr_hdr *)__skb_put(app->pdu,
  354. sizeof(*vah) + attrlen);
  355. put_unaligned(0, &vah->lenflags);
  356. memcpy(vah->firstattrvalue, firstattrvalue, attrlen);
  357. mrp_cb(app->pdu)->vah = vah;
  358. memcpy(mrp_cb(app->pdu)->attrvalue, firstattrvalue, attrlen);
  359. return 0;
  360. }
  361. static int mrp_pdu_append_vecattr_event(struct mrp_applicant *app,
  362. const struct mrp_attr *attr,
  363. enum mrp_vecattr_event vaevent)
  364. {
  365. u16 len, pos;
  366. u8 *vaevents;
  367. int err;
  368. again:
  369. if (!app->pdu) {
  370. err = mrp_pdu_init(app);
  371. if (err < 0)
  372. return err;
  373. }
  374. /* If there is no Message header in the PDU, or the Message header is
  375. * for a different attribute type, add an EndMark (if necessary) and a
  376. * new Message header to the PDU.
  377. */
  378. if (!mrp_cb(app->pdu)->mh ||
  379. mrp_cb(app->pdu)->mh->attrtype != attr->type ||
  380. mrp_cb(app->pdu)->mh->attrlen != attr->len) {
  381. if (mrp_pdu_append_msg_hdr(app, attr->type, attr->len) < 0)
  382. goto queue;
  383. }
  384. /* If there is no VectorAttribute header for this Message in the PDU,
  385. * or this attribute's value does not sequentially follow the previous
  386. * attribute's value, add a new VectorAttribute header to the PDU.
  387. */
  388. if (!mrp_cb(app->pdu)->vah ||
  389. memcmp(mrp_cb(app->pdu)->attrvalue, attr->value, attr->len)) {
  390. if (mrp_pdu_append_vecattr_hdr(app, attr->value, attr->len) < 0)
  391. goto queue;
  392. }
  393. len = be16_to_cpu(get_unaligned(&mrp_cb(app->pdu)->vah->lenflags));
  394. pos = len % 3;
  395. /* Events are packed into Vectors in the PDU, three to a byte. Add a
  396. * byte to the end of the Vector if necessary.
  397. */
  398. if (!pos) {
  399. if (skb_tailroom(app->pdu) < sizeof(u8))
  400. goto queue;
  401. vaevents = (u8 *)__skb_put(app->pdu, sizeof(u8));
  402. } else {
  403. vaevents = (u8 *)(skb_tail_pointer(app->pdu) - sizeof(u8));
  404. }
  405. switch (pos) {
  406. case 0:
  407. *vaevents = vaevent * (__MRP_VECATTR_EVENT_MAX *
  408. __MRP_VECATTR_EVENT_MAX);
  409. break;
  410. case 1:
  411. *vaevents += vaevent * __MRP_VECATTR_EVENT_MAX;
  412. break;
  413. case 2:
  414. *vaevents += vaevent;
  415. break;
  416. default:
  417. WARN_ON(1);
  418. }
  419. /* Increment the length of the VectorAttribute in the PDU, as well as
  420. * the value of the next attribute that would continue its Vector.
  421. */
  422. put_unaligned(cpu_to_be16(++len), &mrp_cb(app->pdu)->vah->lenflags);
  423. mrp_attrvalue_inc(mrp_cb(app->pdu)->attrvalue, attr->len);
  424. return 0;
  425. queue:
  426. mrp_pdu_queue(app);
  427. goto again;
  428. }
  429. static void mrp_attr_event(struct mrp_applicant *app,
  430. struct mrp_attr *attr, enum mrp_event event)
  431. {
  432. enum mrp_applicant_state state;
  433. state = mrp_applicant_state_table[attr->state][event];
  434. if (state == MRP_APPLICANT_INVALID) {
  435. WARN_ON(1);
  436. return;
  437. }
  438. if (event == MRP_EVENT_TX) {
  439. /* When appending the attribute fails, don't update its state
  440. * in order to retry at the next TX event.
  441. */
  442. switch (mrp_tx_action_table[attr->state]) {
  443. case MRP_TX_ACTION_NONE:
  444. case MRP_TX_ACTION_S_JOIN_IN_OPTIONAL:
  445. case MRP_TX_ACTION_S_IN_OPTIONAL:
  446. break;
  447. case MRP_TX_ACTION_S_NEW:
  448. if (mrp_pdu_append_vecattr_event(
  449. app, attr, MRP_VECATTR_EVENT_NEW) < 0)
  450. return;
  451. break;
  452. case MRP_TX_ACTION_S_JOIN_IN:
  453. if (mrp_pdu_append_vecattr_event(
  454. app, attr, MRP_VECATTR_EVENT_JOIN_IN) < 0)
  455. return;
  456. break;
  457. case MRP_TX_ACTION_S_LV:
  458. if (mrp_pdu_append_vecattr_event(
  459. app, attr, MRP_VECATTR_EVENT_LV) < 0)
  460. return;
  461. /* As a pure applicant, sending a leave message
  462. * implies that the attribute was unregistered and
  463. * can be destroyed.
  464. */
  465. mrp_attr_destroy(app, attr);
  466. return;
  467. default:
  468. WARN_ON(1);
  469. }
  470. }
  471. attr->state = state;
  472. }
  473. int mrp_request_join(const struct net_device *dev,
  474. const struct mrp_application *appl,
  475. const void *value, u8 len, u8 type)
  476. {
  477. struct mrp_port *port = rtnl_dereference(dev->mrp_port);
  478. struct mrp_applicant *app = rtnl_dereference(
  479. port->applicants[appl->type]);
  480. struct mrp_attr *attr;
  481. if (sizeof(struct mrp_skb_cb) + len >
  482. FIELD_SIZEOF(struct sk_buff, cb))
  483. return -ENOMEM;
  484. spin_lock_bh(&app->lock);
  485. attr = mrp_attr_create(app, value, len, type);
  486. if (!attr) {
  487. spin_unlock_bh(&app->lock);
  488. return -ENOMEM;
  489. }
  490. mrp_attr_event(app, attr, MRP_EVENT_JOIN);
  491. spin_unlock_bh(&app->lock);
  492. return 0;
  493. }
  494. EXPORT_SYMBOL_GPL(mrp_request_join);
  495. void mrp_request_leave(const struct net_device *dev,
  496. const struct mrp_application *appl,
  497. const void *value, u8 len, u8 type)
  498. {
  499. struct mrp_port *port = rtnl_dereference(dev->mrp_port);
  500. struct mrp_applicant *app = rtnl_dereference(
  501. port->applicants[appl->type]);
  502. struct mrp_attr *attr;
  503. if (sizeof(struct mrp_skb_cb) + len >
  504. FIELD_SIZEOF(struct sk_buff, cb))
  505. return;
  506. spin_lock_bh(&app->lock);
  507. attr = mrp_attr_lookup(app, value, len, type);
  508. if (!attr) {
  509. spin_unlock_bh(&app->lock);
  510. return;
  511. }
  512. mrp_attr_event(app, attr, MRP_EVENT_LV);
  513. spin_unlock_bh(&app->lock);
  514. }
  515. EXPORT_SYMBOL_GPL(mrp_request_leave);
  516. static void mrp_mad_event(struct mrp_applicant *app, enum mrp_event event)
  517. {
  518. struct rb_node *node, *next;
  519. struct mrp_attr *attr;
  520. for (node = rb_first(&app->mad);
  521. next = node ? rb_next(node) : NULL, node != NULL;
  522. node = next) {
  523. attr = rb_entry(node, struct mrp_attr, node);
  524. mrp_attr_event(app, attr, event);
  525. }
  526. }
  527. static void mrp_join_timer_arm(struct mrp_applicant *app)
  528. {
  529. unsigned long delay;
  530. delay = (u64)msecs_to_jiffies(mrp_join_time) * prandom_u32() >> 32;
  531. mod_timer(&app->join_timer, jiffies + delay);
  532. }
  533. static void mrp_join_timer(unsigned long data)
  534. {
  535. struct mrp_applicant *app = (struct mrp_applicant *)data;
  536. spin_lock(&app->lock);
  537. mrp_mad_event(app, MRP_EVENT_TX);
  538. mrp_pdu_queue(app);
  539. spin_unlock(&app->lock);
  540. mrp_queue_xmit(app);
  541. mrp_join_timer_arm(app);
  542. }
  543. static void mrp_periodic_timer_arm(struct mrp_applicant *app)
  544. {
  545. mod_timer(&app->periodic_timer,
  546. jiffies + msecs_to_jiffies(mrp_periodic_time));
  547. }
  548. static void mrp_periodic_timer(unsigned long data)
  549. {
  550. struct mrp_applicant *app = (struct mrp_applicant *)data;
  551. spin_lock(&app->lock);
  552. mrp_mad_event(app, MRP_EVENT_PERIODIC);
  553. mrp_pdu_queue(app);
  554. spin_unlock(&app->lock);
  555. mrp_periodic_timer_arm(app);
  556. }
  557. static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset)
  558. {
  559. __be16 endmark;
  560. if (skb_copy_bits(skb, *offset, &endmark, sizeof(endmark)) < 0)
  561. return -1;
  562. if (endmark == MRP_END_MARK) {
  563. *offset += sizeof(endmark);
  564. return -1;
  565. }
  566. return 0;
  567. }
  568. static void mrp_pdu_parse_vecattr_event(struct mrp_applicant *app,
  569. struct sk_buff *skb,
  570. enum mrp_vecattr_event vaevent)
  571. {
  572. struct mrp_attr *attr;
  573. enum mrp_event event;
  574. attr = mrp_attr_lookup(app, mrp_cb(skb)->attrvalue,
  575. mrp_cb(skb)->mh->attrlen,
  576. mrp_cb(skb)->mh->attrtype);
  577. if (attr == NULL)
  578. return;
  579. switch (vaevent) {
  580. case MRP_VECATTR_EVENT_NEW:
  581. event = MRP_EVENT_R_NEW;
  582. break;
  583. case MRP_VECATTR_EVENT_JOIN_IN:
  584. event = MRP_EVENT_R_JOIN_IN;
  585. break;
  586. case MRP_VECATTR_EVENT_IN:
  587. event = MRP_EVENT_R_IN;
  588. break;
  589. case MRP_VECATTR_EVENT_JOIN_MT:
  590. event = MRP_EVENT_R_JOIN_MT;
  591. break;
  592. case MRP_VECATTR_EVENT_MT:
  593. event = MRP_EVENT_R_MT;
  594. break;
  595. case MRP_VECATTR_EVENT_LV:
  596. event = MRP_EVENT_R_LV;
  597. break;
  598. default:
  599. return;
  600. }
  601. mrp_attr_event(app, attr, event);
  602. }
  603. static int mrp_pdu_parse_vecattr(struct mrp_applicant *app,
  604. struct sk_buff *skb, int *offset)
  605. {
  606. struct mrp_vecattr_hdr _vah;
  607. u16 valen;
  608. u8 vaevents, vaevent;
  609. mrp_cb(skb)->vah = skb_header_pointer(skb, *offset, sizeof(_vah),
  610. &_vah);
  611. if (!mrp_cb(skb)->vah)
  612. return -1;
  613. *offset += sizeof(_vah);
  614. if (get_unaligned(&mrp_cb(skb)->vah->lenflags) &
  615. MRP_VECATTR_HDR_FLAG_LA)
  616. mrp_mad_event(app, MRP_EVENT_R_LA);
  617. valen = be16_to_cpu(get_unaligned(&mrp_cb(skb)->vah->lenflags) &
  618. MRP_VECATTR_HDR_LEN_MASK);
  619. /* The VectorAttribute structure in a PDU carries event information
  620. * about one or more attributes having consecutive values. Only the
  621. * value for the first attribute is contained in the structure. So
  622. * we make a copy of that value, and then increment it each time we
  623. * advance to the next event in its Vector.
  624. */
  625. if (sizeof(struct mrp_skb_cb) + mrp_cb(skb)->mh->attrlen >
  626. FIELD_SIZEOF(struct sk_buff, cb))
  627. return -1;
  628. if (skb_copy_bits(skb, *offset, mrp_cb(skb)->attrvalue,
  629. mrp_cb(skb)->mh->attrlen) < 0)
  630. return -1;
  631. *offset += mrp_cb(skb)->mh->attrlen;
  632. /* In a VectorAttribute, the Vector contains events which are packed
  633. * three to a byte. We process one byte of the Vector at a time.
  634. */
  635. while (valen > 0) {
  636. if (skb_copy_bits(skb, *offset, &vaevents,
  637. sizeof(vaevents)) < 0)
  638. return -1;
  639. *offset += sizeof(vaevents);
  640. /* Extract and process the first event. */
  641. vaevent = vaevents / (__MRP_VECATTR_EVENT_MAX *
  642. __MRP_VECATTR_EVENT_MAX);
  643. if (vaevent >= __MRP_VECATTR_EVENT_MAX) {
  644. /* The byte is malformed; stop processing. */
  645. return -1;
  646. }
  647. mrp_pdu_parse_vecattr_event(app, skb, vaevent);
  648. /* If present, extract and process the second event. */
  649. if (!--valen)
  650. break;
  651. mrp_attrvalue_inc(mrp_cb(skb)->attrvalue,
  652. mrp_cb(skb)->mh->attrlen);
  653. vaevents %= (__MRP_VECATTR_EVENT_MAX *
  654. __MRP_VECATTR_EVENT_MAX);
  655. vaevent = vaevents / __MRP_VECATTR_EVENT_MAX;
  656. mrp_pdu_parse_vecattr_event(app, skb, vaevent);
  657. /* If present, extract and process the third event. */
  658. if (!--valen)
  659. break;
  660. mrp_attrvalue_inc(mrp_cb(skb)->attrvalue,
  661. mrp_cb(skb)->mh->attrlen);
  662. vaevents %= __MRP_VECATTR_EVENT_MAX;
  663. vaevent = vaevents;
  664. mrp_pdu_parse_vecattr_event(app, skb, vaevent);
  665. }
  666. return 0;
  667. }
  668. static int mrp_pdu_parse_msg(struct mrp_applicant *app, struct sk_buff *skb,
  669. int *offset)
  670. {
  671. struct mrp_msg_hdr _mh;
  672. mrp_cb(skb)->mh = skb_header_pointer(skb, *offset, sizeof(_mh), &_mh);
  673. if (!mrp_cb(skb)->mh)
  674. return -1;
  675. *offset += sizeof(_mh);
  676. if (mrp_cb(skb)->mh->attrtype == 0 ||
  677. mrp_cb(skb)->mh->attrtype > app->app->maxattr ||
  678. mrp_cb(skb)->mh->attrlen == 0)
  679. return -1;
  680. while (skb->len > *offset) {
  681. if (mrp_pdu_parse_end_mark(skb, offset) < 0)
  682. break;
  683. if (mrp_pdu_parse_vecattr(app, skb, offset) < 0)
  684. return -1;
  685. }
  686. return 0;
  687. }
  688. static int mrp_rcv(struct sk_buff *skb, struct net_device *dev,
  689. struct packet_type *pt, struct net_device *orig_dev)
  690. {
  691. struct mrp_application *appl = container_of(pt, struct mrp_application,
  692. pkttype);
  693. struct mrp_port *port;
  694. struct mrp_applicant *app;
  695. struct mrp_pdu_hdr _ph;
  696. const struct mrp_pdu_hdr *ph;
  697. int offset = skb_network_offset(skb);
  698. /* If the interface is in promiscuous mode, drop the packet if
  699. * it was unicast to another host.
  700. */
  701. if (unlikely(skb->pkt_type == PACKET_OTHERHOST))
  702. goto out;
  703. skb = skb_share_check(skb, GFP_ATOMIC);
  704. if (unlikely(!skb))
  705. goto out;
  706. port = rcu_dereference(dev->mrp_port);
  707. if (unlikely(!port))
  708. goto out;
  709. app = rcu_dereference(port->applicants[appl->type]);
  710. if (unlikely(!app))
  711. goto out;
  712. ph = skb_header_pointer(skb, offset, sizeof(_ph), &_ph);
  713. if (!ph)
  714. goto out;
  715. offset += sizeof(_ph);
  716. if (ph->version != app->app->version)
  717. goto out;
  718. spin_lock(&app->lock);
  719. while (skb->len > offset) {
  720. if (mrp_pdu_parse_end_mark(skb, &offset) < 0)
  721. break;
  722. if (mrp_pdu_parse_msg(app, skb, &offset) < 0)
  723. break;
  724. }
  725. spin_unlock(&app->lock);
  726. out:
  727. kfree_skb(skb);
  728. return 0;
  729. }
  730. static int mrp_init_port(struct net_device *dev)
  731. {
  732. struct mrp_port *port;
  733. port = kzalloc(sizeof(*port), GFP_KERNEL);
  734. if (!port)
  735. return -ENOMEM;
  736. rcu_assign_pointer(dev->mrp_port, port);
  737. return 0;
  738. }
  739. static void mrp_release_port(struct net_device *dev)
  740. {
  741. struct mrp_port *port = rtnl_dereference(dev->mrp_port);
  742. unsigned int i;
  743. for (i = 0; i <= MRP_APPLICATION_MAX; i++) {
  744. if (rtnl_dereference(port->applicants[i]))
  745. return;
  746. }
  747. RCU_INIT_POINTER(dev->mrp_port, NULL);
  748. kfree_rcu(port, rcu);
  749. }
  750. int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl)
  751. {
  752. struct mrp_applicant *app;
  753. int err;
  754. ASSERT_RTNL();
  755. if (!rtnl_dereference(dev->mrp_port)) {
  756. err = mrp_init_port(dev);
  757. if (err < 0)
  758. goto err1;
  759. }
  760. err = -ENOMEM;
  761. app = kzalloc(sizeof(*app), GFP_KERNEL);
  762. if (!app)
  763. goto err2;
  764. err = dev_mc_add(dev, appl->group_address);
  765. if (err < 0)
  766. goto err3;
  767. app->dev = dev;
  768. app->app = appl;
  769. app->mad = RB_ROOT;
  770. spin_lock_init(&app->lock);
  771. skb_queue_head_init(&app->queue);
  772. rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app);
  773. setup_timer(&app->join_timer, mrp_join_timer, (unsigned long)app);
  774. mrp_join_timer_arm(app);
  775. setup_timer(&app->periodic_timer, mrp_periodic_timer,
  776. (unsigned long)app);
  777. mrp_periodic_timer_arm(app);
  778. return 0;
  779. err3:
  780. kfree(app);
  781. err2:
  782. mrp_release_port(dev);
  783. err1:
  784. return err;
  785. }
  786. EXPORT_SYMBOL_GPL(mrp_init_applicant);
  787. void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
  788. {
  789. struct mrp_port *port = rtnl_dereference(dev->mrp_port);
  790. struct mrp_applicant *app = rtnl_dereference(
  791. port->applicants[appl->type]);
  792. ASSERT_RTNL();
  793. RCU_INIT_POINTER(port->applicants[appl->type], NULL);
  794. /* Delete timer and generate a final TX event to flush out
  795. * all pending messages before the applicant is gone.
  796. */
  797. del_timer_sync(&app->join_timer);
  798. del_timer_sync(&app->periodic_timer);
  799. spin_lock_bh(&app->lock);
  800. mrp_mad_event(app, MRP_EVENT_TX);
  801. mrp_pdu_queue(app);
  802. spin_unlock_bh(&app->lock);
  803. mrp_queue_xmit(app);
  804. dev_mc_del(dev, appl->group_address);
  805. kfree_rcu(app, rcu);
  806. mrp_release_port(dev);
  807. }
  808. EXPORT_SYMBOL_GPL(mrp_uninit_applicant);
  809. int mrp_register_application(struct mrp_application *appl)
  810. {
  811. appl->pkttype.func = mrp_rcv;
  812. dev_add_pack(&appl->pkttype);
  813. return 0;
  814. }
  815. EXPORT_SYMBOL_GPL(mrp_register_application);
  816. void mrp_unregister_application(struct mrp_application *appl)
  817. {
  818. dev_remove_pack(&appl->pkttype);
  819. }
  820. EXPORT_SYMBOL_GPL(mrp_unregister_application);