Commit | Line | Data |
---|---|---|
7db7d9f3 | 1 | // SPDX-License-Identifier: GPL-2.0 |
cfa55c6d | 2 | /* Copyright (C) B.A.T.M.A.N. contributors: |
c6c8fea2 SE |
3 | * |
4 | * Marek Lindner | |
c6c8fea2 SE |
5 | */ |
6 | ||
c6c8fea2 | 7 | #include "gateway_common.h" |
1e2c2a4f SE |
8 | #include "main.h" |
9 | ||
10 | #include <linux/atomic.h> | |
11 | #include <linux/byteorder/generic.h> | |
1e2c2a4f | 12 | #include <linux/stddef.h> |
6f96d46f | 13 | #include <linux/types.h> |
fec149f5 | 14 | #include <uapi/linux/batadv_packet.h> |
e2d0d35b | 15 | #include <uapi/linux/batman_adv.h> |
1e2c2a4f | 16 | |
c6c8fea2 | 17 | #include "gateway_client.h" |
1f8dce49 | 18 | #include "tvlv.h" |
c6c8fea2 | 19 | |
414254e3 | 20 | /** |
7e9a8c2c SE |
21 | * batadv_gw_tvlv_container_update() - update the gw tvlv container after |
22 | * gateway setting change | |
414254e3 ML |
23 | * @bat_priv: the bat priv with all the soft interface information |
24 | */ | |
25 | void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv) | |
26 | { | |
27 | struct batadv_tvlv_gateway_data gw; | |
6b5e971a | 28 | u32 down, up; |
414254e3 ML |
29 | char gw_mode; |
30 | ||
3a24a63e | 31 | gw_mode = atomic_read(&bat_priv->gw.mode); |
414254e3 ML |
32 | |
33 | switch (gw_mode) { | |
34 | case BATADV_GW_MODE_OFF: | |
35 | case BATADV_GW_MODE_CLIENT: | |
36 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1); | |
37 | break; | |
38 | case BATADV_GW_MODE_SERVER: | |
39 | down = atomic_read(&bat_priv->gw.bandwidth_down); | |
40 | up = atomic_read(&bat_priv->gw.bandwidth_up); | |
41 | gw.bandwidth_down = htonl(down); | |
42 | gw.bandwidth_up = htonl(up); | |
43 | batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1, | |
44 | &gw, sizeof(gw)); | |
45 | break; | |
46 | } | |
47 | } | |
48 | ||
414254e3 | 49 | /** |
7e9a8c2c | 50 | * batadv_gw_tvlv_ogm_handler_v1() - process incoming gateway tvlv container |
414254e3 ML |
51 | * @bat_priv: the bat priv with all the soft interface information |
52 | * @orig: the orig_node of the ogm | |
53 | * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags) | |
54 | * @tvlv_value: tvlv buffer containing the gateway data | |
55 | * @tvlv_value_len: tvlv buffer length | |
56 | */ | |
57 | static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, | |
58 | struct batadv_orig_node *orig, | |
6b5e971a SE |
59 | u8 flags, |
60 | void *tvlv_value, u16 tvlv_value_len) | |
414254e3 ML |
61 | { |
62 | struct batadv_tvlv_gateway_data gateway, *gateway_ptr; | |
63 | ||
64 | /* only fetch the tvlv value if the handler wasn't called via the | |
65 | * CIFNOTFND flag and if there is data to fetch | |
66 | */ | |
825ffe1f SE |
67 | if (flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND || |
68 | tvlv_value_len < sizeof(gateway)) { | |
414254e3 ML |
69 | gateway.bandwidth_down = 0; |
70 | gateway.bandwidth_up = 0; | |
71 | } else { | |
72 | gateway_ptr = tvlv_value; | |
73 | gateway.bandwidth_down = gateway_ptr->bandwidth_down; | |
74 | gateway.bandwidth_up = gateway_ptr->bandwidth_up; | |
825ffe1f SE |
75 | if (gateway.bandwidth_down == 0 || |
76 | gateway.bandwidth_up == 0) { | |
414254e3 ML |
77 | gateway.bandwidth_down = 0; |
78 | gateway.bandwidth_up = 0; | |
79 | } | |
80 | } | |
81 | ||
82 | batadv_gw_node_update(bat_priv, orig, &gateway); | |
83 | ||
34d99cfe | 84 | /* restart gateway selection */ |
825ffe1f SE |
85 | if (gateway.bandwidth_down != 0 && |
86 | atomic_read(&bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT) | |
414254e3 ML |
87 | batadv_gw_check_election(bat_priv, orig); |
88 | } | |
89 | ||
90 | /** | |
7e9a8c2c | 91 | * batadv_gw_init() - initialise the gateway handling internals |
414254e3 ML |
92 | * @bat_priv: the bat priv with all the soft interface information |
93 | */ | |
94 | void batadv_gw_init(struct batadv_priv *bat_priv) | |
95 | { | |
1a9070ec SE |
96 | if (bat_priv->algo_ops->gw.init_sel_class) |
97 | bat_priv->algo_ops->gw.init_sel_class(bat_priv); | |
98 | else | |
99 | atomic_set(&bat_priv->gw.sel_class, 1); | |
100 | ||
414254e3 | 101 | batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1, |
0c4061c0 | 102 | NULL, NULL, BATADV_TVLV_GW, 1, |
414254e3 ML |
103 | BATADV_TVLV_HANDLER_OGM_CIFNOTFND); |
104 | } | |
105 | ||
106 | /** | |
7e9a8c2c | 107 | * batadv_gw_free() - free the gateway handling internals |
414254e3 ML |
108 | * @bat_priv: the bat priv with all the soft interface information |
109 | */ | |
110 | void batadv_gw_free(struct batadv_priv *bat_priv) | |
111 | { | |
112 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1); | |
113 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_GW, 1); | |
114 | } |