summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormhemmatp <mhemmatp@cisco.com>2019-12-16 11:07:06 +0100
committermhemmatp <mhemmatp@cisco.com>2019-12-19 10:49:25 +0100
commitcbdfa74c2f0adaf5d7ff51b6e74d75fd9b4cb0b7 (patch)
treeb809569909545ed546f5a5680b80d30235cc3bcf
parenta6325a7343cc971cfca45fb50e4d7a9b9b5a2982 (diff)
[HICN-443] Adding test to hicn sysrepo plugin
Signed-off-by: mhemmatp <mhemmatp@cisco.com> Change-Id: Ib7568d9b44b94664822f3925682bab554c170e5a
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/test/README.md32
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/aface.xml7
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/apunt.xml6
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/aroute.xml13
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/dface.xml3
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/dpunt.xml6
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/droute.xml6
-rwxr-xr-xctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/test.py66
-rwxr-xr-xctrl/sysrepo-plugins/hicn-plugin/test/vapi-test/Makefile2
-rwxr-xr-xctrl/sysrepo-plugins/hicn-plugin/test/vapi-test/test.c290
10 files changed, 431 insertions, 0 deletions
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/README.md b/ctrl/sysrepo-plugins/hicn-plugin/test/README.md
new file mode 100644
index 000000000..a1c9bedff
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/README.md
@@ -0,0 +1,32 @@
+# test hICN sysrepo plugin
+
+Two simple tests are provided to verify the functionality of the plugin. In ```netconf-test``` you can find ```test.py``` which uses netconf-clinet library to send NETCONF command toward the sysrepo. This is the usage:
+```
+python test.py host user password operation
+```
+<b>host</b> indicates the host information. <b>user</b>, <b>password</b> are credentials to connect to the device. <b>Operation</b> can be one of the following:
+```
+- route_dump
+ It receives the route operational data from vpp
+- face_dump
+ It receives the face operational data from vpp
+- face_add
+ It adds an hICN face in the vpp
+- punt_add
+ It adds a punt in the vpp
+- route_add
+ It adds route in the vpp
+- face_dell
+ It deletes face from vpp
+- route_del
+ It deletes route from vpp
+- punt_del
+ It deletes punt from vpp
+```
+
+In the ```vapi-test``` you can find testing the VAPI for the communication between the hICN sysrepo plugin and vpp. This is the usage:
+
+```
+./test [route_add [4|6], punt_add [4|6], face_add [4|6], route_dump, face_dump]
+```
+The definition for the argument is the same as the netconf-test except that here you can choose the test for IPV4 and IPV6.
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/aface.xml b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/aface.xml
new file mode 100644
index 000000000..e1452f722
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/aface.xml
@@ -0,0 +1,7 @@
+<face-ip-add xmlns="urn:sysrepo:hicn">
+ <lip4>192.168.20.10</lip4>
+ <lip6>-1</lip6>
+ <rip4>192.168.100.1</rip4>
+ <rip6>-1</rip6>
+ <swif>0</swif>
+</face-ip-add>
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/apunt.xml b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/apunt.xml
new file mode 100644
index 000000000..b7fa8b741
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/apunt.xml
@@ -0,0 +1,6 @@
+<punting-add xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.0.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+ <swif>0</swif>
+</punting-add>
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/aroute.xml b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/aroute.xml
new file mode 100644
index 000000000..9997452b9
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/aroute.xml
@@ -0,0 +1,13 @@
+<route-nhops-add xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.1.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+ <face_ids0>0</face_ids0>
+ <face_ids1>0</face_ids1>
+ <face_ids2>0</face_ids2>
+ <face_ids3>0</face_ids3>
+ <face_ids4>0</face_ids4>
+ <face_ids5>0</face_ids5>
+ <face_ids6>0</face_ids6>
+ <n_faces>1</n_faces>
+</route-nhops-add>
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/dface.xml b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/dface.xml
new file mode 100644
index 000000000..07a9488a9
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/dface.xml
@@ -0,0 +1,3 @@
+<face-ip-del xmlns="urn:sysrepo:hicn">
+ <faceid>0</faceid>
+</face-ip-del>
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/dpunt.xml b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/dpunt.xml
new file mode 100644
index 000000000..72d5c3c88
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/dpunt.xml
@@ -0,0 +1,6 @@
+<punting-del xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.0.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+ <swif>0</swif>
+</punting-del>
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/droute.xml b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/droute.xml
new file mode 100644
index 000000000..ded28eecf
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/droute.xml
@@ -0,0 +1,6 @@
+<route-nhops-del xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.1.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+ <faceid>0</faceid>
+</route-nhops-del>
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/test.py b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/test.py
new file mode 100755
index 000000000..7c6163521
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/netconf-test/test.py
@@ -0,0 +1,66 @@
+import sys
+import xml.etree.ElementTree as ET
+from netconf.client import connect_ssh
+
+def usage():
+ print('usage: test.py host user password operation{route_dump, face_dump, face_add, route_add, punt_add, face_del, punt_del, route_del}')
+
+def test(host,user,password,operation):
+ with connect_ssh(host, 830, user, password) as session:
+ if (operation=='face_dump'):
+ config = session.get()
+ for root in config:
+ if root.tag=="{urn:sysrepo:hicn}hicn-state":
+ for entity in root:
+ if entity.tag=="{urn:sysrepo:hicn}faces":
+ print('Faces')
+ for face in entity:
+ for elem in face:
+ print(elem.tag +" : "+ elem.text)
+ elif (operation=='state_dump'):
+ config = session.get()
+ for root in config:
+ if root.tag=="{urn:sysrepo:hicn}hicn-state":
+ for entity in root:
+ if entity.tag=="{urn:sysrepo:hicn}states":
+ print('States')
+ for state in entity:
+ print(state.tag +" : "+ state.text)
+ elif (operation=='route_dump'):
+ config = session.get()
+ for root in config:
+ if root.tag=="{urn:sysrepo:hicn}hicn-state":
+ for entity in root:
+ if entity.tag=="{urn:sysrepo:hicn}routes":
+ print('Routes')
+ for route in entity:
+ for elem in route:
+ print(elem.tag +" : "+ elem.text)
+ elif(operation=='face_add'):
+ root = ET.parse('aface.xml').getroot()
+ session.send_rpc(ET.tostring(root, encoding='utf8').decode('utf8'))
+ elif(operation=='punt_add'):
+ root = ET.parse('apunt.xml').getroot()
+ session.send_rpc(ET.tostring(root, encoding='utf8').decode('utf8'))
+ elif(operation=='route_add'):
+ root = ET.parse('aroute.xml').getroot()
+ session.send_rpc(ET.tostring(root, encoding='utf8').decode('utf8'))
+ elif(operation=='face_del'):
+ root = ET.parse('dface.xml').getroot()
+ session.send_rpc(ET.tostring(root, encoding='utf8').decode('utf8'))
+ elif(operation=='punt_del'):
+ root = ET.parse('dpunt.xml').getroot()
+ session.send_rpc(ET.tostring(root, encoding='utf8').decode('utf8'))
+ elif(operation=='route_del'):
+ root = ET.parse('droute.xml').getroot()
+ session.send_rpc(ET.tostring(root, encoding='utf8').decode('utf8'))
+ else:
+ usage()
+
+if __name__ == '__main__':
+ if(len(sys.argv)<4):
+ usage()
+ else:
+ test(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4])
+
+
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/vapi-test/Makefile b/ctrl/sysrepo-plugins/hicn-plugin/test/vapi-test/Makefile
new file mode 100755
index 000000000..8ab5d27de
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/vapi-test/Makefile
@@ -0,0 +1,2 @@
+main:
+ sudo gcc -g -o test test.c -lvapiclient
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/test/vapi-test/test.c b/ctrl/sysrepo-plugins/hicn-plugin/test/vapi-test/test.c
new file mode 100755
index 000000000..f7b92c3c5
--- /dev/null
+++ b/ctrl/sysrepo-plugins/hicn-plugin/test/vapi-test/test.c
@@ -0,0 +1,290 @@
+#include <vapi/vapi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+
+#include<vapi/hicn.api.vapi.h>
+
+
+DEFINE_VAPI_MSG_IDS_HICN_API_JSON;
+
+vapi_ctx_t g_vapi_ctx_instance;
+
+
+#define APP_NAME "test_hicn_plugin"
+#define MAX_OUTSTANDING_REQUESTS 4
+#define RESPONSE_QUEUE_SIZE 2
+
+vapi_ctx_t g_vapi_ctx_instance = NULL;
+
+
+void usage(){
+ printf("choose the test [route_add [4|6], punt_add [4|6], face_add [4|6], route_dump, face_dump]\n");
+}
+
+static vapi_error_e call_hicn_api_punting_add(struct vapi_ctx_s *ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_hicn_api_punting_add_reply *reply){
+if(!reply->retval){
+ printf("Successfully done");
+ return VAPI_OK;
+ }else
+ return VAPI_EUSER;
+}
+
+static vapi_error_e call_hicn_api_face_ip_add(struct vapi_ctx_s *ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_hicn_api_face_ip_add_reply *reply){
+if(!reply->retval){
+ printf("Successfully done");
+ return VAPI_OK;
+ }else
+ return VAPI_EUSER;
+
+}
+
+static vapi_error_e call_hicn_api_route_nhops_add(struct vapi_ctx_s *ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_hicn_api_route_nhops_add_reply *reply){
+if(!reply->retval){
+ printf("Successfully done");
+ return VAPI_OK;
+ }else
+ return VAPI_EUSER;
+}
+
+static vapi_error_e
+hicn_api_routes_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx,
+ vapi_error_e rv, bool is_last,
+ vapi_payload_hicn_api_routes_details *reply)
+{
+
+ char buf[20];
+ if (reply!=NULL){
+ memset(buf, 0x00, 20);
+ if (reply->prefix.address.af==ADDRESS_IP4){
+ struct sockaddr_in sa;
+ memcpy(&sa.sin_addr.s_addr, reply->prefix.address.un.ip4, 4);
+ inet_ntop(AF_INET, &(sa.sin_addr.s_addr), buf, INET_ADDRSTRLEN);
+ printf("Prefix:%s\n",buf);
+ }else{
+ struct sockaddr_in6 sa;
+ memcpy(&sa.sin6_addr,reply->prefix.address.un.ip6,6);
+ inet_ntop(AF_INET6, &(sa.sin6_addr), buf, INET6_ADDRSTRLEN);
+ printf("Prefix:%s\n",buf);
+ }
+ }else
+ {
+ printf("---------Routes------- \n");
+ }
+ return 0;
+
+}
+
+
+
+static vapi_error_e
+hicn_api_face_stats_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx,
+ vapi_error_e rv, bool is_last,
+ vapi_payload_hicn_api_face_stats_details *reply)
+{
+ if (reply!=NULL){
+
+ printf("face_id:%d \n", reply->faceid);
+ printf("irx_packets:%" PRId64 "\n", reply->irx_packets);
+ printf("irx_bytes:%" PRId64 "\n", reply->irx_bytes);
+ printf("itx_packets:%" PRId64 "\n", reply->itx_packets);
+ printf("itx_bytes:%" PRId64 "\n", reply->itx_bytes);
+ printf("drx_packets:%" PRId64 "\n", reply->drx_packets);
+ printf("drx_bytes:%" PRId64 "\n", reply->drx_bytes);
+ printf("dtx_packets:%" PRId64 "\n", reply->dtx_packets);
+ printf("dtx_bytes:%" PRId64 "\n", reply->dtx_bytes);
+
+ }else
+ {
+ printf("---------Facees------- \n");
+ }
+ return 0;
+}
+
+
+int hicn_connect_vpp()
+{
+
+ if (g_vapi_ctx_instance == NULL)
+ {
+ vapi_error_e rv = vapi_ctx_alloc(&g_vapi_ctx_instance);
+ rv = vapi_connect(g_vapi_ctx_instance, APP_NAME, NULL, MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, VAPI_MODE_BLOCKING, true);
+ if (rv != VAPI_OK)
+ {
+ vapi_ctx_free(g_vapi_ctx_instance);
+ return -1;
+ }
+ }
+ else
+ {
+ }
+ return 0;
+}
+
+int hicn_disconnect_vpp()
+{
+ if (NULL != g_vapi_ctx_instance)
+ {
+ vapi_disconnect(g_vapi_ctx_instance);
+ vapi_ctx_free(g_vapi_ctx_instance);
+ g_vapi_ctx_instance = NULL;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+
+ if (argc<2){
+ usage();
+ return 1;
+ }
+
+ /* connect to vpp */
+ int rc = hicn_connect_vpp();
+ if (-1 == rc){
+ perror("vpp connect error");
+ return -1;
+ }
+
+ if (!strcmp(argv[1],"route_add")){
+ vapi_msg_hicn_api_route_nhops_add *msg;
+ msg = vapi_alloc_hicn_api_route_nhops_add(g_vapi_ctx_instance);
+
+ if (!strcmp(argv[2],"4")){
+ struct sockaddr_in sa;
+ inet_pton(AF_INET, "192.168.10.10", &(sa.sin_addr));
+ unsigned char * tmp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix.address.un.ip4[0],tmp,4);
+ msg->payload.prefix.address.af = ADDRESS_IP4;
+ }else{
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, "2001::1", dst);
+ unsigned char * tmp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix.address.un.ip6[0],tmp,16);
+ msg->payload.prefix.address.af = ADDRESS_IP6;
+ }
+
+ msg->payload.prefix.len = 24;
+ msg->payload.face_ids[0] = 0;
+ msg->payload.face_ids[1] = 0;
+ msg->payload.face_ids[2] = 0;
+ msg->payload.face_ids[3] = 0;
+ msg->payload.face_ids[4] = 0;
+ msg->payload.face_ids[5] = 0;
+ msg->payload.face_ids[6] = 0;
+ msg->payload.n_faces = 1;
+
+ if(vapi_hicn_api_route_nhops_add(g_vapi_ctx_instance,msg,call_hicn_api_route_nhops_add,NULL)!=VAPI_OK){
+ perror("Operation failed");
+ return -1;
+ }
+ }else if (!strcmp(argv[1],"face_add")){
+
+ vapi_msg_hicn_api_face_ip_add *fmsg;
+ fmsg = vapi_alloc_hicn_api_face_ip_add(g_vapi_ctx_instance);
+
+
+ if (!strcmp(argv[2],"4")){
+ struct sockaddr_in sa;
+ inet_pton(AF_INET, "192.168.50.19", &(sa.sin_addr));
+ unsigned char * tmp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&fmsg->payload.face.local_addr.un.ip4[0],tmp,4);
+ fmsg->payload.face.local_addr.af = ADDRESS_IP4;
+
+
+ inet_pton(AF_INET, "192.168.60.10", &(sa.sin_addr));
+ tmp = (unsigned char *)&sa.sin_addr.s_addr;
+ memcpy(&fmsg->payload.face.remote_addr.un.ip4[0],tmp,4);
+ fmsg->payload.face.remote_addr.af = ADDRESS_IP4;
+
+ }else{
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, "2001::1", dst);
+ unsigned char * tmp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&fmsg->payload.face.local_addr.un.ip6[0],tmp,16);
+ fmsg->payload.face.local_addr.af = ADDRESS_IP6;
+
+
+ inet_pton(AF_INET6, "3001::1", dst);
+ tmp =(unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&fmsg->payload.face.remote_addr.un.ip6[0],tmp,16);
+ fmsg->payload.face.remote_addr.af = ADDRESS_IP6;
+ }
+
+ fmsg->payload.face.swif = 0; // This is the idx number of interface
+
+ if(vapi_hicn_api_face_ip_add(g_vapi_ctx_instance,fmsg,call_hicn_api_face_ip_add,NULL)!=VAPI_OK){
+ perror("Operation failed");
+ return -1;
+ }
+ }else if (!strcmp(argv[1],"route_dump")){
+ // routes dump
+ vapi_msg_hicn_api_routes_dump *rmsg;
+ rmsg = vapi_alloc_hicn_api_routes_dump(g_vapi_ctx_instance);
+ vapi_hicn_api_routes_dump(g_vapi_ctx_instance, rmsg, hicn_api_routes_dump_cb, NULL);
+
+ }else if (!strcmp(argv[1],"face_dump")){
+ // faces dump
+ vapi_msg_hicn_api_face_stats_dump *fmsg;
+ fmsg = vapi_alloc_hicn_api_face_stats_dump(g_vapi_ctx_instance);
+ vapi_hicn_api_face_stats_dump(g_vapi_ctx_instance, fmsg, hicn_api_face_stats_dump_cb, NULL);
+ }else if (!strcmp(argv[1],"punt_add")){
+
+ vapi_msg_hicn_api_punting_add *pmsg;
+
+ pmsg = vapi_alloc_hicn_api_punting_add(g_vapi_ctx_instance);
+
+ pmsg->payload.type=IP_PUNT;
+
+ if(!strcmp(argv[2],"4")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, "192.168.10.20", &(sa.sin_addr));
+ unsigned char * tmp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&pmsg->payload.rule.ip.prefix.address.un.ip4[0],tmp,4);
+ pmsg->payload.rule.ip.prefix.address.af = ADDRESS_IP4;
+
+
+ }else{
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, "3001::1", dst);
+ unsigned char * tmp =(unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&pmsg->payload.rule.ip.prefix.address.un.ip6[0],tmp,16);
+ pmsg->payload.rule.ip.prefix.address.af = ADDRESS_IP6;
+ }
+
+ pmsg->payload.rule.ip.prefix.len = 24;
+ pmsg->payload.rule.ip.swif = 0;
+
+ if (vapi_hicn_api_punting_add(g_vapi_ctx_instance, pmsg, call_hicn_api_punting_add, NULL)!=VAPI_OK){
+ perror("Operation failed");
+ return -1;
+ }
+ }else
+ {
+ usage();
+ return 1;
+ }
+
+ hicn_disconnect_vpp();
+
+ return rc;
+}