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