Blame SOURCES/open-lldp-v1.0.1-23-lldp-make-TTL-TLV-configurable.patch

89f6b3
From 986eb2e84fd3339a30a4ab09c6d788c63236fed6 Mon Sep 17 00:00:00 2001
89f6b3
From: Gary Loughnane <gary.loughnane@intel.com>
89f6b3
Date: Tue, 21 Apr 2015 17:45:41 +0000
89f6b3
Subject: [PATCH] lldp: make TTL TLV configurable
89f6b3
89f6b3
This allows the TTL TLV to be configured.
89f6b3
89f6b3
Currently the Time To Live TLV is a static value set to 120 seconds.
89f6b3
LLDP specification says this can be a value of between 0 and 65535
89f6b3
seconds. This patch makes the TTL TLV a configurable entity.
89f6b3
89f6b3
Signed-off-by: Gary Loughnane <gary.loughnane@intel.com>
89f6b3
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
89f6b3
---
89f6b3
 include/lldp_mand.h      |  1 +
89f6b3
 include/lldp_mand_cmds.h |  4 +++
89f6b3
 lldp/agent.c             |  2 +-
89f6b3
 lldp/ports.c             |  3 +-
89f6b3
 lldp/states.h            |  2 +-
89f6b3
 lldp/tx.c                | 30 ++++++++++++++--
89f6b3
 lldp_mand.c              | 21 ++++++++---
89f6b3
 lldp_mand_cmds.c         | 90 ++++++++++++++++++++++++++++++++++++++++++++++++
89f6b3
 8 files changed, 141 insertions(+), 12 deletions(-)
89f6b3
89f6b3
diff --git a/include/lldp_mand.h b/include/lldp_mand.h
89f6b3
index 9154b7c..fc21ede 100644
89f6b3
--- a/include/lldp_mand.h
89f6b3
+++ b/include/lldp_mand.h
89f6b3
@@ -93,4 +93,5 @@ void mand_unregister(struct lldp_module *mod);
89f6b3
 struct packed_tlv *mand_gettlv(struct port *, struct lldp_agent *);
89f6b3
 void mand_ifdown(char *, struct lldp_agent *);
89f6b3
 void mand_ifup(char *, struct lldp_agent *);
89f6b3
+void mand_update_ttl(const char *, u16);
89f6b3
 #endif /* _LLDP_MAND_H */
89f6b3
diff --git a/include/lldp_mand_cmds.h b/include/lldp_mand_cmds.h
89f6b3
index aacac7c..8effc6e 100644
89f6b3
--- a/include/lldp_mand_cmds.h
89f6b3
+++ b/include/lldp_mand_cmds.h
89f6b3
@@ -28,6 +28,10 @@
89f6b3
 #define _LLDP_MAND_CMDS_H
89f6b3
 
89f6b3
 #define ARG_MAND_SUBTYPE "subtype"
89f6b3
+#define ARG_TTL_VALUE "value"
89f6b3
+
89f6b3
+#define TTL_MIN_VAL 0x0
89f6b3
+#define TTL_MAX_VAL 0xFFFF
89f6b3
 
89f6b3
 struct arg_handlers *mand_get_arg_handlers();
89f6b3
 
89f6b3
diff --git a/lldp/agent.c b/lldp/agent.c
89f6b3
index 4bc5394..73ab054 100644
89f6b3
--- a/lldp/agent.c
89f6b3
+++ b/lldp/agent.c
89f6b3
@@ -101,7 +101,7 @@ void lldp_init_agent(struct port *port, struct lldp_agent *agent, int type)
89f6b3
 
89f6b3
 	/* init TX path */
89f6b3
 	txInitializeTimers(agent);
89f6b3
-	txInitializeLLDP(agent);
89f6b3
+	txInitializeLLDP(port, agent);
89f6b3
 }
89f6b3
 
89f6b3
 int lldp_add_agent(const char *ifname, enum agent_type type)
89f6b3
diff --git a/lldp/ports.c b/lldp/ports.c
89f6b3
index 3bd6a2a..6384f14 100644
89f6b3
--- a/lldp/ports.c
89f6b3
+++ b/lldp/ports.c
89f6b3
@@ -230,7 +230,6 @@ int reinit_port(const char *ifname)
89f6b3
 		/* Reset relevant state variables */
89f6b3
 		agent->tx.state  = TX_LLDP_INITIALIZE;
89f6b3
 		agent->rx.state = LLDP_WAIT_PORT_OPERATIONAL;
89f6b3
-		agent->tx.txTTL = 0;
89f6b3
 		agent->msap.length1 = 0;
89f6b3
 		agent->msap.msap1 = NULL;
89f6b3
 		agent->msap.length2 = 0;
89f6b3
@@ -243,7 +242,7 @@ int reinit_port(const char *ifname)
89f6b3
 
89f6b3
 		/* init TX path */
89f6b3
 		txInitializeTimers(agent);
89f6b3
-		txInitializeLLDP(agent);
89f6b3
+		txInitializeLLDP(port, agent);
89f6b3
 	}
89f6b3
 
89f6b3
 	return 0;
89f6b3
diff --git a/lldp/states.h b/lldp/states.h
89f6b3
index fa5f11f..7cf69b8 100644
89f6b3
--- a/lldp/states.h
89f6b3
+++ b/lldp/states.h
89f6b3
@@ -52,7 +52,7 @@ enum {
89f6b3
  * The txInitializeLLDP () procedure initializes the LLDP transmit module as
89f6b3
  * defined in 10.1.1.
89f6b3
 */
89f6b3
-void txInitializeLLDP(struct lldp_agent *agent);
89f6b3
+void txInitializeLLDP(struct port *port, struct lldp_agent *agent);
89f6b3
 
89f6b3
 /**
89f6b3
  * The mibConstrInfoLLDPDU () procedure constructs an information LLDPDU as
89f6b3
diff --git a/lldp/tx.c b/lldp/tx.c
89f6b3
index 69c1a1a..c3a5c62 100644
89f6b3
--- a/lldp/tx.c
89f6b3
+++ b/lldp/tx.c
89f6b3
@@ -34,6 +34,8 @@
89f6b3
 #include "lldp_tlv.h"
89f6b3
 #include "lldp_mod.h"
89f6b3
 #include "lldp_mand.h"
89f6b3
+#include "config.h"
89f6b3
+#include "lldp_mand_clif.h"
89f6b3
 
89f6b3
 bool mibConstrInfoLLDPDU(struct port *port, struct lldp_agent *agent)
89f6b3
 {
89f6b3
@@ -110,7 +112,29 @@ error:
89f6b3
 	return false;
89f6b3
 }
89f6b3
 
89f6b3
-void txInitializeLLDP(struct lldp_agent *agent)
89f6b3
+static u16 get_ttl_init_val(char *ifname, struct lldp_agent *agent)
89f6b3
+{
89f6b3
+	u16 ttl;
89f6b3
+	int config_ttl;
89f6b3
+	int read_config_err;
89f6b3
+	char arg_path[512] = { 0 };
89f6b3
+
89f6b3
+	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s",
89f6b3
+			TLVID_PREFIX,
89f6b3
+			TLVID_NOUI(TIME_TO_LIVE_TLV),
89f6b3
+			ARG_TTL_VALUE);
89f6b3
+	read_config_err = get_config_setting(ifname, agent->type,
89f6b3
+			arg_path, &config_ttl, CONFIG_TYPE_INT);
89f6b3
+
89f6b3
+	if (read_config_err)
89f6b3
+		ttl = DEFAULT_TX_HOLD * DEFAULT_TX_INTERVAL;
89f6b3
+	else
89f6b3
+		ttl = (u16)(config_ttl);
89f6b3
+
89f6b3
+	return ttl;
89f6b3
+}
89f6b3
+
89f6b3
+void txInitializeLLDP(struct port *port, struct lldp_agent *agent)
89f6b3
 {
89f6b3
 	if (agent->tx.frameout) {
89f6b3
 		free(agent->tx.frameout);
89f6b3
@@ -125,7 +149,7 @@ void txInitializeLLDP(struct lldp_agent *agent)
89f6b3
 	agent->timers.msgTxInterval = DEFAULT_TX_INTERVAL;
89f6b3
 	agent->timers.msgFastTx     = FAST_TX_INTERVAL;
89f6b3
 
89f6b3
-	agent->tx.txTTL = 0;
89f6b3
+	agent->tx.txTTL = get_ttl_init_val(port->ifname, agent);
89f6b3
 	agent->msap.length1 = 0;
89f6b3
 	agent->msap.msap1 = NULL;
89f6b3
 	agent->msap.length2 = 0;
89f6b3
@@ -240,7 +264,7 @@ void run_tx_sm(struct port *port, struct lldp_agent *agent)
89f6b3
 	do {
89f6b3
 		switch(agent->tx.state) {
89f6b3
 		case TX_LLDP_INITIALIZE:
89f6b3
-			txInitializeLLDP(agent);
89f6b3
+			txInitializeLLDP(port, agent);
89f6b3
 			break;
89f6b3
 		case TX_IDLE:
89f6b3
 			process_tx_idle(agent);
89f6b3
diff --git a/lldp_mand.c b/lldp_mand.c
89f6b3
index b269d3f..652a454 100644
89f6b3
--- a/lldp_mand.c
89f6b3
+++ b/lldp_mand.c
89f6b3
@@ -446,11 +446,7 @@ static int mand_bld_ttl_tlv(struct mand_data *md, struct lldp_agent *agent)
89f6b3
 	}
89f6b3
 	memset(tlv->info, 0, tlv->length);
89f6b3
 
89f6b3
-	if (agent->tx.txTTL)
89f6b3
-		ttl = htons(agent->tx.txTTL);
89f6b3
-	else
89f6b3
-		ttl = htons(DEFAULT_TX_HOLD * DEFAULT_TX_INTERVAL);
89f6b3
-
89f6b3
+	ttl = htons(agent->tx.txTTL);
89f6b3
 	memcpy(tlv->info, &ttl, tlv->length);
89f6b3
 	LLDPAD_DBG("%s:%s:done:type=%d length=%d ttl=%d\n", __func__,
89f6b3
 		md->ifname, tlv->type, tlv->length, ntohs(ttl));
89f6b3
@@ -685,3 +681,18 @@ void mand_unregister(struct lldp_module *mod)
89f6b3
 	free(mod);
89f6b3
 	LLDPAD_INFO("%s:done\n", __func__); 
89f6b3
 }
89f6b3
+
89f6b3
+void mand_update_ttl(const char *ifname, u16 ttl_val)
89f6b3
+{
89f6b3
+	struct port *port = port_find_by_ifindex(get_ifidx(ifname));
89f6b3
+	struct lldp_agent *agent;
89f6b3
+
89f6b3
+	if (!port)
89f6b3
+		return;
89f6b3
+
89f6b3
+	LIST_FOREACH(agent, &port->agent_head, entry) {
89f6b3
+		agent->tx.txTTL = ttl_val;
89f6b3
+		agent->tx.localChange = 1;
89f6b3
+		agent->tx.txFast = agent->timers.txFastInit;
89f6b3
+	}
89f6b3
+}
89f6b3
diff --git a/lldp_mand_cmds.c b/lldp_mand_cmds.c
89f6b3
index 532337b..7d24bf8 100644
89f6b3
--- a/lldp_mand_cmds.c
89f6b3
+++ b/lldp_mand_cmds.c
89f6b3
@@ -58,6 +58,11 @@ static int get_mand_subtype(struct cmd *, char *, char *, char *, int);
89f6b3
 static int set_mand_subtype(struct cmd *, char *, char *, char *, int);
89f6b3
 static int test_mand_subtype(struct cmd *, char *, char *, char *, int);
89f6b3
 
89f6b3
+
89f6b3
+static int get_mand_ttl_value(struct cmd *, char *, char *, char *, int);
89f6b3
+static int set_mand_ttl_value(struct cmd *, char *, char *, char *, int);
89f6b3
+static int test_mand_ttl_value(struct cmd *, char *, char *, char *, int);
89f6b3
+
89f6b3
 static struct arg_handlers arg_handlers[] = {
89f6b3
 	{	.arg = ARG_ADMINSTATUS, .arg_class = LLDP_ARG,
89f6b3
 		.handle_get = get_arg_adminstatus,
89f6b3
@@ -72,6 +77,11 @@ static struct arg_handlers arg_handlers[] = {
89f6b3
 		.handle_get = get_mand_subtype,
89f6b3
 		.handle_set = set_mand_subtype,
89f6b3
 		.handle_test = test_mand_subtype, },
89f6b3
+	{	.arg = ARG_TTL_VALUE,
89f6b3
+		.arg_class = TLV_ARG,
89f6b3
+		.handle_get = get_mand_ttl_value,
89f6b3
+		.handle_set = set_mand_ttl_value,
89f6b3
+		.handle_test = test_mand_ttl_value, },
89f6b3
 	{	.arg = 0 }
89f6b3
 };
89f6b3
 
89f6b3
@@ -271,6 +281,86 @@ static int _set_mand_subtype(struct cmd *cmd, char *arg, char *argvalue,
89f6b3
 	return 0;
89f6b3
 }
89f6b3
 
89f6b3
+static int get_mand_ttl_value(struct cmd *cmd, char *arg,
89f6b3
+		UNUSED char *argvalue, char *obuf, int obuf_len)
89f6b3
+{
89f6b3
+	int ttl_val;
89f6b3
+	char string[8], arg_path[256];
89f6b3
+
89f6b3
+	if (cmd->cmd != cmd_gettlv)
89f6b3
+		return cmd_invalid;
89f6b3
+
89f6b3
+	switch (cmd->tlvid) {
89f6b3
+	case TIME_TO_LIVE_TLV:
89f6b3
+		snprintf(arg_path, sizeof(arg_path), "%s%08x.%s",
89f6b3
+			 TLVID_PREFIX, TLVID_NOUI(TIME_TO_LIVE_TLV),
89f6b3
+			 ARG_TTL_VALUE);
89f6b3
+		get_config_setting(cmd->ifname, cmd->type, arg_path,
89f6b3
+				   &ttl_val, CONFIG_TYPE_INT);
89f6b3
+		break;
89f6b3
+	case INVALID_TLVID:
89f6b3
+		return cmd_invalid;
89f6b3
+	default:
89f6b3
+		return cmd_not_applicable;
89f6b3
+	}
89f6b3
+
89f6b3
+	snprintf(string, sizeof(string), "%d", ttl_val);
89f6b3
+	snprintf(obuf, obuf_len, "%02x%s%04x%s",
89f6b3
+		 (unsigned int) strlen(arg), arg,
89f6b3
+		 (unsigned int)strlen(string), string);
89f6b3
+
89f6b3
+	return 0;
89f6b3
+}
89f6b3
+
89f6b3
+static int _set_mand_ttl_value(struct cmd *cmd, char *arg, char *argvalue,
89f6b3
+			     char *obuf, int obuf_len, bool test)
89f6b3
+{
89f6b3
+	int ttl_val;
89f6b3
+	char *end;
89f6b3
+	char arg_path[256];
89f6b3
+
89f6b3
+	if (cmd->cmd != cmd_settlv)
89f6b3
+		return cmd_invalid;
89f6b3
+
89f6b3
+	switch (cmd->tlvid) {
89f6b3
+	case TIME_TO_LIVE_TLV:
89f6b3
+		break;
89f6b3
+	case INVALID_TLVID:
89f6b3
+		return cmd_invalid;
89f6b3
+	default:
89f6b3
+		return cmd_not_applicable;
89f6b3
+	}
89f6b3
+
89f6b3
+	ttl_val = strtoul(argvalue, &end, 0);
89f6b3
+	if ((*end) || (TTL_MIN_VAL > ttl_val) || (ttl_val > TTL_MAX_VAL))
89f6b3
+		return cmd_bad_params;
89f6b3
+
89f6b3
+	if (test)
89f6b3
+		return cmd_success;
89f6b3
+
89f6b3
+	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
89f6b3
+			cmd->tlvid, arg);
89f6b3
+	snprintf(obuf, obuf_len, "%s=%s\n", arg, argvalue);
89f6b3
+	set_config_setting(cmd->ifname, cmd->type,
89f6b3
+			arg_path, &ttl_val, CONFIG_TYPE_INT);
89f6b3
+
89f6b3
+	mand_update_ttl(cmd->ifname, ttl_val);
89f6b3
+
89f6b3
+	return 0;
89f6b3
+}
89f6b3
+
89f6b3
+static int set_mand_ttl_value(struct cmd *cmd, char *arg, char *argvalue,
89f6b3
+		char *obuf, int obuf_len)
89f6b3
+{
89f6b3
+	return _set_mand_ttl_value(cmd, arg, argvalue, obuf, obuf_len, false);
89f6b3
+}
89f6b3
+
89f6b3
+static int test_mand_ttl_value(struct cmd *cmd, char *arg, char *argvalue,
89f6b3
+		char *obuf, int obuf_len)
89f6b3
+{
89f6b3
+	return _set_mand_ttl_value(cmd, arg, argvalue, obuf, obuf_len, true);
89f6b3
+}
89f6b3
+
89f6b3
 static int set_mand_subtype(struct cmd *cmd, char *arg, char *argvalue,
89f6b3
 			    char *obuf, int obuf_len)
89f6b3
 {
89f6b3
-- 
89f6b3
2.1.0
89f6b3