[2/7] batman-adv: tvlv - convert gateway flags

Message ID 1366125995-18034-3-git-send-email-lindner_marek@yahoo.de (mailing list archive)
State Superseded, archived
Headers

Commit Message

Marek Lindner April 16, 2013, 3:26 p.m. UTC
  From: Spyros Gasteratos <morfeas3000@gmail.com>

This patch changes the gateway feature to announce the gateway flags
using the tvlv infrastructure.

Signed-off-by: Spyros Gasteratos <morfeas3000@gmail.com>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
---
 bat_iv_ogm.c     |   23 +--------------
 gateway_common.c |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gateway_common.h |    3 ++
 main.c           |    7 +++++
 packet.h         |   10 ++++++-
 sysfs.c          |    1 +
 6 files changed, 107 insertions(+), 23 deletions(-)
  

Patch

diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
index 54227ef..d0a8cc5 100644
--- a/bat_iv_ogm.c
+++ b/bat_iv_ogm.c
@@ -118,6 +118,7 @@  static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
 	batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
 	batadv_ogm_packet->header.ttl = 2;
 	batadv_ogm_packet->flags = BATADV_NO_FLAGS;
+	batadv_ogm_packet->reserved = 0;
 	batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
 	batadv_ogm_packet->tt_num_changes = 0;
 	batadv_ogm_packet->ttvn = 0;
@@ -639,7 +640,6 @@  static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
 	int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
 	int vis_server, tt_num_changes = 0;
 	uint32_t seqno;
-	uint8_t bandwidth;
 	uint16_t tvlv_len = 0;
 
 	vis_server = atomic_read(&bat_priv->vis_mode);
@@ -668,14 +668,6 @@  static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
 	else
 		batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
 
-	if (hard_iface == primary_if &&
-	    atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) {
-		bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
-		batadv_ogm_packet->gw_flags = bandwidth;
-	} else {
-		batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
-	}
-
 	batadv_slide_own_bcast_window(hard_iface);
 	batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
 				hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
@@ -810,19 +802,6 @@  update_tt:
 				      batadv_ogm_packet->tt_num_changes,
 				      batadv_ogm_packet->ttvn,
 				      ntohs(batadv_ogm_packet->tt_crc));
-
-	if (orig_node->gw_flags != batadv_ogm_packet->gw_flags)
-		batadv_gw_node_update(bat_priv, orig_node,
-				      batadv_ogm_packet->gw_flags);
-
-	orig_node->gw_flags = batadv_ogm_packet->gw_flags;
-
-	/* restart gateway selection if fast or late switching was enabled */
-	if ((orig_node->gw_flags) &&
-	    (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
-	    (atomic_read(&bat_priv->gw_sel_class) > 2))
-		batadv_gw_check_election(bat_priv, orig_node);
-
 	goto out;
 
 unlock:
diff --git a/gateway_common.c b/gateway_common.c
index 84bb2b1..ead96eb 100644
--- a/gateway_common.c
+++ b/gateway_common.c
@@ -20,6 +20,7 @@ 
 #include "main.h"
 #include "gateway_common.h"
 #include "gateway_client.h"
+#include "packet.h"
 
 /* calculates the gateway class from kbit */
 static void batadv_kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class)
@@ -134,6 +135,31 @@  static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff,
 	return true;
 }
 
+/**
+ * batadv_gw_tvlv_container_update - update the gw tvlv container after gateway
+ *  setting change
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
+{
+	char gw_mode, gw_tvlv_value;
+
+	gw_mode = atomic_read(&bat_priv->gw_mode);
+
+	switch (gw_mode) {
+	case BATADV_GW_MODE_OFF:
+	case BATADV_GW_MODE_CLIENT:
+		batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
+		break;
+	case BATADV_GW_MODE_SERVER:
+		gw_tvlv_value = atomic_read(&bat_priv->gw_bandwidth);
+		batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1,
+					       &gw_tvlv_value,
+					       sizeof(gw_tvlv_value));
+		break;
+	}
+}
+
 ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
 				size_t count)
 {
@@ -173,7 +199,67 @@  ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
 		    (up > 2048 ? "MBit" : "KBit"));
 
 	atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp);
+	batadv_gw_tvlv_container_update(bat_priv);
 
 end:
 	return count;
 }
+
+/**
+ * batadv_gw_tvlv_ogm_handler_v1 - process incoming gateway tvlv container
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: the orig_node of the ogm
+ * @flags: flags indicating the tvlv state (see batadv_tvlv_handler_flags)
+ * @tvlv_value: tvlv buffer containing the gateway data
+ * @tvlv_value_len: tvlv buffer length
+ */
+static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
+					  struct batadv_orig_node *orig,
+					  uint8_t flags,
+					  void *tvlv_value,
+					  uint16_t tvlv_value_len)
+{
+	uint8_t gw_flags = BATADV_NO_FLAGS;
+
+	/* only fetch the tvlv value if the handler wasn't called via the
+	 * CIFNOTFND flag and if there is data to fetch
+	 */
+	if (!(flags & BATADV_TVLV_HANDLER_OGM_CIFNOTFND) &&
+	    (tvlv_value) && (tvlv_value_len == 1))
+		gw_flags = *(unsigned char *)tvlv_value;
+
+	if (orig->gw_flags != gw_flags)
+		batadv_gw_node_update(bat_priv, orig, gw_flags);
+
+	orig->gw_flags = gw_flags;
+
+	/* restart gateway selection if fast or late switching was enabled */
+	if ((orig->gw_flags != BATADV_NO_FLAGS) &&
+	    (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_CLIENT) &&
+	    (atomic_read(&bat_priv->gw_sel_class) > 2))
+		batadv_gw_check_election(bat_priv, orig);
+}
+
+/**
+ * batadv_gw_init - initialise the gateway handling internals
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Return 0 on success or negative error number in case of failure.
+ */
+int batadv_gw_init(struct batadv_priv *bat_priv)
+{
+	batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
+				     NULL, BATADV_TVLV_GW, 1,
+				     BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
+	return 0;
+}
+
+/**
+ * batadv_gw_free - free the gateway handling internals
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+void batadv_gw_free(struct batadv_priv *bat_priv)
+{
+	batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
+	batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_GW, 1);
+}
diff --git a/gateway_common.h b/gateway_common.h
index 509b2bf..6b43c0e 100644
--- a/gateway_common.h
+++ b/gateway_common.h
@@ -33,5 +33,8 @@  enum batadv_gw_modes {
 void batadv_gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up);
 ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff,
 				size_t count);
+void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv);
+int batadv_gw_init(struct batadv_priv *bat_priv);
+void batadv_gw_free(struct batadv_priv *bat_priv);
 
 #endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */
diff --git a/main.c b/main.c
index 7a72cfc..b631c05 100644
--- a/main.c
+++ b/main.c
@@ -33,6 +33,7 @@ 
 #include "bridge_loop_avoidance.h"
 #include "distributed-arp-table.h"
 #include "unicast.h"
+#include "gateway_common.h"
 #include "vis.h"
 #include "hash.h"
 #include "bat_algo.h"
@@ -147,6 +148,10 @@  int batadv_mesh_init(struct net_device *soft_iface)
 	if (ret < 0)
 		goto err;
 
+	ret = batadv_gw_init(bat_priv);
+	if (ret < 0)
+		goto err;
+
 	atomic_set(&bat_priv->gw.reselect, 0);
 	atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
 
@@ -177,6 +182,8 @@  void batadv_mesh_free(struct net_device *soft_iface)
 
 	batadv_dat_free(bat_priv);
 
+	batadv_gw_free(bat_priv);
+
 	free_percpu(bat_priv->bat_counters);
 
 	atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
diff --git a/packet.h b/packet.h
index 4de94c7..a5bd6ee 100644
--- a/packet.h
+++ b/packet.h
@@ -118,6 +118,14 @@  enum batadv_bla_claimframe {
 	BATADV_CLAIM_TYPE_REQUEST	= 0x03,
 };
 
+/**
+ * enum batadv_tvlv_type - tvlv type definitions
+ * @BATADV_TVLV_GW: gateway tvlv
+ */
+enum batadv_tvlv_type {
+	BATADV_TVLV_GW		= 0x01,
+};
+
 /* the destination hardware field in the ARP frame is used to
  * transport the claim type and the group id
  */
@@ -147,7 +155,7 @@  struct batadv_ogm_packet {
 	__be32   seqno;
 	uint8_t  orig[ETH_ALEN];
 	uint8_t  prev_sender[ETH_ALEN];
-	uint8_t  gw_flags;  /* flags related to gateway class */
+	uint8_t  reserved;
 	uint8_t  tq;
 	uint8_t  tt_num_changes;
 	uint8_t  ttvn; /* translation table version number */
diff --git a/sysfs.c b/sysfs.c
index 15a22ef..db38f79 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -386,6 +386,7 @@  static ssize_t batadv_store_gw_mode(struct kobject *kobj,
 
 	batadv_gw_deselect(bat_priv);
 	atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
+	batadv_gw_tvlv_container_update(bat_priv);
 	return count;
 }