Blame SOURCES/open-lldp-v1.0.1-6-VDP-Support-in-VDP22-for-correct-error-code-status-t.patch

74731f
From faf19bd8bdb1a6ca0dd98843cd09fd96b1f2f901 Mon Sep 17 00:00:00 2001
74731f
From: padkrish <padkrish@cisco.com>
74731f
Date: Wed, 21 Jan 2015 03:37:57 +0000
74731f
Subject: [PATCH] VDP: Support in VDP22 for correct error code/status to
74731f
 vdptool
74731f
74731f
This commit has the following changes:
74731f
a. Returning the status or error code to vdptool for the error cases. Errors
74731f
can be Tx error, invalid parameters, incorrect configuration etc. The vdptool
74731f
 is modified to print the error messages from lldpad.
74731f
b. Modify the vdptool option from set-tlv/get-tlv to set-vsi/get-vsi. The
74731f
 vdptool man page document is also modified accordingly.
74731f
c. Re-arrange the definitions in header files.
74731f
d. Fix some formatting issues.
74731f
74731f
Signed-off-by: padkrish <padkrish@cisco.com>
74731f
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
74731f
---
74731f
 docs/vdptool.8           |  12 ++--
74731f
 include/lldpad_status.h  |  25 +++++----
74731f
 include/qbg_vdp22.h      |  50 +++++++++--------
74731f
 include/qbg_vdp22_clif.h |   8 +++
74731f
 include/qbg_vdp22def.h   |  39 +++++++++++++
74731f
 qbg/vdp22.c              |  20 ++++++-
74731f
 qbg/vdp22_cmds.c         |  63 +++++++++++++++------
74731f
 qbg/vdp22sm.c            |  15 -----
74731f
 qbg/vdp_ascii.c          |  56 +++++++++++++++----
74731f
 vdptool.c                | 141 ++++++++++++++++++++++++++++++++++++++---------
74731f
 10 files changed, 316 insertions(+), 113 deletions(-)
74731f
74731f
diff --git a/docs/vdptool.8 b/docs/vdptool.8
74731f
index 02b4e8e..0b50a13 100644
74731f
--- a/docs/vdptool.8
74731f
+++ b/docs/vdptool.8
74731f
@@ -98,7 +98,7 @@ Wait for the bridge response message
74731f
 .SS VSI Parameter
74731f
 Each VDP22 TLVs contains a command mode, manager identifier,
74731f
 type identifier, type identifier version, VSI instance identifier,
74731f
-migiration hints and filter information.
74731f
+migration hints and filter information.
74731f
 The fields are explained next:
74731f
 .TP
74731f
 .B "mode (Command Mode):"
74731f
@@ -140,7 +140,7 @@ an UUID according to RFC 4122
74731f
 with optional dashes in between.
74731f
 .TP
74731f
 .B "hints (Migration Hints):"
74731f
-The migiration hints is a string aiding in
74731f
+The migration hints is a string aiding in
74731f
 migration of virtual machines:
74731f
 .RS
74731f
 .IP none:
74731f
@@ -193,11 +193,11 @@ show usage information
74731f
 .B \-v, version
74731f
 show version information
74731f
 .TP
74731f
-.B \-t, get-tlv
74731f
-get TLV information for the specified interface
74731f
+.B \-t, get-vsi
74731f
+get VSI information for the specified interface
74731f
 .TP
74731f
-.B \-T, set-tlv
74731f
-set TLV information for the specified interface
74731f
+.B \-T, set-vsi
74731f
+set VSI information for the specified interface
74731f
 .TP
74731f
 .B \-p, ping
74731f
 display the process identifier of the running lldpad process
74731f
diff --git a/include/lldpad_status.h b/include/lldpad_status.h
74731f
index df6e0f7..568063b 100644
74731f
--- a/include/lldpad_status.h
74731f
+++ b/include/lldpad_status.h
74731f
@@ -33,18 +33,19 @@
74731f
 #define LLDPAD_STATUS_H
74731f
 
74731f
 typedef enum {
74731f
-    cmd_success = 0,
74731f
-    cmd_failed,
74731f
-    cmd_device_not_found,
74731f
-    cmd_agent_not_found,
74731f
-    cmd_invalid,
74731f
-    cmd_bad_params,
74731f
-    cmd_peer_not_present,
74731f
-    cmd_ctrl_vers_not_compatible,
74731f
-    cmd_not_capable,
74731f
-    cmd_not_applicable,
74731f
-    cmd_no_access,
74731f
-    cmd_agent_not_supported,
74731f
+	cmd_success = 0,
74731f
+	cmd_failed,
74731f
+	cmd_device_not_found,
74731f
+	cmd_agent_not_found,
74731f
+	cmd_invalid,
74731f
+	cmd_bad_params,
74731f
+	cmd_peer_not_present,
74731f
+	cmd_ctrl_vers_not_compatible,
74731f
+	cmd_not_capable,
74731f
+	cmd_not_applicable,
74731f
+	cmd_no_access,
74731f
+	cmd_agent_not_supported,
74731f
+	cmd_max_status,
74731f
 } cmd_status;
74731f
 
74731f
 #endif /* LLDPAD_STATUS_H */
74731f
diff --git a/include/qbg_vdp22.h b/include/qbg_vdp22.h
74731f
index af0aa15..6c3c9ee 100644
74731f
--- a/include/qbg_vdp22.h
74731f
+++ b/include/qbg_vdp22.h
74731f
@@ -65,22 +65,36 @@ enum vdp22_role {		/* State for VDP22 bridge processing */
74731f
 	VDP22_STATION		/* State role */
74731f
 };
74731f
 
74731f
-enum vdp22_cmdresp {			/* VDP22 Protocol command responses */
74731f
-	VDP22_RESP_SUCCESS = 0,		/* Success */
74731f
-	VDP22_RESP_INVALID_FORMAT = 1,
74731f
-	VDP22_RESP_NO_RESOURCES = 2,
74731f
-	VDP22_RESP_NO_VSIMGR = 3,	/* No contact to VSI manager */
74731f
-	VDP22_RESP_OTHER = 4,		/* Other reasons */
74731f
-	VDP22_RESP_NOADDR = 5,		/* Invalid VID, MAC, GROUP etc */
74731f
-	VDP22_RESP_DEASSOC = 252,	/* Deassoc response */
74731f
-	VDP22_RESP_TIMEOUT = 253,	/* Timeout response */
74731f
-	VDP22_RESP_KEEP = 254,		/* Keep response */
74731f
-	VDP22_RESP_NONE = 255		/* No response returned so far */
74731f
+/*
74731f
+ * VSI information. One node per matching entry (same mgrid, type_id, type_ver,
74731f
+ * id_fmt, id and fif). Filter data can be added and removed.
74731f
+ */
74731f
+enum vsi22_flags {			/* Flags (or'ed in) */
74731f
+	VDP22_BUSY = 1,			/* This node is under work */
74731f
+	VDP22_DELETE_ME = 2,		/* Deallocate this node */
74731f
+	VDP22_RETURN_VID = 4,		/* Return wildcard vlan id */
74731f
+	VDP22_NOTIFY = 8,		/* Send netlink message to requestor */
74731f
+	VDP22_NLCMD = 16		/* Netlink command pending */
74731f
+};
74731f
+
74731f
+enum {                                  /* VDP22 Protocol command responses */
74731f
+	USEC_PER_SEC = 1000000,         /* Microseconds per second */
74731f
+	VDP22_RESBIT = 0x80,            /* VSI reserved bit */
74731f
+	VDP22_ACKBIT = 0x40,            /* VSI Acknowledgement bit */
74731f
+	VDP22_KEEPBIT = 0x20,           /* VSI keep error bit */
74731f
+	VDP22_HARDBIT = 0x10,           /* VSI hard error bit */
74731f
+	VDP22_STATUS_MASK = 0x0f,       /* Status mask */
74731f
+	VDP22_STATUS_SHIFT = 0,         /* Status offset */
74731f
 };
74731f
 
74731f
 enum {
74731f
 	VDP22_MGRIDSZ = 16,		/* Size of manager identifier */
74731f
-	VDP22_IDSZ = 16			/* Size of vsi identifier */
74731f
+	VDP22_IDSZ = 16,		/* Size of vsi identifier */
74731f
+};
74731f
+
74731f
+struct vdp22_ptlv {                     /* Packed TLV for VDP data exchange */
74731f
+	unsigned short head;            /* TLV 16 bit header */
74731f
+	unsigned char data[];           /* TLV Data buffer */
74731f
 };
74731f
 
74731f
 struct vsi_origin {		/* Originator of VSI request */
74731f
@@ -99,18 +113,6 @@ struct fid22 {				/* Filter data: GROUP,MAC,VLAN entry */
74731f
 	struct vsi_origin requestor;
74731f
 };
74731f
 
74731f
-/*
74731f
- * VSI information. One node per matching entry (same mgrid, type_id, type_ver,
74731f
- * id_fmt, id and fif). Filter data can be added and removed.
74731f
- */
74731f
-enum vsi22_flags {			/* Flags (or'ed in) */
74731f
-	VDP22_BUSY = 1,			/* This node is under work */
74731f
-	VDP22_DELETE_ME = 2,		/* Deallocate this node */
74731f
-	VDP22_RETURN_VID = 4,		/* Return wildcard vlan id */
74731f
-	VDP22_NOTIFY = 8,		/* Send netlink message to requestor */
74731f
-	VDP22_NLCMD = 16		/* Netlink command pending */
74731f
-};
74731f
-
74731f
 struct vdp22smi {		/* Data structure for VDP22 state machine */
74731f
 	int state;		/* State of VDP state machine for VSI */
74731f
 	bool kato;		/* VSI KA ACK timeout hit for this VSI */
74731f
diff --git a/include/qbg_vdp22_clif.h b/include/qbg_vdp22_clif.h
74731f
index 8346b98..0cc603e 100644
74731f
--- a/include/qbg_vdp22_clif.h
74731f
+++ b/include/qbg_vdp22_clif.h
74731f
@@ -33,6 +33,8 @@
74731f
 #define OP_FID_POS 8 /* Second Byte */
74731f
 #define OP_OUI_POS 16 /* Third Byte */
74731f
 
74731f
+#include "lldpad_status.h"
74731f
+
74731f
 typedef enum {
74731f
 	cmd_getstats,
74731f
 	cmd_gettlv,
74731f
@@ -60,5 +62,11 @@ typedef enum {
74731f
 	 */
74731f
 } vdp22_op;
74731f
 
74731f
+enum vdp22_cmd_status {
74731f
+	cmd_vdp_prot_no_support = cmd_max_status + 1,
74731f
+	cmd_vdp_nomem,
74731f
+	cmd_vdp_busy,
74731f
+};
74731f
+
74731f
 struct lldp_module *vdp22_cli_register(void);
74731f
 #endif
74731f
diff --git a/include/qbg_vdp22def.h b/include/qbg_vdp22def.h
74731f
index ff4270c..c305a2b 100644
74731f
--- a/include/qbg_vdp22def.h
74731f
+++ b/include/qbg_vdp22def.h
74731f
@@ -94,6 +94,31 @@ enum vsi_key_arg {
74731f
 	VSI_INVALID_ARG
74731f
 };
74731f
 
74731f
+enum vdp22_cmdresp {			/* VDP22 Protocol command responses */
74731f
+	VDP22_RESP_SUCCESS = 0,		/* Success */
74731f
+	VDP22_RESP_INVALID_FORMAT = 1,
74731f
+	VDP22_RESP_NO_RESOURCES = 2,
74731f
+	VDP22_RESP_NO_VSIMGR = 3,	/* No contact to VSI manager */
74731f
+	VDP22_RESP_OTHER = 4,		/* Other reasons */
74731f
+	VDP22_RESP_NOADDR = 5,		/* Invalid VID, MAC, GROUP etc */
74731f
+	VDP22_RESP_DEASSOC = 252,	/* Deassoc response */
74731f
+	VDP22_RESP_TIMEOUT = 253,	/* Timeout response */
74731f
+	VDP22_RESP_KEEP = 254,		/* Keep response */
74731f
+	VDP22_RESP_NONE = 255		/* No response returned so far */
74731f
+};
74731f
+
74731f
+/*
74731f
+ * Errors applicable mostly for VDP22_RESP_NONE
74731f
+ */
74731f
+
74731f
+enum vdp22_cmderr {
74731f
+	VDP22_KATO = 0,
74731f
+	VDP22_ACKTO,
74731f
+	VDP22_TXERR
74731f
+};
74731f
+
74731f
+#define VDP22_STATUS_BITS  8          /* Number of bits in Status field */
74731f
+
74731f
 #define VSI22_ARG_MODE_STR "mode"
74731f
 #define VSI22_ARG_MGRID_STR "mgrid2"
74731f
 #define VSI22_ARG_TYPEID_STR "typeid"
74731f
@@ -105,4 +130,18 @@ enum vsi_key_arg {
74731f
 #define VSI22_ARG_FILTER_STR "filter"
74731f
 #define VSI22_ARG_OUI_STR "oui"
74731f
 
74731f
+#define VSI22_KATO_ERR_STR "Keepalive Timeout"
74731f
+#define VSI22_ACKTO_ERR_STR "Ack not received from bridge"
74731f
+#define VSI22_TX_ERR_STR "Transmission Error"
74731f
+
74731f
+#define VSI22_INVALID_FRMT_ERR_STR "VDP TLV Format is Invalid"
74731f
+#define VSI22_NO_RES_ERR_STR "Insufficient resources at bridge"
74731f
+#define VSI22_NO_VSIMGR_ERR_STR "Unable to contact VSI Mgr"
74731f
+#define VSI22_OTHER_ERR_STR "Other Failures"
74731f
+#define VSI22_NOADDR_ERR_STR "Invalid VID, GroupID or MAC address field"
74731f
+#define VSI22_DEASS_ERR_STR "Deassoc received from switch"
74731f
+#define VSI22_TIMEOUT_ERR_STR "Timeout Error"
74731f
+#define VSI22_KEEP_ERR_STR "Command rejected by bridge and state prior to" \
74731f
+			   " requested command is kept"
74731f
+
74731f
 #endif
74731f
diff --git a/qbg/vdp22.c b/qbg/vdp22.c
74731f
index af11af8..d7aa648 100644
74731f
--- a/qbg/vdp22.c
74731f
+++ b/qbg/vdp22.c
74731f
@@ -42,6 +42,7 @@
74731f
 #include "qbg_vdp22.h"
74731f
 #include "qbg_utils.h"
74731f
 #include "qbg_vdp22_cmds.h"
74731f
+#include "qbg_vdp22def.h"
74731f
 
74731f
 /*
74731f
  * VDP22 helper functions
74731f
@@ -469,7 +470,8 @@ static bool filter_ok(unsigned char ffmt, struct fid22 *fp,
74731f
 		else
74731f
 			rc = false;
74731f
 	}
74731f
-	LLDPAD_DBG("%s:rc:%d\n", __func__, rc);
74731f
+	LLDPAD_DBG("%s: ffmt:%d gpid_on:%d rc:%d\n", __func__, ffmt,
74731f
+		   gpid_on, rc);
74731f
 	return rc;
74731f
 }
74731f
 
74731f
@@ -1007,12 +1009,26 @@ static pid_t havepid(struct vsi22 *vsi)
74731f
 	return mypid;
74731f
 }
74731f
 
74731f
+unsigned char vdp22_getsm_errcode(struct vsi22 *vsi)
74731f
+{
74731f
+	unsigned char err_code = 0;
74731f
+
74731f
+	if (vsi->smi.kato)
74731f
+		err_code |= (1 << VDP22_KATO);
74731f
+	if (vsi->smi.acktimeout)
74731f
+		err_code |= (1 << VDP22_ACKTO);
74731f
+	if (vsi->smi.txmit_error)
74731f
+		err_code |= (1 << VDP22_TXERR);
74731f
+	return err_code;
74731f
+}
74731f
+
74731f
 /*
74731f
  * Convert and VSI22 to VDP netlink format and send it back to the originator.
74731f
  */
74731f
 static int vdp22_back(struct vsi22 *vsi, pid_t to,
74731f
 		      int (*fct)(struct vdpnl_vsi *))
74731f
 {
74731f
+	unsigned char err_code;
74731f
 	int i;
74731f
 	struct vdpnl_vsi nl;
74731f
 	struct vdpnl_mac nlmac[vsi->no_fdata];
74731f
@@ -1025,6 +1041,8 @@ static int vdp22_back(struct vsi22 *vsi, pid_t to,
74731f
 	memcpy(nl.ifname, vsi->vdp->ifname, sizeof(nl.ifname));
74731f
 	nl.request = vsi->vsi_mode;
74731f
 	nl.response = vsi->status;
74731f
+	err_code = vdp22_getsm_errcode(vsi);
74731f
+	nl.response |= (err_code << VDP22_STATUS_BITS);
74731f
 	nl.vsi_mgrid = vsi->mgrid[0];
74731f
 	memcpy(nl.vsi_mgrid2, vsi->mgrid, sizeof(nl.vsi_mgrid2));
74731f
 	nl.vsi_typeversion = vsi->type_ver;
74731f
diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c
74731f
index 409858d..5d5ef6b 100644
74731f
--- a/qbg/vdp22_cmds.c
74731f
+++ b/qbg/vdp22_cmds.c
74731f
@@ -165,7 +165,8 @@ static int handle_set_arg(struct cmd *cmd, char *arg, char *argvalue,
74731f
  * bb:  C for command and 2 or 3 for message version number
74731f
  * cc: 1 for get command and 2 for set command
74731f
  * dddddddd: 8 hex digits options, supported are op_arg, op_argval, op_conifg
74731f
- *           and op_local
74731f
+ *           and op_local. The number of filter (fid) parameters are encoded
74731f
+ *           here (second byte from right).
74731f
  * ee: 2 hex digit length of interface name
74731f
  * ffff: string for interface name
74731f
  * gg: 2 hex digit for bridge type (nearest customer bridge only)
74731f
@@ -179,7 +180,7 @@ static int handle_set_arg(struct cmd *cmd, char *arg, char *argvalue,
74731f
  * The total input length can be used to determine the number of arguaments.
74731f
  *
74731f
  * The member ops of struct cmd settings depends on the invoked with
74731f
- * -T (cmd_gettlv) -a assoc:
74731f
+ * -T (cmd_getvsi) -a assoc:
74731f
  * -c key      --> ops=(0x15) op_config,op_arg,op_local), numargs > 0
74731f
  * -c key=abc  --> ops=(0x1d) op_config,op_arg,op_argval,op_local), numargs > 0
74731f
  * -c          --> ops=0x11 (op_config,op_local), numargs = 0
74731f
@@ -279,8 +280,16 @@ int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from,
74731f
 int vdp22_sendevent(struct vdpnl_vsi *p)
74731f
 {
74731f
 	char msg[MAX_CLIF_MSGBUF];
74731f
+	char tmp_buf[MAX_CLIF_MSGBUF];
74731f
+	int c, len;
74731f
 
74731f
-	vdp_vdpnl2str(p, msg, sizeof(msg));
74731f
+	vdp_vdpnl2str(p, tmp_buf, sizeof(msg));
74731f
+	len = strlen(tmp_buf);
74731f
+	if ((unsigned)len > sizeof(msg))
74731f
+		return 0;
74731f
+	c = snprintf(msg, sizeof(msg), "%04x%s", len, tmp_buf);
74731f
+	if ((c < 0) || ((unsigned)c >= sizeof(msg)))
74731f
+		return 0;
74731f
 	LLDPAD_DBG("%s:%s vsi:%p(%#2x), len:%zd msg:%s\n", __func__,
74731f
 		   p->ifname, p, p->vsi_uuid[0], strlen(msg), msg);
74731f
 	send_event(16, LLDP_MOD_VDP22, msg);
74731f
@@ -324,6 +333,29 @@ static int ifok(struct cmd *cmd)
74731f
 	return good_cmd;
74731f
 }
74731f
 
74731f
+static int get_vdp22_retval(int rc)
74731f
+{
74731f
+	if (!rc)
74731f
+		return cmd_success;
74731f
+
74731f
+	switch (rc) {
74731f
+	case -EPROTONOSUPPORT:
74731f
+		return cmd_vdp_prot_no_support;
74731f
+	case -EOPNOTSUPP:
74731f
+		return cmd_not_capable;
74731f
+	case -EINVAL:
74731f
+		return cmd_bad_params;
74731f
+	case -ENOMEM:
74731f
+		return cmd_vdp_nomem;
74731f
+	case -EBUSY:
74731f
+		return cmd_vdp_busy;
74731f
+	case -ENODEV:
74731f
+		return cmd_device_not_found;
74731f
+	default:
74731f
+		return cmd_failed;
74731f
+	}
74731f
+}
74731f
+
74731f
 static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size)
74731f
 {
74731f
 	cmd_status good_cmd = vdp22_cmdok(cmd, cmd_settlv);
74731f
@@ -340,7 +372,7 @@ static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size)
74731f
 	vsi.macsz = size;
74731f
 	rc = vdp_str2vdpnl(argvalue, &vsi, cmd->ifname);
74731f
 	if (rc) {
74731f
-		good_cmd = cmd_bad_params;
74731f
+		good_cmd = get_vdp22_retval(rc);
74731f
 		goto out;
74731f
 	}
74731f
 	if (!port_find_by_ifindex(get_ifidx(cmd->ifname))) {
74731f
@@ -351,12 +383,8 @@ static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size)
74731f
 	if (good_cmd != cmd_success || test)
74731f
 		goto out;
74731f
 	rc = vdp22_request(&vsi, 1);
74731f
-	if (!rc)
74731f
-		good_cmd = cmd_success;
74731f
-	else if (rc == -ENODEV)
74731f
-		good_cmd = cmd_device_not_found;
74731f
-	else
74731f
-		good_cmd = cmd_failed;
74731f
+	good_cmd = get_vdp22_retval(rc);
74731f
+
74731f
 out:
74731f
 	return good_cmd;
74731f
 }
74731f
@@ -480,7 +508,8 @@ static int get_vsi_partial_arg(UNUSED char *arg, char *orig_argvalue,
74731f
 	int rc = -ENOMEM, len, c;
74731f
 	u16 vsi_arg_key_flags = 0;
74731f
 
74731f
-	if (vdp22_parse_str_vdpnl(vsinl, &vsi_arg_key_flags, orig_argvalue))
74731f
+	rc = vdp22_parse_str_vdpnl(vsinl, &vsi_arg_key_flags, orig_argvalue);
74731f
+	if (rc)
74731f
 		goto out;
74731f
 	vdp = vdp22_getvdp(vsinl->ifname);
74731f
 	if (!vdp)
74731f
@@ -498,7 +527,6 @@ static int get_vsi_partial_arg(UNUSED char *arg, char *orig_argvalue,
74731f
 			len = strlen(tmp_buf);
74731f
 			c = snprintf(out + used, out_len - used, "%04x%s",
74731f
 				     len, tmp_buf);
74731f
-			vdp22_freemaclist(vsinl);
74731f
 			if ((c < 0) || ((unsigned)c >= (out_len - used)))
74731f
 				goto out_delvsi;
74731f
 			if (rc)
74731f
@@ -544,11 +572,14 @@ static int get_arg_vsi(struct cmd *cmd, char *arg, char *argvalue,
74731f
 		memset(&mac, 0, sizeof(mac));
74731f
 		vsi.macsz = fsize;
74731f
 		vsi.maclist = mac;
74731f
-		if (!get_vsi_partial_arg(arg, argvalue, &vsi, vsi_str,
74731f
-					 sizeof(vsi_str)))
74731f
-			goto out;
74731f
-	} else if (!catvsis(&vsi, vsi_str, sizeof(vsi_str)))
74731f
+		rc = get_vsi_partial_arg(arg, argvalue, &vsi, vsi_str,
74731f
+					 sizeof(vsi_str));
74731f
+	} else
74731f
+		rc = catvsis(&vsi, vsi_str, sizeof(vsi_str));
74731f
+	if (!rc) {
74731f
+		good_cmd = get_vdp22_retval(rc);
74731f
 		goto out;
74731f
+	}
74731f
 	rc = snprintf(obuf, obuf_len, "%s", vsi_str);
74731f
 	if (rc > 0 || rc < obuf_len)
74731f
 		good_cmd = cmd_success;
74731f
diff --git a/qbg/vdp22sm.c b/qbg/vdp22sm.c
74731f
index 6264f74..83a97fb 100644
74731f
--- a/qbg/vdp22sm.c
74731f
+++ b/qbg/vdp22sm.c
74731f
@@ -46,21 +46,6 @@
74731f
 #include "qbg_vdp22.h"
74731f
 #include "qbg_utils.h"
74731f
 
74731f
-struct vdp22_ptlv {			/* Packed TLV for VDP data exchange */
74731f
-	unsigned short head;		/* TLV 16 bit header */
74731f
-	unsigned char data[];		/* TLV Data buffer */
74731f
-};
74731f
-
74731f
-enum {					/* VDP22 Protocol command responses */
74731f
-	USEC_PER_SEC = 1000000,		/* Microseconds per second */
74731f
-	VDP22_RESBIT = 0x80,		/* VSI reserved bit */
74731f
-	VDP22_ACKBIT = 0x40,		/* VSI Acknowledgement bit */
74731f
-	VDP22_KEEPBIT = 0x20,		/* VSI keep error bit */
74731f
-	VDP22_HARDBIT = 0x10,		/* VSI hard error bit */
74731f
-	VDP22_STATUS_MASK = 0x0f,	/* Status mask */
74731f
-	VDP22_STATUS_SHIFT = 0,		/* Status offset */
74731f
-};
74731f
-
74731f
 /*
74731f
  * Set status code
74731f
  */
74731f
diff --git a/qbg/vdp_ascii.c b/qbg/vdp_ascii.c
74731f
index 76dde4a..70ec79b 100644
74731f
--- a/qbg/vdp_ascii.c
74731f
+++ b/qbg/vdp_ascii.c
74731f
@@ -44,6 +44,7 @@
74731f
 #include "qbg_vdpnl.h"
74731f
 #include "qbg_utils.h"
74731f
 #include "lldp_util.h"
74731f
+#include "messages.h"
74731f
 
74731f
 struct vsi_keyword_handler vsi_key_handle[] = {
74731f
 	{VSI22_ARG_MODE_STR, VSI_MODE_ARG},
74731f
@@ -285,6 +286,24 @@ enum vsi_key_arg get_keywork_val(char *keyword)
74731f
 	return VSI_INVALID_ARG;
74731f
 }
74731f
 
74731f
+/*
74731f
+ * If the ordering is maintained in vsi_key_handle, then this function is not
74731f
+ * necessary as the keyword can be retrieved using
74731f
+ * 'vsi_key_handle[keyval].keyword'.
74731f
+ */
74731f
+
74731f
+char *get_keyword_str(enum vsi_key_arg keyval)
74731f
+{
74731f
+	int count, key_str_size;
74731f
+
74731f
+	key_str_size = sizeof(vsi_key_handle) / sizeof(vsi_key_handle[0]);
74731f
+	for (count = 0; count < key_str_size; count++) {
74731f
+		if (vsi_key_handle[count].val == keyval)
74731f
+			return vsi_key_handle[count].keyword;
74731f
+	}
74731f
+	return NULL;
74731f
+}
74731f
+
74731f
 int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags,
74731f
 			  char *orig_argvalue)
74731f
 {
74731f
@@ -315,52 +334,57 @@ int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags,
74731f
 	numargs = get_arg_val_list(argvalue, ilen, &ioff, args, argvals);
74731f
 	if (numargs == 0)
74731f
 		goto out_free;
74731f
+	rc = -EINVAL;
74731f
 	for (i = 0; i < numargs; i++) {
74731f
 		vsi_key = get_keywork_val(args[i]);
74731f
 		switch (vsi_key) {
74731f
 		case VSI_MODE_ARG:
74731f
 			if (!argvals[i] || !getmode(vsi, argvals[i]))
74731f
-				goto out_free;
74731f
+				goto out_err;
74731f
 			break;
74731f
 		case VSI_MGRID2_ARG:
74731f
 			if (!argvals[i] || !getmgr2id(vsi, argvals[i]))
74731f
-				goto out_free;
74731f
+				goto out_err;
74731f
 			break;
74731f
 		case VSI_TYPEID_ARG:
74731f
 			if (!argvals[i] ||
74731f
 				!getnumber(argvals[i], 0, 0xffffff, &no))
74731f
-				goto out_free;
74731f
+				goto out_err;
74731f
 			vsi->vsi_typeid = no;
74731f
 			break;
74731f
 		case VSI_TYPEIDVER_ARG:
74731f
 			if (!argvals[i] || !getnumber(argvals[i], 0, 0xff, &no))
74731f
-				goto out_free;
74731f
+				goto out_err;
74731f
 			vsi->vsi_typeversion = no;
74731f
 			break;
74731f
 		case VSI_VSIID_ARG:
74731f
 			if (!argvals[i] ||
74731f
 				vdp_str2uuid(vsi->vsi_uuid, argvals[i],
74731f
 					sizeof(vsi->vsi_uuid)))
74731f
-				goto out_free;
74731f
+				goto out_err;
74731f
 			vsi->vsi_idfmt = VDP22_ID_UUID;
74731f
 			break;
74731f
 		case VSI_FILTER_ARG:
74731f
 			if (idx < vsi->macsz && !getfid(vsi, argvals[i], idx))
74731f
-				goto out_free;
74731f
+				goto out_err;
74731f
 			idx++;
74731f
 			break;
74731f
 		case VSI_HINTS_ARG:
74731f
 			if (!argvals[i] || !gethints(vsi, argvals[i]))
74731f
-				goto out_free;
74731f
+				goto out_err;
74731f
 			break;
74731f
 		default:
74731f
-			goto out_free;
74731f
+			goto out_err;
74731f
 		}
74731f
 		num_arg_keys |= (1 << vsi_key);
74731f
 	}
74731f
 	*key_flags = num_arg_keys;
74731f
 	rc = 0;
74731f
 
74731f
+out_err:
74731f
+	if (rc)
74731f
+		LLDPAD_ERR("Incorrect arguments specified for key %s\n",
74731f
+			   get_keyword_str(vsi_key));
74731f
 out_free:
74731f
 	free(argvals);
74731f
 out_args:
74731f
@@ -400,11 +424,16 @@ static int str2vdpnl(char *orig_argvalue, struct vdpnl_vsi *vsi)
74731f
 	u16 vsi_mand_mask = (1 << VSI_MAND_NUM_ARG) - 1;
74731f
 	u16 num_arg_keys = 0;
74731f
 
74731f
-	if (vdp22_parse_str_vdpnl(vsi, &num_arg_keys, orig_argvalue))
74731f
+	rc = vdp22_parse_str_vdpnl(vsi, &num_arg_keys, orig_argvalue);
74731f
+	if (rc) {
74731f
+		LLDPAD_ERR("%s: Incorrect arguments\n", __func__);
74731f
 		goto out;
74731f
+	}
74731f
 	/* Return error if no filter information provided */
74731f
 	if ((num_arg_keys & vsi_mand_mask) == vsi_mand_mask)
74731f
 		rc = 0;
74731f
+	else
74731f
+		LLDPAD_ERR("%s: Incomplete arguments\n", __func__);
74731f
 out:
74731f
 	return rc;
74731f
 }
74731f
@@ -444,7 +473,6 @@ static char *check_and_update(size_t *total, size_t *length, char *s, int c)
74731f
 /*
74731f
  * Convert VSI association to string.
74731f
  */
74731f
-#ifdef LATER_USE
74731f
 static const char *mode2str(unsigned char x)
74731f
 {
74731f
 	if (x == VDP22_ASSOC)
74731f
@@ -457,7 +485,6 @@ static const char *mode2str(unsigned char x)
74731f
 		return "deassoc";
74731f
 	return "unknown";
74731f
 }
74731f
-#endif
74731f
 
74731f
 /*
74731f
  * Convert filter information format into vlan[-mac][-group] string.
74731f
@@ -544,7 +571,12 @@ int vdp_vdpnl2str(struct vdpnl_vsi *p, char *s, size_t length)
74731f
 	char instance[VDP_UUID_STRLEN + 2];
74731f
 
74731f
 	mgrid2str(instance, p, sizeof(instance));
74731f
-	c = snprintf(s, length, "%02x%s%04x%s%02x%s%04x%lu%02x%s%04x%d",
74731f
+	c = snprintf(s, length, "%02x%s%04x%s%02x%s%04x%s%02x%s%04x%lu%02x%s"
74731f
+		     "%04x%d",
74731f
+		     (unsigned int)strlen(VSI22_ARG_MODE_STR),
74731f
+		     VSI22_ARG_MODE_STR,
74731f
+		     (unsigned int)strlen(mode2str(p->request)),
74731f
+		     mode2str(p->request),
74731f
 		     (unsigned int)strlen(VSI22_ARG_MGRID_STR),
74731f
 		     VSI22_ARG_MGRID_STR,
74731f
 		     (unsigned int)strlen(instance), instance,
74731f
diff --git a/vdptool.c b/vdptool.c
74731f
index 551e829..f7fd288 100644
74731f
--- a/vdptool.c
74731f
+++ b/vdptool.c
74731f
@@ -54,6 +54,28 @@
74731f
 #include "qbg22.h"
74731f
 #include "qbg_vdp22_clif.h"
74731f
 #include "lldp_util.h"
74731f
+#include "qbg_vdp22def.h"
74731f
+
74731f
+static char *print_vdp_status(enum vdp22_cmd_status status)
74731f
+{
74731f
+	char *str;
74731f
+
74731f
+	switch (status) {
74731f
+	case cmd_vdp_prot_no_support:
74731f
+		str = "VDP protocol not supported on interface";
74731f
+		break;
74731f
+	case cmd_vdp_nomem:
74731f
+		str = "Not enough memory";
74731f
+		break;
74731f
+	case cmd_vdp_busy:
74731f
+		str = "VSI association in progress";
74731f
+		break;
74731f
+	default:
74731f
+		str = "Unknown status";
74731f
+		break;
74731f
+	}
74731f
+	return str;
74731f
+}
74731f
 
74731f
 static char *print_status(cmd_status status)
74731f
 {
74731f
@@ -97,7 +119,7 @@ static char *print_status(cmd_status status)
74731f
 		str = "TLV does not support agent type";
74731f
 		break;
74731f
 	default:
74731f
-		str = "Unknown status";
74731f
+		str = print_vdp_status(status);
74731f
 		break;
74731f
 	}
74731f
 	return str;
74731f
@@ -165,7 +187,7 @@ static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals)
74731f
 
74731f
 int vdp_clif_command(struct clif *, char *, int);
74731f
 
74731f
-static int vdp_cmd_gettlv(struct clif *clif, int argc, char *argv[],
74731f
+static int vdp_cmd_getvsi(struct clif *clif, int argc, char *argv[],
74731f
 			  struct cmd *cmd, int raw)
74731f
 {
74731f
 	int numargs = 0;
74731f
@@ -219,7 +241,7 @@ out:
74731f
 	return cmd_invalid;
74731f
 }
74731f
 
74731f
-static int vdp_cmd_settlv(struct clif *clif, int argc, char *argv[],
74731f
+static int vdp_cmd_setvsi(struct clif *clif, int argc, char *argv[],
74731f
 			  struct cmd *cmd, int raw)
74731f
 {
74731f
 	int numargs = 0;
74731f
@@ -299,12 +321,77 @@ static int vdp_parse_response(char *buf)
74731f
 	return hex2u8(buf + CLIF_STAT_OFF);
74731f
 }
74731f
 
74731f
-int get_vsi_args(char *ibuf)
74731f
+void print_vsi_err_msg(char *key_val)
74731f
+{
74731f
+	unsigned long errcode;
74731f
+	int resp_err, smi_err;
74731f
+
74731f
+	errcode = strtol(key_val, NULL, 10);
74731f
+	resp_err = errcode & 0xff;
74731f
+	smi_err = (errcode >> VDP22_STATUS_BITS) & 0xff;
74731f
+
74731f
+	switch (resp_err) {
74731f
+	case VDP22_RESP_INVALID_FORMAT:
74731f
+		printf("\tError returned by Bridge: %s\n",
74731f
+			VSI22_INVALID_FRMT_ERR_STR);
74731f
+		break;
74731f
+	case VDP22_RESP_NO_RESOURCES:
74731f
+		printf("\tError returned by Bridge: %s\n",
74731f
+			VSI22_NO_RES_ERR_STR);
74731f
+		break;
74731f
+	case VDP22_RESP_NO_VSIMGR:
74731f
+		printf("\tError returned by Bridge: %s\n",
74731f
+			VSI22_NO_VSIMGR_ERR_STR);
74731f
+		break;
74731f
+	case VDP22_RESP_OTHER:
74731f
+		printf("\tError returned by Bridge: %s\n", VSI22_OTHER_ERR_STR);
74731f
+		break;
74731f
+	case VDP22_RESP_NOADDR:
74731f
+		printf("\tError returned by Bridge: %s\n",
74731f
+			VSI22_NOADDR_ERR_STR);
74731f
+		break;
74731f
+	case VDP22_RESP_DEASSOC:
74731f
+		printf("\tError returned by Bridge: %s\n", VSI22_DEASS_ERR_STR);
74731f
+		break;
74731f
+	case VDP22_RESP_TIMEOUT:
74731f
+		printf("\tError returned by Bridge: %s\n",
74731f
+			VSI22_TIMEOUT_ERR_STR);
74731f
+		break;
74731f
+	case VDP22_RESP_KEEP:
74731f
+		printf("\tError returned by Bridge: %s\n", VSI22_KEEP_ERR_STR);
74731f
+		break;
74731f
+	default:
74731f
+		break;
74731f
+	}
74731f
+	if (smi_err & (1 << VDP22_KATO))
74731f
+		printf("\tInternal Error : %s\n", VSI22_KATO_ERR_STR);
74731f
+	if (smi_err & (1 << VDP22_ACKTO))
74731f
+		printf("\tInternal Error : %s\n", VSI22_ACKTO_ERR_STR);
74731f
+	if (smi_err & (1 << VDP22_TXERR))
74731f
+		printf("\tInternal Error : %s\n", VSI22_TX_ERR_STR);
74731f
+}
74731f
+
74731f
+static void print_vsi(char **args, char **argvals, int numargs,
74731f
+		      bool err_flag)
74731f
+{
74731f
+	int i;
74731f
+
74731f
+	for (i = 0; i < numargs; i++) {
74731f
+		if (err_flag && (!strcmp(args[i], VSI22_ARG_HINTS_STR)))
74731f
+			print_vsi_err_msg(argvals[i]);
74731f
+		else {
74731f
+			printf("\t%s", args[i]);
74731f
+			printf(" = %s\n", argvals[i]);
74731f
+		}
74731f
+	}
74731f
+}
74731f
+
74731f
+int get_vsi_args(char *ibuf, bool print_err_code)
74731f
 {
74731f
 	int ioff = 0;
74731f
 	char **args;
74731f
 	char **argvals;
74731f
-	int numargs, i;
74731f
+	int numargs;
74731f
 	int ilen = strlen(ibuf);
74731f
 
74731f
 	/* count args and argvalus */
74731f
@@ -321,17 +408,14 @@ int get_vsi_args(char *ibuf)
74731f
 	}
74731f
 
74731f
 	numargs = get_arg_val_list(ibuf, ilen, &ioff, args, argvals);
74731f
-	for (i = 0; i < numargs; i++) {
74731f
-		printf("\t%s", args[i]);
74731f
-		printf(" = %s\n", argvals[i]);
74731f
-	}
74731f
+	print_vsi(args, argvals, numargs, print_err_code);
74731f
 
74731f
 	free(args);
74731f
 	free(argvals);
74731f
 	return ioff;
74731f
 }
74731f
 
74731f
-static void print_all_vsis(char *ibuf)
74731f
+static void print_all_vsis(char *ibuf, bool err_code, char *msg)
74731f
 {
74731f
 	size_t ilen = strlen(ibuf);
74731f
 	u16 vsi_len;
74731f
@@ -346,8 +430,11 @@ static void print_all_vsis(char *ibuf)
74731f
 		ilen -= 2 * sizeof(u16);
74731f
 		strncpy(tmp_ibuf, ibuf + offset, vsi_len);
74731f
 		tmp_ibuf[vsi_len] = '\0';
74731f
-		printf("%s %d:\n", "VSI ", vsi_cnt);
74731f
-		get_vsi_args(tmp_ibuf);
74731f
+		if (msg)
74731f
+			printf("%s\n", msg);
74731f
+		else
74731f
+			printf("%s %d:\n", "VSI ", vsi_cnt);
74731f
+		get_vsi_args(tmp_ibuf, err_code);
74731f
 		offset += vsi_len;
74731f
 		ilen -= vsi_len;
74731f
 		vsi_cnt++;
74731f
@@ -361,7 +448,7 @@ static void print_cmd_response(char *ibuf, int status)
74731f
 	int ioff;
74731f
 
74731f
 	if (status != cmd_success) {
74731f
-		printf("%s\n", print_status(status));
74731f
+		printf("FAILED: %s\n", print_status(status));
74731f
 		return;
74731f
 	}
74731f
 
74731f
@@ -385,7 +472,7 @@ static void print_cmd_response(char *ibuf, int status)
74731f
 
74731f
 	switch (cmd.cmd) {
74731f
 	case cmd_gettlv:
74731f
-		print_all_vsis(ibuf + ioff);
74731f
+		print_all_vsis(ibuf + ioff, false, NULL);
74731f
 		break;
74731f
 	case cmd_settlv:
74731f
 		printf("%s", ibuf + ioff);
74731f
@@ -423,6 +510,7 @@ static void vdp_print_response(char *buf, int status)
74731f
 static void vdp_print_event_msg(char *buf)
74731f
 {
74731f
 	printf("%s buf:%s\n", __func__, buf);
74731f
+	print_all_vsis(buf + CLIF_RSP_OFF, true, "Response from VDP");
74731f
 }
74731f
 
74731f
 /*
74731f
@@ -519,8 +607,8 @@ static const char *commands_help =
74731f
 "  -v|version show version\n"
74731f
 "  -p|ping    ping lldpad and query pid of lldpad\n"
74731f
 "  -q|quit    exit lldptool (interactive mode)\n"
74731f
-"  -t|get-tlv get tlvid value\n"
74731f
-"  -T|set-tlv set arg for tlvid to value\n";
74731f
+"  -t|get-vsi get VSI association(s)\n"
74731f
+"  -T|set-vsi set VSI association\n";
74731f
 
74731f
 static struct clif *clif_conn;
74731f
 static int cli_quit;
74731f
@@ -638,7 +726,7 @@ static int _clif_command(struct clif *clif, char *cmd, int print)
74731f
 	size_t len;
74731f
 	int ret;
74731f
 	int rc;
74731f
-	char reply[200];
74731f
+	char reply[MAX_CLIF_MSGBUF];
74731f
 	size_t reply_len2 = sizeof(reply);
74731f
 
74731f
 	print_raw_message(cmd, print);
74731f
@@ -653,7 +741,8 @@ static int _clif_command(struct clif *clif, char *cmd, int print)
74731f
 		printf("'%s' command timed out.\n", cmd);
74731f
 		return -2;
74731f
 	} else if (ret < 0) {
74731f
-		printf("'%s' command failed.\n", cmd);
74731f
+		printf("'%s' command failed with error %s.\n", cmd,
74731f
+			strerror(errno));
74731f
 		return -1;
74731f
 	}
74731f
 	if (print) {
74731f
@@ -662,10 +751,8 @@ static int _clif_command(struct clif *clif, char *cmd, int print)
74731f
 	}
74731f
 	if (cli_attached) {
74731f
 		rc = clif_vsievt(clif, reply, &reply_len2, 5);
74731f
-		printf("\nReturn from vsievt %d ret %d Reply %s\n", rc, ret,
74731f
-			reply);
74731f
 		if (!rc)
74731f
-			printf("\nMsg is %s\n", reply);
74731f
+			print_all_vsis(reply, true, "Response from VDP");
74731f
 	}
74731f
 
74731f
 	return ret;
74731f
@@ -739,10 +826,10 @@ static struct cli_cmd {
74731f
 	{ cmd_license,  "license",   cli_cmd_license },
74731f
 	{ cmd_version,  "version",   cli_cmd_version },
74731f
 	{ cmd_quit,     "quit",      cli_cmd_quit },
74731f
-	{ cmd_gettlv,   "gettlv",    vdp_cmd_gettlv },
74731f
-	{ cmd_gettlv,   "get-tlv",   vdp_cmd_gettlv },
74731f
-	{ cmd_settlv,   "settlv",    vdp_cmd_settlv },
74731f
-	{ cmd_settlv,   "set-tlv",   vdp_cmd_settlv },
74731f
+	{ cmd_gettlv,   "getvsi",    vdp_cmd_getvsi },
74731f
+	{ cmd_gettlv,   "get-vsi",   vdp_cmd_getvsi },
74731f
+	{ cmd_settlv,   "setvsi",    vdp_cmd_setvsi },
74731f
+	{ cmd_settlv,   "set-vsi",   vdp_cmd_setvsi },
74731f
 	{ cmd_nop,       NULL,       cli_cmd_nop }
74731f
 };
74731f
 
74731f
@@ -774,8 +861,8 @@ static struct option lldptool_opts[] = {
74731f
 	{"help", 0, NULL, 'h'},
74731f
 	{"version", 0, NULL, 'v'},
74731f
 	{"stats", 0, NULL, 'S'},
74731f
-	{"get-tlv", 0, NULL, 't'},
74731f
-	{"set-tlv", 0, NULL, 'T'},
74731f
+	{"get-vsi", 0, NULL, 't'},
74731f
+	{"set-vsi", 0, NULL, 'T'},
74731f
 	{"get-lldp", 0, NULL, 'l'},
74731f
 	{"set-lldp", 0, NULL, 'L'},
74731f
 	{0, 0, 0, 0}
74731f
-- 
74731f
2.1.0
74731f