summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--hicn-light/src/hicn/core/mapme.c4
-rw-r--r--hicn-plugin/src/faces/app/face_prod.c2
-rw-r--r--hicn-plugin/src/faces/app/face_prod.h2
-rw-r--r--hicn-plugin/src/faces/app/face_prod_node.c1
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_node.c130
15 files changed, 562 insertions, 8 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;
+}
diff --git a/hicn-light/src/hicn/core/mapme.c b/hicn-light/src/hicn/core/mapme.c
index a0a34e8ce..e426e7575 100644
--- a/hicn-light/src/hicn/core/mapme.c
+++ b/hicn-light/src/hicn/core/mapme.c
@@ -783,8 +783,8 @@ static bool mapme_onSpecialInterest(const MapMe *mapme,
mapmeTFIB_Remove(TFIB(fibEntry), conn_in_id);
/* Remove all next hops */
- for (size_t k = 0; k < numberSet_Length(nexthops_old); k++) {
- unsigned conn_id = numberSet_GetItem(nexthops_old, k);
+ for (size_t k = 0; k < numberSet_Length(nexthops); k++) {
+ unsigned conn_id = numberSet_GetItem(nexthops, k);
INFO(mapme, "[MAP-Me] - Replaced next hops by connection %d", conn_id);
fibEntry_RemoveNexthopByConnectionId(fibEntry, conn_id);
}
diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c
index 14e100adc..c183d6589 100644
--- a/hicn-plugin/src/faces/app/face_prod.c
+++ b/hicn-plugin/src/faces/app/face_prod.c
@@ -307,7 +307,7 @@ hicn_face_prod_del (hicn_face_id_t face_id)
hicn_route_del_nhop (&(face_state_vec[face->shared.sw_if].prefix),
face_id);
- /*
+ /*
* Delete the content in the CS before deleting the face.
* Mandatory to prevent hitting the CS and not having the lru list
* due to a early deletion of the face.
diff --git a/hicn-plugin/src/faces/app/face_prod.h b/hicn-plugin/src/faces/app/face_prod.h
index 74c62c3bb..33e2a4199 100644
--- a/hicn-plugin/src/faces/app/face_prod.h
+++ b/hicn-plugin/src/faces/app/face_prod.h
@@ -54,6 +54,8 @@ typedef struct
extern hicn_face_prod_state_t *face_state_vec;
+#define DEFAULT_PROBING_PORT 3784
+
typedef struct __attribute__ ((packed)) hicn_face_prod_t_
{
hicn_face_ip_t ip_face;
diff --git a/hicn-plugin/src/faces/app/face_prod_node.c b/hicn-plugin/src/faces/app/face_prod_node.c
index c92585624..48e7c4259 100644
--- a/hicn-plugin/src/faces/app/face_prod_node.c
+++ b/hicn-plugin/src/faces/app/face_prod_node.c
@@ -317,7 +317,6 @@ VLIB_REGISTER_NODE(hicn_face_prod_input_node) =
};
/* *INDENT-ON* */
-
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/hicn-plugin/src/faces/ip/face_ip_node.c b/hicn-plugin/src/faces/ip/face_ip_node.c
index 3f1f6a0d0..1229b4eaa 100644
--- a/hicn-plugin/src/faces/ip/face_ip_node.c
+++ b/hicn-plugin/src/faces/ip/face_ip_node.c
@@ -18,6 +18,7 @@
#include "face_ip.h"
#include "face_ip_node.h"
#include "dpo_ip.h"
+#include "../app/face_prod.h"
#include "../../strategy_dpo_manager.h"
#include "../face.h"
#include "../../cache_policies/cs_lru.h"
@@ -464,11 +465,99 @@ VLIB_REGISTER_NODE(hicn_face_ip6_input_node) =
/**** FACE OUTPUT *****/
+typedef enum
+{
+ HICN_FACE_IP4_NEXT_ECHO_REPLY = IP4_LOOKUP_N_NEXT,
+ HICN_FACE_IP4_N_NEXT,
+} hicn_face_ip4_next_t;
+
+typedef enum
+{
+ HICN_FACE_IP6_NEXT_ECHO_REPLY = IP6_LOOKUP_N_NEXT,
+ HICN_FACE_IP6_N_NEXT,
+} hicn_face_ip6_next_t;
+
+static_always_inline void
+hicn_reply_probe_v4 (vlib_buffer_t * b, hicn_face_t * face)
+{
+ hicn_header_t *h0 = vlib_buffer_get_current (b);
+ hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data);
+ h0->v4.ip.saddr = h0->v4.ip.daddr;
+ h0->v4.ip.daddr = face_ip->local_addr.ip4;
+ vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if;
+
+ u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t) + sizeof(u16));
+ u16 dst_port = *dst_port_ptr;
+ u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t));
+
+ *dst_port_ptr = *src_port_ptr;
+ *src_port_ptr = dst_port;
+
+ hicn_type_t type = hicn_get_buffer (b)->type;
+ hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0);
+}
+
+static_always_inline void
+hicn_reply_probe_v6 (vlib_buffer_t * b, hicn_face_t * face)
+{
+ hicn_header_t *h0 = vlib_buffer_get_current (b);
+ hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data);
+ h0->v6.ip.saddr = h0->v6.ip.daddr;
+ h0->v6.ip.daddr = face_ip->local_addr.ip6;
+ vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if;
+
+ u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t) + sizeof(u16));
+ u16 dst_port = *dst_port_ptr;
+ u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t));
+
+ *dst_port_ptr = *src_port_ptr;
+ *src_port_ptr = dst_port;
+
+ hicn_type_t type = hicn_get_buffer (b)->type;
+ hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0);
+
+}
+
+static_always_inline u32
+hicn_face_match_probe (vlib_buffer_t * b, hicn_face_t * face, u32 * next)
+{
+
+ u8 *ptr = vlib_buffer_get_current (b);
+ u8 v = *ptr & 0xf0;
+ u8 res = 0;
+
+ if ( v == 0x40 )
+ {
+ u16 * dst_port = (u16 *)(ptr + sizeof(ip4_header_t) + sizeof(u16));
+ if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT))
+ {
+ hicn_reply_probe_v6(b, face);
+ *next = HICN_FACE_IP4_NEXT_ECHO_REPLY;
+ res = 1;
+ }
+ }
+ else if ( v == 0x60 )
+ {
+ u16 * dst_port = (u16 *)(ptr + sizeof(ip6_header_t) + sizeof(u16));
+ if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT))
+ {
+ hicn_reply_probe_v6(b, face);
+ *next = HICN_FACE_IP6_NEXT_ECHO_REPLY;
+ res = 1;
+ }
+ }
+ return res;
+}
+
+
static inline void
hicn_face_rewrite_interest (vlib_main_t * vm, vlib_buffer_t * b0,
hicn_face_t * face, u32 * next)
{
+ if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) && hicn_face_match_probe(b0, face, next))
+ return;
+
hicn_header_t *hicn = vlib_buffer_get_current (b0);
hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
@@ -517,6 +606,8 @@ hicn_face_rewrite_interest (vlib_main_t * vm, vlib_buffer_t * b0,
vnet_buffer (b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
*next = adj->lookup_next_index;
+
+
}
static char *hicn_face_ip4_output_error_strings[] = {
@@ -782,9 +873,23 @@ VLIB_REGISTER_NODE(hicn_face_ip4_output_node) =
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = ARRAY_LEN(hicn_face_ip4_output_error_strings),
.error_strings = hicn_face_ip4_output_error_strings,
- .n_next_nodes = IP4_LOOKUP_N_NEXT,
+ .n_next_nodes = HICN_FACE_IP4_N_NEXT,
/* Reusing the list of nodes from lookup to be compatible with arp */
- .next_nodes = IP4_LOOKUP_NEXT_NODES,
+ .next_nodes =
+ {
+ [IP_LOOKUP_NEXT_DROP] = "ip4-drop",
+ [IP_LOOKUP_NEXT_PUNT] = "ip4-punt",
+ [IP_LOOKUP_NEXT_LOCAL] = "ip4-local",
+ [IP_LOOKUP_NEXT_ARP] = "ip4-arp",
+ [IP_LOOKUP_NEXT_GLEAN] = "ip4-glean",
+ [IP_LOOKUP_NEXT_REWRITE] = "ip4-rewrite",
+ [IP_LOOKUP_NEXT_MCAST] = "ip4-rewrite-mcast",
+ [IP_LOOKUP_NEXT_BCAST] = "ip4-rewrite-bcast",
+ [IP_LOOKUP_NEXT_MIDCHAIN] = "ip4-midchain",
+ [IP_LOOKUP_NEXT_MCAST_MIDCHAIN] = "ip4-mcast-midchain",
+ [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip4-icmp-error",
+ [HICN_FACE_IP4_NEXT_ECHO_REPLY] = "hicn-face-ip4-input",
+ }
};
/* *INDENT-ON* */
@@ -856,9 +961,26 @@ VLIB_REGISTER_NODE(hicn_face_ip6_output_node) =
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = ARRAY_LEN(hicn_face_ip6_output_error_strings),
.error_strings = hicn_face_ip6_output_error_strings,
- .n_next_nodes = IP6_LOOKUP_N_NEXT,
+ .n_next_nodes = HICN_FACE_IP6_N_NEXT,
/* Reusing the list of nodes from lookup to be compatible with neighbour discovery */
- .next_nodes = IP6_LOOKUP_NEXT_NODES,
+ .next_nodes =
+ {
+ [IP_LOOKUP_NEXT_DROP] = "ip6-drop",
+ [IP_LOOKUP_NEXT_PUNT] = "ip6-punt",
+ [IP_LOOKUP_NEXT_LOCAL] = "ip6-local",
+ [IP_LOOKUP_NEXT_ARP] = "ip6-discover-neighbor",
+ [IP_LOOKUP_NEXT_GLEAN] = "ip6-glean",
+ [IP_LOOKUP_NEXT_REWRITE] = "ip6-rewrite",
+ [IP_LOOKUP_NEXT_BCAST] = "ip6-rewrite-bcast",
+ [IP_LOOKUP_NEXT_MCAST] = "ip6-rewrite-mcast",
+ [IP_LOOKUP_NEXT_MIDCHAIN] = "ip6-midchain",
+ [IP_LOOKUP_NEXT_MCAST_MIDCHAIN] = "ip6-mcast-midchain",
+ [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip6-icmp-error",
+ [IP6_LOOKUP_NEXT_HOP_BY_HOP] = "ip6-hop-by-hop",
+ [IP6_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip6-add-hop-by-hop",
+ [IP6_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop",
+ [HICN_FACE_IP6_NEXT_ECHO_REPLY] = "hicn-face-ip6-input"
+ }
};
/* *INDENT-ON* */