gateway_client.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (C) B.A.T.M.A.N. contributors:
  3. *
  4. * Marek Lindner
  5. */
  6. #include "gateway_client.h"
  7. #include "main.h"
  8. #include <linux/atomic.h>
  9. #include <linux/byteorder/generic.h>
  10. #include <linux/container_of.h>
  11. #include <linux/err.h>
  12. #include <linux/errno.h>
  13. #include <linux/etherdevice.h>
  14. #include <linux/gfp.h>
  15. #include <linux/if_ether.h>
  16. #include <linux/if_vlan.h>
  17. #include <linux/in.h>
  18. #include <linux/ip.h>
  19. #include <linux/ipv6.h>
  20. #include <linux/kref.h>
  21. #include <linux/list.h>
  22. #include <linux/lockdep.h>
  23. #include <linux/netdevice.h>
  24. #include <linux/netlink.h>
  25. #include <linux/rculist.h>
  26. #include <linux/rcupdate.h>
  27. #include <linux/skbuff.h>
  28. #include <linux/slab.h>
  29. #include <linux/spinlock.h>
  30. #include <linux/sprintf.h>
  31. #include <linux/stddef.h>
  32. #include <linux/udp.h>
  33. #include <uapi/linux/batadv_packet.h>
  34. #include <uapi/linux/batman_adv.h>
  35. #include "hard-interface.h"
  36. #include "log.h"
  37. #include "netlink.h"
  38. #include "originator.h"
  39. #include "routing.h"
  40. #include "translation-table.h"
  41. /* These are the offsets of the "hw type" and "hw address length" in the dhcp
  42. * packet starting at the beginning of the dhcp header
  43. */
  44. #define BATADV_DHCP_HTYPE_OFFSET 1
  45. #define BATADV_DHCP_HLEN_OFFSET 2
  46. /* Value of htype representing Ethernet */
  47. #define BATADV_DHCP_HTYPE_ETHERNET 0x01
  48. /* This is the offset of the "chaddr" field in the dhcp packet starting at the
  49. * beginning of the dhcp header
  50. */
  51. #define BATADV_DHCP_CHADDR_OFFSET 28
  52. /**
  53. * batadv_gw_node_release() - release gw_node from lists and queue for free
  54. * after rcu grace period
  55. * @ref: kref pointer of the gw_node
  56. */
  57. void batadv_gw_node_release(struct kref *ref)
  58. {
  59. struct batadv_gw_node *gw_node;
  60. gw_node = container_of(ref, struct batadv_gw_node, refcount);
  61. batadv_orig_node_put(gw_node->orig_node);
  62. kfree_rcu(gw_node, rcu);
  63. }
  64. /**
  65. * batadv_gw_get_selected_gw_node() - Get currently selected gateway
  66. * @bat_priv: the bat priv with all the mesh interface information
  67. *
  68. * Return: selected gateway (with increased refcnt), NULL on errors
  69. */
  70. struct batadv_gw_node *
  71. batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv)
  72. {
  73. struct batadv_gw_node *gw_node;
  74. rcu_read_lock();
  75. gw_node = rcu_dereference(bat_priv->gw.curr_gw);
  76. if (!gw_node)
  77. goto out;
  78. if (!kref_get_unless_zero(&gw_node->refcount))
  79. gw_node = NULL;
  80. out:
  81. rcu_read_unlock();
  82. return gw_node;
  83. }
  84. /**
  85. * batadv_gw_get_selected_orig() - Get originator of currently selected gateway
  86. * @bat_priv: the bat priv with all the mesh interface information
  87. *
  88. * Return: orig_node of selected gateway (with increased refcnt), NULL on errors
  89. */
  90. struct batadv_orig_node *
  91. batadv_gw_get_selected_orig(struct batadv_priv *bat_priv)
  92. {
  93. struct batadv_gw_node *gw_node;
  94. struct batadv_orig_node *orig_node = NULL;
  95. gw_node = batadv_gw_get_selected_gw_node(bat_priv);
  96. if (!gw_node)
  97. goto out;
  98. rcu_read_lock();
  99. orig_node = gw_node->orig_node;
  100. if (!orig_node)
  101. goto unlock;
  102. if (!kref_get_unless_zero(&orig_node->refcount))
  103. orig_node = NULL;
  104. unlock:
  105. rcu_read_unlock();
  106. out:
  107. batadv_gw_node_put(gw_node);
  108. return orig_node;
  109. }
  110. static void batadv_gw_select(struct batadv_priv *bat_priv,
  111. struct batadv_gw_node *new_gw_node)
  112. {
  113. struct batadv_gw_node *curr_gw_node;
  114. spin_lock_bh(&bat_priv->gw.list_lock);
  115. if (new_gw_node)
  116. kref_get(&new_gw_node->refcount);
  117. curr_gw_node = rcu_replace_pointer(bat_priv->gw.curr_gw, new_gw_node,
  118. true);
  119. batadv_gw_node_put(curr_gw_node);
  120. spin_unlock_bh(&bat_priv->gw.list_lock);
  121. }
  122. /**
  123. * batadv_gw_reselect() - force a gateway reselection
  124. * @bat_priv: the bat priv with all the mesh interface information
  125. *
  126. * Set a flag to remind the GW component to perform a new gateway reselection.
  127. * However this function does not ensure that the current gateway is going to be
  128. * deselected. The reselection mechanism may elect the same gateway once again.
  129. *
  130. * This means that invoking batadv_gw_reselect() does not guarantee a gateway
  131. * change and therefore a uevent is not necessarily expected.
  132. */
  133. void batadv_gw_reselect(struct batadv_priv *bat_priv)
  134. {
  135. atomic_set(&bat_priv->gw.reselect, 1);
  136. }
  137. /**
  138. * batadv_gw_check_client_stop() - check if client mode has been switched off
  139. * @bat_priv: the bat priv with all the mesh interface information
  140. *
  141. * This function assumes the caller has checked that the gw state *is actually
  142. * changing*. This function is not supposed to be called when there is no state
  143. * change.
  144. */
  145. void batadv_gw_check_client_stop(struct batadv_priv *bat_priv)
  146. {
  147. struct batadv_gw_node *curr_gw;
  148. if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
  149. return;
  150. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  151. if (!curr_gw)
  152. return;
  153. /* deselect the current gateway so that next time that client mode is
  154. * enabled a proper GW_ADD event can be sent
  155. */
  156. batadv_gw_select(bat_priv, NULL);
  157. /* if batman-adv is switching the gw client mode off and a gateway was
  158. * already selected, send a DEL uevent
  159. */
  160. batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL, NULL);
  161. batadv_gw_node_put(curr_gw);
  162. }
  163. /**
  164. * batadv_gw_election() - Elect the best gateway
  165. * @bat_priv: the bat priv with all the mesh interface information
  166. */
  167. void batadv_gw_election(struct batadv_priv *bat_priv)
  168. {
  169. struct batadv_gw_node *curr_gw = NULL;
  170. struct batadv_gw_node *next_gw = NULL;
  171. struct batadv_neigh_node *router = NULL;
  172. struct batadv_neigh_ifinfo *router_ifinfo = NULL;
  173. char gw_addr[18] = { '\0' };
  174. if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
  175. goto out;
  176. if (!bat_priv->algo_ops->gw.get_best_gw_node)
  177. goto out;
  178. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  179. if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw)
  180. goto out;
  181. /* if gw.reselect is set to 1 it means that a previous call to
  182. * gw.is_eligible() said that we have a new best GW, therefore it can
  183. * now be picked from the list and selected
  184. */
  185. next_gw = bat_priv->algo_ops->gw.get_best_gw_node(bat_priv);
  186. if (curr_gw == next_gw)
  187. goto out;
  188. if (next_gw) {
  189. sprintf(gw_addr, "%pM", next_gw->orig_node->orig);
  190. router = batadv_orig_router_get(next_gw->orig_node,
  191. BATADV_IF_DEFAULT);
  192. if (!router) {
  193. batadv_gw_reselect(bat_priv);
  194. goto out;
  195. }
  196. router_ifinfo = batadv_neigh_ifinfo_get(router,
  197. BATADV_IF_DEFAULT);
  198. if (!router_ifinfo) {
  199. batadv_gw_reselect(bat_priv);
  200. goto out;
  201. }
  202. }
  203. if (curr_gw && !next_gw) {
  204. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  205. "Removing selected gateway - no gateway in range\n");
  206. batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL,
  207. NULL);
  208. } else if (!curr_gw && next_gw) {
  209. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  210. "Adding route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
  211. next_gw->orig_node->orig,
  212. next_gw->bandwidth_down / 10,
  213. next_gw->bandwidth_down % 10,
  214. next_gw->bandwidth_up / 10,
  215. next_gw->bandwidth_up % 10,
  216. router_ifinfo->bat_iv.tq_avg);
  217. batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
  218. gw_addr);
  219. } else {
  220. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  221. "Changing route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
  222. next_gw->orig_node->orig,
  223. next_gw->bandwidth_down / 10,
  224. next_gw->bandwidth_down % 10,
  225. next_gw->bandwidth_up / 10,
  226. next_gw->bandwidth_up % 10,
  227. router_ifinfo->bat_iv.tq_avg);
  228. batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
  229. gw_addr);
  230. }
  231. batadv_gw_select(bat_priv, next_gw);
  232. out:
  233. batadv_gw_node_put(curr_gw);
  234. batadv_gw_node_put(next_gw);
  235. batadv_neigh_node_put(router);
  236. batadv_neigh_ifinfo_put(router_ifinfo);
  237. }
  238. /**
  239. * batadv_gw_check_election() - Elect orig node as best gateway when eligible
  240. * @bat_priv: the bat priv with all the mesh interface information
  241. * @orig_node: orig node which is to be checked
  242. */
  243. void batadv_gw_check_election(struct batadv_priv *bat_priv,
  244. struct batadv_orig_node *orig_node)
  245. {
  246. struct batadv_orig_node *curr_gw_orig;
  247. /* abort immediately if the routing algorithm does not support gateway
  248. * election
  249. */
  250. if (!bat_priv->algo_ops->gw.is_eligible)
  251. return;
  252. curr_gw_orig = batadv_gw_get_selected_orig(bat_priv);
  253. if (!curr_gw_orig)
  254. goto reselect;
  255. /* this node already is the gateway */
  256. if (curr_gw_orig == orig_node)
  257. goto out;
  258. if (!bat_priv->algo_ops->gw.is_eligible(bat_priv, curr_gw_orig,
  259. orig_node))
  260. goto out;
  261. reselect:
  262. batadv_gw_reselect(bat_priv);
  263. out:
  264. batadv_orig_node_put(curr_gw_orig);
  265. }
  266. /**
  267. * batadv_gw_node_add() - add gateway node to list of available gateways
  268. * @bat_priv: the bat priv with all the mesh interface information
  269. * @orig_node: originator announcing gateway capabilities
  270. * @gateway: announced bandwidth information
  271. *
  272. * Has to be called with the appropriate locks being acquired
  273. * (gw.list_lock).
  274. */
  275. static void batadv_gw_node_add(struct batadv_priv *bat_priv,
  276. struct batadv_orig_node *orig_node,
  277. struct batadv_tvlv_gateway_data *gateway)
  278. {
  279. struct batadv_gw_node *gw_node;
  280. lockdep_assert_held(&bat_priv->gw.list_lock);
  281. if (gateway->bandwidth_down == 0)
  282. return;
  283. gw_node = kzalloc_obj(*gw_node, GFP_ATOMIC);
  284. if (!gw_node)
  285. return;
  286. kref_init(&gw_node->refcount);
  287. INIT_HLIST_NODE(&gw_node->list);
  288. kref_get(&orig_node->refcount);
  289. gw_node->orig_node = orig_node;
  290. gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
  291. gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
  292. kref_get(&gw_node->refcount);
  293. hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list);
  294. bat_priv->gw.generation++;
  295. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  296. "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
  297. orig_node->orig,
  298. ntohl(gateway->bandwidth_down) / 10,
  299. ntohl(gateway->bandwidth_down) % 10,
  300. ntohl(gateway->bandwidth_up) / 10,
  301. ntohl(gateway->bandwidth_up) % 10);
  302. /* don't return reference to new gw_node */
  303. batadv_gw_node_put(gw_node);
  304. }
  305. /**
  306. * batadv_gw_node_get() - retrieve gateway node from list of available gateways
  307. * @bat_priv: the bat priv with all the mesh interface information
  308. * @orig_node: originator announcing gateway capabilities
  309. *
  310. * Return: gateway node if found or NULL otherwise.
  311. */
  312. struct batadv_gw_node *batadv_gw_node_get(struct batadv_priv *bat_priv,
  313. struct batadv_orig_node *orig_node)
  314. {
  315. struct batadv_gw_node *gw_node_tmp, *gw_node = NULL;
  316. rcu_read_lock();
  317. hlist_for_each_entry_rcu(gw_node_tmp, &bat_priv->gw.gateway_list,
  318. list) {
  319. if (gw_node_tmp->orig_node != orig_node)
  320. continue;
  321. if (!kref_get_unless_zero(&gw_node_tmp->refcount))
  322. continue;
  323. gw_node = gw_node_tmp;
  324. break;
  325. }
  326. rcu_read_unlock();
  327. return gw_node;
  328. }
  329. /**
  330. * batadv_gw_node_update() - update list of available gateways with changed
  331. * bandwidth information
  332. * @bat_priv: the bat priv with all the mesh interface information
  333. * @orig_node: originator announcing gateway capabilities
  334. * @gateway: announced bandwidth information
  335. */
  336. void batadv_gw_node_update(struct batadv_priv *bat_priv,
  337. struct batadv_orig_node *orig_node,
  338. struct batadv_tvlv_gateway_data *gateway)
  339. {
  340. struct batadv_gw_node *gw_node, *curr_gw = NULL;
  341. spin_lock_bh(&bat_priv->gw.list_lock);
  342. gw_node = batadv_gw_node_get(bat_priv, orig_node);
  343. if (!gw_node) {
  344. batadv_gw_node_add(bat_priv, orig_node, gateway);
  345. spin_unlock_bh(&bat_priv->gw.list_lock);
  346. goto out;
  347. }
  348. spin_unlock_bh(&bat_priv->gw.list_lock);
  349. if (gw_node->bandwidth_down == ntohl(gateway->bandwidth_down) &&
  350. gw_node->bandwidth_up == ntohl(gateway->bandwidth_up))
  351. goto out;
  352. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  353. "Gateway bandwidth of originator %pM changed from %u.%u/%u.%u MBit to %u.%u/%u.%u MBit\n",
  354. orig_node->orig,
  355. gw_node->bandwidth_down / 10,
  356. gw_node->bandwidth_down % 10,
  357. gw_node->bandwidth_up / 10,
  358. gw_node->bandwidth_up % 10,
  359. ntohl(gateway->bandwidth_down) / 10,
  360. ntohl(gateway->bandwidth_down) % 10,
  361. ntohl(gateway->bandwidth_up) / 10,
  362. ntohl(gateway->bandwidth_up) % 10);
  363. gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
  364. gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
  365. if (ntohl(gateway->bandwidth_down) == 0) {
  366. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  367. "Gateway %pM removed from gateway list\n",
  368. orig_node->orig);
  369. /* Note: We don't need a NULL check here, since curr_gw never
  370. * gets dereferenced.
  371. */
  372. spin_lock_bh(&bat_priv->gw.list_lock);
  373. if (!hlist_unhashed(&gw_node->list)) {
  374. hlist_del_init_rcu(&gw_node->list);
  375. batadv_gw_node_put(gw_node);
  376. bat_priv->gw.generation++;
  377. }
  378. spin_unlock_bh(&bat_priv->gw.list_lock);
  379. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  380. if (gw_node == curr_gw)
  381. batadv_gw_reselect(bat_priv);
  382. batadv_gw_node_put(curr_gw);
  383. }
  384. out:
  385. batadv_gw_node_put(gw_node);
  386. }
  387. /**
  388. * batadv_gw_node_delete() - Remove orig_node from gateway list
  389. * @bat_priv: the bat priv with all the mesh interface information
  390. * @orig_node: orig node which is currently in process of being removed
  391. */
  392. void batadv_gw_node_delete(struct batadv_priv *bat_priv,
  393. struct batadv_orig_node *orig_node)
  394. {
  395. struct batadv_tvlv_gateway_data gateway;
  396. gateway.bandwidth_down = 0;
  397. gateway.bandwidth_up = 0;
  398. batadv_gw_node_update(bat_priv, orig_node, &gateway);
  399. }
  400. /**
  401. * batadv_gw_node_free() - Free gateway information from mesh interface
  402. * @bat_priv: the bat priv with all the mesh interface information
  403. */
  404. void batadv_gw_node_free(struct batadv_priv *bat_priv)
  405. {
  406. struct batadv_gw_node *gw_node;
  407. struct hlist_node *node_tmp;
  408. spin_lock_bh(&bat_priv->gw.list_lock);
  409. hlist_for_each_entry_safe(gw_node, node_tmp,
  410. &bat_priv->gw.gateway_list, list) {
  411. hlist_del_init_rcu(&gw_node->list);
  412. batadv_gw_node_put(gw_node);
  413. bat_priv->gw.generation++;
  414. }
  415. spin_unlock_bh(&bat_priv->gw.list_lock);
  416. }
  417. /**
  418. * batadv_gw_dump() - Dump gateways into a message
  419. * @msg: Netlink message to dump into
  420. * @cb: Control block containing additional options
  421. *
  422. * Return: Error code, or length of message
  423. */
  424. int batadv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb)
  425. {
  426. struct batadv_hard_iface *primary_if = NULL;
  427. struct net_device *mesh_iface;
  428. struct batadv_priv *bat_priv;
  429. int ret;
  430. mesh_iface = batadv_netlink_get_meshif(cb);
  431. if (IS_ERR(mesh_iface))
  432. return PTR_ERR(mesh_iface);
  433. bat_priv = netdev_priv(mesh_iface);
  434. primary_if = batadv_primary_if_get_selected(bat_priv);
  435. if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
  436. ret = -ENOENT;
  437. goto out;
  438. }
  439. if (!bat_priv->algo_ops->gw.dump) {
  440. ret = -EOPNOTSUPP;
  441. goto out;
  442. }
  443. bat_priv->algo_ops->gw.dump(msg, cb, bat_priv);
  444. ret = msg->len;
  445. out:
  446. batadv_hardif_put(primary_if);
  447. dev_put(mesh_iface);
  448. return ret;
  449. }
  450. /**
  451. * batadv_gw_dhcp_recipient_get() - check if a packet is a DHCP message
  452. * @skb: the packet to check
  453. * @header_len: a pointer to the batman-adv header size
  454. * @chaddr: buffer where the client address will be stored. Valid
  455. * only if the function returns BATADV_DHCP_TO_CLIENT
  456. *
  457. * This function may re-allocate the data buffer of the skb passed as argument.
  458. *
  459. * Return:
  460. * - BATADV_DHCP_NO if the packet is not a dhcp message or if there was an error
  461. * while parsing it
  462. * - BATADV_DHCP_TO_SERVER if this is a message going to the DHCP server
  463. * - BATADV_DHCP_TO_CLIENT if this is a message going to a DHCP client
  464. */
  465. enum batadv_dhcp_recipient
  466. batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
  467. u8 *chaddr)
  468. {
  469. enum batadv_dhcp_recipient ret = BATADV_DHCP_NO;
  470. struct ethhdr *ethhdr;
  471. struct iphdr *iphdr;
  472. struct ipv6hdr *ipv6hdr;
  473. struct udphdr *udphdr;
  474. struct vlan_ethhdr *vhdr;
  475. int chaddr_offset;
  476. __be16 proto;
  477. u8 *p;
  478. /* check for ethernet header */
  479. if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
  480. return BATADV_DHCP_NO;
  481. ethhdr = eth_hdr(skb);
  482. proto = ethhdr->h_proto;
  483. *header_len += ETH_HLEN;
  484. /* check for initial vlan header */
  485. if (proto == htons(ETH_P_8021Q)) {
  486. if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
  487. return BATADV_DHCP_NO;
  488. vhdr = vlan_eth_hdr(skb);
  489. proto = vhdr->h_vlan_encapsulated_proto;
  490. *header_len += VLAN_HLEN;
  491. }
  492. /* check for ip header */
  493. switch (proto) {
  494. case htons(ETH_P_IP):
  495. if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr)))
  496. return BATADV_DHCP_NO;
  497. iphdr = (struct iphdr *)(skb->data + *header_len);
  498. *header_len += iphdr->ihl * 4;
  499. /* check for udp header */
  500. if (iphdr->protocol != IPPROTO_UDP)
  501. return BATADV_DHCP_NO;
  502. break;
  503. case htons(ETH_P_IPV6):
  504. if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr)))
  505. return BATADV_DHCP_NO;
  506. ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len);
  507. *header_len += sizeof(*ipv6hdr);
  508. /* check for udp header */
  509. if (ipv6hdr->nexthdr != IPPROTO_UDP)
  510. return BATADV_DHCP_NO;
  511. break;
  512. default:
  513. return BATADV_DHCP_NO;
  514. }
  515. if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr)))
  516. return BATADV_DHCP_NO;
  517. udphdr = (struct udphdr *)(skb->data + *header_len);
  518. *header_len += sizeof(*udphdr);
  519. /* check for bootp port */
  520. switch (proto) {
  521. case htons(ETH_P_IP):
  522. if (udphdr->dest == htons(67))
  523. ret = BATADV_DHCP_TO_SERVER;
  524. else if (udphdr->source == htons(67))
  525. ret = BATADV_DHCP_TO_CLIENT;
  526. break;
  527. case htons(ETH_P_IPV6):
  528. if (udphdr->dest == htons(547))
  529. ret = BATADV_DHCP_TO_SERVER;
  530. else if (udphdr->source == htons(547))
  531. ret = BATADV_DHCP_TO_CLIENT;
  532. break;
  533. }
  534. chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET;
  535. /* store the client address if the message is going to a client */
  536. if (ret == BATADV_DHCP_TO_CLIENT) {
  537. if (!pskb_may_pull(skb, chaddr_offset + ETH_ALEN))
  538. return BATADV_DHCP_NO;
  539. /* check if the DHCP packet carries an Ethernet DHCP */
  540. p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET;
  541. if (*p != BATADV_DHCP_HTYPE_ETHERNET)
  542. return BATADV_DHCP_NO;
  543. /* check if the DHCP packet carries a valid Ethernet address */
  544. p = skb->data + *header_len + BATADV_DHCP_HLEN_OFFSET;
  545. if (*p != ETH_ALEN)
  546. return BATADV_DHCP_NO;
  547. ether_addr_copy(chaddr, skb->data + chaddr_offset);
  548. }
  549. return ret;
  550. }
  551. /**
  552. * batadv_gw_out_of_range() - check if the dhcp request destination is the best
  553. * gateway
  554. * @bat_priv: the bat priv with all the mesh interface information
  555. * @skb: the outgoing packet
  556. *
  557. * Check if the skb is a DHCP request and if it is sent to the current best GW
  558. * server. Due to topology changes it may be the case that the GW server
  559. * previously selected is not the best one anymore.
  560. *
  561. * This call might reallocate skb data.
  562. * Must be invoked only when the DHCP packet is going TO a DHCP SERVER.
  563. *
  564. * Return: true if the packet destination is unicast and it is not the best gw,
  565. * false otherwise.
  566. */
  567. bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
  568. struct sk_buff *skb)
  569. {
  570. struct batadv_neigh_node *neigh_curr = NULL;
  571. struct batadv_neigh_node *neigh_old = NULL;
  572. struct batadv_orig_node *orig_dst_node = NULL;
  573. struct batadv_gw_node *gw_node = NULL;
  574. struct batadv_gw_node *curr_gw = NULL;
  575. struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
  576. struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
  577. bool out_of_range = false;
  578. u8 curr_tq_avg;
  579. unsigned short vid;
  580. vid = batadv_get_vid(skb, 0);
  581. if (is_multicast_ether_addr(ethhdr->h_dest))
  582. goto out;
  583. orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
  584. ethhdr->h_dest, vid);
  585. if (!orig_dst_node)
  586. goto out;
  587. gw_node = batadv_gw_node_get(bat_priv, orig_dst_node);
  588. if (!gw_node)
  589. goto out;
  590. switch (atomic_read(&bat_priv->gw.mode)) {
  591. case BATADV_GW_MODE_SERVER:
  592. /* If we are a GW then we are our best GW. We can artificially
  593. * set the tq towards ourself as the maximum value
  594. */
  595. curr_tq_avg = BATADV_TQ_MAX_VALUE;
  596. break;
  597. case BATADV_GW_MODE_CLIENT:
  598. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  599. if (!curr_gw)
  600. goto out;
  601. /* packet is going to our gateway */
  602. if (curr_gw->orig_node == orig_dst_node)
  603. goto out;
  604. /* If the dhcp packet has been sent to a different gw,
  605. * we have to evaluate whether the old gw is still
  606. * reliable enough
  607. */
  608. neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node,
  609. NULL);
  610. if (!neigh_curr)
  611. goto out;
  612. curr_ifinfo = batadv_neigh_ifinfo_get(neigh_curr,
  613. BATADV_IF_DEFAULT);
  614. if (!curr_ifinfo)
  615. goto out;
  616. curr_tq_avg = curr_ifinfo->bat_iv.tq_avg;
  617. batadv_neigh_ifinfo_put(curr_ifinfo);
  618. break;
  619. case BATADV_GW_MODE_OFF:
  620. default:
  621. goto out;
  622. }
  623. neigh_old = batadv_find_router(bat_priv, orig_dst_node, NULL);
  624. if (!neigh_old)
  625. goto out;
  626. old_ifinfo = batadv_neigh_ifinfo_get(neigh_old, BATADV_IF_DEFAULT);
  627. if (!old_ifinfo)
  628. goto out;
  629. if ((curr_tq_avg - old_ifinfo->bat_iv.tq_avg) > BATADV_GW_THRESHOLD)
  630. out_of_range = true;
  631. batadv_neigh_ifinfo_put(old_ifinfo);
  632. out:
  633. batadv_orig_node_put(orig_dst_node);
  634. batadv_gw_node_put(curr_gw);
  635. batadv_gw_node_put(gw_node);
  636. batadv_neigh_node_put(neigh_old);
  637. batadv_neigh_node_put(neigh_curr);
  638. return out_of_range;
  639. }