gateway_client.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. /* Copyright (C) 2009-2014 B.A.T.M.A.N. contributors:
  2. *
  3. * Marek Lindner
  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 "sysfs.h"
  19. #include "gateway_client.h"
  20. #include "gateway_common.h"
  21. #include "hard-interface.h"
  22. #include "originator.h"
  23. #include "translation-table.h"
  24. #include "routing.h"
  25. #include <linux/ip.h>
  26. #include <linux/ipv6.h>
  27. #include <linux/udp.h>
  28. #include <linux/if_vlan.h>
  29. /* These are the offsets of the "hw type" and "hw address length" in the dhcp
  30. * packet starting at the beginning of the dhcp header
  31. */
  32. #define BATADV_DHCP_HTYPE_OFFSET 1
  33. #define BATADV_DHCP_HLEN_OFFSET 2
  34. /* Value of htype representing Ethernet */
  35. #define BATADV_DHCP_HTYPE_ETHERNET 0x01
  36. /* This is the offset of the "chaddr" field in the dhcp packet starting at the
  37. * beginning of the dhcp header
  38. */
  39. #define BATADV_DHCP_CHADDR_OFFSET 28
  40. static void batadv_gw_node_free_ref(struct batadv_gw_node *gw_node)
  41. {
  42. if (atomic_dec_and_test(&gw_node->refcount)) {
  43. batadv_orig_node_free_ref(gw_node->orig_node);
  44. kfree_rcu(gw_node, rcu);
  45. }
  46. }
  47. static struct batadv_gw_node *
  48. batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv)
  49. {
  50. struct batadv_gw_node *gw_node;
  51. rcu_read_lock();
  52. gw_node = rcu_dereference(bat_priv->gw.curr_gw);
  53. if (!gw_node)
  54. goto out;
  55. if (!atomic_inc_not_zero(&gw_node->refcount))
  56. gw_node = NULL;
  57. out:
  58. rcu_read_unlock();
  59. return gw_node;
  60. }
  61. struct batadv_orig_node *
  62. batadv_gw_get_selected_orig(struct batadv_priv *bat_priv)
  63. {
  64. struct batadv_gw_node *gw_node;
  65. struct batadv_orig_node *orig_node = NULL;
  66. gw_node = batadv_gw_get_selected_gw_node(bat_priv);
  67. if (!gw_node)
  68. goto out;
  69. rcu_read_lock();
  70. orig_node = gw_node->orig_node;
  71. if (!orig_node)
  72. goto unlock;
  73. if (!atomic_inc_not_zero(&orig_node->refcount))
  74. orig_node = NULL;
  75. unlock:
  76. rcu_read_unlock();
  77. out:
  78. if (gw_node)
  79. batadv_gw_node_free_ref(gw_node);
  80. return orig_node;
  81. }
  82. static void batadv_gw_select(struct batadv_priv *bat_priv,
  83. struct batadv_gw_node *new_gw_node)
  84. {
  85. struct batadv_gw_node *curr_gw_node;
  86. spin_lock_bh(&bat_priv->gw.list_lock);
  87. if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
  88. new_gw_node = NULL;
  89. curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1);
  90. rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node);
  91. if (curr_gw_node)
  92. batadv_gw_node_free_ref(curr_gw_node);
  93. spin_unlock_bh(&bat_priv->gw.list_lock);
  94. }
  95. /**
  96. * batadv_gw_reselect - force a gateway reselection
  97. * @bat_priv: the bat priv with all the soft interface information
  98. *
  99. * Set a flag to remind the GW component to perform a new gateway reselection.
  100. * However this function does not ensure that the current gateway is going to be
  101. * deselected. The reselection mechanism may elect the same gateway once again.
  102. *
  103. * This means that invoking batadv_gw_reselect() does not guarantee a gateway
  104. * change and therefore a uevent is not necessarily expected.
  105. */
  106. void batadv_gw_reselect(struct batadv_priv *bat_priv)
  107. {
  108. atomic_set(&bat_priv->gw.reselect, 1);
  109. }
  110. static struct batadv_gw_node *
  111. batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
  112. {
  113. struct batadv_neigh_node *router;
  114. struct batadv_neigh_ifinfo *router_ifinfo;
  115. struct batadv_gw_node *gw_node, *curr_gw = NULL;
  116. uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
  117. uint32_t gw_divisor;
  118. uint8_t max_tq = 0;
  119. uint8_t tq_avg;
  120. struct batadv_orig_node *orig_node;
  121. gw_divisor = BATADV_TQ_LOCAL_WINDOW_SIZE * BATADV_TQ_LOCAL_WINDOW_SIZE;
  122. gw_divisor *= 64;
  123. rcu_read_lock();
  124. hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
  125. if (gw_node->deleted)
  126. continue;
  127. orig_node = gw_node->orig_node;
  128. router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
  129. if (!router)
  130. continue;
  131. router_ifinfo = batadv_neigh_ifinfo_get(router,
  132. BATADV_IF_DEFAULT);
  133. if (!router_ifinfo)
  134. goto next;
  135. if (!atomic_inc_not_zero(&gw_node->refcount))
  136. goto next;
  137. tq_avg = router_ifinfo->bat_iv.tq_avg;
  138. switch (atomic_read(&bat_priv->gw_sel_class)) {
  139. case 1: /* fast connection */
  140. tmp_gw_factor = tq_avg * tq_avg;
  141. tmp_gw_factor *= gw_node->bandwidth_down;
  142. tmp_gw_factor *= 100 * 100;
  143. tmp_gw_factor /= gw_divisor;
  144. if ((tmp_gw_factor > max_gw_factor) ||
  145. ((tmp_gw_factor == max_gw_factor) &&
  146. (tq_avg > max_tq))) {
  147. if (curr_gw)
  148. batadv_gw_node_free_ref(curr_gw);
  149. curr_gw = gw_node;
  150. atomic_inc(&curr_gw->refcount);
  151. }
  152. break;
  153. default: /* 2: stable connection (use best statistic)
  154. * 3: fast-switch (use best statistic but change as
  155. * soon as a better gateway appears)
  156. * XX: late-switch (use best statistic but change as
  157. * soon as a better gateway appears which has
  158. * $routing_class more tq points)
  159. */
  160. if (tq_avg > max_tq) {
  161. if (curr_gw)
  162. batadv_gw_node_free_ref(curr_gw);
  163. curr_gw = gw_node;
  164. atomic_inc(&curr_gw->refcount);
  165. }
  166. break;
  167. }
  168. if (tq_avg > max_tq)
  169. max_tq = tq_avg;
  170. if (tmp_gw_factor > max_gw_factor)
  171. max_gw_factor = tmp_gw_factor;
  172. batadv_gw_node_free_ref(gw_node);
  173. next:
  174. batadv_neigh_node_free_ref(router);
  175. if (router_ifinfo)
  176. batadv_neigh_ifinfo_free_ref(router_ifinfo);
  177. }
  178. rcu_read_unlock();
  179. return curr_gw;
  180. }
  181. /**
  182. * batadv_gw_check_client_stop - check if client mode has been switched off
  183. * @bat_priv: the bat priv with all the soft interface information
  184. *
  185. * This function assumes the caller has checked that the gw state *is actually
  186. * changing*. This function is not supposed to be called when there is no state
  187. * change.
  188. */
  189. void batadv_gw_check_client_stop(struct batadv_priv *bat_priv)
  190. {
  191. struct batadv_gw_node *curr_gw;
  192. if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
  193. return;
  194. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  195. if (!curr_gw)
  196. return;
  197. /* deselect the current gateway so that next time that client mode is
  198. * enabled a proper GW_ADD event can be sent
  199. */
  200. batadv_gw_select(bat_priv, NULL);
  201. /* if batman-adv is switching the gw client mode off and a gateway was
  202. * already selected, send a DEL uevent
  203. */
  204. batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL, NULL);
  205. batadv_gw_node_free_ref(curr_gw);
  206. }
  207. void batadv_gw_election(struct batadv_priv *bat_priv)
  208. {
  209. struct batadv_gw_node *curr_gw = NULL, *next_gw = NULL;
  210. struct batadv_neigh_node *router = NULL;
  211. struct batadv_neigh_ifinfo *router_ifinfo = NULL;
  212. char gw_addr[18] = { '\0' };
  213. if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
  214. goto out;
  215. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  216. if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw)
  217. goto out;
  218. next_gw = batadv_gw_get_best_gw_node(bat_priv);
  219. if (curr_gw == next_gw)
  220. goto out;
  221. if (next_gw) {
  222. sprintf(gw_addr, "%pM", next_gw->orig_node->orig);
  223. router = batadv_orig_router_get(next_gw->orig_node,
  224. BATADV_IF_DEFAULT);
  225. if (!router) {
  226. batadv_gw_reselect(bat_priv);
  227. goto out;
  228. }
  229. router_ifinfo = batadv_neigh_ifinfo_get(router,
  230. BATADV_IF_DEFAULT);
  231. if (!router_ifinfo) {
  232. batadv_gw_reselect(bat_priv);
  233. goto out;
  234. }
  235. }
  236. if ((curr_gw) && (!next_gw)) {
  237. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  238. "Removing selected gateway - no gateway in range\n");
  239. batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_DEL,
  240. NULL);
  241. } else if ((!curr_gw) && (next_gw)) {
  242. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  243. "Adding route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
  244. next_gw->orig_node->orig,
  245. next_gw->bandwidth_down / 10,
  246. next_gw->bandwidth_down % 10,
  247. next_gw->bandwidth_up / 10,
  248. next_gw->bandwidth_up % 10,
  249. router_ifinfo->bat_iv.tq_avg);
  250. batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
  251. gw_addr);
  252. } else {
  253. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  254. "Changing route to gateway %pM (bandwidth: %u.%u/%u.%u MBit, tq: %i)\n",
  255. next_gw->orig_node->orig,
  256. next_gw->bandwidth_down / 10,
  257. next_gw->bandwidth_down % 10,
  258. next_gw->bandwidth_up / 10,
  259. next_gw->bandwidth_up % 10,
  260. router_ifinfo->bat_iv.tq_avg);
  261. batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
  262. gw_addr);
  263. }
  264. batadv_gw_select(bat_priv, next_gw);
  265. out:
  266. if (curr_gw)
  267. batadv_gw_node_free_ref(curr_gw);
  268. if (next_gw)
  269. batadv_gw_node_free_ref(next_gw);
  270. if (router)
  271. batadv_neigh_node_free_ref(router);
  272. if (router_ifinfo)
  273. batadv_neigh_ifinfo_free_ref(router_ifinfo);
  274. }
  275. void batadv_gw_check_election(struct batadv_priv *bat_priv,
  276. struct batadv_orig_node *orig_node)
  277. {
  278. struct batadv_neigh_ifinfo *router_orig_tq = NULL;
  279. struct batadv_neigh_ifinfo *router_gw_tq = NULL;
  280. struct batadv_orig_node *curr_gw_orig;
  281. struct batadv_neigh_node *router_gw = NULL, *router_orig = NULL;
  282. uint8_t gw_tq_avg, orig_tq_avg;
  283. curr_gw_orig = batadv_gw_get_selected_orig(bat_priv);
  284. if (!curr_gw_orig)
  285. goto reselect;
  286. router_gw = batadv_orig_router_get(curr_gw_orig, BATADV_IF_DEFAULT);
  287. if (!router_gw)
  288. goto reselect;
  289. router_gw_tq = batadv_neigh_ifinfo_get(router_gw,
  290. BATADV_IF_DEFAULT);
  291. if (!router_gw_tq)
  292. goto reselect;
  293. /* this node already is the gateway */
  294. if (curr_gw_orig == orig_node)
  295. goto out;
  296. router_orig = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
  297. if (!router_orig)
  298. goto out;
  299. router_orig_tq = batadv_neigh_ifinfo_get(router_orig,
  300. BATADV_IF_DEFAULT);
  301. if (!router_orig_tq)
  302. goto out;
  303. gw_tq_avg = router_gw_tq->bat_iv.tq_avg;
  304. orig_tq_avg = router_orig_tq->bat_iv.tq_avg;
  305. /* the TQ value has to be better */
  306. if (orig_tq_avg < gw_tq_avg)
  307. goto out;
  308. /* if the routing class is greater than 3 the value tells us how much
  309. * greater the TQ value of the new gateway must be
  310. */
  311. if ((atomic_read(&bat_priv->gw_sel_class) > 3) &&
  312. (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class)))
  313. goto out;
  314. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  315. "Restarting gateway selection: better gateway found (tq curr: %i, tq new: %i)\n",
  316. gw_tq_avg, orig_tq_avg);
  317. reselect:
  318. batadv_gw_reselect(bat_priv);
  319. out:
  320. if (curr_gw_orig)
  321. batadv_orig_node_free_ref(curr_gw_orig);
  322. if (router_gw)
  323. batadv_neigh_node_free_ref(router_gw);
  324. if (router_orig)
  325. batadv_neigh_node_free_ref(router_orig);
  326. if (router_gw_tq)
  327. batadv_neigh_ifinfo_free_ref(router_gw_tq);
  328. if (router_orig_tq)
  329. batadv_neigh_ifinfo_free_ref(router_orig_tq);
  330. }
  331. /**
  332. * batadv_gw_node_add - add gateway node to list of available gateways
  333. * @bat_priv: the bat priv with all the soft interface information
  334. * @orig_node: originator announcing gateway capabilities
  335. * @gateway: announced bandwidth information
  336. */
  337. static void batadv_gw_node_add(struct batadv_priv *bat_priv,
  338. struct batadv_orig_node *orig_node,
  339. struct batadv_tvlv_gateway_data *gateway)
  340. {
  341. struct batadv_gw_node *gw_node;
  342. if (gateway->bandwidth_down == 0)
  343. return;
  344. if (!atomic_inc_not_zero(&orig_node->refcount))
  345. return;
  346. gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC);
  347. if (!gw_node) {
  348. batadv_orig_node_free_ref(orig_node);
  349. return;
  350. }
  351. INIT_HLIST_NODE(&gw_node->list);
  352. gw_node->orig_node = orig_node;
  353. atomic_set(&gw_node->refcount, 1);
  354. spin_lock_bh(&bat_priv->gw.list_lock);
  355. hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list);
  356. spin_unlock_bh(&bat_priv->gw.list_lock);
  357. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  358. "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
  359. orig_node->orig,
  360. ntohl(gateway->bandwidth_down) / 10,
  361. ntohl(gateway->bandwidth_down) % 10,
  362. ntohl(gateway->bandwidth_up) / 10,
  363. ntohl(gateway->bandwidth_up) % 10);
  364. }
  365. /**
  366. * batadv_gw_node_get - retrieve gateway node from list of available gateways
  367. * @bat_priv: the bat priv with all the soft interface information
  368. * @orig_node: originator announcing gateway capabilities
  369. *
  370. * Returns gateway node if found or NULL otherwise.
  371. */
  372. static struct batadv_gw_node *
  373. batadv_gw_node_get(struct batadv_priv *bat_priv,
  374. struct batadv_orig_node *orig_node)
  375. {
  376. struct batadv_gw_node *gw_node_tmp, *gw_node = NULL;
  377. rcu_read_lock();
  378. hlist_for_each_entry_rcu(gw_node_tmp, &bat_priv->gw.list, list) {
  379. if (gw_node_tmp->orig_node != orig_node)
  380. continue;
  381. if (gw_node_tmp->deleted)
  382. continue;
  383. if (!atomic_inc_not_zero(&gw_node_tmp->refcount))
  384. continue;
  385. gw_node = gw_node_tmp;
  386. break;
  387. }
  388. rcu_read_unlock();
  389. return gw_node;
  390. }
  391. /**
  392. * batadv_gw_node_update - update list of available gateways with changed
  393. * bandwidth information
  394. * @bat_priv: the bat priv with all the soft interface information
  395. * @orig_node: originator announcing gateway capabilities
  396. * @gateway: announced bandwidth information
  397. */
  398. void batadv_gw_node_update(struct batadv_priv *bat_priv,
  399. struct batadv_orig_node *orig_node,
  400. struct batadv_tvlv_gateway_data *gateway)
  401. {
  402. struct batadv_gw_node *gw_node, *curr_gw = NULL;
  403. gw_node = batadv_gw_node_get(bat_priv, orig_node);
  404. if (!gw_node) {
  405. batadv_gw_node_add(bat_priv, orig_node, gateway);
  406. goto out;
  407. }
  408. if ((gw_node->bandwidth_down == ntohl(gateway->bandwidth_down)) &&
  409. (gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)))
  410. goto out;
  411. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  412. "Gateway bandwidth of originator %pM changed from %u.%u/%u.%u MBit to %u.%u/%u.%u MBit\n",
  413. orig_node->orig,
  414. gw_node->bandwidth_down / 10,
  415. gw_node->bandwidth_down % 10,
  416. gw_node->bandwidth_up / 10,
  417. gw_node->bandwidth_up % 10,
  418. ntohl(gateway->bandwidth_down) / 10,
  419. ntohl(gateway->bandwidth_down) % 10,
  420. ntohl(gateway->bandwidth_up) / 10,
  421. ntohl(gateway->bandwidth_up) % 10);
  422. gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
  423. gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
  424. gw_node->deleted = 0;
  425. if (ntohl(gateway->bandwidth_down) == 0) {
  426. gw_node->deleted = jiffies;
  427. batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
  428. "Gateway %pM removed from gateway list\n",
  429. orig_node->orig);
  430. /* Note: We don't need a NULL check here, since curr_gw never
  431. * gets dereferenced.
  432. */
  433. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  434. if (gw_node == curr_gw)
  435. batadv_gw_reselect(bat_priv);
  436. }
  437. out:
  438. if (curr_gw)
  439. batadv_gw_node_free_ref(curr_gw);
  440. if (gw_node)
  441. batadv_gw_node_free_ref(gw_node);
  442. }
  443. void batadv_gw_node_delete(struct batadv_priv *bat_priv,
  444. struct batadv_orig_node *orig_node)
  445. {
  446. struct batadv_tvlv_gateway_data gateway;
  447. gateway.bandwidth_down = 0;
  448. gateway.bandwidth_up = 0;
  449. batadv_gw_node_update(bat_priv, orig_node, &gateway);
  450. }
  451. void batadv_gw_node_purge(struct batadv_priv *bat_priv)
  452. {
  453. struct batadv_gw_node *gw_node, *curr_gw;
  454. struct hlist_node *node_tmp;
  455. unsigned long timeout = msecs_to_jiffies(2 * BATADV_PURGE_TIMEOUT);
  456. int do_reselect = 0;
  457. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  458. spin_lock_bh(&bat_priv->gw.list_lock);
  459. hlist_for_each_entry_safe(gw_node, node_tmp,
  460. &bat_priv->gw.list, list) {
  461. if (((!gw_node->deleted) ||
  462. (time_before(jiffies, gw_node->deleted + timeout))) &&
  463. atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE)
  464. continue;
  465. if (curr_gw == gw_node)
  466. do_reselect = 1;
  467. hlist_del_rcu(&gw_node->list);
  468. batadv_gw_node_free_ref(gw_node);
  469. }
  470. spin_unlock_bh(&bat_priv->gw.list_lock);
  471. /* gw_reselect() needs to acquire the gw_list_lock */
  472. if (do_reselect)
  473. batadv_gw_reselect(bat_priv);
  474. if (curr_gw)
  475. batadv_gw_node_free_ref(curr_gw);
  476. }
  477. /* fails if orig_node has no router */
  478. static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
  479. struct seq_file *seq,
  480. const struct batadv_gw_node *gw_node)
  481. {
  482. struct batadv_gw_node *curr_gw;
  483. struct batadv_neigh_node *router;
  484. struct batadv_neigh_ifinfo *router_ifinfo = NULL;
  485. int ret = -1;
  486. router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
  487. if (!router)
  488. goto out;
  489. router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
  490. if (!router_ifinfo)
  491. goto out;
  492. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  493. ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
  494. (curr_gw == gw_node ? "=>" : " "),
  495. gw_node->orig_node->orig,
  496. router_ifinfo->bat_iv.tq_avg, router->addr,
  497. router->if_incoming->net_dev->name,
  498. gw_node->bandwidth_down / 10,
  499. gw_node->bandwidth_down % 10,
  500. gw_node->bandwidth_up / 10,
  501. gw_node->bandwidth_up % 10);
  502. if (curr_gw)
  503. batadv_gw_node_free_ref(curr_gw);
  504. out:
  505. if (router_ifinfo)
  506. batadv_neigh_ifinfo_free_ref(router_ifinfo);
  507. if (router)
  508. batadv_neigh_node_free_ref(router);
  509. return ret;
  510. }
  511. int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
  512. {
  513. struct net_device *net_dev = (struct net_device *)seq->private;
  514. struct batadv_priv *bat_priv = netdev_priv(net_dev);
  515. struct batadv_hard_iface *primary_if;
  516. struct batadv_gw_node *gw_node;
  517. int gw_count = 0;
  518. primary_if = batadv_seq_print_text_primary_if_get(seq);
  519. if (!primary_if)
  520. goto out;
  521. seq_printf(seq,
  522. " %-12s (%s/%i) %17s [%10s]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
  523. "Gateway", "#", BATADV_TQ_MAX_VALUE, "Nexthop", "outgoingIF",
  524. BATADV_SOURCE_VERSION, primary_if->net_dev->name,
  525. primary_if->net_dev->dev_addr, net_dev->name);
  526. rcu_read_lock();
  527. hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.list, list) {
  528. if (gw_node->deleted)
  529. continue;
  530. /* fails if orig_node has no router */
  531. if (batadv_write_buffer_text(bat_priv, seq, gw_node) < 0)
  532. continue;
  533. gw_count++;
  534. }
  535. rcu_read_unlock();
  536. if (gw_count == 0)
  537. seq_puts(seq, "No gateways in range ...\n");
  538. out:
  539. if (primary_if)
  540. batadv_hardif_free_ref(primary_if);
  541. return 0;
  542. }
  543. /**
  544. * batadv_gw_dhcp_recipient_get - check if a packet is a DHCP message
  545. * @skb: the packet to check
  546. * @header_len: a pointer to the batman-adv header size
  547. * @chaddr: buffer where the client address will be stored. Valid
  548. * only if the function returns BATADV_DHCP_TO_CLIENT
  549. *
  550. * Returns:
  551. * - BATADV_DHCP_NO if the packet is not a dhcp message or if there was an error
  552. * while parsing it
  553. * - BATADV_DHCP_TO_SERVER if this is a message going to the DHCP server
  554. * - BATADV_DHCP_TO_CLIENT if this is a message going to a DHCP client
  555. *
  556. * This function may re-allocate the data buffer of the skb passed as argument.
  557. */
  558. enum batadv_dhcp_recipient
  559. batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
  560. uint8_t *chaddr)
  561. {
  562. enum batadv_dhcp_recipient ret = BATADV_DHCP_NO;
  563. struct ethhdr *ethhdr;
  564. struct iphdr *iphdr;
  565. struct ipv6hdr *ipv6hdr;
  566. struct udphdr *udphdr;
  567. struct vlan_ethhdr *vhdr;
  568. int chaddr_offset;
  569. __be16 proto;
  570. uint8_t *p;
  571. /* check for ethernet header */
  572. if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
  573. return BATADV_DHCP_NO;
  574. ethhdr = eth_hdr(skb);
  575. proto = ethhdr->h_proto;
  576. *header_len += ETH_HLEN;
  577. /* check for initial vlan header */
  578. if (proto == htons(ETH_P_8021Q)) {
  579. if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
  580. return BATADV_DHCP_NO;
  581. vhdr = vlan_eth_hdr(skb);
  582. proto = vhdr->h_vlan_encapsulated_proto;
  583. *header_len += VLAN_HLEN;
  584. }
  585. /* check for ip header */
  586. switch (proto) {
  587. case htons(ETH_P_IP):
  588. if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr)))
  589. return BATADV_DHCP_NO;
  590. iphdr = (struct iphdr *)(skb->data + *header_len);
  591. *header_len += iphdr->ihl * 4;
  592. /* check for udp header */
  593. if (iphdr->protocol != IPPROTO_UDP)
  594. return BATADV_DHCP_NO;
  595. break;
  596. case htons(ETH_P_IPV6):
  597. if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr)))
  598. return BATADV_DHCP_NO;
  599. ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len);
  600. *header_len += sizeof(*ipv6hdr);
  601. /* check for udp header */
  602. if (ipv6hdr->nexthdr != IPPROTO_UDP)
  603. return BATADV_DHCP_NO;
  604. break;
  605. default:
  606. return BATADV_DHCP_NO;
  607. }
  608. if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr)))
  609. return BATADV_DHCP_NO;
  610. /* skb->data might have been reallocated by pskb_may_pull() */
  611. ethhdr = eth_hdr(skb);
  612. if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
  613. ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
  614. udphdr = (struct udphdr *)(skb->data + *header_len);
  615. *header_len += sizeof(*udphdr);
  616. /* check for bootp port */
  617. switch (proto) {
  618. case htons(ETH_P_IP):
  619. if (udphdr->dest == htons(67))
  620. ret = BATADV_DHCP_TO_SERVER;
  621. else if (udphdr->source == htons(67))
  622. ret = BATADV_DHCP_TO_CLIENT;
  623. break;
  624. case htons(ETH_P_IPV6):
  625. if (udphdr->dest == htons(547))
  626. ret = BATADV_DHCP_TO_SERVER;
  627. else if (udphdr->source == htons(547))
  628. ret = BATADV_DHCP_TO_CLIENT;
  629. break;
  630. }
  631. chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET;
  632. /* store the client address if the message is going to a client */
  633. if (ret == BATADV_DHCP_TO_CLIENT &&
  634. pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) {
  635. /* check if the DHCP packet carries an Ethernet DHCP */
  636. p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET;
  637. if (*p != BATADV_DHCP_HTYPE_ETHERNET)
  638. return BATADV_DHCP_NO;
  639. /* check if the DHCP packet carries a valid Ethernet address */
  640. p = skb->data + *header_len + BATADV_DHCP_HLEN_OFFSET;
  641. if (*p != ETH_ALEN)
  642. return BATADV_DHCP_NO;
  643. ether_addr_copy(chaddr, skb->data + chaddr_offset);
  644. }
  645. return ret;
  646. }
  647. /**
  648. * batadv_gw_out_of_range - check if the dhcp request destination is the best gw
  649. * @bat_priv: the bat priv with all the soft interface information
  650. * @skb: the outgoing packet
  651. *
  652. * Check if the skb is a DHCP request and if it is sent to the current best GW
  653. * server. Due to topology changes it may be the case that the GW server
  654. * previously selected is not the best one anymore.
  655. *
  656. * Returns true if the packet destination is unicast and it is not the best gw,
  657. * false otherwise.
  658. *
  659. * This call might reallocate skb data.
  660. * Must be invoked only when the DHCP packet is going TO a DHCP SERVER.
  661. */
  662. bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
  663. struct sk_buff *skb)
  664. {
  665. struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL;
  666. struct batadv_orig_node *orig_dst_node = NULL;
  667. struct batadv_gw_node *gw_node = NULL, *curr_gw = NULL;
  668. struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
  669. struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
  670. bool out_of_range = false;
  671. uint8_t curr_tq_avg;
  672. unsigned short vid;
  673. vid = batadv_get_vid(skb, 0);
  674. orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
  675. ethhdr->h_dest, vid);
  676. if (!orig_dst_node)
  677. goto out;
  678. gw_node = batadv_gw_node_get(bat_priv, orig_dst_node);
  679. if (!gw_node->bandwidth_down == 0)
  680. goto out;
  681. switch (atomic_read(&bat_priv->gw_mode)) {
  682. case BATADV_GW_MODE_SERVER:
  683. /* If we are a GW then we are our best GW. We can artificially
  684. * set the tq towards ourself as the maximum value
  685. */
  686. curr_tq_avg = BATADV_TQ_MAX_VALUE;
  687. break;
  688. case BATADV_GW_MODE_CLIENT:
  689. curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
  690. if (!curr_gw)
  691. goto out;
  692. /* packet is going to our gateway */
  693. if (curr_gw->orig_node == orig_dst_node)
  694. goto out;
  695. /* If the dhcp packet has been sent to a different gw,
  696. * we have to evaluate whether the old gw is still
  697. * reliable enough
  698. */
  699. neigh_curr = batadv_find_router(bat_priv, curr_gw->orig_node,
  700. NULL);
  701. if (!neigh_curr)
  702. goto out;
  703. curr_ifinfo = batadv_neigh_ifinfo_get(neigh_curr,
  704. BATADV_IF_DEFAULT);
  705. if (!curr_ifinfo)
  706. goto out;
  707. curr_tq_avg = curr_ifinfo->bat_iv.tq_avg;
  708. batadv_neigh_ifinfo_free_ref(curr_ifinfo);
  709. break;
  710. case BATADV_GW_MODE_OFF:
  711. default:
  712. goto out;
  713. }
  714. neigh_old = batadv_find_router(bat_priv, orig_dst_node, NULL);
  715. if (!neigh_old)
  716. goto out;
  717. old_ifinfo = batadv_neigh_ifinfo_get(neigh_old, BATADV_IF_DEFAULT);
  718. if (!old_ifinfo)
  719. goto out;
  720. if ((curr_tq_avg - old_ifinfo->bat_iv.tq_avg) > BATADV_GW_THRESHOLD)
  721. out_of_range = true;
  722. batadv_neigh_ifinfo_free_ref(old_ifinfo);
  723. out:
  724. if (orig_dst_node)
  725. batadv_orig_node_free_ref(orig_dst_node);
  726. if (curr_gw)
  727. batadv_gw_node_free_ref(curr_gw);
  728. if (gw_node)
  729. batadv_gw_node_free_ref(gw_node);
  730. if (neigh_old)
  731. batadv_neigh_node_free_ref(neigh_old);
  732. if (neigh_curr)
  733. batadv_neigh_node_free_ref(neigh_curr);
  734. return out_of_range;
  735. }