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

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