gateway_common.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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_common.h"
  7. #include "main.h"
  8. #include <linux/atomic.h>
  9. #include <linux/byteorder/generic.h>
  10. #include <linux/stddef.h>
  11. #include <linux/types.h>
  12. #include <uapi/linux/batadv_packet.h>
  13. #include <uapi/linux/batman_adv.h>
  14. #include "gateway_client.h"
  15. #include "tvlv.h"
  16. /**
  17. * batadv_gw_tvlv_container_update() - update the gw tvlv container after
  18. * gateway setting change
  19. * @bat_priv: the bat priv with all the soft interface information
  20. */
  21. void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
  22. {
  23. struct batadv_tvlv_gateway_data gw;
  24. u32 down, up;
  25. char gw_mode;
  26. gw_mode = atomic_read(&bat_priv->gw.mode);
  27. switch (gw_mode) {
  28. case BATADV_GW_MODE_OFF:
  29. case BATADV_GW_MODE_CLIENT:
  30. batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
  31. break;
  32. case BATADV_GW_MODE_SERVER:
  33. down = atomic_read(&bat_priv->gw.bandwidth_down);
  34. up = atomic_read(&bat_priv->gw.bandwidth_up);
  35. gw.bandwidth_down = htonl(down);
  36. gw.bandwidth_up = htonl(up);
  37. batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1,
  38. &gw, sizeof(gw));
  39. break;
  40. }
  41. }
  42. /**
  43. * batadv_gw_tvlv_ogm_handler_v1() - process incoming gateway tvlv container
  44. * @bat_priv: the bat priv with all the soft interface information
  45. * @orig: the orig_node of the ogm
  46. * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
  47. * @tvlv_value: tvlv buffer containing the gateway data
  48. * @tvlv_value_len: tvlv buffer length
  49. */
  50. static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
  51. struct batadv_orig_node *orig,
  52. u8 flags,
  53. void *tvlv_value, u16 tvlv_value_len)
  54. {
  55. struct batadv_tvlv_gateway_data gateway, *gateway_ptr;
  56. /* only fetch the tvlv value if the handler wasn't called via the
  57. * CIFNOTFND flag and if there is data to fetch
  58. */
  59. if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND ||
  60. tvlv_value_len < sizeof(gateway)) {
  61. gateway.bandwidth_down = 0;
  62. gateway.bandwidth_up = 0;
  63. } else {
  64. gateway_ptr = tvlv_value;
  65. gateway.bandwidth_down = gateway_ptr->bandwidth_down;
  66. gateway.bandwidth_up = gateway_ptr->bandwidth_up;
  67. if (gateway.bandwidth_down == 0 ||
  68. gateway.bandwidth_up == 0) {
  69. gateway.bandwidth_down = 0;
  70. gateway.bandwidth_up = 0;
  71. }
  72. }
  73. batadv_gw_node_update(bat_priv, orig, &gateway);
  74. /* restart gateway selection */
  75. if (gateway.bandwidth_down != 0 &&
  76. atomic_read(&bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT)
  77. batadv_gw_check_election(bat_priv, orig);
  78. }
  79. /**
  80. * batadv_gw_init() - initialise the gateway handling internals
  81. * @bat_priv: the bat priv with all the soft interface information
  82. */
  83. void batadv_gw_init(struct batadv_priv *bat_priv)
  84. {
  85. if (bat_priv->algo_ops->gw.init_sel_class)
  86. bat_priv->algo_ops->gw.init_sel_class(bat_priv);
  87. else
  88. atomic_set(&bat_priv->gw.sel_class, 1);
  89. batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
  90. NULL, NULL, BATADV_TVLV_GW, 1,
  91. BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
  92. }
  93. /**
  94. * batadv_gw_free() - free the gateway handling internals
  95. * @bat_priv: the bat priv with all the soft interface information
  96. */
  97. void batadv_gw_free(struct batadv_priv *bat_priv)
  98. {
  99. batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
  100. batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_GW, 1);
  101. }