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