tvlv.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. /* Copyright (C) 2007-2016 B.A.T.M.A.N. contributors:
  2. *
  3. * Marek Lindner, Simon Wunderlich
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of version 2 of the GNU General Public
  7. * License as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "main.h"
  18. #include <linux/byteorder/generic.h>
  19. #include <linux/etherdevice.h>
  20. #include <linux/fs.h>
  21. #include <linux/if_ether.h>
  22. #include <linux/kernel.h>
  23. #include <linux/kref.h>
  24. #include <linux/list.h>
  25. #include <linux/lockdep.h>
  26. #include <linux/netdevice.h>
  27. #include <linux/pkt_sched.h>
  28. #include <linux/rculist.h>
  29. #include <linux/rcupdate.h>
  30. #include <linux/skbuff.h>
  31. #include <linux/slab.h>
  32. #include <linux/spinlock.h>
  33. #include <linux/stddef.h>
  34. #include <linux/string.h>
  35. #include <linux/types.h>
  36. #include "originator.h"
  37. #include "packet.h"
  38. #include "send.h"
  39. #include "tvlv.h"
  40. /**
  41. * batadv_tvlv_handler_release - release tvlv handler from lists and queue for
  42. * free after rcu grace period
  43. * @ref: kref pointer of the tvlv
  44. */
  45. static void batadv_tvlv_handler_release(struct kref *ref)
  46. {
  47. struct batadv_tvlv_handler *tvlv_handler;
  48. tvlv_handler = container_of(ref, struct batadv_tvlv_handler, refcount);
  49. kfree_rcu(tvlv_handler, rcu);
  50. }
  51. /**
  52. * batadv_tvlv_handler_put - decrement the tvlv container refcounter and
  53. * possibly release it
  54. * @tvlv_handler: the tvlv handler to free
  55. */
  56. static void batadv_tvlv_handler_put(struct batadv_tvlv_handler *tvlv_handler)
  57. {
  58. kref_put(&tvlv_handler->refcount, batadv_tvlv_handler_release);
  59. }
  60. /**
  61. * batadv_tvlv_handler_get - retrieve tvlv handler from the tvlv handler list
  62. * based on the provided type and version (both need to match)
  63. * @bat_priv: the bat priv with all the soft interface information
  64. * @type: tvlv handler type to look for
  65. * @version: tvlv handler version to look for
  66. *
  67. * Return: tvlv handler if found or NULL otherwise.
  68. */
  69. static struct batadv_tvlv_handler *
  70. batadv_tvlv_handler_get(struct batadv_priv *bat_priv, u8 type, u8 version)
  71. {
  72. struct batadv_tvlv_handler *tvlv_handler_tmp, *tvlv_handler = NULL;
  73. rcu_read_lock();
  74. hlist_for_each_entry_rcu(tvlv_handler_tmp,
  75. &bat_priv->tvlv.handler_list, list) {
  76. if (tvlv_handler_tmp->type != type)
  77. continue;
  78. if (tvlv_handler_tmp->version != version)
  79. continue;
  80. if (!kref_get_unless_zero(&tvlv_handler_tmp->refcount))
  81. continue;
  82. tvlv_handler = tvlv_handler_tmp;
  83. break;
  84. }
  85. rcu_read_unlock();
  86. return tvlv_handler;
  87. }
  88. /**
  89. * batadv_tvlv_container_release - release tvlv from lists and free
  90. * @ref: kref pointer of the tvlv
  91. */
  92. static void batadv_tvlv_container_release(struct kref *ref)
  93. {
  94. struct batadv_tvlv_container *tvlv;
  95. tvlv = container_of(ref, struct batadv_tvlv_container, refcount);
  96. kfree(tvlv);
  97. }
  98. /**
  99. * batadv_tvlv_container_put - decrement the tvlv container refcounter and
  100. * possibly release it
  101. * @tvlv: the tvlv container to free
  102. */
  103. static void batadv_tvlv_container_put(struct batadv_tvlv_container *tvlv)
  104. {
  105. kref_put(&tvlv->refcount, batadv_tvlv_container_release);
  106. }
  107. /**
  108. * batadv_tvlv_container_get - retrieve tvlv container from the tvlv container
  109. * list based on the provided type and version (both need to match)
  110. * @bat_priv: the bat priv with all the soft interface information
  111. * @type: tvlv container type to look for
  112. * @version: tvlv container version to look for
  113. *
  114. * Has to be called with the appropriate locks being acquired
  115. * (tvlv.container_list_lock).
  116. *
  117. * Return: tvlv container if found or NULL otherwise.
  118. */
  119. static struct batadv_tvlv_container *
  120. batadv_tvlv_container_get(struct batadv_priv *bat_priv, u8 type, u8 version)
  121. {
  122. struct batadv_tvlv_container *tvlv_tmp, *tvlv = NULL;
  123. lockdep_assert_held(&bat_priv->tvlv.container_list_lock);
  124. hlist_for_each_entry(tvlv_tmp, &bat_priv->tvlv.container_list, list) {
  125. if (tvlv_tmp->tvlv_hdr.type != type)
  126. continue;
  127. if (tvlv_tmp->tvlv_hdr.version != version)
  128. continue;
  129. kref_get(&tvlv_tmp->refcount);
  130. tvlv = tvlv_tmp;
  131. break;
  132. }
  133. return tvlv;
  134. }
  135. /**
  136. * batadv_tvlv_container_list_size - calculate the size of the tvlv container
  137. * list entries
  138. * @bat_priv: the bat priv with all the soft interface information
  139. *
  140. * Has to be called with the appropriate locks being acquired
  141. * (tvlv.container_list_lock).
  142. *
  143. * Return: size of all currently registered tvlv containers in bytes.
  144. */
  145. static u16 batadv_tvlv_container_list_size(struct batadv_priv *bat_priv)
  146. {
  147. struct batadv_tvlv_container *tvlv;
  148. u16 tvlv_len = 0;
  149. lockdep_assert_held(&bat_priv->tvlv.container_list_lock);
  150. hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) {
  151. tvlv_len += sizeof(struct batadv_tvlv_hdr);
  152. tvlv_len += ntohs(tvlv->tvlv_hdr.len);
  153. }
  154. return tvlv_len;
  155. }
  156. /**
  157. * batadv_tvlv_container_remove - remove tvlv container from the tvlv container
  158. * list
  159. * @bat_priv: the bat priv with all the soft interface information
  160. * @tvlv: the to be removed tvlv container
  161. *
  162. * Has to be called with the appropriate locks being acquired
  163. * (tvlv.container_list_lock).
  164. */
  165. static void batadv_tvlv_container_remove(struct batadv_priv *bat_priv,
  166. struct batadv_tvlv_container *tvlv)
  167. {
  168. lockdep_assert_held(&bat_priv->tvlv.container_list_lock);
  169. if (!tvlv)
  170. return;
  171. hlist_del(&tvlv->list);
  172. /* first call to decrement the counter, second call to free */
  173. batadv_tvlv_container_put(tvlv);
  174. batadv_tvlv_container_put(tvlv);
  175. }
  176. /**
  177. * batadv_tvlv_container_unregister - unregister tvlv container based on the
  178. * provided type and version (both need to match)
  179. * @bat_priv: the bat priv with all the soft interface information
  180. * @type: tvlv container type to unregister
  181. * @version: tvlv container type to unregister
  182. */
  183. void batadv_tvlv_container_unregister(struct batadv_priv *bat_priv,
  184. u8 type, u8 version)
  185. {
  186. struct batadv_tvlv_container *tvlv;
  187. spin_lock_bh(&bat_priv->tvlv.container_list_lock);
  188. tvlv = batadv_tvlv_container_get(bat_priv, type, version);
  189. batadv_tvlv_container_remove(bat_priv, tvlv);
  190. spin_unlock_bh(&bat_priv->tvlv.container_list_lock);
  191. }
  192. /**
  193. * batadv_tvlv_container_register - register tvlv type, version and content
  194. * to be propagated with each (primary interface) OGM
  195. * @bat_priv: the bat priv with all the soft interface information
  196. * @type: tvlv container type
  197. * @version: tvlv container version
  198. * @tvlv_value: tvlv container content
  199. * @tvlv_value_len: tvlv container content length
  200. *
  201. * If a container of the same type and version was already registered the new
  202. * content is going to replace the old one.
  203. */
  204. void batadv_tvlv_container_register(struct batadv_priv *bat_priv,
  205. u8 type, u8 version,
  206. void *tvlv_value, u16 tvlv_value_len)
  207. {
  208. struct batadv_tvlv_container *tvlv_old, *tvlv_new;
  209. if (!tvlv_value)
  210. tvlv_value_len = 0;
  211. tvlv_new = kzalloc(sizeof(*tvlv_new) + tvlv_value_len, GFP_ATOMIC);
  212. if (!tvlv_new)
  213. return;
  214. tvlv_new->tvlv_hdr.version = version;
  215. tvlv_new->tvlv_hdr.type = type;
  216. tvlv_new->tvlv_hdr.len = htons(tvlv_value_len);
  217. memcpy(tvlv_new + 1, tvlv_value, ntohs(tvlv_new->tvlv_hdr.len));
  218. INIT_HLIST_NODE(&tvlv_new->list);
  219. kref_init(&tvlv_new->refcount);
  220. spin_lock_bh(&bat_priv->tvlv.container_list_lock);
  221. tvlv_old = batadv_tvlv_container_get(bat_priv, type, version);
  222. batadv_tvlv_container_remove(bat_priv, tvlv_old);
  223. kref_get(&tvlv_new->refcount);
  224. hlist_add_head(&tvlv_new->list, &bat_priv->tvlv.container_list);
  225. spin_unlock_bh(&bat_priv->tvlv.container_list_lock);
  226. /* don't return reference to new tvlv_container */
  227. batadv_tvlv_container_put(tvlv_new);
  228. }
  229. /**
  230. * batadv_tvlv_realloc_packet_buff - reallocate packet buffer to accommodate
  231. * requested packet size
  232. * @packet_buff: packet buffer
  233. * @packet_buff_len: packet buffer size
  234. * @min_packet_len: requested packet minimum size
  235. * @additional_packet_len: requested additional packet size on top of minimum
  236. * size
  237. *
  238. * Return: true of the packet buffer could be changed to the requested size,
  239. * false otherwise.
  240. */
  241. static bool batadv_tvlv_realloc_packet_buff(unsigned char **packet_buff,
  242. int *packet_buff_len,
  243. int min_packet_len,
  244. int additional_packet_len)
  245. {
  246. unsigned char *new_buff;
  247. new_buff = kmalloc(min_packet_len + additional_packet_len, GFP_ATOMIC);
  248. /* keep old buffer if kmalloc should fail */
  249. if (!new_buff)
  250. return false;
  251. memcpy(new_buff, *packet_buff, min_packet_len);
  252. kfree(*packet_buff);
  253. *packet_buff = new_buff;
  254. *packet_buff_len = min_packet_len + additional_packet_len;
  255. return true;
  256. }
  257. /**
  258. * batadv_tvlv_container_ogm_append - append tvlv container content to given
  259. * OGM packet buffer
  260. * @bat_priv: the bat priv with all the soft interface information
  261. * @packet_buff: ogm packet buffer
  262. * @packet_buff_len: ogm packet buffer size including ogm header and tvlv
  263. * content
  264. * @packet_min_len: ogm header size to be preserved for the OGM itself
  265. *
  266. * The ogm packet might be enlarged or shrunk depending on the current size
  267. * and the size of the to-be-appended tvlv containers.
  268. *
  269. * Return: size of all appended tvlv containers in bytes.
  270. */
  271. u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
  272. unsigned char **packet_buff,
  273. int *packet_buff_len, int packet_min_len)
  274. {
  275. struct batadv_tvlv_container *tvlv;
  276. struct batadv_tvlv_hdr *tvlv_hdr;
  277. u16 tvlv_value_len;
  278. void *tvlv_value;
  279. bool ret;
  280. spin_lock_bh(&bat_priv->tvlv.container_list_lock);
  281. tvlv_value_len = batadv_tvlv_container_list_size(bat_priv);
  282. ret = batadv_tvlv_realloc_packet_buff(packet_buff, packet_buff_len,
  283. packet_min_len, tvlv_value_len);
  284. if (!ret)
  285. goto end;
  286. if (!tvlv_value_len)
  287. goto end;
  288. tvlv_value = (*packet_buff) + packet_min_len;
  289. hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) {
  290. tvlv_hdr = tvlv_value;
  291. tvlv_hdr->type = tvlv->tvlv_hdr.type;
  292. tvlv_hdr->version = tvlv->tvlv_hdr.version;
  293. tvlv_hdr->len = tvlv->tvlv_hdr.len;
  294. tvlv_value = tvlv_hdr + 1;
  295. memcpy(tvlv_value, tvlv + 1, ntohs(tvlv->tvlv_hdr.len));
  296. tvlv_value = (u8 *)tvlv_value + ntohs(tvlv->tvlv_hdr.len);
  297. }
  298. end:
  299. spin_unlock_bh(&bat_priv->tvlv.container_list_lock);
  300. return tvlv_value_len;
  301. }
  302. /**
  303. * batadv_tvlv_call_handler - parse the given tvlv buffer to call the
  304. * appropriate handlers
  305. * @bat_priv: the bat priv with all the soft interface information
  306. * @tvlv_handler: tvlv callback function handling the tvlv content
  307. * @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet
  308. * @orig_node: orig node emitting the ogm packet
  309. * @src: source mac address of the unicast packet
  310. * @dst: destination mac address of the unicast packet
  311. * @tvlv_value: tvlv content
  312. * @tvlv_value_len: tvlv content length
  313. *
  314. * Return: success if handler was not found or the return value of the handler
  315. * callback.
  316. */
  317. static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
  318. struct batadv_tvlv_handler *tvlv_handler,
  319. bool ogm_source,
  320. struct batadv_orig_node *orig_node,
  321. u8 *src, u8 *dst,
  322. void *tvlv_value, u16 tvlv_value_len)
  323. {
  324. if (!tvlv_handler)
  325. return NET_RX_SUCCESS;
  326. if (ogm_source) {
  327. if (!tvlv_handler->ogm_handler)
  328. return NET_RX_SUCCESS;
  329. if (!orig_node)
  330. return NET_RX_SUCCESS;
  331. tvlv_handler->ogm_handler(bat_priv, orig_node,
  332. BATADV_NO_FLAGS,
  333. tvlv_value, tvlv_value_len);
  334. tvlv_handler->flags |= BATADV_TVLV_HANDLER_OGM_CALLED;
  335. } else {
  336. if (!src)
  337. return NET_RX_SUCCESS;
  338. if (!dst)
  339. return NET_RX_SUCCESS;
  340. if (!tvlv_handler->unicast_handler)
  341. return NET_RX_SUCCESS;
  342. return tvlv_handler->unicast_handler(bat_priv, src,
  343. dst, tvlv_value,
  344. tvlv_value_len);
  345. }
  346. return NET_RX_SUCCESS;
  347. }
  348. /**
  349. * batadv_tvlv_containers_process - parse the given tvlv buffer to call the
  350. * appropriate handlers
  351. * @bat_priv: the bat priv with all the soft interface information
  352. * @ogm_source: flag indicating whether the tvlv is an ogm or a unicast packet
  353. * @orig_node: orig node emitting the ogm packet
  354. * @src: source mac address of the unicast packet
  355. * @dst: destination mac address of the unicast packet
  356. * @tvlv_value: tvlv content
  357. * @tvlv_value_len: tvlv content length
  358. *
  359. * Return: success when processing an OGM or the return value of all called
  360. * handler callbacks.
  361. */
  362. int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,
  363. bool ogm_source,
  364. struct batadv_orig_node *orig_node,
  365. u8 *src, u8 *dst,
  366. void *tvlv_value, u16 tvlv_value_len)
  367. {
  368. struct batadv_tvlv_handler *tvlv_handler;
  369. struct batadv_tvlv_hdr *tvlv_hdr;
  370. u16 tvlv_value_cont_len;
  371. u8 cifnotfound = BATADV_TVLV_HANDLER_OGM_CIFNOTFND;
  372. int ret = NET_RX_SUCCESS;
  373. while (tvlv_value_len >= sizeof(*tvlv_hdr)) {
  374. tvlv_hdr = tvlv_value;
  375. tvlv_value_cont_len = ntohs(tvlv_hdr->len);
  376. tvlv_value = tvlv_hdr + 1;
  377. tvlv_value_len -= sizeof(*tvlv_hdr);
  378. if (tvlv_value_cont_len > tvlv_value_len)
  379. break;
  380. tvlv_handler = batadv_tvlv_handler_get(bat_priv,
  381. tvlv_hdr->type,
  382. tvlv_hdr->version);
  383. ret |= batadv_tvlv_call_handler(bat_priv, tvlv_handler,
  384. ogm_source, orig_node,
  385. src, dst, tvlv_value,
  386. tvlv_value_cont_len);
  387. if (tvlv_handler)
  388. batadv_tvlv_handler_put(tvlv_handler);
  389. tvlv_value = (u8 *)tvlv_value + tvlv_value_cont_len;
  390. tvlv_value_len -= tvlv_value_cont_len;
  391. }
  392. if (!ogm_source)
  393. return ret;
  394. rcu_read_lock();
  395. hlist_for_each_entry_rcu(tvlv_handler,
  396. &bat_priv->tvlv.handler_list, list) {
  397. if ((tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) &&
  398. !(tvlv_handler->flags & BATADV_TVLV_HANDLER_OGM_CALLED))
  399. tvlv_handler->ogm_handler(bat_priv, orig_node,
  400. cifnotfound, NULL, 0);
  401. tvlv_handler->flags &= ~BATADV_TVLV_HANDLER_OGM_CALLED;
  402. }
  403. rcu_read_unlock();
  404. return NET_RX_SUCCESS;
  405. }
  406. /**
  407. * batadv_tvlv_ogm_receive - process an incoming ogm and call the appropriate
  408. * handlers
  409. * @bat_priv: the bat priv with all the soft interface information
  410. * @batadv_ogm_packet: ogm packet containing the tvlv containers
  411. * @orig_node: orig node emitting the ogm packet
  412. */
  413. void batadv_tvlv_ogm_receive(struct batadv_priv *bat_priv,
  414. struct batadv_ogm_packet *batadv_ogm_packet,
  415. struct batadv_orig_node *orig_node)
  416. {
  417. void *tvlv_value;
  418. u16 tvlv_value_len;
  419. if (!batadv_ogm_packet)
  420. return;
  421. tvlv_value_len = ntohs(batadv_ogm_packet->tvlv_len);
  422. if (!tvlv_value_len)
  423. return;
  424. tvlv_value = batadv_ogm_packet + 1;
  425. batadv_tvlv_containers_process(bat_priv, true, orig_node, NULL, NULL,
  426. tvlv_value, tvlv_value_len);
  427. }
  428. /**
  429. * batadv_tvlv_handler_register - register tvlv handler based on the provided
  430. * type and version (both need to match) for ogm tvlv payload and/or unicast
  431. * payload
  432. * @bat_priv: the bat priv with all the soft interface information
  433. * @optr: ogm tvlv handler callback function. This function receives the orig
  434. * node, flags and the tvlv content as argument to process.
  435. * @uptr: unicast tvlv handler callback function. This function receives the
  436. * source & destination of the unicast packet as well as the tvlv content
  437. * to process.
  438. * @type: tvlv handler type to be registered
  439. * @version: tvlv handler version to be registered
  440. * @flags: flags to enable or disable TVLV API behavior
  441. */
  442. void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
  443. void (*optr)(struct batadv_priv *bat_priv,
  444. struct batadv_orig_node *orig,
  445. u8 flags,
  446. void *tvlv_value,
  447. u16 tvlv_value_len),
  448. int (*uptr)(struct batadv_priv *bat_priv,
  449. u8 *src, u8 *dst,
  450. void *tvlv_value,
  451. u16 tvlv_value_len),
  452. u8 type, u8 version, u8 flags)
  453. {
  454. struct batadv_tvlv_handler *tvlv_handler;
  455. tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
  456. if (tvlv_handler) {
  457. batadv_tvlv_handler_put(tvlv_handler);
  458. return;
  459. }
  460. tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC);
  461. if (!tvlv_handler)
  462. return;
  463. tvlv_handler->ogm_handler = optr;
  464. tvlv_handler->unicast_handler = uptr;
  465. tvlv_handler->type = type;
  466. tvlv_handler->version = version;
  467. tvlv_handler->flags = flags;
  468. kref_init(&tvlv_handler->refcount);
  469. INIT_HLIST_NODE(&tvlv_handler->list);
  470. spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
  471. kref_get(&tvlv_handler->refcount);
  472. hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list);
  473. spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
  474. /* don't return reference to new tvlv_handler */
  475. batadv_tvlv_handler_put(tvlv_handler);
  476. }
  477. /**
  478. * batadv_tvlv_handler_unregister - unregister tvlv handler based on the
  479. * provided type and version (both need to match)
  480. * @bat_priv: the bat priv with all the soft interface information
  481. * @type: tvlv handler type to be unregistered
  482. * @version: tvlv handler version to be unregistered
  483. */
  484. void batadv_tvlv_handler_unregister(struct batadv_priv *bat_priv,
  485. u8 type, u8 version)
  486. {
  487. struct batadv_tvlv_handler *tvlv_handler;
  488. tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
  489. if (!tvlv_handler)
  490. return;
  491. batadv_tvlv_handler_put(tvlv_handler);
  492. spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
  493. hlist_del_rcu(&tvlv_handler->list);
  494. spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
  495. batadv_tvlv_handler_put(tvlv_handler);
  496. }
  497. /**
  498. * batadv_tvlv_unicast_send - send a unicast packet with tvlv payload to the
  499. * specified host
  500. * @bat_priv: the bat priv with all the soft interface information
  501. * @src: source mac address of the unicast packet
  502. * @dst: destination mac address of the unicast packet
  503. * @type: tvlv type
  504. * @version: tvlv version
  505. * @tvlv_value: tvlv content
  506. * @tvlv_value_len: tvlv content length
  507. */
  508. void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, u8 *src,
  509. u8 *dst, u8 type, u8 version,
  510. void *tvlv_value, u16 tvlv_value_len)
  511. {
  512. struct batadv_unicast_tvlv_packet *unicast_tvlv_packet;
  513. struct batadv_tvlv_hdr *tvlv_hdr;
  514. struct batadv_orig_node *orig_node;
  515. struct sk_buff *skb;
  516. unsigned char *tvlv_buff;
  517. unsigned int tvlv_len;
  518. ssize_t hdr_len = sizeof(*unicast_tvlv_packet);
  519. int res;
  520. orig_node = batadv_orig_hash_find(bat_priv, dst);
  521. if (!orig_node)
  522. return;
  523. tvlv_len = sizeof(*tvlv_hdr) + tvlv_value_len;
  524. skb = netdev_alloc_skb_ip_align(NULL, ETH_HLEN + hdr_len + tvlv_len);
  525. if (!skb)
  526. goto out;
  527. skb->priority = TC_PRIO_CONTROL;
  528. skb_reserve(skb, ETH_HLEN);
  529. tvlv_buff = skb_put(skb, sizeof(*unicast_tvlv_packet) + tvlv_len);
  530. unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)tvlv_buff;
  531. unicast_tvlv_packet->packet_type = BATADV_UNICAST_TVLV;
  532. unicast_tvlv_packet->version = BATADV_COMPAT_VERSION;
  533. unicast_tvlv_packet->ttl = BATADV_TTL;
  534. unicast_tvlv_packet->reserved = 0;
  535. unicast_tvlv_packet->tvlv_len = htons(tvlv_len);
  536. unicast_tvlv_packet->align = 0;
  537. ether_addr_copy(unicast_tvlv_packet->src, src);
  538. ether_addr_copy(unicast_tvlv_packet->dst, dst);
  539. tvlv_buff = (unsigned char *)(unicast_tvlv_packet + 1);
  540. tvlv_hdr = (struct batadv_tvlv_hdr *)tvlv_buff;
  541. tvlv_hdr->version = version;
  542. tvlv_hdr->type = type;
  543. tvlv_hdr->len = htons(tvlv_value_len);
  544. tvlv_buff += sizeof(*tvlv_hdr);
  545. memcpy(tvlv_buff, tvlv_value, tvlv_value_len);
  546. res = batadv_send_skb_to_orig(skb, orig_node, NULL);
  547. if (res == -1)
  548. kfree_skb(skb);
  549. out:
  550. batadv_orig_node_put(orig_node);
  551. }