[Feature] add GA346 baseline version
Change-Id: Ic62933698569507dcf98240cdf5d9931ae34348f
diff --git a/src/extended/hw_nat/Makefile b/src/extended/hw_nat/Makefile
new file mode 100644
index 0000000..dc0f303
--- /dev/null
+++ b/src/extended/hw_nat/Makefile
@@ -0,0 +1,52 @@
+ifeq ($(CONFIG_SUPPORT_OPENWRT),y)
+EXEC = hwnat
+
+HWNAT_OBJS = hw_nat.o hwnat_api.o util.o
+
+all: $(EXEC)
+
+hwnat: $(HWNAT_OBJS) $(CONF_H)
+ $(CC) $(LDFLAGS) -o $@ $(HWNAT_OBJS)
+
+clean:
+ -rm -f $(EXEC) *.elf *.gdb *.o
+
+else #CONFIG_SUPPORT_OPENWRT
+
+EXEC = hw_nat
+
+HWNAT_OBJS = hw_nat.o hwnat_api.o util.o
+
+ifeq ($(CONFIG_GLIBC_2_20),y)
+
+ifneq ($(KERNEL_HEADERS),)
+CONF_H = $(ROOTDIR)/$(KERNEL_HEADERS)/include/linux/autoconf.h
+KERNEL_H = $(ROOTDIR)/$(KERNEL_HEADERS)/include
+else
+CONF_H = $(ROOTDIR)/$(LINUXDIR)/include/linux/autoconf.h
+KERNEL_H = $(ROOTDIR)/$(LINUXDIR)/include
+endif
+CFLAGS = -I$(KERNEL_H) -DRT3052_SUPPORT
+CFLAGS += -I$(ROOTDIR)/$(LINUXDIR)/net/nat/hw_nat
+CFLAGS += -I$(ROOTDIR)/$(LINUXDIR)/drivers/net/ethernet/raeth
+else
+
+CONF_H = $(ROOTDIR)/$(LINUXDIR)/include/linux/autoconf.h
+CFLAGS += -I$(ROOTDIR)/$(LINUXDIR)/net/nat/hw_nat
+CFLAGS += -I$(ROOTDIR)/$(LINUXDIR)/drivers/net/ethernet/raeth
+endif
+CFLAGS += -I$(ROOTDIR)/config/
+ccflags-y += -I../../../config/
+
+all: $(EXEC)
+
+hw_nat: $(HWNAT_OBJS) $(CONF_H)
+ $(CC) $(LDFLAGS) -o $@ $(HWNAT_OBJS)
+
+romfs:
+ $(ROMFSINST) /bin/hw_nat
+
+clean:
+ -rm -f $(EXEC) *.elf *.gdb *.o
+endif #CONFIG_SUPPORT_OPENWRT
+
diff --git a/src/extended/hw_nat/ac.c b/src/extended/hw_nat/ac.c
new file mode 100644
index 0000000..607ccfe
--- /dev/null
+++ b/src/extended/hw_nat/ac.c
@@ -0,0 +1,260 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <getopt.h>
+
+#include "ac_ioctl.h"
+#include "ac_api.h"
+
+void show_usage(void)
+{
+
+ printf("Add Mac Upload Accounting Rule\n");
+ printf("ac -a -m [Mac] \n");
+
+ printf("Add Mac Download Accounting Rule\n");
+ printf("ac -b -m [Mac] \n");
+
+ printf("Del Mac Upload Accounting Rule\n");
+ printf("ac -c -m [Mac]\n");
+
+ printf("Del Mac download Accounting Rule\n");
+ printf("ac -d -m [Mac]\n");
+
+ printf("Add Vlan Upload Accounting Rule\n");
+ printf("ac -A -k [Vlan] \n");
+
+ printf("Add Vlan Download Accounting Rule\n");
+ printf("ac -B -k [Vlan] \n");
+
+ printf("Del Vlan Upload Accounting Rule\n");
+ printf("ac -C -k [Vlan]\n");
+
+ printf("Del Vlan download Accounting Rule\n");
+ printf("ac -D -k [Vlan]\n");
+
+ printf("Add IP Upload Accounting Rule\n");
+ printf("ac -e -i [IpS] -j [IpE]\n");
+
+ printf("Add IP Download Accounting Rule\n");
+ printf("ac -f -i [IpS] -j [IpE] \n");
+
+ printf("Del IP Upload Accounting Rule\n");
+ printf("ac -g -i [IpS] -j [IpE] \n");
+
+ printf("Del IP Download Accounting Rule\n");
+ printf("ac -h -i [IpS] -j [IpE]\n");
+
+ printf("Show Upload Packet Count of the Mac\n");
+ printf("ac -p -m [Mac] \n");
+
+ printf("Show Download Packet Count of the Mac\n");
+ printf("ac -q -m [Mac]\n");
+
+ printf("Show Upload Byte Count of the Mac\n");
+ printf("ac -r -m [Mac]\n");
+
+ printf("Show Download Byte Count of the Mac\n");
+ printf("ac -s -m [Mac]\n");
+
+ printf("Show Upload Packet Count of the Vlan\n");
+ printf("ac -P -k [Vlan] \n");
+
+ printf("Show Download Packet Count of the Vlan\n");
+ printf("ac -Q -k [Vlan]\n");
+
+ printf("Show Upload Byte Count of the Vlan\n");
+ printf("ac -R -k [Vlan]\n");
+
+ printf("Show Download Byte Count of the Vlan\n");
+ printf("ac -S -k [Vlan]\n");
+
+ printf("Show Upload Packet Count of the IP\n");
+ printf("ac -t -i [IpS] -j [IpE]\n");
+
+ printf("Show Download Packet Count of the IP\n");
+ printf("ac -u -i [IpS] -j [IpE]\n");
+
+ printf("Show Upload Byte Count of the IP\n");
+ printf("ac -v -i [IpS] -j [IpE]\n");
+
+ printf("Show Download Byte Count of the IP\n");
+ printf("ac -w -i [IpS] -j [IpE]\n");
+
+ printf("Clear Ac Table\n");
+ printf("ac -z\n");
+
+}
+
+int main(int argc, char *argv[])
+{
+ int opt;
+ char options[] = "ABCDabcdefghPQRSpqrstuvwz?m:i:j:k:";
+ int fd;
+ int method=-1;
+ struct ac_args args;
+ int result;
+
+
+ fd = open("/dev/"AC_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"AC_DEVNAME);
+ return 0;
+ }
+
+ if(argc < 2) {
+ show_usage();
+ close(fd);
+ return 0;
+ }
+
+ while ((opt = getopt (argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'a':
+ method=AC_ADD_MAC_UL_ENTRY;
+ break;
+ case 'b':
+ method=AC_ADD_MAC_DL_ENTRY;
+ break;
+ case 'c':
+ method=AC_DEL_MAC_UL_ENTRY;
+ break;
+ case 'd':
+ method=AC_DEL_MAC_DL_ENTRY;
+ break;
+ case 'e':
+ method=AC_ADD_IP_UL_ENTRY;
+ break;
+ case 'f':
+ method=AC_ADD_IP_DL_ENTRY;
+ break;
+ case 'g':
+ method=AC_DEL_IP_UL_ENTRY;
+ break;
+ case 'h':
+ method=AC_DEL_IP_DL_ENTRY;
+ break;
+ case 'A':
+ method=AC_ADD_VLAN_UL_ENTRY;
+ break;
+ case 'B':
+ method=AC_ADD_VLAN_DL_ENTRY;
+ break;
+ case 'C':
+ method=AC_DEL_VLAN_UL_ENTRY;
+ break;
+ case 'D':
+ method=AC_DEL_VLAN_DL_ENTRY;
+ break;
+ case 'p':
+ method=AC_GET_MAC_UL_PKT_CNT;
+ break;
+ case 'q':
+ method=AC_GET_MAC_DL_PKT_CNT;
+ break;
+ case 'r':
+ method=AC_GET_MAC_UL_BYTE_CNT;
+ break;
+ case 's':
+ method=AC_GET_MAC_DL_BYTE_CNT;
+ break;
+ case 't':
+ method=AC_GET_IP_UL_PKT_CNT;
+ break;
+ case 'u':
+ method=AC_GET_IP_DL_PKT_CNT;
+ break;
+ case 'v':
+ method=AC_GET_IP_UL_BYTE_CNT;
+ break;
+ case 'w':
+ method=AC_GET_IP_DL_BYTE_CNT;
+ break;
+ case 'P':
+ method=AC_GET_VLAN_UL_PKT_CNT;
+ break;
+ case 'Q':
+ method=AC_GET_VLAN_DL_PKT_CNT;
+ break;
+ case 'R':
+ method=AC_GET_VLAN_UL_BYTE_CNT;
+ break;
+ case 'S':
+ method=AC_GET_VLAN_DL_BYTE_CNT;
+ break;
+ case 'z': /* CleanTbl */
+ method=AC_CLEAN_TBL;
+ break;
+ case 'm': /* Mac */
+ str_to_mac(args.mac, optarg);
+ break;
+ case 'i': /* IP */
+ str_to_ip(&args.ip_s, optarg);
+ break;
+ case 'j':
+ str_to_ip(&args.ip_e, optarg);
+ break;
+ case 'k':
+ args.vid = strtoll(optarg, NULL, 10);
+ break;
+
+ case '?': /* Help */
+ show_usage();
+ break;
+ }
+ }
+
+
+ switch(method) {
+ case AC_ADD_VLAN_UL_ENTRY:
+ case AC_ADD_VLAN_DL_ENTRY:
+ case AC_ADD_MAC_UL_ENTRY:
+ case AC_ADD_MAC_DL_ENTRY:
+ case AC_ADD_IP_UL_ENTRY:
+ case AC_ADD_IP_DL_ENTRY:
+ case AC_CLEAN_TBL:
+ SetAcEntry(&args, method);
+ result = args.result;
+ break;
+ case AC_DEL_VLAN_UL_ENTRY:
+ case AC_DEL_VLAN_DL_ENTRY:
+ case AC_DEL_MAC_UL_ENTRY:
+ case AC_DEL_MAC_DL_ENTRY:
+ case AC_DEL_IP_UL_ENTRY:
+ case AC_DEL_IP_DL_ENTRY:
+ SetAcEntry(&args, method);
+ result = args.result;
+ break;
+ case AC_GET_VLAN_UL_PKT_CNT:
+ case AC_GET_VLAN_DL_PKT_CNT:
+ case AC_GET_MAC_UL_PKT_CNT:
+ case AC_GET_MAC_DL_PKT_CNT:
+ case AC_GET_IP_UL_PKT_CNT:
+ case AC_GET_IP_DL_PKT_CNT:
+ case AC_GET_VLAN_UL_BYTE_CNT:
+ case AC_GET_VLAN_DL_BYTE_CNT:
+ case AC_GET_MAC_UL_BYTE_CNT:
+ case AC_GET_MAC_DL_BYTE_CNT:
+ case AC_GET_IP_UL_BYTE_CNT:
+ case AC_GET_IP_DL_BYTE_CNT:
+ result = GetAcEntry(&args, method);
+ printf("Count=%lld\n",args.cnt);
+ break;
+ default:
+ result = AC_FAIL;
+ }
+
+ if(result == AC_SUCCESS) {
+ printf("done\n");
+ }else if (result == AC_TBL_FULL) {
+ printf("table full\n");
+ } else {
+ printf("fail\n");
+ }
+
+ close(fd);
+ return 0;
+}
diff --git a/src/extended/hw_nat/ac_api.c b/src/extended/hw_nat/ac_api.c
new file mode 100644
index 0000000..2f448b9
--- /dev/null
+++ b/src/extended/hw_nat/ac_api.c
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include "ac_ioctl.h"
+
+int SetAcEntry(struct ac_args *opt, unsigned int cmd)
+{
+ int fd;
+
+ fd = open("/dev/"AC_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"AC_DEVNAME);
+ return AC_FAIL;
+ }
+
+ if(ioctl(fd, cmd, opt)<0) {
+ printf("AC_API: ioctl error\n");
+ close(fd);
+ return AC_FAIL;
+ }
+
+ close(fd);
+ return AC_SUCCESS;
+}
+
+
+int GetAcEntry(struct ac_args *opt, unsigned int cmd)
+{
+ int fd;
+
+ fd = open("/dev/"AC_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"AC_DEVNAME);
+ return AC_FAIL;
+ }
+
+ if(ioctl(fd, cmd, opt)<0) {
+ printf("AC_API: ioctl error\n");
+ close(fd);
+ return AC_FAIL;
+ }
+
+ close(fd);
+ return AC_SUCCESS;
+}
diff --git a/src/extended/hw_nat/ac_api.h b/src/extended/hw_nat/ac_api.h
new file mode 100644
index 0000000..dd5a40f
--- /dev/null
+++ b/src/extended/hw_nat/ac_api.h
@@ -0,0 +1,6 @@
+#ifndef __AC_API
+#define __AC_API
+
+int SetAcEntry(struct ac_args *opt, unsigned int cmd);
+int GetAcEntry(struct ac_args *opt, unsigned int cmd);
+#endif
diff --git a/src/extended/hw_nat/acl.c b/src/extended/hw_nat/acl.c
new file mode 100644
index 0000000..e6683d3
--- /dev/null
+++ b/src/extended/hw_nat/acl.c
@@ -0,0 +1,341 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <getopt.h>
+
+#include "acl_ioctl.h"
+#include "acl_api.h"
+
+void show_usage(void)
+{
+ printf("Add SDMAC Entry for Any Protocol\n");
+ printf("acl -A -n [SDMAC] -U[UP] -u [Allow/Deny/FP]\n");
+ printf("Ex: acl -A -n 00:11:22:33:44:55 -u Deny \n\n");
+ printf("Ex: acl -A -n 00:11:22:33:44:55 -U 3 -u FP \n\n");
+
+ printf("Add SMAC to DIP Entry for Any Protocol\n");
+ printf("acl -a -n [SMAC] -q [DipS] -r [DipE] -U[UP] -u [Allow/Deny/FP]\n");
+ printf("Ex: acl -a -n 00:11:22:33:44:55 -q 10.10.10.3 -r 10.10.10.5 -u Deny \n\n");
+ printf("Ex: acl -a -n 00:11:22:33:44:55 -q 10.10.10.3 -r 10.10.10.5 -U 3 -u FP \n\n");
+
+ printf("Add SMAC to DIP Entry for Tcp Protocol\n");
+ printf("acl -b -n [SMAC] -q [DipS] -r [DipE] -s [DpS] -t [DpE] -U[UP] -u [Allow/Deny/FP]\n");
+ printf("Ex: acl -b -n 00:11:22:33:44:55 -q 10.10.10.3 -r 10.10.10.5 -s 1 -t 1024 -u Deny\n\n");
+
+ printf("SMAC to DIP Entry for Udp Protocol\n");
+ printf("acl -c -n [SMAC] -q [DipS] -r [DipE] -s [DpS] -t [DpE] -U[UP] -u [Allow/Deny/FP]\n");
+ printf("Ex: acl -c -n 00:11:22:33:44:55 -q 10.10.10.3 -r 10.10.10.5 -s 1 -t 1024 -u Deny\n\n");
+
+ printf("Del SDMAC Entry for Any Protocol\n");
+ printf("acl -D -n [SMAC]\n");
+ printf("Ex: acl -D -n 00:11:22:33:44:55 \n\n");
+
+ printf("Del SMAC to DIP Entry for Any Protocol\n");
+ printf("acl -d -n [SMAC] -q [DipS] -r [DipE]\n");
+ printf("Ex: acl -d -n 00:11:22:33:44:55 -q 10.10.10.3 -r 10.10.10.5\n\n");
+
+ printf("Del SMAC to DIP Entry for Tcp Protocol\n");
+ printf("acl -e -n [SMAC] -q [DipS] -r [DipE] -s [DpS] -t [DpE]\n");
+ printf("Ex: acl -e -n 00:11:22:33:44:55 -q 10.10.10.3 -r 10.10.10.5 -s 1 -t 1024\n\n");
+
+ printf("Del SMAC to DIP Entry for Udp Protocol\n");
+ printf("acl -f -n [SMAC] -q [DipS] -r [DipE] -s [DpS] -t [DpE]\n");
+ printf("Ex: acl -f -n 00:11:22:33:44:55 -q 10.10.10.3 -r 10.10.10.5 -s 1 -t 1024\n\n");
+
+ printf("Add SIP to DIP Entry for Any Protocol\n");
+ printf("acl -H -o [SipS] -p [SipE] -q [DipS] -r [DipE] -U[UP] -u [Allow/Deny/FP]\n");
+ printf("Ex: acl -H -o 10.10.10.3 -p 10.10.10.5 -q 10.10.20.3 -r 10.10.20.3 -u Deny\n\n");
+
+
+ printf("Add SIP to DIP Entry for Tcp Protocol\n");
+ printf("acl -h -o [SipS] -p [SipE] -q [DipS] -r [DipE] -s [DpS] -t [DpE] -U[UP] -u [Allow/Deny/FP]\n");
+ printf("Ex: acl -h -o 10.10.10.3 -p 10.10.10.5 -q 10.10.20.3 -r 10.10.20.3 -s 1 -t 1024 -u Deny\n\n");
+
+
+ printf("Add SIP to DIP Entry for Udp Protocol\n");
+ printf("acl -i -o [SipS] -p [SipE] -q [DipS] -r [DipE] -s [DpS] -t [DpE]-U[UP] -u [Allow/Deny/FP]\n");
+ printf("Ex: acl -i -o 10.10.10.3 -p 10.10.10.5 -q 10.10.20.3 -r 10.10.20.3 -s 1 -t 1024 -u Deny\n\n");
+
+ printf("Del SIP to DIP Entry for Any Protocol\n");
+ printf("acl -j -o [SipS] -p [SipE] -q [DipS] -r [DipE]\n");
+ printf("Ex: acl -j -o 10.10.10.3 -p 10.10.10.5 -q 10.10.20.3 -r 10.10.20.3\n\n");
+
+
+ printf("Del SIP to DIP Entry for Tcp Protocol\n");
+ printf("acl -k -o [SipS] -p [SipE] -q [DipS] -r [DipE] -s [DpS] -t [DpE]\n");
+ printf("Ex: acl -k -o 10.10.10.3 -p 10.10.10.5 -q 10.10.20.3 -r 10.10.20.3 -s 1 -t 1024\n\n");
+
+
+ printf("Del SIP to DIP Entry for Udp Protocol\n");
+ printf("acl -l -o [SipS] -p [SipE] -q [DipS] -r [DipE] -s [DpS] -t [DpE]\n");
+ printf("Ex: acl -l -o 10.10.10.3 -p 10.10.10.5 -q 10.10.20.3 -r 10.10.20.3 -s 1 -t 1024\n\n");
+ printf("Del All Entries\n");
+ printf("acl -m\n\n");
+
+ printf("Add S/DMAC ETYPE VID PROTOCOL SIP DIP SP DP Entry\n");
+ printf("acl -E -n[SMAC] -N[DMAC] -P[ESW Port] -Z[Ethertype] -S[Protocol] -o[SipS] -p[SipE] -q[DipS] -r[DipE] -s[DpS] -t[DpE] -v[SpS] -x[SpE] -y[TosS] -z[TosE] -F[TCP/UDP/ANY] -V[VID] -u[Allow/Deny/FP]\n");
+ printf("Ex: acl -E -o 10.10.10.3 -p 10.10.10.5 -q 10.10.20.3 -r 10.10.20.3 -s 1 -t 1024 -F UDP -u Deny\n\n");
+
+
+ printf("Del S/DMAC ETYPE VID PROTOCOL SIP DIP SP DP Entry\n");
+ printf("acl -G -n[SMAC] -N[DMAC] -P[ESW Port] -Z[Ethertype] -S[Protocol] -o[SipS] -p[SipE] -q[DipS] -r[DipE] -s[DpS] -t[DpE] -v[SpS] -x[SpE] -y[TosS] -z[TosE] -F[TCP/UDP/ANY] -V[VID] \n");
+ printf("Ex: acl -G -o 10.10.10.3 -p 10.10.10.5 -q 10.10.20.3 -r 10.10.20.3 -s 1 -t 1024 -F UDP\n\n");
+
+ printf("Show All ACL Entry\n");
+ printf("Ex: acl -g\n\n");
+
+}
+
+int main(int argc, char *argv[])
+{
+ int opt;
+ char options[] = "AabcDdEefGgHhijklm?F:n:N:o:P:p:q:r:s:S:t:u:U:v:x:y:V:z:Z:";
+ int fd;
+ struct acl_args args;
+ struct acl_list_args *args2;
+ int method=-1;
+ int result;
+ int i;
+
+ memset(&args, 0, sizeof(struct acl_args));
+ args.pn = 7; /* Default do not care*/
+ /* Max 511 acl entries */
+ args2=malloc(sizeof(struct acl_list_args) + sizeof(struct acl_args)*511);
+ if (NULL == args2)
+ {
+ printf(" Allocate memory for acl_list_args and acl_args failed.\n");
+ return 0;
+ }
+ fd = open("/dev/"ACL_DEVNAME, O_RDONLY);
+
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"ACL_DEVNAME);
+ free(args2);
+ return 0;
+ }
+
+ if(argc < 2) {
+ show_usage();
+ free(args2);
+ close(fd);
+ return 0;
+ }
+
+ while ((opt = getopt (argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'A':
+ method=ACL_ADD_SDMAC_ANY;
+ break;
+ case 'a':
+ method=ACL_ADD_SMAC_DIP_ANY;
+ break;
+ case 'b':
+ method=ACL_ADD_SMAC_DIP_TCP;
+ break;
+ case 'c':
+ method=ACL_ADD_SMAC_DIP_UDP;
+ break;
+ case 'D':
+ method=ACL_DEL_SDMAC_ANY;
+ break;
+ case 'd':
+ method=ACL_DEL_SMAC_DIP_ANY;
+ break;
+ case 'e':
+ method=ACL_DEL_SMAC_DIP_TCP;
+ break;
+ case 'E':
+ method=ACL_ADD_SMAC_DMAC_ETYPE_VID_SIP_DIP_TOS_PORT;
+ break;
+ case 'F':
+ if(strcasecmp(optarg,"TCP")==0){
+ args.L4=ACL_PROTO_TCP;
+ }else if(strcasecmp(optarg,"UDP")==0){
+ args.L4=ACL_PROTO_UDP;
+ }else if(strcasecmp(optarg,"ANY")==0){
+ args.L4=ACL_PROTO_ANY;
+ }else{
+ printf("Error: -t TCP or UDP or ANY\n");
+ free(args2);
+ close(fd);
+ return 0;
+ }
+
+ break;
+ case 'G':
+ method=ACL_DEL_SMAC_DMAC_ETYPE_VID_SIP_DIP_TOS_PORT;
+ break;
+ case 'f':
+ method=ACL_DEL_SMAC_DIP_UDP;
+ break;
+ case 'H':
+ method=ACL_ADD_SIP_DIP_ANY;
+ break;
+ case 'g':
+ method = ACL_GET_ALL_ENTRIES;
+ break;
+ case 'h':
+ method=ACL_ADD_SIP_DIP_TCP;
+ break;
+ case 'i':
+ method=ACL_ADD_SIP_DIP_UDP;
+ break;
+ case 'j':
+ method=ACL_DEL_SIP_DIP_ANY;
+ break;
+ case 'k':
+ method=ACL_DEL_SIP_DIP_TCP;
+ break;
+ case 'l':
+ method=ACL_DEL_SIP_DIP_UDP;
+ break;
+ case 'm':
+ method=ACL_CLEAN_TBL;
+ break;
+ case 'n': /* source mac address */
+ str_to_mac(args.mac, optarg);
+ break;
+ case 'N': /* destination mac address */
+ str_to_mac(args.dmac, optarg);
+ break;
+ case 'o': /* start of sip */
+ str_to_ip(&args.sip_s, optarg);
+ break;
+ case 'p': /* end of sip */
+ str_to_ip(&args.sip_e, optarg);
+ break;
+ case 'P': /* Port Number */
+ args.pn=strtoll(optarg, NULL, 10);
+ break;
+ case 'q': /* start of dip */
+ str_to_ip(&args.dip_s, optarg);
+ break;
+ case 'r': /* end of dip */
+ str_to_ip(&args.dip_e, optarg);
+ break;
+ case 's': /* start of dp */
+ args.dp_s=strtoll(optarg, NULL, 10);
+ break;
+ case 't': /* end of dp */
+ args.dp_e=strtoll(optarg, NULL, 10);
+ break;
+ case 'S': /* Protocol */
+ args.protocol=strtoll(optarg, NULL, 10);
+ break;
+
+ case 'v': /* start of sp */
+ args.sp_s=strtoll(optarg, NULL, 10);
+ break;
+ case 'x': /* end of sp */
+ args.sp_e=strtoll(optarg, NULL, 10);
+ break;
+ case 'y': /* start of tos */
+ args.tos_s=strtoll(optarg, NULL, 10);
+ break;
+ case 'z': /* end of tos */
+ args.tos_e=strtoll(optarg, NULL, 10);
+ break;
+ case 'Z': /* ethertype */
+ args.ethertype=strtoll(optarg, NULL, 16);
+ break;
+ case 'V': /* VID */
+ args.vid=strtoll(optarg, NULL, 10);
+ break;
+ case 'u': /* Deny/Allow */
+ if(strcasecmp(optarg,"Deny")==0){
+ args.method=ACL_DENY_RULE;
+ }else if(strcasecmp(optarg,"Allow")==0){
+ args.method=ACL_ALLOW_RULE;
+ }else if(strcasecmp(optarg,"FP")==0){
+ args.method=ACL_PRIORITY_RULE;
+ }else{
+ printf("Error: -t Deny or Allow\n");
+ free(args2);
+ close(fd);
+ return 0;
+ }
+ break;
+ case 'U': /* User Priority */
+ args.up=strtoll(optarg, NULL, 10);
+ break;
+ case '?':
+ default:
+ show_usage();
+ free(args2);
+ close(fd);
+ return 0;
+ }
+ }
+ switch(method) {
+ case ACL_ADD_SDMAC_ANY:
+ case ACL_ADD_ETYPE_ANY:
+ case ACL_ADD_SMAC_DIP_ANY:
+ case ACL_ADD_SMAC_DIP_TCP:
+ case ACL_ADD_SMAC_DIP_UDP:
+ case ACL_DEL_SDMAC_ANY:
+ case ACL_DEL_ETYPE_ANY:
+ case ACL_DEL_SMAC_DIP_ANY:
+ case ACL_DEL_SMAC_DIP_TCP:
+ case ACL_DEL_SMAC_DIP_UDP:
+ case ACL_ADD_SIP_DIP_ANY:
+ case ACL_ADD_SIP_DIP_TCP:
+ case ACL_ADD_SIP_DIP_UDP:
+ case ACL_ADD_SMAC_DMAC_ETYPE_VID_SIP_DIP_TOS_PORT:
+ case ACL_DEL_SIP_DIP_ANY:
+ case ACL_DEL_SIP_DIP_TCP:
+ case ACL_DEL_SIP_DIP_UDP:
+ case ACL_DEL_SMAC_DMAC_ETYPE_VID_SIP_DIP_TOS_PORT:
+ case ACL_CLEAN_TBL:
+ SetAclEntry(&args, method);
+ result = args.result;
+ break;
+ case ACL_GET_ALL_ENTRIES:
+ AclGetAllEntries(args2);
+ result = args2->result;
+
+ printf("Total Entry Count = %d\n",args2->num_of_entries);
+ for(i=0;i<args2->num_of_entries;i++){
+ printf("#%d :SMAC=%02X:%02X:%02X:%02X:%02X:%02X => DMAC=%02X:%02X:%02X:%02X:%02X:%02X PROTOCOL=0x%2x\n", \
+ i, args2->entries[i].mac[0], args2->entries[i].mac[1], args2->entries[i].mac[2], \
+ args2->entries[i].mac[3], args2->entries[i].mac[4], args2->entries[i].mac[5], \
+ args2->entries[i].dmac[0], args2->entries[i].dmac[1],args2->entries[i].dmac[2], \
+ args2->entries[i].dmac[3], args2->entries[i].dmac[4],args2->entries[i].dmac[5], \
+ args2->entries[i].protocol);
+
+ printf(" :SIP %u.%u.%u.%u->%u.%u.%u.%u=>DIP %u.%u.%u.%u->%u.%u.%u.%u SP %d->%d=>DP %d->%d TOS:0x%2x->0x%2x VID:%d ETYPE=0x%4x TCP_UDP=0/TCP=1/UDP=2:%d PN:%d\n\r", \
+ NIPQUAD(args2->entries[i].sip_s), \
+ NIPQUAD(args2->entries[i].sip_e), \
+ NIPQUAD(args2->entries[i].dip_s), \
+ NIPQUAD(args2->entries[i].dip_e), \
+ args2->entries[i].sp_s, \
+ args2->entries[i].sp_e, \
+ args2->entries[i].dp_s, \
+ args2->entries[i].dp_e, \
+ args2->entries[i].tos_s, \
+ args2->entries[i].tos_e, \
+ args2->entries[i].vid, \
+ args2->entries[i].ethertype, \
+ args2->entries[i].L4, \
+ args2->entries[i].pn);
+ }
+ break;
+ default:
+ result = ACL_FAIL;
+ }
+
+
+ if(result == ACL_SUCCESS) {
+ printf("done\n");
+ }else if (result == ACL_TBL_FULL) {
+ printf("table full\n");
+ } else {
+ printf("fail\n");
+ }
+
+ free(args2);
+ close(fd);
+ return 0;
+}
diff --git a/src/extended/hw_nat/acl_api.c b/src/extended/hw_nat/acl_api.c
new file mode 100644
index 0000000..3ee3fae
--- /dev/null
+++ b/src/extended/hw_nat/acl_api.c
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include "acl_ioctl.h"
+
+int SetAclEntry(struct acl_args *opt, unsigned int cmd)
+{
+ int fd;
+
+ fd = open("/dev/"ACL_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"ACL_DEVNAME);
+ return ACL_FAIL;
+ }
+
+ if(ioctl(fd, cmd, opt)<0) {
+ printf("ACL_API: ioctl error\n");
+ close(fd);
+ return ACL_FAIL;
+ }
+
+ close(fd);
+ return ACL_SUCCESS;
+}
+int AclGetAllEntries(struct acl_list_args *opt)
+{
+ int fd=0;
+
+ fd = open("/dev/"ACL_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"ACL_DEVNAME);
+ return ACL_FAIL;
+ }
+
+ if(ioctl(fd, ACL_GET_ALL_ENTRIES, opt)<0) {
+ printf("ACL_API: ioctl error\n");
+ close(fd);
+ return ACL_FAIL;
+ }
+
+ close(fd);
+
+ return ACL_SUCCESS;
+
+}
diff --git a/src/extended/hw_nat/acl_api.h b/src/extended/hw_nat/acl_api.h
new file mode 100644
index 0000000..9b6f574
--- /dev/null
+++ b/src/extended/hw_nat/acl_api.h
@@ -0,0 +1,16 @@
+#ifndef __ACL_API
+#define __ACL_API
+
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[3], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[0]
+#define NIPHALF(addr) \
+ ((unsigned short *)&addr)[0], \
+ ((unsigned short *)&addr)[1]
+
+int SetAclEntry(struct acl_args *opt, unsigned int cmd);
+int AclGetAllEntries(struct acl_list_args *opt);
+
+#endif
diff --git a/src/extended/hw_nat/hw_nat.c b/src/extended/hw_nat/hw_nat.c
new file mode 100644
index 0000000..555d451
--- /dev/null
+++ b/src/extended/hw_nat/hw_nat.c
@@ -0,0 +1,847 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <strings.h>
+#include <unistd.h>
+#ifndef CONFIG_SUPPORT_OPENWRT
+#include <linux/autoconf.h>
+#endif
+
+#if defined CONFIG_COLGIN_SUPPORT
+#include "hnat_ioctl.h"
+#else
+#include "hwnat_ioctl.h"
+#endif
+#include "hwnat_api.h"
+#include "util.h"
+
+void show_usage(void)
+{
+ printf("Add Static Entry\n");
+ printf("hw_nat -a -h [SMAC] -i [DMAC] -1 [type:hnapt(0)/ipv6_rout(5)]-j [Sip] -2 [Dip] -l [Sp] -3 [Dp]\n");
+ printf(" -n [New_Sip] -o [New_Dip] -p [New_Sp] -q [New_Dp] -4 [Vlan_layer] -5 [dscp]\n");
+ printf(" -s [VLAN1_ID] -S [VLAN2_ID] -v [Tcp/Udp] -w [OutIf:CPU/GE1/GE2]\n");
+ printf("Ex(ipv4): hw_nat -a -h 00:0C:43:28:80:11 -i E0:18:77:BD:D5:18 -1 0 -j 10.10.10.3 -2 10.10.20.3\n");
+ printf("-l 1000 -3 2000 -n 10.10.20.254 -o 10.10.20.3 -p 1000 -q 2000 -4 1 -s 1 -v Tcp -w GE2 -5 32\n\n");
+
+ printf("Ex(ipv6): hw_nat -a -h 00:0C:43:28:02:14 -i 00:1B:21:00:9B:03 -1 5 -6 2001:1111:2222:3333:0000:0000:0000:2\n");
+ printf("-7 2001:aaa:6401:101:8000:0000:0000:2 -l 3000 -3 2000 -4 0 -v Tcp -w GE1 -5 32\n\n");
+
+ printf("Del Static Entry\n");
+ printf("hw_nat -b -1 [type:hnapt(0)/ipv6_rout(5)] -j [Sip] -2 [Dip] -l [Sp] -3 [Dp] -v [Tcp/Udp] \n");
+ printf("Ex: hw_nat -b -j 10.10.10.3 -k 10.10.20.3 -l 30 -m 40 -v Tcp\n\n");
+#if defined (CONFIG_HW_NAT_SEMI_AUTO_MODE)
+ printf("Add semi-auto Entry\n");
+ printf("hw_nat -a -1 [type:hnapt(0)/ipv6_rout(5)]-j [Sip] -2 [Dip] -l [Sp] -m [Dp]\n");
+ printf("hw_nat -a -1 0 -j 10.10.10.3 -2 10.10.20.3 -l 1000 -3 2000 \n");
+ printf("hw_nat -a -1 5 -j 2001:1111:2222:3333:0000:0000:0000:2 -2 2001:aaa:6401:101:8000:0000:0000:2 -l 3000 -3 2000\n");
+ printf("Delete semi-auto Entry\n");
+ printf("hw_nat -b -1 0 -j 10.10.10.3 -2 10.10.20.3 -l 1000 -3 2000\n");
+ printf("hw_nat -b -1 5 -j 2001:1111:2222:3333:0000:0000:0000:2 -2 2001:aaa:6401:101:8000:0000:0000:2 -l 3000 -3 2000\n");
+#endif
+ printf("Show Foe Entry\n");
+ printf("hw_nat -c [entry_num]\n");
+ printf("Ex: hw_nat -c 1234\n\n");
+
+ printf("Set Debug Level (0:disable) \n");
+ printf("hw_nat -d [0~7]\n");
+ printf("Ex: hw_nat -d \n\n");
+
+ printf("Show All Foe Invalid Entry\n");
+ printf("Ex: hw_nat -e\n\n");
+
+ printf("Show All Foe Unbinded Entry\n");
+ printf("Ex: hw_nat -f\n\n");
+
+ printf("Show All Foe Binded Entry\n");
+ printf("Ex: hw_nat -g\n\n");
+
+ printf("Unbind Foe Entry\n");
+ printf("hw_nat -x [entry_num]\n");
+ printf("Ex: hw_nat -x 1234\n\n");
+
+ printf("Set Foe Entry to PacketDrop\n");
+ printf("hw_nat -k [entry_num]\n");
+ printf("Ex: hw_nat -k 1234\n\n");
+
+
+#if defined (CONFIG_PPE_MCAST)
+ printf("Add member port in multicast entry\n");
+ printf("Ex: hw_nat -B [vid] [mac] [px_en] [px_qos_en] [mc_qos_qid]\n\n");
+
+ printf("Del member port multicast entry\n");
+ printf("Ex: hw_nat -C [vid] [mac] [px_en] [px_qos_en] [mc_qos_qid]\n\n");
+
+ printf("Dump all multicast entry\n");
+ printf("Ex: hw_nat -D\n\n");
+#endif
+
+ printf("Set PPE Cofigurations:\n");
+ printf("Set HNAT binding threshold per second (d=30)\n");
+ printf("Ex: hw_nat -N [1~65535]\n\n");
+
+
+ printf("Set HNAT TCP/UDP keepalive interval (d=1, 1)(unit:4sec)\n");
+ printf("Ex: hw_nat -Q [1~255][1~255]\n\n");
+
+ printf("Disable Hook API (hook_id: 0=ETH, 1=MD, 2=WIFI, 3=RNDIS, 4=EXT)\n");
+ printf("Ex: hw_nat -O <hook_id>, hwnat -O [0/1/2/3/4]\n\n");
+
+ printf("Restore Hook API (hook_id: 0=ETH, 1=MD, 2=WIFI, 3=RNDIS, 4=EXT)\n");
+ printf("Ex: hw_nat -T <hook_id>, hwnat -T [0/1/2/3/4]\n\n");
+
+ printf("Disable Hook API on specific direction (hook_id: 0=ETH, 1=MD, 2=WIFI, 3=RNDIS, 4=EXT) (dir: 1:rx, 2:tx)\n");
+ printf("Ex: hw_nat -O <hook_id> -P <dir_id>, hwnat -O [0/1/2/3/4] -P[1/2]\n\n");
+
+ printf("Restore Hook API on specific direction (hook_id: 0=ETH, 1=MD, 2=WIFI, 3=RNDIS, 4=EXT) (dir: 1:rx, 2:tx)\n");
+ printf("Ex: hw_nat -T <hook_id> -P <dir_id>, hwnat -T [0/1/2/3/4] -P[1/2]\n\n");
+
+ printf("Set HNAT Life time of Binded TCP/UDP/FIN entry(d=5, 5, 5)(unit:1Sec) \n");
+ printf("Ex: hw_nat -U [1~65535][1~65535][1~65535]\n\n");
+
+ printf("Set LAN/WAN port VLAN ID\n");
+ printf("Ex: hw_nat -V [LAN_VID] [WAN_VID]\n\n");
+ printf("Ex: hw_nat -V 1 2\n\n");
+
+ printf("Only Speed UP (0=Upstream, 1=Downstream, 2=Bi-Direction) flow \n");
+ printf("Ex: hw_nat -Z 1\n\n");
+
+#if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621)
+ printf("Switch Ds-Lite and Map-E(0=Ds-Lite, 1=Map-E,(d=0)):\n");
+ printf("Ex: hw_nat -W [0/1]\n\n");
+#endif
+#if defined (CONFIG_PPE_MIB)
+ printf("Get ppe entry mib counter\n");
+ printf("hw_nat -M -1 [type:hnapt(0)/ipv6_rout(5)]-j [Sip] -2 [Dip] -l [Sp] -m [Dp]\n");
+ printf("hw_nat -M -1 0 -j 10.10.10.3 -2 10.10.20.3 -l 1000 -3 2000 \n");
+ printf("hw_nat -M -1 5 -j 2001:1111:2222:3333:0000:0000:0000:2 -2 2001:aaa:6401:101:8000:0000:0000:2 -l 3000 -3 2000\n");
+ printf("Get ppe entry all mib counter sort by IP\n");
+ printf("hw_nat -X\n");
+#endif
+#if defined (CONFIG_HW_NAT_IPI)
+ printf("Set HNAT IPI control from extif:\n");
+ printf("EX: hw_nat -G [ipi_enable] [queue_thresh] [drop_pkt] [ipi_cnt_mod]\n\n");
+ printf("Set HNAT IPI control from ppehit:\n");
+ printf("EX: hw_nat -L [ipi_enable] [queue_thresh] [drop_pkt] [ipi_cnt_mod]\n\n");
+ printf("hw_nat -G 1 1000 20000 5\n");
+ printf("hw_nat -L 1 1000 20000 44\n");
+#endif
+}
+#if defined CONFIG_COLGIN_SUPPORT
+static void dump_all_ip_cnt(struct hwnat_mib_all_ip_args *args)
+{
+ int i;
+ if(args->entry_num > 0)
+ printf("IP tx_packets tx_bytes rx_packets rx_bytes\n");
+ for(i=0; i<args->entry_num; i++) {
+ if(args->entries[i].is_ipv4) { //IPV4_NAPT
+ printf("%8x %10ld %10ld %10ld %10ld\n",
+ args->entries[i].ip.ipv4_addr,
+ args->entries[i].tx_packets,
+ args->entries[i].tx_bytes,
+ args->entries[i].rx_packets,
+ args->entries[i].rx_bytes);
+ } else { //IPV6_5T_ROUTE
+ printf(" %4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x %10ld %10ld %10ld %10ld\n",
+ NIPHALF(args->entries[i].ip.ipv6_addr[0]),
+ NIPHALF(args->entries[i].ip.ipv6_addr[1]),
+ NIPHALF(args->entries[i].ip.ipv6_addr[2]),
+ NIPHALF(args->entries[i].ip.ipv6_addr[3]),
+ args->entries[i].tx_packets,
+ args->entries[i].tx_bytes,
+ args->entries[i].rx_packets,
+ args->entries[i].rx_bytes);
+ }
+ }
+}
+#endif
+int main(int argc, char *argv[])
+{
+ int opt;
+
+ //char options[] = "aefgy?c:x:k:d:A:B:C:DN:O:P:Q:T:U:V:Z:";
+ char options[] = "abefgyzMD?c:m:r:A:B:C:G:I:J:K:L:S:d:h:i:j:1:k:2:l:3:n:o:p:q:4:s:P:t:u:v:w:5:x:y:N:O:Q:T:U:Z:L:7:8:9:E:F:H:R:6:X";
+
+ int fd, method = -1;
+ int i=0;
+ unsigned int entry_num;
+ unsigned int debug;
+ unsigned int type;
+ struct hwnat_args *args;
+ struct hwnat_tuple args2 = {0};
+ struct hwnat_ac_args args3;
+ struct hwnat_config_args args4;
+#if defined (CONFIG_HW_NAT_IPI)
+ struct hwnat_ipi_args args6;
+ struct hwnat_ipi_args args7;
+#endif
+
+#if defined (CONFIG_PPE_MCAST)
+ struct hwnat_mcast_args args5;
+ unsigned char mac[6];
+#endif
+#if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621)
+ unsigned int swit;
+#endif
+ int result;
+#if defined CONFIG_COLGIN_SUPPORT
+ int org_tot_len = 1362;
+ int org_id = 0;
+ int org_frag =0;
+ int chksum_tmp, tot_len_tmp, id_tmp, frag_tmp;
+ int chksum_base = 0;
+ struct hwnat_mib_all_ip_args *args8;
+#endif
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return 0;
+ }
+
+ if(argc < 2) {
+ show_usage();
+ close(fd);
+ return 0;
+ }
+
+ /* Max table size is 16K */
+ args=malloc(sizeof(struct hwnat_args)+sizeof(struct hwnat_tuple)*1024*16);
+ if (NULL == args)
+ {
+ printf(" Allocate memory for hwnat_args and hwnat_tuple failed.\n");
+ close(fd);
+ return 0;
+ }
+
+ while ((opt = getopt (argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'h':
+ str_to_mac(args2.smac, optarg);
+ break;
+ case 'i':
+ str_to_mac(args2.dmac, optarg);
+ break;
+ case '1':
+ type = strtoll(optarg, NULL, 10);
+ args2.pkt_type = type;
+ break;
+ case 'j':
+ if ((type == 0) || (type == 7)) {
+ str_to_ip(&args2.ing_sipv4, optarg);
+ } else if((type == 5) || (type == 3)) {
+ str_to_ipv6(&args2.ing_sipv6_0, optarg, 0);
+ str_to_ipv6(&args2.ing_sipv6_1, optarg, 1);
+ str_to_ipv6(&args2.ing_sipv6_2, optarg, 2);
+ str_to_ipv6(&args2.ing_sipv6_3, optarg, 3);
+ } else {
+ printf("hwnat type error\n");
+ free(args);
+ close(fd);
+ return 0;
+ }
+ break;
+ case '2':
+ if ((type == 0) || (type == 7)) {
+ str_to_ip(&args2.ing_dipv4, optarg);
+ } else if((type == 5) || (type == 3)) {
+ str_to_ipv6(&args2.ing_dipv6_0, optarg, 0);
+ str_to_ipv6(&args2.ing_dipv6_1, optarg, 1);
+ str_to_ipv6(&args2.ing_dipv6_2, optarg, 2);
+ str_to_ipv6(&args2.ing_dipv6_3, optarg, 3);
+ } else {
+ printf("hwnat type error\n");
+ free(args);
+ close(fd);
+ return 0;
+ }
+ break;
+ case 'l':
+ args2.ing_sp = strtoll(optarg, NULL, 10);
+ break;
+ case '3':
+ args2.ing_dp = strtoll(optarg, NULL, 10);
+ break;
+ case 'n':
+ str_to_ip(&args2.eg_sipv4, optarg);
+ break;
+ case 'o':
+ str_to_ip(&args2.eg_dipv4, optarg);
+ break;
+ case 'p':
+ args2.eg_sp = strtoll(optarg, NULL, 10);
+ break;
+ case 'q':
+ args2.eg_dp = strtoll(optarg, NULL, 10);
+ break;
+ case '4':
+ args2.vlan_layer = strtoll(optarg, NULL, 10);
+ break;
+ case 's':
+ args2.vlan1 = strtoll(optarg, NULL, 10);
+ break;
+ case 'S':
+ args2.vlan2 = strtoll(optarg, NULL, 10);
+ break;
+#if defined CONFIG_COLGIN_SUPPORT
+ case 'P':
+ args2.etype = strtoll(optarg, NULL, 16);
+ break;
+#endif
+ case 't':
+ if(strcasecmp(optarg,"Ins")==0){
+ args2.pppoe_act=1;
+ }else if(strcasecmp(optarg,"Del")==0){
+ args2.pppoe_act=0;
+ }else{
+ printf("Error: -t No/Mod/Ins/Del\n");
+ free(args);
+ close(fd);
+ return 0;
+ }
+ break;
+ case 'u':
+ args2.pppoe_id = strtoll(optarg, NULL, 10);
+ break;
+ case 'v':
+ if(strcasecmp(optarg,"Tcp")==0){
+ args2.is_udp=0;
+ }else if(strcasecmp(optarg,"Udp")==0){
+ args2.is_udp=1;
+ }else {
+ printf("Error: -v Tcp/Udp\n");
+ free(args);
+ close(fd);
+ return 0;
+ }
+ break;
+ case 'w':
+ if(strcasecmp(optarg,"CPU")==0){
+ args2.dst_port=0;
+ }else if(strcasecmp(optarg,"GE1")==0){
+ args2.dst_port=1;
+ }else if(strcasecmp(optarg,"GE2")==0){
+ args2.dst_port=2;
+ }else if(strcasecmp(optarg,"P9")==0){
+ args2.dst_port=9;
+ }else if(strcasecmp(optarg,"P8")==0){
+ args2.dst_port=8;
+ }else if(strcasecmp(optarg,"p10")==0){
+ args2.dst_port=10;
+ }else if(strcasecmp(optarg,"p11")==0){
+ args2.dst_port=11;
+ }else if(strcasecmp(optarg,"p12")==0){
+ args2.dst_port=12;
+ }else {
+ printf("Error: -w CPU/GE1/GE2\n");
+ free(args);
+ close(fd);
+ return 0;
+ }
+ break;
+ case '5':
+ args2.dscp = strtoll(optarg, NULL, 10);
+ break;
+ case '7':
+ str_to_ipv6(&args2.ing_sipv6_0, optarg, 0);
+ str_to_ipv6(&args2.ing_sipv6_1, optarg, 1);
+ str_to_ipv6(&args2.ing_sipv6_2, optarg, 2);
+ str_to_ipv6(&args2.ing_sipv6_3, optarg, 3);
+ break;
+ case '8':
+ str_to_ipv6(&args2.ing_dipv6_0, optarg, 0);
+ str_to_ipv6(&args2.ing_dipv6_1, optarg, 1);
+ str_to_ipv6(&args2.ing_dipv6_2, optarg, 2);
+ str_to_ipv6(&args2.ing_dipv6_3, optarg, 3);
+ break;
+#if defined CONFIG_COLGIN_SUPPORT
+ case '9':
+ args2.rmt = strtoll(optarg, NULL, 10);
+ break;
+#endif
+ case 'E':
+ args2.hash_index = strtoll(optarg, NULL, 10);
+ break;
+#if defined CONFIG_COLGIN_SUPPORT
+ case 'F':
+ args2.frag = strtoll(optarg, NULL, 10);
+ break;
+ case 'H':
+ chksum_tmp = strtoll(optarg, NULL, 16);
+ chksum_tmp = (0xffff-chksum_tmp);
+ chksum_tmp = (chksum_tmp - org_tot_len - org_id);
+ chksum_base = chksum_tmp & 0xFFFF;
+ printf("chksum_base = %x\n", chksum_base);
+ args2.checksum = chksum_base;
+ break;
+ case 'R':
+ args2.ttl = strtoll(optarg, NULL, 10);
+ break;
+#endif
+ case 'a':
+ method = HW_NAT_ADD_ENTRY;
+ break;
+
+ case 'b':
+ method = HW_NAT_DEL_ENTRY;
+ break;
+ case 'z':
+ method = HW_NAT_DUMP_CACHE_ENTRY;
+ break;
+ case 'c':
+ method = HW_NAT_DUMP_ENTRY;
+ entry_num = strtoll(optarg, NULL, 10);
+ break;
+ case 'I':
+ method = HW_NAT_INVALID_ENTRY;
+ entry_num = strtoll(optarg, NULL, 10);
+ break;
+ case 'x':
+ method = HW_NAT_UNBIND_ENTRY;
+ entry_num = strtoll(optarg, NULL, 10);
+ break;
+ case 'k':
+ method = HW_NAT_DROP_ENTRY;
+ entry_num = strtoll(optarg, NULL, 10);
+ break;
+ case 'd':
+ method = HW_NAT_DEBUG;
+ debug = strtoll(optarg, NULL, 10);
+ break;
+#if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621)
+ case 'W':
+ method = HW_NAT_SWITCH_DSL_MAPE;
+ swit = strtoll(optarg, NULL, 10);
+ break;
+#endif
+ case 'e':
+ method = HW_NAT_GET_ALL_ENTRIES;
+ args->entry_state=0; /* invalid entry */
+ break;
+ case 'f':
+ method = HW_NAT_GET_ALL_ENTRIES;
+ args->entry_state=1; /* unbinded entry */
+ break;
+ case 'g':
+ method = HW_NAT_GET_ALL_ENTRIES;
+ args->entry_state=2; /* binded entry */
+ break;
+ case 'y':
+ method = HW_NAT_TBL_CLEAR;
+ break;
+ case 'A':
+ method = HW_NAT_GET_AC_CNT;
+ args3.ag_index = strtoll(optarg, NULL, 10);
+ break;
+#if defined (CONFIG_PPE_MCAST)
+ case 'B':
+ method = HW_NAT_MCAST_INS;
+ args5.mc_vid = strtoll(argv[2], NULL, 10);
+ str_to_mac(mac, argv[3]);
+ memcpy(args5.dst_mac, mac, sizeof(mac));
+ args5.mc_px_en = strtoll(argv[4], NULL, 10);
+ args5.mc_px_qos_en = strtoll(argv[5], NULL, 10);
+ args5.mc_qos_qid = strtoll(argv[6], NULL, 10);
+ break;
+ case 'C':
+ method = HW_NAT_MCAST_DEL;
+ args5.mc_vid = strtoll(argv[2], NULL, 10);
+ str_to_mac(mac, argv[3]);
+ memcpy(args5.dst_mac, mac, sizeof(mac));
+ memcpy(args5.dst_mac, mac, sizeof(mac));
+ args5.mc_px_en = strtoll(argv[4], NULL, 10);
+ args5.mc_px_qos_en = strtoll(argv[5], NULL, 10);
+ args5.mc_qos_qid = strtoll(argv[6], NULL, 10);
+ break;
+ case 'D':
+ method = HW_NAT_MCAST_DUMP;
+ break;
+#endif
+#if defined (CONFIG_PPE_MIB)
+ case 'm':
+ method = HW_NAT_MIB_DUMP;
+ entry_num = strtoll(optarg, NULL, 10);
+ break;
+ case 'r':
+ method = HW_NAT_MIB_DRAM_DUMP;
+ entry_num = strtoll(optarg, NULL, 10);
+ break;
+ case 'M':
+ method = HW_NAT_MIB_GET;
+ break;
+#if defined CONFIG_COLGIN_SUPPORT
+ case 'X':
+ method = HW_NAT_MIB_GET_ALL_IP;
+ break;
+#endif
+#endif
+ case 'N':
+ method = HW_NAT_BIND_THRESHOLD;
+ args4.bind_threshold = strtoll(argv[2], NULL, 10);
+ break;
+ case 'Q':
+ method = HW_NAT_KA_INTERVAL;
+ args4.foe_tcp_ka = strtoll(argv[2], NULL, 10);
+ args4.foe_udp_ka = strtoll(argv[3], NULL, 10);
+ break;
+ case 'U':
+ method = HW_NAT_BIND_LIFETIME;
+ args4.foe_tcp_dlta = strtoll(argv[2], NULL, 10);
+ args4.foe_udp_dlta = strtoll(argv[3], NULL, 10);
+ args4.foe_fin_dlta = strtoll(argv[4], NULL, 10);
+ break;
+ case 'V':
+ method = HW_NAT_VLAN_ID;
+ args4.lan_vid = strtoll(argv[2], NULL, 10);
+ args4.wan_vid = strtoll(argv[3], NULL, 10);
+ break;
+ case 'Z':
+ method = HW_NAT_BIND_DIRECTION;
+ args4.bind_dir = strtoll(optarg, NULL, 10);
+ break;
+#if defined (CONFIG_HW_NAT_IPI)
+ case 'G': /*FIXME..........................*/
+ method = HW_NAT_IPI_CTRL_FROM_EXTIF;
+ args6.hnat_ipi_enable = strtoll(argv[2], NULL, 10);
+ args6.queue_thresh = strtoll(argv[3], NULL, 10);
+ args6.drop_pkt = strtoll(argv[4], NULL, 10);
+ args6.ipi_cnt_mod = strtoll(argv[5], NULL, 10);
+ //printf("##### hnat_ipi_enable=%d, queue_thresh=%d, drop_pkt=%d #####\n",
+ // args6.hnat_ipi_enable, args6.queue_thresh, args6.drop_pkt);
+ break;
+ case 'L': /*FIXME..........................*/
+ method = HW_NAT_IPI_CTRL_FROM_PPEHIT;
+ args7.hnat_ipi_enable = strtoll(argv[2], NULL, 10);
+ args7.queue_thresh = strtoll(argv[3], NULL, 10);
+ args7.drop_pkt = strtoll(argv[4], NULL, 10);
+ args7.ipi_cnt_mod = strtoll(argv[5], NULL, 10);
+ //printf("##### hnat_ipi_enable2=%d, queue_thresh2=%d, drop_pkt2=%d #####\n",
+ // args7.hnat_ipi_enable2, args7.queue_thresh2, args7.drop_pkt);
+ break;
+#endif
+ case '6':
+ method = HW_NAT_DPORT;
+ break;
+ case 'O':
+ method = HW_NAT_CLEAR_HOOK;
+ args2.dst_port = strtoll(optarg, NULL, 10);
+ break;
+ case 'T':
+ method = HW_NAT_RESTORE_HOOK;
+ args2.dst_port = strtoll(optarg, NULL, 10);
+ break;
+ case '?':
+ show_usage();
+
+ }
+ }
+
+ switch(method){
+//#if defined (CONFIG_HW_NAT_MANUAL_MODE) || defined (CONFIG_HW_NAT_SEMI_AUTO_MODE)
+ case HW_NAT_ADD_ENTRY:
+ result = HwNatAddEntry(&args2);
+ break;
+ case HW_NAT_DEL_ENTRY:
+ result = HwNatDelEntry(&args2);
+ break;
+//#endif
+ case HW_NAT_GET_ALL_ENTRIES:
+ HwNatGetAllEntries(args);
+
+ printf("Total Entry Count = %d\n",args->num_of_entries);
+ for(i=0;i<args->num_of_entries;i++){
+ if(args->entries[i].pkt_type==0) { //IPV4_NAPT
+ printf("IPv4_NAPT=%d : %u.%u.%u.%u:%d->%u.%u.%u.%u:%d => %u.%u.%u.%u:%d->%u.%u.%u.%u:%d (RX=%d FP=%d FQOS=%d QID=%d)\n",
+ args->entries[i].hash_index,
+ NIPQUAD(args->entries[i].ing_sipv4),
+ args->entries[i].ing_sp,
+ NIPQUAD(args->entries[i].ing_dipv4),
+ args->entries[i].ing_dp,
+ NIPQUAD(args->entries[i].eg_sipv4),
+ args->entries[i].eg_sp,
+ NIPQUAD(args->entries[i].eg_dipv4),
+ args->entries[i].eg_dp,
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+
+ } else if(args->entries[i].pkt_type==1) { //IPV4_NAT
+ printf("IPv4_NAT=%d : %u.%u.%u.%u->%u.%u.%u.%u => %u.%u.%u.%u->%u.%u.%u.%u (RX=%d FP=%d FQOS=%d QID=%d)\n",
+ args->entries[i].hash_index,
+ NIPQUAD(args->entries[i].ing_sipv4),
+ NIPQUAD(args->entries[i].ing_dipv4),
+ NIPQUAD(args->entries[i].eg_sipv4),
+ NIPQUAD(args->entries[i].eg_dipv4),
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+
+ } else if(args->entries[i].pkt_type==2) { //IPV6_ROUTING
+ printf("IPv6_1T= %d /DIP: %x:%x:%x:%x:%x:%x:%x:%x (RX=%d FP=%d FQOS=%d QID=%d)\n",
+ args->entries[i].hash_index,
+ NIPHALF(args->entries[i].ing_dipv6_0),
+ NIPHALF(args->entries[i].ing_dipv6_1),
+ NIPHALF(args->entries[i].ing_dipv6_2),
+ NIPHALF(args->entries[i].ing_dipv6_3),
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+
+ } else if(args->entries[i].pkt_type==3) { //IPV4_DSLITE
+ printf("DS-Lite= %d : %u.%u.%u.%u:%d->%u.%u.%u.%u:%d (%x:%x:%x:%x:%x:%x:%x:%x -> %x:%x:%x:%x:%x:%x:%x:%x)(RX=%d FP=%d FQOS=%d QID=%d)\n", \
+ args->entries[i].hash_index,
+ NIPQUAD(args->entries[i].ing_sipv4),
+ args->entries[i].ing_sp,
+ NIPQUAD(args->entries[i].ing_dipv4),
+ args->entries[i].ing_dp,
+ NIPHALF(args->entries[i].eg_sipv6_0),
+ NIPHALF(args->entries[i].eg_sipv6_1),
+ NIPHALF(args->entries[i].eg_sipv6_2),
+ NIPHALF(args->entries[i].eg_sipv6_3),
+ NIPHALF(args->entries[i].eg_dipv6_0),
+ NIPHALF(args->entries[i].eg_dipv6_1),
+ NIPHALF(args->entries[i].eg_dipv6_2),
+ NIPHALF(args->entries[i].eg_dipv6_3),
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+
+ } else if(args->entries[i].pkt_type==4) { //IPV6_3T_ROUTE
+ printf("IPv6_3T= %d SIP: %x:%x:%x:%x:%x:%x:%x:%x DIP: %x:%x:%x:%x:%x:%x:%x:%x (RX=%d FP=%d FQOS=%d QID=%d)\n",
+ args->entries[i].hash_index,
+ NIPHALF(args->entries[i].ing_sipv6_0),
+ NIPHALF(args->entries[i].ing_sipv6_1),
+ NIPHALF(args->entries[i].ing_sipv6_2),
+ NIPHALF(args->entries[i].ing_sipv6_3),
+ NIPHALF(args->entries[i].ing_dipv6_0),
+ NIPHALF(args->entries[i].ing_dipv6_1),
+ NIPHALF(args->entries[i].ing_dipv6_2),
+ NIPHALF(args->entries[i].ing_dipv6_3),
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+
+ } else if(args->entries[i].pkt_type==5) { //IPV6_5T_ROUTE
+ if(args->entries[i].ipv6_flowlabel==1) {
+ printf("IPv6_5T= %d SIP: %x:%x:%x:%x:%x:%x:%x:%x DIP: %x:%x:%x:%x:%x:%x:%x:%x (Flow Label=%x) (RX=%d FP=%d FQOS=%d QID=%d)\n",
+ args->entries[i].hash_index,
+ NIPHALF(args->entries[i].ing_sipv6_0),
+ NIPHALF(args->entries[i].ing_sipv6_1),
+ NIPHALF(args->entries[i].ing_sipv6_2),
+ NIPHALF(args->entries[i].ing_sipv6_3),
+ NIPHALF(args->entries[i].ing_dipv6_0),
+ NIPHALF(args->entries[i].ing_dipv6_1),
+ NIPHALF(args->entries[i].ing_dipv6_2),
+ NIPHALF(args->entries[i].ing_dipv6_3),
+ ((args->entries[i].ing_sp << 16) | (args->entries[i].ing_dp))&0xFFFFF,
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+
+ }else {
+ printf("IPv6_5T= %d SIP: %x:%x:%x:%x:%x:%x:%x:%x %d DIP: %x:%x:%x:%x:%x:%x:%x:%x %d (RX=%d FP=%d FQOS=%d QID=%d)\n",
+ args->entries[i].hash_index,
+ NIPHALF(args->entries[i].ing_sipv6_0),
+ NIPHALF(args->entries[i].ing_sipv6_1),
+ NIPHALF(args->entries[i].ing_sipv6_2),
+ NIPHALF(args->entries[i].ing_sipv6_3),
+ args->entries[i].ing_sp,
+ NIPHALF(args->entries[i].ing_dipv6_0),
+ NIPHALF(args->entries[i].ing_dipv6_1),
+ NIPHALF(args->entries[i].ing_dipv6_2),
+ NIPHALF(args->entries[i].ing_dipv6_3),
+ args->entries[i].ing_dp,
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+ }
+
+ } else if(args->entries[i].pkt_type==7) { //IPV6_6RD
+ if(args->entries[i].ipv6_flowlabel==1) {
+ printf("6RD= %d %x:%x:%x:%x:%x:%x:%x:%x->%x:%x:%x:%x:%x:%x:%x:%x [Flow Label=%x]\n",
+ args->entries[i].hash_index, \
+ NIPHALF(args->entries[i].ing_sipv6_0),
+ NIPHALF(args->entries[i].ing_sipv6_1),
+ NIPHALF(args->entries[i].ing_sipv6_2),
+ NIPHALF(args->entries[i].ing_sipv6_3),
+ NIPHALF(args->entries[i].ing_dipv6_0),
+ NIPHALF(args->entries[i].ing_dipv6_1),
+ NIPHALF(args->entries[i].ing_dipv6_2),
+ NIPHALF(args->entries[i].ing_dipv6_3),
+ ((args->entries[i].ing_sp << 16) | (args->entries[i].ing_dp))&0xFFFFF);
+ printf("(%u.%u.%u.%u->%u.%u.%u.%u)(RX=%d FP=%d FQOS=%d QID=%d)\n",
+ NIPQUAD(args->entries[i].eg_sipv4),
+ NIPQUAD(args->entries[i].eg_dipv4),
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+ }else {
+ printf("6RD= %d /SIP: %x:%x:%x:%x:%x:%x:%x:%x [SP:%d] /DIP: %x:%x:%x:%x:%x:%x:%x:%x [DP=%d]",
+ args->entries[i].hash_index,
+ NIPHALF(args->entries[i].ing_sipv6_0),
+ NIPHALF(args->entries[i].ing_sipv6_1),
+ NIPHALF(args->entries[i].ing_sipv6_2),
+ NIPHALF(args->entries[i].ing_sipv6_3),
+ args->entries[i].ing_sp,
+ NIPHALF(args->entries[i].ing_dipv6_0),
+ NIPHALF(args->entries[i].ing_dipv6_1),
+ NIPHALF(args->entries[i].ing_dipv6_2),
+ NIPHALF(args->entries[i].ing_dipv6_3),
+ args->entries[i].ing_dp);
+ printf("(%u.%u.%u.%u->%u.%u.%u.%u)(RX=%d FP=%d FQOS=%d QID=%d)\n",
+ NIPQUAD(args->entries[i].eg_sipv4),
+ NIPQUAD(args->entries[i].eg_dipv4),
+ args->entries[i].rxif_idx,
+ args->entries[i].fport,
+ args->entries[i].fqos,
+ args->entries[i].qid);
+ }
+ } else{
+ printf("unknown packet type! (pkt_type=%d) \n", args->entries[i].pkt_type);
+ }
+ }
+ result = args->result;
+ break;
+ case HW_NAT_DUMP_CACHE_ENTRY:
+ result = HwNatCacheDumpEntry();
+ break;
+ case HW_NAT_DUMP_ENTRY:
+ result = HwNatDumpEntry(entry_num);
+ break;
+ case HW_NAT_UNBIND_ENTRY:
+ result = HwNatUnBindEntry(entry_num);
+ break;
+ case HW_NAT_DROP_ENTRY:
+ result = HwNatDropEntry(entry_num);
+ break;
+ case HW_NAT_DEBUG:
+ result = HwNatDebug(debug);
+ break;
+#if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621)
+ case HW_NAT_SWITCH_DSL_MAPE:
+ result = HwNatSwitchDsliteMape(swit);
+ break;
+#endif
+ case HW_NAT_GET_AC_CNT:
+ HwNatGetAGCnt(&args3);
+ printf("Byte cnt=%llu\n", args3.ag_byte_cnt);
+ printf("Pkt cnt=%llu\n", args3.ag_pkt_cnt);
+ result = args3.result;
+ break;
+
+ case HW_NAT_BIND_THRESHOLD:
+ result = HwNatSetBindThreshold(&args4);
+ break;
+ case HW_NAT_MAX_ENTRY_LMT:
+ HwNatSetMaxEntryRateLimit(&args4);
+ result = args4.result;
+ break;
+ case HW_NAT_RULE_SIZE:
+ HwNatSetRuleSize(&args4);
+ result = args4.result;
+ break;
+ case HW_NAT_KA_INTERVAL:
+ HwNatSetKaInterval(&args4);
+ result = args4.result;
+ break;
+ case HW_NAT_UB_LIFETIME:
+ HwNatSetUnbindLifeTime(&args4);
+ result = args4.result;
+ break;
+ case HW_NAT_BIND_LIFETIME:
+ result = HwNatSetBindLifeTime(&args4);
+ break;
+ case HW_NAT_VLAN_ID:
+ result = HwNatSetVID(&args4);
+ break;
+ case HW_NAT_BIND_DIRECTION:
+ result = HwNatSetBindDir(&args4);
+ break;
+#if defined (CONFIG_PPE_MCAST)
+ case HW_NAT_MCAST_INS:
+ result = HwNatMcastIns(&args5);
+ break;
+ case HW_NAT_MCAST_DEL:
+ result = HwNatMcastDel(&args5);
+ break;
+ case HW_NAT_MCAST_DUMP:
+ result = HwNatMcastDump();
+ break;
+#endif
+#if defined (CONFIG_PPE_MIB)
+ case HW_NAT_MIB_DUMP:
+ result = HwNatMibDumpEntry(entry_num);
+ break;
+ case HW_NAT_MIB_DRAM_DUMP:
+ result = HwNatMibDramDumpEntry(entry_num);
+ break;
+ case HW_NAT_MIB_GET:
+ result = HwNatMibGet(&args2);
+ break;
+#if defined CONFIG_COLGIN_SUPPORT
+ case HW_NAT_MIB_GET_ALL_IP:
+ args8=malloc(sizeof(struct hwnat_mib_all_ip_args));
+ if (NULL == args8)
+ {
+ printf(" Allocate memory for hwnat_mib_all_ip_args failed.\n");
+ close(fd);
+ return 0;
+ }
+ memset(args8, 0, sizeof(struct hwnat_mib_all_ip_args));
+ result = HwNatMibGetAllIP(args8);
+ dump_all_ip_cnt(args8);
+ free(args8);
+ break;
+#endif
+#endif
+ case HW_NAT_TBL_CLEAR:
+ result = HwNatTblClear();
+ break;
+#if defined (CONFIG_HW_NAT_IPI)
+ case HW_NAT_IPI_CTRL_FROM_EXTIF:
+ result = HwNatIPICtrlFromExtIf(&args6);
+ break;
+ case HW_NAT_IPI_CTRL_FROM_PPEHIT:
+ result = HwNatIPICtrlFromPPEHit(&args7);
+ break;
+#endif
+ case HW_NAT_DPORT:
+ result = HwNatDumpDport();
+ break;
+ case HW_NAT_INVALID_ENTRY:
+ result = HwNatInvalEntry(entry_num);
+ break;
+ case HW_NAT_CLEAR_HOOK:
+ result = HwNatHookModify(&args2, 1);
+ break;
+ case HW_NAT_RESTORE_HOOK:
+ result = HwNatHookModify(&args2, 0);
+ break;
+ default:
+ result = HWNAT_FAIL;
+
+ }
+
+ if(result==HWNAT_SUCCESS){
+ printf("done\n");
+ }else if(result==HWNAT_ENTRY_NOT_FOUND) {
+ printf("entry not found\n");
+ }else {
+ printf("fail\n");
+ }
+
+ free(args);
+ close(fd);
+ return 0;
+}
diff --git a/src/extended/hw_nat/hwnat_api.c b/src/extended/hw_nat/hwnat_api.c
new file mode 100644
index 0000000..1ce5b24
--- /dev/null
+++ b/src/extended/hw_nat/hwnat_api.c
@@ -0,0 +1,764 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <getopt.h>
+#ifndef CONFIG_SUPPORT_OPENWRT
+#include <linux/autoconf.h>
+#endif
+#if defined CONFIG_COLGIN_SUPPORT
+#include "hnat_ioctl.h"
+#else
+#include "hwnat_ioctl.h"
+#endif
+
+int HwNatInvalEntry(unsigned int entry_num)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ opt.entry_num=entry_num;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_INVALID_ENTRY, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatDumpDport(void)
+{
+ int fd;
+ struct hwnat_args opt;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+ if(ioctl(fd, HW_NAT_DPORT, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+#if defined (CONFIG_HW_NAT_IPI)
+int HwNatIPICtrlFromExtIf(struct hwnat_ipi_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_IPI_CTRL_FROM_EXTIF, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatIPICtrlFromPPEHit(struct hwnat_ipi_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_IPI_CTRL_FROM_PPEHIT, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+#endif
+
+int HwNatDelEntry(struct hwnat_tuple *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+ if(ioctl(fd, HW_NAT_DEL_ENTRY, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatAddEntry(struct hwnat_tuple *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_ADD_ENTRY, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatHookModify(struct hwnat_tuple *opt, int clear)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+ if(ioctl(fd, (clear == 1) ? HW_NAT_CLEAR_HOOK : HW_NAT_RESTORE_HOOK, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+
+
+#if defined (CONFIG_PPE_MIB)
+int HwNatMibDumpEntry(unsigned int entry_num)
+{
+ struct hwnat_mib_args opt;
+ int fd;
+ opt.entry_num=entry_num;
+ printf("!!!!!!!!HwNatMibDumpEntry\n");
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_MIB_DUMP, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+int HwNatMibDramDumpEntry(unsigned int entry_num)
+{
+ struct hwnat_mib_args opt;
+ int fd;
+
+ opt.entry_num=entry_num;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_MIB_DRAM_DUMP, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatMibGet(struct hwnat_tuple *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_MIB_GET, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+#if defined CONFIG_COLGIN_SUPPORT
+int HwNatMibGetAllIP(struct hwnat_mib_all_ip_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_MIB_GET_ALL_IP, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+#endif
+#endif
+
+int HwNatTblClear(void)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_TBL_CLEAR, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatDumpEntry(unsigned int entry_num)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ opt.entry_num=entry_num;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_DUMP_ENTRY, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatBindEntry(unsigned int entry_num)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ opt.entry_num=entry_num;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_BIND_ENTRY, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatUnBindEntry(unsigned int entry_num)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ opt.entry_num=entry_num;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_UNBIND_ENTRY, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatDropEntry(unsigned int entry_num)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ opt.entry_num=entry_num;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_DROP_ENTRY, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+
+
+int HwNatInvalidEntry(unsigned int entry_num)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ opt.entry_num=entry_num;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_INVALID_ENTRY, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatCacheDumpEntry(void)
+{
+
+ struct hwnat_args opt;
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+ if(ioctl(fd, HW_NAT_DUMP_CACHE_ENTRY, &opt)<0) {
+
+
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatGetAGCnt(struct hwnat_ac_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_GET_AC_CNT, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatSetBindThreshold(struct hwnat_config_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_BIND_THRESHOLD, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatSetMaxEntryRateLimit(struct hwnat_config_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_MAX_ENTRY_LMT, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+
+int HwNatSetRuleSize(struct hwnat_config_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_RULE_SIZE, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatSetKaInterval(struct hwnat_config_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_KA_INTERVAL, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatSetUnbindLifeTime(struct hwnat_config_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_UB_LIFETIME, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatSetBindLifeTime(struct hwnat_config_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_BIND_LIFETIME, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatSetVID(struct hwnat_config_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_VLAN_ID, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatSetBindDir(struct hwnat_config_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_BIND_DIRECTION, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatGetAllEntries(struct hwnat_args *opt)
+{
+ int fd=0;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_GET_ALL_ENTRIES, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+
+
+ return HWNAT_SUCCESS;
+
+}
+
+int HwNatDebug(unsigned int debug)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ opt.debug=debug;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_DEBUG, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+#if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621)
+int HwNatSwitchDsliteMape(unsigned int swit)
+{
+ struct hwnat_args opt;
+ int fd;
+
+ opt.swit=swit;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_SWITCH_DSL_MAPE, &opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+#endif
+
+#ifdef CONFIG_PPE_MCAST
+int HwNatMcastIns(struct hwnat_mcast_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_MCAST_INS, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatMcastDel(struct hwnat_mcast_args *opt)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_MCAST_DEL, opt)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+
+int HwNatMcastDump(void)
+{
+ int fd;
+
+ fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME);
+ return HWNAT_FAIL;
+ }
+
+ if(ioctl(fd, HW_NAT_MCAST_DUMP, NULL)<0) {
+ printf("HW_NAT_API: ioctl error\n");
+ close(fd);
+ return HWNAT_FAIL;
+ }
+
+ close(fd);
+ return HWNAT_SUCCESS;
+}
+#endif
diff --git a/src/extended/hw_nat/hwnat_api.h b/src/extended/hw_nat/hwnat_api.h
new file mode 100644
index 0000000..c816be4
--- /dev/null
+++ b/src/extended/hw_nat/hwnat_api.h
@@ -0,0 +1,62 @@
+#ifndef __HW_NAT_API
+#define __HW_NAT_API
+
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[3], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[0]
+#define NIPHALF(addr) \
+ ((unsigned short *)&addr)[1], \
+ ((unsigned short *)&addr)[0]
+
+int HwNatAddEntry(struct hwnat_tuple *opt);
+int HwNatDelEntry(struct hwnat_tuple *opt);
+int HwNatDumpEntry(unsigned int entry_num);
+int HwNatBindEntry(unsigned int entry_num);
+int HwNatUnBindEntry(unsigned int entry_num);
+int HwNatDropEntry(unsigned int entry_num);
+int HwNatInvalidEntry(unsigned int entry_num);
+int HwNatDscpRemarkEbl(struct hwnat_qos_args *opt);
+int HwNatVpriRemarkEbl(struct hwnat_qos_args *opt);
+int HwNatSetFoeWeight(struct hwnat_qos_args *opt);
+int HwNatSetAclWeight(struct hwnat_qos_args *opt);
+int HwNatSetDscpWeight(struct hwnat_qos_args *opt);
+int HwNatSetVpriWeight(struct hwnat_qos_args *opt);
+int HwNatSetDscp_Up(struct hwnat_qos_args *opt);
+int HwNatSetUp_InDscp(struct hwnat_qos_args *opt);
+int HwNatSetUp_OutDscp(struct hwnat_qos_args *opt);
+int HwNatSetUp_Vpri(struct hwnat_qos_args *opt);
+int HwNatSetUp_Ac(struct hwnat_qos_args *opt);
+int HwNatSetSchMode(struct hwnat_qos_args *opt);
+int HwNatSetSchWeight(struct hwnat_qos_args *opt);
+int HwNatSetBindThreshold(struct hwnat_config_args *opt);
+int HwNatSetMaxEntryRateLimit(struct hwnat_config_args *opt);
+int HwNatSetRuleSize(struct hwnat_config_args *opt);
+int HwNatSetKaInterval(struct hwnat_config_args *opt);
+int HwNatSetUnbindLifeTime(struct hwnat_config_args *opt);
+int HwNatSetBindLifeTime(struct hwnat_config_args *opt);
+int HwNatSetVID(struct hwnat_config_args *opt);
+int HwNatSetBindDir(struct hwnat_config_args *opt);
+int HwNatGetAllEntries(struct hwnat_args *opt);
+int HwNatDebug(unsigned int debug);
+int HwNatGetAGCnt(struct hwnat_ac_args *opt);
+#if defined (CONFIG_PPE_MCAST)
+int HwNatMcastIns(struct hwnat_mcast_args *opt);
+int HwNatMcastDel(struct hwnat_mcast_args *opt);
+int HwNatMcastDump(void);
+#endif
+#if defined (CONFIG_PPE_MIB)
+int HwNatMibDumpEntry(unsigned int entry_num);
+int HwNatMibGet(struct hwnat_tuple *opt);
+int HwNatMibDramDumpEntry(unsigned int entry_num);
+#if defined CONFIG_COLGIN_SUPPORT
+int HwNatMibGetAllIP(struct hwnat_mib_all_ip_args *opt);
+#endif
+#endif
+int HwNatTblClear(void);
+int HwNatCacheDumpEntry(void);
+int HwNatDumpDport(void);
+int HwNatInvalEntry(unsigned int entry_num);
+int HwNatHookModify(struct hwnat_tuple *opt, int clear);
+#endif
diff --git a/src/extended/hw_nat/mtr.c b/src/extended/hw_nat/mtr.c
new file mode 100644
index 0000000..089320e
--- /dev/null
+++ b/src/extended/hw_nat/mtr.c
@@ -0,0 +1,283 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <string.h>
+#ifndef CONFIG_SUPPORT_OPENWRT
+#include "linux/autoconf.h"
+#endif
+#include "mtr_ioctl.h"
+#include "mtr_api.h"
+
+
+void show_usage(void)
+{
+
+ printf("Add Mac Upload Meter Rule\n");
+ printf("mtr -a -m [Mac] -t [KB/s] -s [BucketSize:4K/8K/16K/32K or 0~127]\n");
+ printf(" -u [MtrIntval:1ms/10ms/50ms/100ms/500ms/1000ms/5000ms/10000ms] -v [Base:Byte/Pkt]\n");
+ printf("ByteBase:mtr -a -m 00:11:22:33:44:55 -t 10 -s 8K -v Byte\n\n");
+ printf("PktBase:mtr -a -m 00:11:22:33:44:55 -s 100 -u 1ms -v Pkt\n\n");
+
+ printf("Add Mac Download Meter Rule\n");
+ printf("mtr -b -m [Mac] -t [KB/s] -s [BucketSize:4K/8K/16K/32K or 0~127]\n");
+ printf(" -u [MtrIntval:1ms/10ms/50ms/100ms/500ms/1000ms/5000ms/10000ms] -v [Base:Byte/Pkt]\n");
+ printf("ByteBase: mtr -b -m 00:11:22:33:44:55 -t 10 -s 8K -v Byte\n\n");
+ printf("PktBase: mtr -b -m 00:11:22:33:44:55 -s 100 -u 1ms -v Pkt\n\n");
+ printf("Del Mac Upload Meter Rule\n");
+ printf("mtr -c -m [Mac]\n");
+ printf("Ex: mtr -c -m 00:11:22:33:44:55\n\n");
+
+ printf("Del Mac download Meter Rule\n");
+ printf("mtr -d -m [Mac]\n");
+ printf("Ex: mtr -d -m 00:11:22:33:44:55\n\n");
+
+
+ printf("Add IP Upload Meter Rule\n");
+ printf("mtr -e -i [IpS] -j [IpE] -t [KB/s] -s [BucketSize:4K/8K/16K/32K or 0~127]\n");
+ printf(" -u [MtrIntval:1ms/10ms/50ms/100ms/500ms/1000ms/5000ms/10000ms] -v [Base:Byte/Pkt]\n");
+ printf("ByteBase: mtr -e -i 10.10.10.3 -j 10.10.10.3 -t 10 -s 8K -v Byte\n\n");
+ printf("PktBase: mtr -e -i 10.10.10.3 -j 10.10.10.3 -s 100 -u 1ms -v Pkt\n\n");
+
+ printf("Add IP Download Meter Rule\n");
+ printf("mtr -f -i [IpS] -j [IpE] -t [KB/s] -s [BucketSize:4K/8K/16K/32K or 0~127] \n");
+ printf(" -u [MtrIntval:1ms/10ms/50ms/100ms/500ms/1000ms/5000ms/10000ms] -v [Base:Byte/Pkt]\n");
+ printf("ByteBase: mtr -f -i 10.10.10.3 -t 10 -s 8K -v Byte\n\n");
+ printf("PktBase: mtr -f -i 10.10.10.3 -j 10.10.10.3 -s 100 -u 50ms -v Pkt\n\n");
+
+ printf("Del IP Upload Meter Rule\n");
+ printf("mtr -g -i [IpS] -j [IpE]\n");
+ printf("mtr -g -i 10.10.10.3 -j 10.10.10.3\n\n");
+
+ printf("Del IP Download Meter Rule\n");
+ printf("mtr -h -i [IpS] -j [IpE]\n");
+ printf("mtr -h -i 10.10.10.3 -j 10.10.10.3\n\n");
+
+ printf("Clear Meter Table\n");
+ printf("mtr -z\n\n");
+
+ printf("Add SYN Meter Rule: mtr -k\n");
+ printf("Add FIN Meter Rule: mtr -l\n");
+ printf("Add UDP Meter Rule: mtr -n\n");
+ printf("Add ICMP Meter Rule: -o\n");
+ printf(" -t [KB/s] -s [BucketSize:4K/8K/16K/32K or 0~127]\n");
+ printf(" -u [MtrIntval:1ms/10ms/50ms/100ms/500ms/1000ms/5000ms/10000ms] -v [Base:Byte/Pkt]\n\n");
+ printf("Del SYN Meter Rule:mtr -p\n");
+ printf("Del FIN Meter Rule:mtr -q\n");
+ printf("Del UDP Meter Rule:mtr -r\n");
+ printf("Del ICMP Meter Rule:mtr -y\n\n");
+
+ printf("Get All Mtr Entries: mtr -w\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int opt;
+ char options[] = "abcdefghklnopqryz?m:i:j:t:s:u:v:w";
+
+ int fd;
+ int method=-1;
+ struct mtr_args args;
+ struct mtr_list_args *args2;
+ int result;
+ int i;
+
+ args2=malloc(sizeof(struct mtr_list_args) + sizeof(struct mtr_args)*511);
+ if (NULL == args2)
+ {
+ printf(" allocate memory for mtr_list_args and mtr_args failed.\n");
+ return 0;
+ }
+ fd = open("/dev/"MTR_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"MTR_DEVNAME);
+ free(args2);
+ return 0;
+ }
+
+ if(argc < 2) {
+ show_usage();
+ free(args2);
+ close(fd);
+ return 0;
+ }
+
+
+ while ((opt = getopt (argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'a':
+ method=MTR_ADD_MAC_UL_ENTRY;
+ break;
+ case 'b':
+ method=MTR_ADD_MAC_DL_ENTRY;
+ break;
+ case 'c':
+ method=MTR_DEL_MAC_UL_ENTRY;
+ break;
+ case 'd':
+ method=MTR_DEL_MAC_DL_ENTRY;
+ break;
+ case 'e':
+ method=MTR_ADD_IP_UL_ENTRY;
+ break;
+ case 'f':
+ method=MTR_ADD_IP_DL_ENTRY;
+ break;
+ case 'g':
+ method=MTR_DEL_IP_UL_ENTRY;
+ break;
+ case 'h':
+ method=MTR_DEL_IP_DL_ENTRY;
+ break;
+ case 'k':
+ method=MTR_ADD_SYN_ENTRY;
+ break;
+ case 'l':
+ method=MTR_ADD_FIN_ENTRY;
+ break;
+ case 'n':
+ method=MTR_ADD_UDP_ENTRY;
+ break;
+ case 'o':
+ method=MTR_ADD_ICMP_ENTRY;
+ break;
+ case 'p':
+ method=MTR_DEL_SYN_ENTRY;
+ break;
+ case 'q':
+ method=MTR_DEL_FIN_ENTRY;
+ break;
+ case 'r':
+ method=MTR_DEL_UDP_ENTRY;
+ break;
+ case 'y':
+ method=MTR_DEL_ICMP_ENTRY;
+ break;
+ case 'z': /* CleanTbl */
+ method=MTR_CLEAN_TBL;
+ break;
+ case 'm': /* Mac */
+ str_to_mac(args.mac, optarg);
+ break;
+ case 'i': /* IpS */
+ str_to_ip(&args.ip_s, optarg);
+ break;
+ case 'j': /* IpE */
+ str_to_ip(&args.ip_e, optarg);
+ break;
+ case 't': /* TokenRate */
+ args.token_rate=strtoll(optarg, NULL, 10);
+ break;
+ case 's': /* Bucket Size */
+ if(strcasecmp(optarg,"4K")==0){
+ args.bk_size=0;
+ }else if(strcasecmp(optarg,"8K")==0){
+ args.bk_size=1;
+ }else if(strcasecmp(optarg,"16K")==0){
+ args.bk_size=2;
+ }else if(strcasecmp(optarg,"32K")==0){
+ args.bk_size=3;
+ }else {
+ args.bk_size=strtoll(optarg, NULL, 10);
+ }
+ break;
+ case 'u':
+ if(strcasecmp(optarg,"1ms")==0){
+ args.mtr_intval=_1MS;
+ }else if(strcasecmp(optarg,"10ms")==0){
+ args.mtr_intval=_10MS;
+ }else if(strcasecmp(optarg,"50ms")==0){
+ args.mtr_intval=_50MS;
+ }else if(strcasecmp(optarg,"100ms")==0){
+ args.mtr_intval=_100MS;
+ }else if(strcasecmp(optarg,"500ms")==0){
+ args.mtr_intval=_500MS;
+ }else if(strcasecmp(optarg,"1000ms")==0){
+ args.mtr_intval=_1000MS;
+ }else if(strcasecmp(optarg,"5000ms")==0){
+ args.mtr_intval=_5000MS;
+ }else if(strcasecmp(optarg,"10000ms")==0){
+ args.mtr_intval=_10000MS;
+ }else {
+ printf("Error: -u 10ms/50ms/100ms/500ms/1000ms/5000ms/10000ms\n");
+ free(args2);
+ close(fd);
+ return 0;
+ }
+ break;
+ case 'v':
+ if(strcasecmp(optarg,"Byte")==0){
+ args.mtr_mode=0;
+ }else if(strcasecmp(optarg,"Pkt")==0){
+ args.mtr_mode=1;
+ }else {
+ printf("Error: -v Byte/Pkt\n");
+ free(args2);
+ close(fd);
+ return 0;
+ }
+ break;
+ case 'w':
+ method=MTR_GET_ALL_ENTRIES;
+ break;
+ case '?': /* Help */
+ show_usage();
+ break;
+ }
+ }
+
+ switch(method)
+ {
+ case MTR_ADD_MAC_UL_ENTRY:
+ case MTR_ADD_MAC_DL_ENTRY:
+ case MTR_DEL_MAC_UL_ENTRY:
+ case MTR_DEL_MAC_DL_ENTRY:
+ case MTR_ADD_IP_UL_ENTRY:
+ case MTR_ADD_IP_DL_ENTRY:
+ case MTR_DEL_IP_UL_ENTRY:
+ case MTR_DEL_IP_DL_ENTRY:
+ case MTR_CLEAN_TBL:
+ case MTR_ADD_SYN_ENTRY:
+ case MTR_ADD_FIN_ENTRY:
+ case MTR_ADD_UDP_ENTRY:
+ case MTR_ADD_ICMP_ENTRY:
+ case MTR_DEL_SYN_ENTRY:
+ case MTR_DEL_FIN_ENTRY:
+ case MTR_DEL_UDP_ENTRY:
+ case MTR_DEL_ICMP_ENTRY:
+ SetMtrEntry(&args, method);
+ result = args.result;
+ break;
+ case MTR_GET_ALL_ENTRIES:
+ MtrGetAllEntries(args2);
+ result = args2->result;
+
+ printf("Total Entry Count = %d\n",args2->num_of_entries);
+ for(i=0;i<args2->num_of_entries;i++){
+ printf("#%d :MAC=%02X:%02X:%02X:%02X:%02X:%02X\n", \
+ i, args2->entries[i].mac[0], args2->entries[i].mac[1], args2->entries[i].mac[2], \
+ args2->entries[i].mac[3], args2->entries[i].mac[4], args2->entries[i].mac[5]);
+ printf(" :SIP %u.%u.%u.%u->%u.%u.%u.%u\n\r", NIPQUAD(args2->entries[i].ip_s), NIPQUAD(args2->entries[i].ip_e));
+ printf(" :BucketSize=%d Token_Rate:%d MtrInterval=%d\n", args2->entries[i].bk_size, args2->entries[i].token_rate, args2->entries[i].mtr_intval);
+ }
+ break;
+ default:
+ result = MTR_FAIL;
+ }
+
+
+ if(result == MTR_TBL_FULL) {
+ printf("table full\n");
+ }else if(result == MTR_FAIL){
+ printf("fail\n");
+ }else{
+ printf("done\n");
+ }
+
+ free(args2);
+ close(fd);
+ return 0;
+}
diff --git a/src/extended/hw_nat/mtr_api.c b/src/extended/hw_nat/mtr_api.c
new file mode 100644
index 0000000..7923018
--- /dev/null
+++ b/src/extended/hw_nat/mtr_api.c
@@ -0,0 +1,52 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include "mtr_ioctl.h"
+
+int SetMtrEntry(struct mtr_args *opt, unsigned int cmd)
+{
+ int fd;
+
+ fd = open("/dev/"MTR_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"MTR_DEVNAME);
+ return MTR_FAIL;
+ }
+
+ if(ioctl(fd, cmd, opt)<0) {
+ printf("MTR_API: ioctl error\n");
+ close(fd);
+ return MTR_FAIL;
+ }
+
+ close(fd);
+ return MTR_SUCCESS;
+}
+
+int MtrGetAllEntries(struct mtr_list_args *opt)
+{
+ int fd=0;
+
+ fd = open("/dev/"MTR_DEVNAME, O_RDONLY);
+ if (fd < 0)
+ {
+ printf("Open %s pseudo device failed\n","/dev/"MTR_DEVNAME);
+ return MTR_FAIL;
+ }
+
+ if(ioctl(fd, MTR_GET_ALL_ENTRIES, opt)<0) {
+ printf("MTR_API: ioctl error\n");
+ close(fd);
+ return MTR_FAIL;
+ }
+
+ close(fd);
+
+ return MTR_SUCCESS;
+
+}
+
diff --git a/src/extended/hw_nat/mtr_api.h b/src/extended/hw_nat/mtr_api.h
new file mode 100644
index 0000000..dd3fbb9
--- /dev/null
+++ b/src/extended/hw_nat/mtr_api.h
@@ -0,0 +1,16 @@
+#ifndef __MTR_API
+#define __MTR_API
+
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[3], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[0]
+#define NIPHALF(addr) \
+ ((unsigned short *)&addr)[1], \
+ ((unsigned short *)&addr)[0]
+
+int SetMtrEntry(struct mtr_args *opt, unsigned int cmd);
+int MtrGetAllEntries(struct mtr_list_args *opt);
+
+#endif
diff --git a/src/extended/hw_nat/util.c b/src/extended/hw_nat/util.c
new file mode 100644
index 0000000..921b3a4
--- /dev/null
+++ b/src/extended/hw_nat/util.c
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <linux/fs.h>
+#include <sys/ioctl.h>
+
+int
+getnext (
+ char * src,
+ int separator,
+ char * dest
+ )
+{
+ char * c;
+ int len;
+
+ if ( (src == NULL) || (dest == NULL) ) {
+ return -1;
+ }
+
+ c = strchr(src, separator);
+ if (c == NULL) {
+ return -1;
+ }
+ len = c - src;
+ strncpy(dest, src, len);
+ dest[len] = '\0';
+ return len + 1;
+}
+
+int
+str_to_mac (
+ unsigned char * mac,
+ char * str
+ )
+{
+ int len;
+ char * ptr = str;
+ char buf[128];
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ if ((len = getnext(ptr, ':', buf)) == -1) {
+ return 1; /* parse error */
+ }
+ mac[i] = strtol(buf, NULL, 16);
+ ptr += len;
+ }
+ mac[5] = strtol(ptr, NULL, 16);
+
+ return 0;
+}
+
+int
+str_to_ip (
+ unsigned int * ip,
+ char * str
+ )
+{
+ int len;
+ char * ptr = str;
+ char buf[128];
+ unsigned char c[4];
+ int i;
+
+ for (i = 0; i < 3; ++i) {
+ if ((len = getnext(ptr, '.', buf)) == -1) {
+ return 1; /* parse error */
+ }
+ c[i] = atoi(buf);
+ ptr += len;
+ }
+ c[3] = atoi(ptr);
+ *ip = (c[0]<<24) + (c[1]<<16) + (c[2]<<8) + c[3];
+ return 0;
+}
+
+int
+str_to_ipv6 (
+ unsigned int * ipv6,
+ char * str,
+ unsigned int byte)
+{
+ int len;
+ char * ptr = str;
+ char buf[128];
+ unsigned short c[8];
+ int i;
+ for (i = 0; i < 7; i++) {
+
+ if ((len = getnext(ptr, ':', buf)) == -1) {
+ return 1; /* parse error */
+ }
+ c[i] = strtoul(buf, NULL, 16);
+ ptr += len;
+ //printf("len=%d, c[%d]=%x\n",len, i, c[i]);
+
+ }
+ c[7] = atoi(ptr);
+ *ipv6 = (c[2*byte] <<16) + (c[2*byte + 1]);
+ return 0;
+}
+
diff --git a/src/extended/hw_nat/util.h b/src/extended/hw_nat/util.h
new file mode 100644
index 0000000..aa57d19
--- /dev/null
+++ b/src/extended/hw_nat/util.h
@@ -0,0 +1,3 @@
+int str_to_mac (unsigned char *mac, char *str);
+int str_to_ip (unsigned int *ip, char *str);
+int str_to_ipv6 ( unsigned int * ipv6, char *str, unsigned int byte);