Blame SOURCES/open-lldp-v1.0.1-4-VDP-Changes-to-make-the-interface-to-VDP22-in-lldpad.patch

df64a6
From e3f6d0eab95ef6b7336aaea2f44ecb79ead4216d Mon Sep 17 00:00:00 2001
df64a6
From: padkrish <padkrish@cisco.com>
df64a6
Date: Wed, 21 Jan 2015 03:37:09 +0000
df64a6
Subject: [PATCH] VDP: Changes to make the interface to VDP22 (in lldpad) as
df64a6
 TLV
df64a6
df64a6
Changes to make the interface to VDP22 (in lldpad) as len, key, len,
df64a6
value, which is in sync with other modules of lldpad.
df64a6
df64a6
Currently, the VSI parameters of VDP22 to LLDPAD are comma separated.
df64a6
This patch has changes to have VSI Parameters being given to VDP22 as
df64a6
Keyword_len followed by Keyword followed by value_len followed by
df64a6
value. vdptool is also modified to reflect the same. This is
df64a6
synchronous with other interface of lldpad like lldptool.
df64a6
df64a6
As an example, if vdptool is invoked as:
df64a6
df64a6
"vdptool -i eth2 -T  -S -V assoc -c mode=assoc -c mgrid2=0 \
df64a6
 -c typeid=0 -c typeidver=0 -c uuid=00000000-3333-2222-888a-aabbccddee72 \
df64a6
 -c hints=none -c filter=0-00:00:00:11:22:72-90001",
df64a6
df64a6
the input to lldpad will be:
df64a6
df64a6
"M000080c4C3020000011c04eth2020000000304mode0005assoc06mgrid20001006typeid0001009typeidver0001004uuid002400000000-3333-2222-888a-aabbccddee7205hints0004none06filter00190-00:00:00:11:22:72-90001"
df64a6
df64a6
Another option is also added to vdptool to wait and print the response
df64a6
from the bridge.
df64a6
df64a6
Signed-off-by: padkrish <padkrish@cisco.com>
df64a6
---
df64a6
 include/qbg_vdp22.h      |   5 ++
df64a6
 include/qbg_vdp22_clif.h |   7 +++
df64a6
 include/qbg_vdp22def.h   |  24 ++++++++
df64a6
 qbg/vdp22_cmds.c         | 125 +++++++-------------------------------
df64a6
 qbg/vdp_ascii.c          | 152 +++++++++++++++++++++++++++++++----------------
df64a6
 vdptool.c                |  53 +++++++++++------
df64a6
 6 files changed, 193 insertions(+), 173 deletions(-)
df64a6
df64a6
diff --git a/include/qbg_vdp22.h b/include/qbg_vdp22.h
df64a6
index b345602..45f44d5 100644
df64a6
--- a/include/qbg_vdp22.h
df64a6
+++ b/include/qbg_vdp22.h
df64a6
@@ -163,6 +163,11 @@ struct vdp22_user_data {		/* Head for all VDP data */
df64a6
 	LIST_HEAD(vdp22_head, vdp22) head;
df64a6
 };
df64a6
 
df64a6
+struct vsi_keyword_handler {
df64a6
+	char *keyword;
df64a6
+	enum vsi_mand_arg val;
df64a6
+};
df64a6
+
df64a6
 struct lldp_module *vdp22_register(void);
df64a6
 void vdp22_unregister(struct lldp_module *);
df64a6
 void vdp22_start(const char *, int);
df64a6
diff --git a/include/qbg_vdp22_clif.h b/include/qbg_vdp22_clif.h
df64a6
index 008022a..8346b98 100644
df64a6
--- a/include/qbg_vdp22_clif.h
df64a6
+++ b/include/qbg_vdp22_clif.h
df64a6
@@ -29,6 +29,10 @@
df64a6
 
df64a6
 #ifndef QBG_VDP22_CLIF_H
df64a6
 #define QBG_VDP22_CLIF_H
df64a6
+
df64a6
+#define OP_FID_POS 8 /* Second Byte */
df64a6
+#define OP_OUI_POS 16 /* Third Byte */
df64a6
+
df64a6
 typedef enum {
df64a6
 	cmd_getstats,
df64a6
 	cmd_gettlv,
df64a6
@@ -51,6 +55,9 @@ typedef enum {
df64a6
 	op_config = 0x10,
df64a6
 	op_delete = 0x20,
df64a6
 	op_key = 0x40
df64a6
+	/* Second Byte is used for signifying the number of Filter fields and
df64a6
+	 * the third byte is used for signifying the number of OUI fields.
df64a6
+	 */
df64a6
 } vdp22_op;
df64a6
 
df64a6
 struct lldp_module *vdp22_cli_register(void);
df64a6
diff --git a/include/qbg_vdp22def.h b/include/qbg_vdp22def.h
df64a6
index 52f4502..21ba15d 100644
df64a6
--- a/include/qbg_vdp22def.h
df64a6
+++ b/include/qbg_vdp22def.h
df64a6
@@ -72,4 +72,28 @@ enum vdp22_migration_hints {
df64a6
 	VDP22_MIGFROM = 32		/* S-bit migrate from hint */
df64a6
 };
df64a6
 
df64a6
+enum vsi_mand_arg {
df64a6
+	VSI_MODE_ARG = 0,
df64a6
+	VSI_MGRID2_ARG,
df64a6
+	VSI_TYPEID_ARG,
df64a6
+	VSI_TYPEIDVER_ARG,
df64a6
+/*	VSI_VSIIDFRMT_ARG, TODO */
df64a6
+	VSI_VSIID_ARG,
df64a6
+	VSI_FILTER_ARG,
df64a6
+	VSI_MAND_NUM_ARG,
df64a6
+	VSI_HINTS_ARG,
df64a6
+	VSI_INVALID_ARG
df64a6
+};
df64a6
+
df64a6
+#define VSI22_ARG_MODE_STR "mode"
df64a6
+#define VSI22_ARG_MGRID_STR "mgrid2"
df64a6
+#define VSI22_ARG_TYPEID_STR "typeid"
df64a6
+#define VSI22_ARG_TYPEIDVER_STR "typeidver"
df64a6
+#define VSI22_ARG_VSIIDFRMT_STR "vsiidfrmt"
df64a6
+/*#define VSI22_ARG_VSIID_STR "vsiid" TODO*/
df64a6
+#define VSI22_ARG_VSIID_STR "uuid"
df64a6
+#define VSI22_ARG_HINTS_STR "hints"
df64a6
+#define VSI22_ARG_FILTER_STR "filter"
df64a6
+#define VSI22_ARG_OUI_STR "oui"
df64a6
+
df64a6
 #endif
df64a6
diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c
df64a6
index f055441..dde4669 100644
df64a6
--- a/qbg/vdp22_cmds.c
df64a6
+++ b/qbg/vdp22_cmds.c
df64a6
@@ -104,37 +104,6 @@ static int handle_get_arg(struct cmd *cmd, char *arg, char *argvalue,
df64a6
 	return status;
df64a6
 }
df64a6
 
df64a6
-static int handle_get(struct cmd *cmd, UNUSED char *arg, char *argvalue,
df64a6
-		      char *obuf, int obuf_len)
df64a6
-{
df64a6
-	struct arg_handlers *ah;
df64a6
-	int rval;
df64a6
-	char *nbuf;
df64a6
-	int nbuf_len;
df64a6
-
df64a6
-	memset(obuf, 0, obuf_len);
df64a6
-	nbuf = obuf + 12;
df64a6
-	nbuf_len = obuf_len - 12;
df64a6
-
df64a6
-	ah = get_my_arghndl(cmd->module_id);
df64a6
-	if (!ah)
df64a6
-		return cmd_not_applicable;
df64a6
-	for (; ah->arg; ++ah) {
df64a6
-		if (strcmp(ah->arg, ARG_VDP22_VSI))
df64a6
-			continue;
df64a6
-		if (ah->handle_get && (ah->arg_class == TLV_ARG)) {
df64a6
-			rval = ah->handle_get(cmd, ah->arg, argvalue,
df64a6
-					      nbuf, nbuf_len);
df64a6
-			if (rval != cmd_success && rval != cmd_not_applicable)
df64a6
-				return rval;
df64a6
-
df64a6
-			nbuf_len -= strlen(nbuf);
df64a6
-			nbuf = nbuf + strlen(nbuf);
df64a6
-		}
df64a6
-	}
df64a6
-	return cmd_success;
df64a6
-}
df64a6
-
df64a6
 static int handle_test_arg(struct cmd *cmd, char *arg, char *argvalue,
df64a6
 			   char *obuf, int obuf_len)
df64a6
 {
df64a6
@@ -223,17 +192,13 @@ static int handle_set_arg(struct cmd *cmd, char *arg, char *argvalue,
df64a6
  */
df64a6
 int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from,
df64a6
 		   UNUSED socklen_t fromlen,
df64a6
-		   char *ibuf, int ilen, char *rbuf, int rlen)
df64a6
+		   char *ibuf, UNUSED int ilen, char *rbuf, int rlen)
df64a6
 {
df64a6
 	struct cmd cmd;
df64a6
 	u8 len, version;
df64a6
 	int ioff, roff;
df64a6
 	int rstatus = cmd_invalid;
df64a6
-	char **args;
df64a6
-	char **argvals;
df64a6
 	bool test_failed = false;
df64a6
-	int numargs = 0;
df64a6
-	int i, offset;
df64a6
 
df64a6
 	memset(&cmd, 0, sizeof(cmd));
df64a6
 	cmd.module_id = LLDP_MOD_VDP22;
df64a6
@@ -275,32 +240,6 @@ int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from,
df64a6
 	if (!(cmd.ops & op_config))
df64a6
 		return cmd_invalid;
df64a6
 
df64a6
-	/* Count args and argvalues */
df64a6
-	offset = ioff;
df64a6
-	for (numargs = 0; (ilen - offset) > 2; numargs++) {
df64a6
-		offset += 2;
df64a6
-		if (ilen - offset > 0) {
df64a6
-			offset++;
df64a6
-			if (ilen - offset > 4)
df64a6
-				offset += 4;
df64a6
-		}
df64a6
-	}
df64a6
-
df64a6
-	args = calloc(numargs, sizeof(char *));
df64a6
-	if (!args)
df64a6
-		return cmd_failed;
df64a6
-
df64a6
-	argvals = calloc(numargs, sizeof(char *));
df64a6
-	if (!argvals) {
df64a6
-		free(args);
df64a6
-		return cmd_failed;
df64a6
-	}
df64a6
-
df64a6
-	if ((cmd.ops & op_arg) && (cmd.ops & op_argval))
df64a6
-		numargs = get_arg_val_list(ibuf, ilen, &ioff, args, argvals);
df64a6
-	else if (cmd.ops & op_arg)
df64a6
-		numargs = get_arg_list(ibuf, ilen, &ioff, args);
df64a6
-
df64a6
 	snprintf(rbuf, rlen, "%c%1x%02x%08x%02x%s",
df64a6
 		 CMD_REQUEST, CLIF_MSG_VERSION,
df64a6
 		 cmd.cmd, cmd.ops,
df64a6
@@ -309,42 +248,29 @@ int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from,
df64a6
 
df64a6
 	/* Confirm port is a valid LLDP port */
df64a6
 	if (!get_ifidx(cmd.ifname) || !is_valid_lldp_device(cmd.ifname)) {
df64a6
-		free(argvals);
df64a6
-		free(args);
df64a6
 		return cmd_device_not_found;
df64a6
 	}
df64a6
 
df64a6
 	snprintf(rbuf + roff, rlen - roff, "%08x", cmd.tlvid);
df64a6
 	roff += 8;
df64a6
 	if (cmd.cmd == cmd_gettlv) {
df64a6
-		if (!numargs)
df64a6
-			rstatus = handle_get(&cmd, NULL, NULL,
df64a6
-					     rbuf + strlen(rbuf),
df64a6
-					     rlen - strlen(rbuf));
df64a6
-		else
df64a6
-			for (i = 0; i < numargs; i++)
df64a6
-				rstatus = handle_get_arg(&cmd, args[i], NULL,
df64a6
-							 rbuf + strlen(rbuf),
df64a6
-							 rlen - strlen(rbuf));
df64a6
+		rstatus = handle_get_arg(&cmd, ARG_VDP22_VSI,
df64a6
+						NULL,
df64a6
+						rbuf + strlen(rbuf),
df64a6
+						rlen - strlen(rbuf));
df64a6
 	} else {
df64a6
-		for (i = 0; i < numargs; i++) {
df64a6
-			rstatus = handle_test_arg(&cmd, args[i], argvals[i],
df64a6
-						  rbuf + strlen(rbuf),
df64a6
-						  rlen - strlen(rbuf));
df64a6
-			if (rstatus != cmd_not_applicable &&
df64a6
-			    rstatus != cmd_success)
df64a6
-				test_failed = true;
df64a6
-		}
df64a6
+		rstatus = handle_test_arg(&cmd, ARG_VDP22_VSI,
df64a6
+						ibuf + ioff,
df64a6
+						rbuf + strlen(rbuf),
df64a6
+						rlen - strlen(rbuf));
df64a6
+		if (rstatus != cmd_not_applicable && rstatus != cmd_success)
df64a6
+			test_failed = true;
df64a6
 		if (!test_failed)
df64a6
-			for (i = 0; i < numargs; i++)
df64a6
-				rstatus = handle_set_arg(&cmd, args[i],
df64a6
-							 argvals[i],
df64a6
-							 rbuf + strlen(rbuf),
df64a6
-							 rlen - strlen(rbuf));
df64a6
+			rstatus = handle_set_arg(&cmd,
df64a6
+						ARG_VDP22_VSI, ibuf + ioff,
df64a6
+						rbuf + strlen(rbuf),
df64a6
+						rlen - strlen(rbuf));
df64a6
 	}
df64a6
-
df64a6
-	free(argvals);
df64a6
-	free(args);
df64a6
 	return rstatus;
df64a6
 }
df64a6
 
df64a6
@@ -436,27 +362,16 @@ out:
df64a6
 	return good_cmd;
df64a6
 }
df64a6
 
df64a6
-/*
df64a6
- * Count the number of fid data fields in the argument value.
df64a6
- */
df64a6
-#define	VDP22_FID_IDX	6		/* Min index of fid data */
df64a6
-static int count_fid(char *argvalue)
df64a6
-{
df64a6
-	char *p = argvalue;
df64a6
-	int i;
df64a6
-
df64a6
-	for (i = 0; (p = strchr(p, ',')); ++i, ++p)
df64a6
-		;
df64a6
-	return i + 1 - VDP22_FID_IDX;
df64a6
-}
df64a6
-
df64a6
 static int set_arg_vsi2(struct cmd *cmd, char *argvalue, bool test)
df64a6
 {
df64a6
-	int no = count_fid(argvalue);
df64a6
+	int no = (cmd->ops >> OP_FID_POS) & 0xff;
df64a6
 
df64a6
 	if (no <= 0)
df64a6
 		return -EINVAL;
df64a6
-	return set_arg_vsi3(cmd, argvalue, test, no);
df64a6
+	if ((cmd->ops & op_arg) && (cmd->ops & op_argval))
df64a6
+		return set_arg_vsi3(cmd, argvalue, test, no);
df64a6
+	else /* Not supported for now */
df64a6
+		return cmd_failed;
df64a6
 }
df64a6
 
df64a6
 static int set_arg_vsi(struct cmd *cmd, UNUSED char *arg, char *argvalue,
df64a6
diff --git a/qbg/vdp_ascii.c b/qbg/vdp_ascii.c
df64a6
index 0ace562..09e53c6 100644
df64a6
--- a/qbg/vdp_ascii.c
df64a6
+++ b/qbg/vdp_ascii.c
df64a6
@@ -43,6 +43,17 @@
df64a6
 #include "qbg_vdp22.h"
df64a6
 #include "qbg_vdpnl.h"
df64a6
 #include "qbg_utils.h"
df64a6
+#include "lldp_util.h"
df64a6
+
df64a6
+struct vsi_keyword_handler vsi_key_handle[] = {
df64a6
+	{VSI22_ARG_MODE_STR, VSI_MODE_ARG},
df64a6
+	{VSI22_ARG_MGRID_STR, VSI_MGRID2_ARG},
df64a6
+	{VSI22_ARG_TYPEID_STR, VSI_TYPEID_ARG},
df64a6
+	{VSI22_ARG_TYPEIDVER_STR, VSI_TYPEIDVER_ARG},
df64a6
+/*	{VSI22_ARG_VSIIDFRMT_STR, VSI_VSIIDFRMT_ARG}, TODO*/
df64a6
+	{VSI22_ARG_VSIID_STR, VSI_VSIID_ARG},
df64a6
+	{VSI22_ARG_HINTS_STR, VSI_HINTS_ARG},
df64a6
+	{VSI22_ARG_FILTER_STR, VSI_FILTER_ARG} };
df64a6
 
df64a6
 /*
df64a6
  * Check if it is a UUID and consists  of hexadecimal digits and dashes only.
df64a6
@@ -253,6 +264,18 @@ static bool getmode(struct vdpnl_vsi *p, char *s)
df64a6
 	return true;
df64a6
 }
df64a6
 
df64a6
+enum vsi_mand_arg get_keywork_val(char *keyword)
df64a6
+{
df64a6
+	int count, key_str_size;
df64a6
+
df64a6
+	key_str_size = sizeof(vsi_key_handle) / sizeof(vsi_key_handle[0]);
df64a6
+	for (count = 0; count < key_str_size; count++) {
df64a6
+		if (!strcmp(keyword, vsi_key_handle[count].keyword))
df64a6
+			return vsi_key_handle[count].val;
df64a6
+	}
df64a6
+	return VSI_INVALID_ARG;
df64a6
+}
df64a6
+
df64a6
 /*
df64a6
  * Parse the mode parameter to create/change an VSI assoication.
df64a6
  * The format is a comma separated list of tokens:
df64a6
@@ -276,66 +299,95 @@ static bool getmode(struct vdpnl_vsi *p, char *s)
df64a6
  * mac := xx:xx:xx:xx:xx:xx
df64a6
  */
df64a6
 
df64a6
-static int str2vdpnl(char *argvalue, struct vdpnl_vsi *vsi)
df64a6
+static int str2vdpnl(char *orig_argvalue, struct vdpnl_vsi *vsi)
df64a6
 {
df64a6
+	char **args;
df64a6
+	char **argvals;
df64a6
+	char *argvalue;
df64a6
 	int rc = -ENOMEM;
df64a6
 	unsigned int no;
df64a6
-	unsigned short idx;
df64a6
-	char *cmdstring, *token;
df64a6
+	unsigned short idx = 0;
df64a6
+	int i, ioff = 0, offset;
df64a6
+	int ilen = strlen(orig_argvalue);
df64a6
+	int numargs;
df64a6
+	enum vsi_mand_arg vsi_key;
df64a6
+	u16 vsi_mand_mask = (1 << VSI_MAND_NUM_ARG) - 1;
df64a6
+	u16 num_arg_keys = 0;
df64a6
 
df64a6
-	cmdstring = strdup(argvalue);
df64a6
-	if (!cmdstring)
df64a6
-		goto out_free;
df64a6
-	rc = -EINVAL;
df64a6
-	/* 1st field is VSI command */
df64a6
-	token = strtok(cmdstring, ",");
df64a6
-	if (!token || !getmode(vsi, token))
df64a6
-		goto out_free;
df64a6
+	argvalue = strdup(orig_argvalue);
df64a6
+	if (!argvalue)
df64a6
+		goto out;
df64a6
+	/* Count args and argvalues */
df64a6
+	offset = ioff;
df64a6
+	for (numargs = 0; (ilen - offset) > 2; numargs++) {
df64a6
+		offset += 2;
df64a6
+		if (ilen - offset > 0) {
df64a6
+			offset++;
df64a6
+			if (ilen - offset > 4)
df64a6
+				offset += 4;
df64a6
+		}
df64a6
+	}
df64a6
+	args = calloc(numargs, sizeof(char *));
df64a6
+	if (!args)
df64a6
+		goto out_argvalue;
df64a6
 
df64a6
-	/* 2nd field is VSI Manager Identifer (16 bytes maximum) */
df64a6
-	token = strtok(NULL, ",");
df64a6
-	if (!token || !getmgr2id(vsi, token))
df64a6
-		goto out_free;
df64a6
-
df64a6
-	/* 3rd field is type identifier */
df64a6
-	token = strtok(NULL, ",");
df64a6
-	if (!token || !getnumber(token, 0, 0xffffff, &no))
df64a6
-		goto out_free;
df64a6
-	vsi->vsi_typeid = no;
df64a6
-
df64a6
-	/* 4th field is type version identifier */
df64a6
-	token = strtok(NULL, ",");
df64a6
-	if (!token || !getnumber(token, 0, 0xff, &no))
df64a6
-		goto out_free;
df64a6
-	vsi->vsi_typeversion = no;
df64a6
-
df64a6
-	/* 5th field is filter VSI UUID */
df64a6
-	token = strtok(NULL, ",");
df64a6
-	if (!token || vdp_str2uuid(vsi->vsi_uuid, token, sizeof(vsi->vsi_uuid)))
df64a6
-		goto out_free;
df64a6
-	vsi->vsi_idfmt = VDP22_ID_UUID;
df64a6
-
df64a6
-	/* 6th field is migration hints */
df64a6
-	token = strtok(NULL, ",");
df64a6
-	if (!token || !gethints(vsi, token))
df64a6
-		goto out_free;
df64a6
-
df64a6
-	/*
df64a6
-	 * 7th and remaining fields are filter information format data.
df64a6
-	 * All fields must have the same format. The first fid field determines
df64a6
-	 * the format.
df64a6
-	 */
df64a6
-	for (idx = 0, token = strtok(NULL, ","); token != NULL;
df64a6
-					++idx, token = strtok(NULL, ",")) {
df64a6
-		if (idx < vsi->macsz && !getfid(vsi, token, idx))
df64a6
+	argvals = calloc(numargs, sizeof(char *));
df64a6
+	if (!argvals)
df64a6
+		goto out_args;
df64a6
+	numargs = get_arg_val_list(argvalue, ilen, &ioff, args, argvals);
df64a6
+	for (i = 0; i < numargs; i++) {
df64a6
+		vsi_key = get_keywork_val(args[i]);
df64a6
+		switch (vsi_key) {
df64a6
+		case VSI_MODE_ARG:
df64a6
+			if (!argvals[i] || !getmode(vsi, argvals[i]))
df64a6
+				goto out_free;
df64a6
+			break;
df64a6
+		case VSI_MGRID2_ARG:
df64a6
+			if (!argvals[i] || !getmgr2id(vsi, argvals[i]))
df64a6
+				goto out_free;
df64a6
+			break;
df64a6
+		case VSI_TYPEID_ARG:
df64a6
+			if (!argvals[i] ||
df64a6
+				!getnumber(argvals[i], 0, 0xffffff, &no))
df64a6
+				goto out_free;
df64a6
+			vsi->vsi_typeid = no;
df64a6
+			break;
df64a6
+		case VSI_TYPEIDVER_ARG:
df64a6
+			if (!argvals[i] || !getnumber(argvals[i], 0, 0xff, &no))
df64a6
+				goto out_free;
df64a6
+			vsi->vsi_typeversion = no;
df64a6
+			break;
df64a6
+		case VSI_VSIID_ARG:
df64a6
+			if (!argvals[i] ||
df64a6
+				vdp_str2uuid(vsi->vsi_uuid, argvals[i],
df64a6
+					sizeof(vsi->vsi_uuid)))
df64a6
+				goto out_free;
df64a6
+			vsi->vsi_idfmt = VDP22_ID_UUID;
df64a6
+			break;
df64a6
+		case VSI_FILTER_ARG:
df64a6
+			if (idx < vsi->macsz && !getfid(vsi, argvals[i], idx))
df64a6
+				goto out_free;
df64a6
+			idx++;
df64a6
+			break;
df64a6
+		case VSI_HINTS_ARG:
df64a6
+			if (!argvals[i] || !gethints(vsi, argvals[i]))
df64a6
+				goto out_free;
df64a6
+			break;
df64a6
+		default:
df64a6
 			goto out_free;
df64a6
+		}
df64a6
+		num_arg_keys |= (1 << vsi_key);
df64a6
 	}
df64a6
-
df64a6
 	/* Return error if no filter information provided */
df64a6
-	if (idx)
df64a6
+	if ((num_arg_keys & vsi_mand_mask) == vsi_mand_mask)
df64a6
 		rc = 0;
df64a6
 out_free:
df64a6
-	free(cmdstring);
df64a6
+	free(argvals);
df64a6
+out_args:
df64a6
+	free(args);
df64a6
+out_argvalue:
df64a6
+	free(argvalue);
df64a6
+out:
df64a6
 	return rc;
df64a6
 }
df64a6
 
df64a6
diff --git a/vdptool.c b/vdptool.c
df64a6
index e7d384a..f506020 100644
df64a6
--- a/vdptool.c
df64a6
+++ b/vdptool.c
df64a6
@@ -125,31 +125,28 @@ static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals)
df64a6
 {
df64a6
 	int len;
df64a6
 	int i;
df64a6
+	int fid = 0, oui = 0;
df64a6
 
df64a6
 	len = sizeof(cmd->obuf);
df64a6
 
df64a6
+	if (cmd->cmd == cmd_settlv) {
df64a6
+		for (i = 0; i < argc; i++) {
df64a6
+			if (args[i]) {
df64a6
+				if (!strncasecmp(args[i], "filter",
df64a6
+						strlen("filter")))
df64a6
+					fid++;
df64a6
+				else if (!strncasecmp(args[i], "oui",
df64a6
+						strlen("oui")))
df64a6
+					oui++;
df64a6
+			}
df64a6
+		}
df64a6
+	}
df64a6
+	cmd->ops |= (fid << OP_FID_POS) | (oui << OP_OUI_POS);
df64a6
 	/* all command messages begin this way */
df64a6
 	snprintf(cmd->obuf, len, "%c%08x%c%1x%02x%08x%02x%s%02x%08x",
df64a6
 		MOD_CMD, cmd->module_id, CMD_REQUEST, CLIF_MSG_VERSION,
df64a6
 		cmd->cmd, cmd->ops, (unsigned int) strlen(cmd->ifname),
df64a6
 		cmd->ifname, cmd->type, cmd->tlvid);
df64a6
-#if PADDU
df64a6
-	if (cmd->cmd == cmd_settlv) {
df64a6
-		size_t len2 = 0;
df64a6
-		/*
df64a6
-		 * Get total length and append it plus any args and argvals
df64a6
-		 * to the command message
df64a6
-		 */
df64a6
-		for (i = 0; i < argc; i++) {
df64a6
-			if (args[i])
df64a6
-				len2 += 2 + strlen(args[i]);
df64a6
-			if (argvals[i])
df64a6
-				len2 += 4 + strlen(argvals[i]);
df64a6
-		}
df64a6
-		snprintf(cmd->obuf + strlen(cmd->obuf), len - strlen(cmd->obuf),
df64a6
-			 "%04zx", len2);
df64a6
-	}
df64a6
-#endif
df64a6
 	/* Add any args and argvals to the command message */
df64a6
 	for (i = 0; i < argc; i++) {
df64a6
 		if (args[i])
df64a6
@@ -710,6 +707,9 @@ static int _clif_command(struct clif *clif, char *cmd, int print)
df64a6
 	char buf[MAX_CLIF_MSGBUF];
df64a6
 	size_t len;
df64a6
 	int ret;
df64a6
+	int rc;
df64a6
+	char reply[100];
df64a6
+	size_t reply_len2 = sizeof(reply);
df64a6
 
df64a6
 	print_raw_message(cmd, print);
df64a6
 
df64a6
@@ -730,6 +730,13 @@ static int _clif_command(struct clif *clif, char *cmd, int print)
df64a6
 		buf[len] = '\0';
df64a6
 		ret = parse_print_message(buf, print);
df64a6
 	}
df64a6
+	if (cli_attached) {
df64a6
+		rc = clif_vsievt(clif, reply, &reply_len2, 5);
df64a6
+		printf("\nReturn from vsievt %d ret %d Reply %s\n", rc, ret,
df64a6
+			reply);
df64a6
+		if (!rc)
df64a6
+			printf("\nMsg is %s\n", reply);
df64a6
+	}
df64a6
 
df64a6
 	return ret;
df64a6
 }
df64a6
@@ -854,6 +861,7 @@ static int request(struct clif *clif, int argc, char *argv[])
df64a6
 	int numargs = 0;
df64a6
 	char **argptr = &argv[0];
df64a6
 	char *end;
df64a6
+	char attach_str[9] = "";
df64a6
 	int c;
df64a6
 	int option_index;
df64a6
 
df64a6
@@ -865,7 +873,7 @@ static int request(struct clif *clif, int argc, char *argv[])
df64a6
 
df64a6
 	opterr = 0;
df64a6
 	for (;;) {
df64a6
-		c = getopt_long(argc, argv, "i:tThcnvrRpqV:",
df64a6
+		c = getopt_long(argc, argv, "i:tTWhcnvrRpqV:",
df64a6
 				lldptool_opts, &option_index);
df64a6
 		if (c < 0)
df64a6
 			break;
df64a6
@@ -936,6 +944,15 @@ static int request(struct clif *clif, int argc, char *argv[])
df64a6
 		case 'v':
df64a6
 			command.cmd = cmd_version;
df64a6
 			break;
df64a6
+		case 'W':
df64a6
+			snprintf(attach_str, sizeof(attach_str), "%x",
df64a6
+				LLDP_MOD_VDP22);
df64a6
+			if (clif_attach(clif, attach_str) != 0) {
df64a6
+				printf("Warning: Failed to attach to lldpad.\n");
df64a6
+				return -1;
df64a6
+			}
df64a6
+			cli_attached = 1;
df64a6
+			break;
df64a6
 		default:
df64a6
 			usage();
df64a6
 			ret = -1;
df64a6
-- 
df64a6
2.1.0
df64a6