zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/app/zte_comm/zte_mainctrl/netdev_proc.c b/ap/app/zte_comm/zte_mainctrl/netdev_proc.c
new file mode 100755
index 0000000..003d88b
--- /dev/null
+++ b/ap/app/zte_comm/zte_mainctrl/netdev_proc.c
@@ -0,0 +1,2532 @@
+#include "zte_mainctrl.h"
+#include "netapi.h"
+#include <asm/unistd.h>
+
+#define IPV6_RA_FLAG_PD (1<<2)
+#define IPV6_RA_FLAG_MANAGED (1<<1)
+#define IPV6_RA_FLAG_OTHER_CONFIG (1<<0)
+
+char defwan_if_old[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+char defwan6_if_old[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+
+static const char g_dhcp_conf[]="start %s\nend %s\ninterface %s\noption subnet %s\noption dns %s %s\noption router %s\noption lease 86400\npidfile %s\nlease_file %s\n";
+static const char g_dns_conf[]="nameserver %s\r\n";
+static const char g_dhcp6_pd_conf[]="interface %s {\n\tserver-preference 255;\n\trenew-time 6000;\n\trebind-time 9000;\n\tprefer-life-time 1300;\n\tvalid-life-time 2000;\n\tallow rapid-commit;\n\tlink %s {\n\t\tallow unicast;\n\t\tsend unicast;\n\t\tprefix %s:/%d;\n\t};\n\toption dns_servers %s %s;\n};";
+static const char g_dhcp6_state_conf[]="interface %s {\n\tserver-preference 255;\n\trenew-time 6000;\n\trebind-time 9000;\n\tprefer-life-time 1300;\n\tvalid-life-time 2000;\n\tallow rapid-commit;\n\tlink %s {\n\t\tallow unicast;\n\t\tsend unicast;\n\t\tpool {\n\t\t\trange %s to %s/%d;\n\t\t};\n\t};\n\toption dns_servers %s %s;\n};";
+static const char g_dhcp6_stateless_conf[]="interface %s {\n\tlink %s {\n\t};\n\toption dns_servers %s %s;\n};";
+static const char g_radvd_state_conf[]="interface %s\n{\n\tAdvSendAdvert on;\n\tAdvManagedFlag on;\n};";
+static const char g_radvd_stateless_conf[]="interface %s\n{\n\tAdvSendAdvert on;\n\tAdvOtherConfigFlag on;\n\tMinRtrAdvInterval 30;\n\tMaxRtrAdvInterval 100;\n\n\tprefix %s/%d\n\t{\n\t\tAdvOnLink on;\n\t\tAdvAutonomous on;\n\t\tAdvRouterAddr off;\n\n\t\tAdvValidLifetime 300;\n\t\tAdvPreferredLifetime 120;\n\t};\n};";
+static const char g_radvd_autocfg_conf[]="interface %s\n{\n\tAdvSendAdvert on;\n\tAdvOtherConfigFlag off;\n\tMinRtrAdvInterval 30;\n\tMaxRtrAdvInterval 100;\n\n\tprefix %s/%d\n\t{\n\t\tAdvOnLink on;\n\t\tAdvAutonomous on;\n\t\tAdvRouterAddr off;\n\n\t\tAdvValidLifetime 300;\n\t\tAdvPreferredLifetime 120;\n\t};\n\tRDNSS %s %s\n\t{\n\t\tAdvRDNSSPreference 15;\n\t\tAdvRDNSSOpen on;\n\t};\n};";
+
+struct dhcp_conf_info {
+	char *start;
+	char *end;
+	char *interface;
+	char *subnet;
+	char *dns1;
+	char *dns2;
+	char *router;
+	char *pidfile;
+	char *lease_file;
+};
+
+struct dhcp6_conf_info {
+	char *interface;
+	char *link;
+	char *start;
+	char *end;
+	char *prefix;
+	int prefix_len;
+	char *dns1;
+	char *dns2;
+};
+
+struct radvd_conf_info {
+	char *interface;
+	char *prefix;
+	int prefix_len;
+	char *dns1;
+	char *dns2;
+};
+
+struct in6_ifreq {
+	struct in6_addr ifr6_addr;
+	unsigned int ifr6_prefixlen;
+	int ifr6_ifindex;
+};
+
+static void save_interface_id(char *nv_name, char * ip6)
+{
+
+	int i = 0;
+	char * postptr = NULL;
+	int ip6_seg = 0; //ipv6µØÖ·ÖÐðºÅµÄ¸öÊý
+	int ip6_seg_loc = 0;
+	int len;
+
+	len = strlen(ip6);
+
+	for (i = 0; i < len; i++) {
+		if (ip6[i] == ':') {
+			ip6_seg++;
+			if (ip6_seg == 4)
+				ip6_seg_loc = i;
+		}
+	}
+
+	if (ip6_seg == 3) //¼¤»îÐÅϢΪipv6ºó׺£¬²»ÐèÒª½Ø¶Ï
+		postptr = ip6;
+
+	else if (ip6_seg == 7) //¼¤»îÐÅϢΪipv6ǰ׺+ºó׺£¬ÐèÒª½Ø¶Ï´¦Àí
+		postptr = &ip6[ip6_seg_loc + 1];
+	else
+		softap_assert("ipv6 address %s is wrong!", ip6);
+
+	cfg_set(nv_name, postptr);
+}
+
+static inline void zxic_inet_pton(int af, const char *src, void *dst)
+{
+	if(inet_pton(af, src, dst) < 0)
+		slog(NET_PRINT, SLOG_ERR, "inet_pton fail, error:%s src:%s\n", strerror(errno), src);
+}
+
+static inline void zxic_inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
+{
+	if(inet_ntop(af, src, dst, cnt) == NULL)
+		slog(NET_PRINT, SLOG_ERR, "inet_ntop fail, error:%s\n", strerror(errno));
+}
+
+static inline void zxic_remove(char *filename)
+{
+	if(remove(filename) != 0)
+		slog(NET_PRINT, SLOG_ERR, "remove fail, error:%s file:%s\n", strerror(errno), filename);
+}
+
+int net_read_file(const char *path, void *vptr, size_t n)
+{
+	int fd;
+	size_t  nleft;
+	ssize_t nread;
+	char   *ptr;
+	if (path == NULL || vptr == NULL){
+		slog(NET_PRINT, SLOG_ERR, "net_read_file Input err %p %p\n", path, vptr);
+		return -1;
+	}
+	ptr = vptr;
+	nleft = n;
+	fd = open(path, O_RDONLY);
+	if (fd < 0){
+		slog(NET_PRINT, SLOG_ERR, "net_read_file Open fail, error:%s path:%s\n", strerror(errno), path);
+		return -1;
+	}
+	while (nleft > 0) {
+		nread = read(fd, ptr, nleft);
+		if (nread < 0) {
+			if (errno == EINTR){
+				nread = 0;      /* and call read() again */
+			}else{
+				slog(NET_PRINT, SLOG_ERR, "net_read_file fail, error:%s path:%s\n", strerror(errno), path);
+				close(fd);
+				return (-1);
+			}
+		} else if (nread == 0){
+			slog(NET_PRINT, SLOG_ERR, "Read NULL! path:%s\n", path);
+			break;              /* EOF */
+		}else{
+			nleft -= nread;
+			ptr += nread;
+		}
+	}
+	close(fd);
+	return (n - nleft);         /* return >= 0 */
+}
+
+int net_write_file(const char *path, const char *buf, int len)
+{
+	int fd;
+	size_t nleft;
+	ssize_t nwritten;
+	char *ptr;
+	int err_no;
+
+	if (path == NULL || buf == NULL){
+		slog(NET_PRINT, SLOG_ERR, "net_write_file Input err %p %p\n", path, buf);
+		return -1;
+	}
+	ptr = buf;
+	nleft = len;
+	// O_TRUNC:½«Îļþ³¤¶È½Ø¶ÏΪ0£¬×öΪÐÂÎļþдÈë
+	fd = open(path, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 777);
+	if (fd < 0){
+		slog(NET_PRINT, SLOG_ERR, "net_write_file Open fail, error:%s, path:%s\n", strerror(errno), path);
+		return -1;
+	}
+	while (nleft > 0){
+		if ( (nwritten = write(fd, ptr, nleft)) <= 0){
+			err_no = errno;
+			if (nwritten < 0 && err_no == EINTR){
+				nwritten = 0;	/* and call write() again */
+			}else{
+				slog(NET_PRINT, SLOG_ERR, "net_write_file fail, error:%s, left=%d path:%s\n", strerror(err_no), nleft, path);
+				close(fd);
+				return -1;
+			}
+		}
+		nleft -= nwritten;
+		ptr += nwritten;
+	}
+	if (fsync(fd) < 0) {
+		slog(NET_PRINT, SLOG_ERR, "net_write_file Sync fail:%s, path:%s\n", strerror(errno), path);
+		close(fd);
+		return -1;
+	}
+	close(fd);
+	return len;
+}
+
+static void kill_pid_by_nv(char *nv_name)
+{
+	char pid_s[16] = {0};
+	pid_t pid = 0;
+	
+	cfg_get_item(nv_name, pid_s, sizeof(pid_s));
+	pid = atoi(pid_s);
+	if(pid > 0)
+	{
+		slog(NET_PRINT, SLOG_NORMAL, "kill %s pid=%d \n", nv_name, pid);
+		kill(pid, SIGKILL);
+	}
+	cfg_set(nv_name, "");
+}
+
+static void kill_pid_by_path(char *path)
+{
+	char pid_s[16] = {0};
+	pid_t pid = 0;
+	
+	if(access(path, F_OK))
+		return;
+	if(net_read_file(path, pid_s, sizeof(pid_s)-1) > 0){
+		pid = atoi(pid_s);
+		if(pid > 0)
+		{
+			slog(NET_PRINT, SLOG_NORMAL, "kill udhcpd pid=%d \n", pid);
+			kill(pid, SIGKILL);
+		}
+		zxic_remove(path);
+	}
+}
+
+static void arp_down(int cid)
+{
+	char nv_name[32] = {0};
+	
+	snprintf(nv_name, sizeof(nv_name), "br%d_arp_pid", cid);
+	kill_pid_by_nv(nv_name);
+}
+
+static void dhcp_down(int cid)
+{
+	char path_conf[16] = {0};
+	char path[32] = {0};
+	
+	cfg_get_item("path_conf", path_conf, sizeof(path_conf));
+	snprintf(path, sizeof(path), "%s/udhcpd%d.pid", path_conf, cid);
+	kill_pid_by_path(path);
+}
+
+static void ndp_down(int cid)
+{
+	char nv_name[32] = {0};
+	
+	snprintf(nv_name, sizeof(nv_name), "br%d_ndp_pid", cid);
+	kill_pid_by_nv(nv_name);
+}
+
+static void dhcp6s_down(int cid)
+{
+	char nv_name[32] = {0};
+	
+	snprintf(nv_name, sizeof(nv_name), "br%d_dhcp6s_pid", cid);
+	kill_pid_by_nv(nv_name);
+}
+
+static void radvd_down(int cid)
+{
+	char path_tmp[16] = {0};
+	char path[32] = {0};
+	
+	cfg_get_item("path_tmp", path_tmp, sizeof(path_tmp));
+	snprintf(path, sizeof(path), "%s/radvd%d.pid", path_tmp, cid);
+	kill_pid_by_path(path);
+}
+
+static int config_udhcpd(const char *path, struct dhcp_conf_info *info)
+{
+	char buf[512] = {0};
+	int buf_len = 0;
+
+	if (path == NULL || info == NULL){
+		slog(NET_PRINT, SLOG_ERR, "config_udhcpd Input err %p %p\n", path, info);
+		return -1;
+	}
+	buf_len = snprintf(buf, sizeof(buf), g_dhcp_conf, info->start, info->end, info->interface, 
+		info->subnet, info->dns1, info->dns2, info->router, info->pidfile, info->lease_file);
+	if(buf_len <= 0 || buf_len != strlen(buf)){
+		slog(NET_PRINT, SLOG_ERR, "config_udhcpd snprintf err ret=%d cur=%d\n", buf_len, strlen(buf));
+		return -1;
+	}
+	return net_write_file(path, buf, strlen(buf));
+}
+
+static int config_dns(const char *path, const char *dns1, const char *dns2)
+{
+	char buf[512] = {0};
+	char *pbuf = buf;
+	int ret = 0;
+
+	if (path == NULL || (dns1 == NULL && dns2 == NULL)){
+		slog(NET_PRINT, SLOG_ERR, "config_dns Input err\n");
+		return -1;
+	}
+	ret = net_read_file(path, buf, sizeof(buf)-1);
+	if(ret > 0 && ret < (sizeof(buf) >> 1)){
+		pbuf = pbuf + strlen(pbuf);
+	}
+	else
+		slog(NET_PRINT, SLOG_ERR, "config_dns read err ret=%d\n",ret);
+	if(dns1 != NULL && strlen(dns1) > 6){
+		snprintf(pbuf, sizeof(buf), g_dns_conf, dns1);
+		pbuf = pbuf + strlen(pbuf);
+	}
+	if(dns2 != NULL && strlen(dns2) > 6){
+		snprintf(pbuf, sizeof(buf)-strlen(buf), g_dns_conf, dns2);
+	}
+	if(strlen(buf) > 0)
+		return net_write_file(path, buf, strlen(buf));
+	return 0;
+}
+
+/*¼¤»îIPµÄ×îºóÒ»¸öÊý×ÖµÄ2½øÖƵĺó3λÊÇ010 001 000ʱ+2£¬·ñÔò-2*/
+FILE *pdp_direct_config_quick4(const char *nv_pswan, struct pdp_active_info *actinfo)
+{
+	int i = 0;
+	unsigned int addr = 0;
+	unsigned int dns1 = 0;
+	unsigned int dns2 = 0;
+	unsigned int route_ip = 0;
+	unsigned int wan_ip = 0;
+	unsigned int netmask = 0;
+	char dns1_s[IPV4ADDLEN_MAX] = {0};
+	char dns2_s[IPV4ADDLEN_MAX] = {0};
+	char route_ip_s[IPV4ADDLEN_MAX] = {0};
+	char wan_ip_s[IPV4ADDLEN_MAX] = {0};
+	char netmask_s[IPV4ADDLEN_MAX] = {0};
+	char path_conf[16] = {0};
+	char dev[16] = {0};
+	char pidfile[32] = {0};
+	char lease_file[32] = {0};
+	char path[32] = {0};
+	char cmd[64] = {0};
+	char nv_name[NV_NAME_LEN] = {0};
+	struct dhcp_conf_info info = {0};
+	
+	cfg_get_item("path_conf", path_conf, sizeof(path_conf));
+	snprintf(dev, sizeof(dev), "br%d", actinfo->c_id);
+	snprintf(pidfile, sizeof(pidfile), "%s/udhcpd%d.pid", path_conf, actinfo->c_id);
+	snprintf(lease_file, sizeof(lease_file), "%s/udhcpd%d.leases", path_conf, actinfo->c_id);
+	snprintf(path, sizeof(path), "%s/udhcpd%d.conf", path_conf, actinfo->c_id);
+	zxic_inet_pton(AF_INET, actinfo->act_info.ip, &addr);
+	zxic_inet_pton(AF_INET, actinfo->act_info.pri_dns, &dns1);
+	zxic_inet_pton(AF_INET, actinfo->act_info.sec_dns, &dns2);
+	addr = htonl(addr);
+	if(dns1)
+		snprintf(dns1_s, sizeof(dns1_s), "%s", actinfo->act_info.pri_dns);
+	else
+		snprintf(dns1_s, sizeof(dns1_s), "%s", "114.114.114.114");
+	if(dns2)
+		snprintf(dns2_s, sizeof(dns2_s), "%s", actinfo->act_info.sec_dns);
+	else
+		snprintf(dns2_s, sizeof(dns2_s), "%s", "8.8.8.8");
+
+#if 0 //btrunk
+	netmask = 0xffff0000;
+	if((addr&0xff) <= 1){
+		route_ip = addr+2;
+		wan_ip = addr+1;
+	}
+	else if((addr&0xff) >= 254){
+		route_ip = addr-2;
+		wan_ip = addr-1;
+	}else{
+		route_ip = addr+1;
+		wan_ip = addr-1;
+	}
+#else
+	if((addr&7) < 3){
+		route_ip = addr+2;
+		wan_ip = addr+1;
+	}else{
+		route_ip = addr-2;
+		wan_ip = addr-1;
+	}
+	for(i = 3; i < 32; i++){
+		/*²»ÊÇÁ¬ÐøµÄÈ«0 && ²»ÊÇÁ¬ÐøµÄÈ«1*/
+		if(((addr>>i)<<i) != addr && (((1<<i)-1)|addr) != addr)
+			break;
+	}
+	netmask = 0xfffffff8;
+	if(i > 3 && i < 32)//cov
+		netmask = ((netmask>>i)<<i);
+#endif
+	route_ip = htonl(route_ip);
+	wan_ip = htonl(wan_ip);
+	netmask = htonl(netmask);
+	inet_ntop(AF_INET, (void *)&route_ip, route_ip_s, IPV4ADDLEN_MAX);
+	inet_ntop(AF_INET, (void *)&wan_ip, wan_ip_s, IPV4ADDLEN_MAX);
+	inet_ntop(AF_INET, (void *)&netmask, netmask_s, IPV4ADDLEN_MAX);
+	snprintf(nv_name, sizeof(nv_name), "%s%d_pdp_ip", nv_pswan, actinfo->c_id);
+	cfg_set(nv_name, actinfo->act_info.ip);
+	snprintf(nv_name, sizeof(nv_name), "%s%d_ip", nv_pswan, actinfo->c_id);
+	cfg_set(nv_name, wan_ip_s);
+	snprintf(nv_name, sizeof(nv_name), "br%d_ip", actinfo->c_id);
+	cfg_set(nv_name, route_ip_s);
+	snprintf(nv_name, sizeof(nv_name), "br%d_nm", actinfo->c_id);//for mbim
+	cfg_set(nv_name, netmask_s);
+	snprintf(nv_name, sizeof(nv_name), "%s%d_pridns", nv_pswan, actinfo->c_id);
+	cfg_set(nv_name, dns1_s);
+	snprintf(nv_name, sizeof(nv_name), "%s%d_secdns", nv_pswan, actinfo->c_id);
+	cfg_set(nv_name, dns2_s);
+	
+	info.start = actinfo->act_info.ip;
+	info.end = actinfo->act_info.ip;
+	info.interface = dev;
+	info.subnet = netmask_s;
+	info.dns1 = dns1_s;
+	info.dns2 = dns2_s;
+	info.router = route_ip_s;
+	info.pidfile = pidfile;
+	info.lease_file = lease_file;
+	if(config_udhcpd(path, &info) < 0)
+		return NULL;
+	if(config_dns("/etc/resolv.conf", dns1_s, dns2_s) < 0)
+		return NULL;
+	snprintf(cmd, sizeof(cmd), "psext_up.sh %d", actinfo->c_id);
+	dhcp_down(actinfo->c_id);
+	return popen(cmd, "r");
+}
+
+static int config_dhcp6s(const char *path, struct dhcp6_conf_info *info, int M_O_flag)
+{
+	char buf[1024] = {0};
+	int buf_len = 0;;
+
+	if (path == NULL || info == NULL){
+		slog(NET_PRINT, SLOG_ERR, "config_dhcpd6s Input err %p %p\n", path, info);
+		return -1;
+	}
+	if(M_O_flag & IPV6_RA_FLAG_PD){
+		buf_len = snprintf(buf, sizeof(buf), g_dhcp6_pd_conf, info->interface, info->link, info->prefix, 
+			info->prefix_len, info->dns1, info->dns2);
+	}else if(M_O_flag & IPV6_RA_FLAG_MANAGED){
+		buf_len = snprintf(buf, sizeof(buf), g_dhcp6_state_conf, info->interface, info->link, info->start, 
+			info->end, info->prefix_len, info->dns1, info->dns2);
+	}else if(M_O_flag & IPV6_RA_FLAG_OTHER_CONFIG){
+		buf_len = snprintf(buf, sizeof(buf), g_dhcp6_stateless_conf, info->interface, info->link,
+			info->dns1, info->dns2);
+	}else{
+		slog(NET_PRINT, SLOG_ERR, "config_dhcpd6s err m=0 o=0\n");
+		return 0;
+	}
+	if(buf_len <= 0 || buf_len != strlen(buf)){
+		slog(NET_PRINT, SLOG_ERR, "config_dhcpd6s snprintf err ret=%d cur=%d\n", buf_len, strlen(buf));
+		return -1;
+	}
+	return net_write_file(path, buf, strlen(buf));
+}
+
+static int config_radvd(const char *path, struct radvd_conf_info *info, int M_O_flag)
+{
+	char buf[1024] = {0};
+	int buf_len;
+
+	if (path == NULL || info == NULL){
+		slog(NET_PRINT, SLOG_ERR, "config_radvd Input err %p %p\n", path, info);
+		return -1;
+	}
+	if((M_O_flag & IPV6_RA_FLAG_MANAGED) || (M_O_flag & IPV6_RA_FLAG_PD)){
+		buf_len = snprintf(buf, sizeof(buf), g_radvd_state_conf, info->interface);
+	}else if(M_O_flag & IPV6_RA_FLAG_OTHER_CONFIG){
+		buf_len = snprintf(buf, sizeof(buf), g_radvd_stateless_conf, info->interface, info->prefix, info->prefix_len);
+	}else{
+		buf_len = snprintf(buf, sizeof(buf), g_radvd_autocfg_conf, info->interface, info->prefix, info->prefix_len,
+			info->dns1, info->dns2);
+	}
+	if(buf_len <= 0 || buf_len != strlen(buf)){
+		slog(NET_PRINT, SLOG_ERR, "config_radvd snprintf err ret=%d cur=%d\n", buf_len, strlen(buf));
+		return -1;
+	}
+	return net_write_file(path, buf, strlen(buf));
+}
+
+FILE *pdp_direct_config_quick6(const char *nv_pswan, struct pdp_active_info *actinfo, char *prefix, int prefix_len)
+{
+	char cmd[100] = {0};
+	char nv_pridns6[NV_NAME_LEN] = {0};
+	char nv_secdns6[NV_NAME_LEN] = {0};
+	char nv_ip6[NV_NAME_LEN] = {0};
+	snprintf(nv_ip6, sizeof(nv_ip6), "%s%d_ipv6_interface_id", nv_pswan, actinfo->c_id);
+	save_interface_id(nv_ip6, actinfo->act_info.ip6);
+	snprintf(nv_pridns6, sizeof(nv_pridns6), "%s%d_ipv6_pridns_auto", nv_pswan, actinfo->c_id);
+	cfg_set(nv_pridns6, actinfo->act_info.pri_dns6);
+	snprintf(nv_secdns6, sizeof(nv_secdns6), "%s%d_ipv6_secdns_auto", nv_pswan, actinfo->c_id);
+	cfg_set(nv_secdns6, actinfo->act_info.sec_dns6);
+	slog(NET_PRINT, SLOG_NORMAL, "pdp_quick6 prefix=%s len=%d \n", prefix, prefix_len);
+	if(prefix_len > 0)
+	{
+		char nv_name[NV_NAME_LEN] = {0};
+		struct in6_addr ipv6_addr = {0};
+		char br_ip6[IPV6ADDLEN_MAX] = {0};
+		char wan_ip6[IPV6ADDLEN_MAX] = {0};
+		char pdp_ip6[IPV6ADDLEN_MAX] = {0};
+		int M_O_flag = 0;
+		char PdFlag[4] = {0};
+		char AdvManagedFlag[4] = {0};
+		char AdvOtherConfigFlag[4] = {0};
+		struct dhcp6_conf_info dhcp6_info = {0};
+		struct radvd_conf_info radvd_info = {0};
+		char path_conf[16] = {0};
+		char dev[16] = {0};
+		char dhcp6_path[32] = {0};
+		char radvd_path[32] = {0};
+		
+		snprintf(nv_name, sizeof(nv_name), "%s%d_ipv6_local", nv_pswan, actinfo->c_id);
+		cfg_get_item(nv_ip6, cmd, sizeof(cmd));
+		snprintf(pdp_ip6, sizeof(pdp_ip6), "fe80::%s", cmd);
+		cfg_set(nv_name, pdp_ip6);//actinfo->act_info.ip6
+		memcpy(pdp_ip6, actinfo->act_info.ip6, IPV6ADDLEN_MAX -1);
+		if((prefix_len/16)*5 < IPV6ADDLEN_MAX)//kw
+			memcpy(pdp_ip6, prefix, (prefix_len/16)*5);
+		pdp_ip6[IPV6ADDLEN_MAX-1]='\0';//kw
+		snprintf(nv_name, sizeof(nv_name), "%s%d_ipv6_pdp", nv_pswan, actinfo->c_id);
+		cfg_set(nv_name, pdp_ip6);
+		snprintf(nv_name, sizeof(nv_name), "%s%d_dhcpv6_end", nv_pswan, actinfo->c_id);//for mbim
+		cfg_set(nv_name, pdp_ip6);
+		zxic_inet_pton(AF_INET6, pdp_ip6, &ipv6_addr);
+		ipv6_addr.s6_addr[14]++;
+		zxic_inet_ntop(AF_INET6, &ipv6_addr, br_ip6, sizeof(br_ip6));
+		snprintf(nv_name, sizeof(nv_name), "br%d_ipv6_ip", actinfo->c_id);
+		cfg_set(nv_name, br_ip6);
+		ipv6_addr.s6_addr[14]++;
+		zxic_inet_ntop(AF_INET6, &ipv6_addr, wan_ip6, sizeof(wan_ip6));
+		snprintf(nv_name, sizeof(nv_name), "%s%d_ipv6_ip", nv_pswan, actinfo->c_id);
+		cfg_set(nv_name, wan_ip6);
+		snprintf(dev, sizeof(dev), "br%d", actinfo->c_id);
+		cfg_get_item("path_conf", path_conf, sizeof(path_conf));
+		snprintf(dhcp6_path, sizeof(dhcp6_path), "%s/dhcp6s%d.conf", path_conf, actinfo->c_id);
+		snprintf(radvd_path, sizeof(radvd_path), "%s/radvd%d.conf", path_conf, actinfo->c_id);
+		cfg_get_item("dhcpv6statePdEnabled", PdFlag, sizeof(PdFlag));
+		cfg_get_item("dhcpv6stateEnabled", AdvManagedFlag, sizeof(AdvManagedFlag));
+		cfg_get_item("dhcpv6statelessEnabled", AdvOtherConfigFlag, sizeof(AdvOtherConfigFlag));
+		if(atoi(PdFlag) == 1)
+			M_O_flag = M_O_flag|IPV6_RA_FLAG_PD;
+		if(atoi(AdvManagedFlag) == 1)
+			M_O_flag = M_O_flag|IPV6_RA_FLAG_MANAGED;
+		if(atoi(AdvOtherConfigFlag) == 1)
+			M_O_flag = M_O_flag|IPV6_RA_FLAG_OTHER_CONFIG;
+		dhcp6_info.interface = dev;
+		dhcp6_info.link = dev;
+		dhcp6_info.start = pdp_ip6;
+		dhcp6_info.end = pdp_ip6;
+		dhcp6_info.prefix = prefix;
+		dhcp6_info.prefix_len = prefix_len;
+		dhcp6_info.dns1 = actinfo->act_info.pri_dns6;
+		dhcp6_info.dns2 = actinfo->act_info.sec_dns6;
+		if(config_dhcp6s(dhcp6_path, &dhcp6_info, M_O_flag) < 0)
+			return NULL;
+		radvd_info.interface = dev;
+		radvd_info.prefix = br_ip6;
+		radvd_info.prefix_len = prefix_len;
+		radvd_info.dns1 = actinfo->act_info.pri_dns6;
+		radvd_info.dns2 = actinfo->act_info.sec_dns6;
+		if(config_radvd(radvd_path, &radvd_info, M_O_flag) < 0)
+			return NULL;
+		if(config_dns("/etc/resolv.conf", actinfo->act_info.pri_dns6, actinfo->act_info.sec_dns6) < 0)
+			return NULL;
+		snprintf(cmd, sizeof(cmd), "psext_up_ipv6.sh %d", actinfo->c_id);
+		dhcp6s_down(actinfo->c_id);
+		return popen(cmd, "r");
+	}else{
+		sprintf(cmd, "psext_updown_ipv6.sh linkup %d", actinfo->c_id);
+		return popen(cmd, "r");
+	}
+}
+
+void pdp_direct_config_quick(struct pdp_active_info *actinfo, char *prefix, int prefix_len)
+{
+	FILE *fpv4 = NULL;
+	FILE *fpv6 = NULL;
+
+	zxic_remove("/etc_rw/resolv.conf");
+	
+	if (actinfo->act_info.ip46flag == V4_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		fpv4 = pdp_direct_config_quick4(ps_wan, actinfo);
+		slog(NET_PRINT, SLOG_NORMAL, "psext_up4 popen=%p \n", fpv4);
+	}
+
+	if (actinfo->act_info.ip46flag == V6_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		fpv6 = pdp_direct_config_quick6(ps_wan, actinfo, prefix, prefix_len);
+		slog(NET_PRINT, SLOG_NORMAL, "psext_up6 popen=%p \n", fpv6);
+	}
+	if(fpv4 != NULL)
+		pclose(fpv4);
+	if(fpv6 != NULL)
+		pclose(fpv6);
+}
+
+void net_br_deact_quick(int c_id, unsigned char ip46flag)
+{
+	FILE *fpv4 = NULL;
+	FILE *fpv6 = NULL;
+	char cmd[64] = {0};
+	
+	if (ip46flag == V4_VALID || ip46flag == V46_VALID) {
+		sprintf(cmd, "psext_down.sh %d", c_id);
+		fpv4 = popen(cmd, "r");
+		arp_down(c_id);
+		dhcp_down(c_id);
+	}
+	if (ip46flag == V6_VALID || ip46flag == V46_VALID) {
+		memset(cmd, 0, sizeof(cmd));
+		sprintf(cmd, "psext_down_ipv6.sh %d", c_id);
+		fpv6 = popen(cmd, "r");
+		radvd_down(c_id);
+		dhcp6s_down(c_id);
+		ndp_down(c_id);
+	}
+	net_write_file("/etc/resolv.conf", "", 0);
+	if(fpv4 != NULL)
+		pclose(fpv4);
+	if(fpv6 != NULL)
+		pclose(fpv6);
+}
+
+void net_sendmsg_2_atctl(int cid, int iptype, int cmd)
+{
+	int ret = -1;
+	TScriptMSG scriptmsg;
+	memset(&scriptmsg, 0, sizeof(TScriptMSG));
+	scriptmsg.cid = cid;
+	scriptmsg.iptype = iptype;
+	char buffer[128] = {0};
+	
+	slog(NET_PRINT, SLOG_NORMAL, "$$$$$net_sendmsg_2_atctl cid=%d,iptype=%d\n", cid, iptype);
+	ret = ipc_send_message(MODULE_ID_MAIN_CTRL, MODULE_ID_AT_CTL, cmd, sizeof(TScriptMSG), &scriptmsg, 0); 
+	if (0 != ret) {
+		softap_assert("send msg to at_ctl error");		
+	}
+	snprintf(buffer, sizeof(buffer), "pdp_act_state_%d", cid);
+	if(cmd == MSG_CMD_LINKUP_END)
+		cfg_set(buffer, "act");
+	else if(cmd == MSG_CMD_LINKDOWN_END)
+		cfg_set(buffer, "deact");
+}
+
+void pdp_wan_config_quick(struct pdp_active_info *actinfo, char *prefix, int prefix_len)
+{
+	int flag = 0;
+	struct in6_addr ipv6_addr = {0};
+	char wan_name[NV_NAME_LEN] = {0};
+	char br_ip6[IPV6ADDLEN_MAX] = {0};
+	char pdp_ip6[IPV6ADDLEN_MAX] = {0};
+	char dhcp_ip6_start[IPV6ADDLEN_MAX] = {0};
+	char dhcp_ip6_end[IPV6ADDLEN_MAX] = {0};
+	char tc_enable[4] = {0};
+	char buffer[128] = {0};
+	char mtu[16] = {0};
+	char xlat_enable[4] = {0};
+	
+	cfg_get_item("tc_enable", tc_enable, sizeof(tc_enable));
+	snprintf(wan_name,NV_NAME_LEN,	"%s%d", ps_wan, actinfo->c_id);
+	slog(NET_PRINT, SLOG_NORMAL, "act ifconfig wanname:%s!\n", wan_name);
+
+	//ifconfig wan down
+	snprintf(buffer, sizeof(buffer), "ifconfig %s down", wan_name);
+	system_cmd_ex(buffer);
+	//ifconfig mtu
+	cfg_get_item("mtu", mtu, sizeof(mtu));
+	snprintf(buffer, sizeof(buffer), "ifconfig %s mtu %s", wan_name, mtu);
+	system_cmd_ex(buffer);
+	//ifconfig ip
+	if(actinfo->act_info.ip46flag & V4_VALID){
+		snprintf(buffer, sizeof(buffer), "%s_ip", wan_name);
+		cfg_set(buffer, actinfo->act_info.ip);
+		snprintf(buffer, sizeof(buffer), "%s_gw", wan_name);
+		cfg_set(buffer, actinfo->act_info.ip);
+		snprintf(buffer, sizeof(buffer), "%s_pridns", wan_name);
+		cfg_set(buffer, actinfo->act_info.pri_dns);
+		snprintf(buffer, sizeof(buffer), "%s_secdns", wan_name);
+		cfg_set(buffer, actinfo->act_info.sec_dns);
+		snprintf(buffer, sizeof(buffer), "ifconfig %s %s netmask 255.255.255.0", wan_name, actinfo->act_info.ip);
+		system_cmd_ex(buffer);
+	}
+	//ifconfig up
+	snprintf(buffer, sizeof(buffer), "ifconfig %s up", wan_name);
+	system_cmd_ex(buffer);
+	//ifconfig ipv6
+	if(actinfo->act_info.ip46flag & V6_VALID){
+		snprintf(buffer, sizeof(buffer), "%s_ipv6_interface_id", wan_name);
+		save_interface_id(buffer, actinfo->act_info.ip6);
+		snprintf(buffer, sizeof(buffer), "%s_ipv6_pridns_auto", wan_name);
+		cfg_set(buffer, actinfo->act_info.pri_dns6);
+		snprintf(buffer, sizeof(buffer), "%s_ipv6_secdns_auto", wan_name);
+		cfg_set(buffer, actinfo->act_info.sec_dns6);
+		memcpy(pdp_ip6, actinfo->act_info.ip6, IPV6ADDLEN_MAX -1);
+		if((prefix_len/16)*5 < IPV6ADDLEN_MAX)//kw
+			memcpy(pdp_ip6, prefix, (prefix_len/16)*5);
+		pdp_ip6[IPV6ADDLEN_MAX-1]='\0';//kw
+		snprintf(buffer, sizeof(buffer), "ifconfig %s %s/126", wan_name, pdp_ip6);
+		system_cmd_ex(buffer);
+		snprintf(buffer, sizeof(buffer), "%s_ipv6_ip", wan_name);
+		cfg_set(buffer, pdp_ip6);
+		zxic_inet_pton(AF_INET6, pdp_ip6, &ipv6_addr);
+		ipv6_addr.s6_addr[14]++;
+		zxic_inet_ntop(AF_INET6, &ipv6_addr, br_ip6, sizeof(br_ip6));
+		ipv6_addr.s6_addr[14]++;
+		if (0xFF == ipv6_addr.s6_addr[14]) {
+			ipv6_addr.s6_addr[14] = 0;
+		}
+		zxic_inet_ntop(AF_INET6, &ipv6_addr, dhcp_ip6_start, sizeof(dhcp_ip6_start));
+		ipv6_addr.s6_addr[14]++;
+		zxic_inet_ntop(AF_INET6, &ipv6_addr, dhcp_ip6_end, sizeof(dhcp_ip6_end));
+	}
+	{
+		char path[32] = {0};
+		char path_tmp[32] = {0};
+		char dns_path[64] = {0};
+		char wan_pri[32] = {0};
+		char lan_if[16] = {0};
+		int defwan_pri = 0;
+		int pri = 0;
+		char defwan_if[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+		char defwan_real[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+		char defwan_dev_name[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+		int defwan4_change = 0;
+		int defwan6_change = 0;
+		struct default_dev_info defwan_dev_info = {0};
+		
+		cfg_get_item("lan_name", lan_if, sizeof(lan_if));
+		cfg_get_item("path_conf", path, sizeof(path));
+		cfg_get_item("path_tmp", path_tmp, sizeof(path_tmp));
+		defwan_dev_info.ip46flag = actinfo->act_info.ip46flag;
+		cfg_get_item("pswan_priority", wan_pri, sizeof(wan_pri));
+		pri = atoi(wan_pri);
+		if(pri < 0 || pri > 65535)
+			return;
+		if (actinfo->pdp_type == PDP_NORMAL) {
+			if(default_route_check()){
+				cfg_get_item("default_wan_name", defwan_if, sizeof(defwan_if));
+				if(strncmp(defwan_if, wifi_wan, strlen(wifi_wan)) == 0){
+					cfg_get_item("wifiwan_priority", wan_pri, sizeof(wan_pri));
+					defwan_pri = atoi(wan_pri);
+					strcpy(defwan_dev_name, wifi_wan);
+				}
+				else if (strncmp(defwan_if, eth_wan, strlen(eth_wan)) == 0){
+					cfg_get_item("ethwan_priority", wan_pri, sizeof(wan_pri));
+					defwan_pri = atoi(wan_pri);
+					strcpy(defwan_dev_name, eth_wan);
+				}
+			}
+			if (pri > defwan_pri) {
+				defwan_pri = pri;
+				snprintf(defwan_if, sizeof(defwan_if), "%s%d", ps_wan, actinfo->c_id);
+				strcpy(defwan_real, defwan_if);
+				strcpy(defwan_dev_name, ps_wan);
+				//½«µ±Ç°ÓÐÐ§Íø¿ÚÖÐÓÅÏȼ¶×î¸ßµÄÉèÖÃΪȱʡÍâÍø¿Ú
+				if(actinfo->act_info.ip46flag & V4_VALID){
+					cfg_set("default_wan_name", defwan_if);
+					cfg_set("default_wan_rel", defwan_real);
+				}
+				if(actinfo->act_info.ip46flag & V6_VALID){
+					cfg_set("default_wan6_name", defwan_if);
+					cfg_set("default_wan6_rel", defwan_real);
+				}
+			}
+			defwan_dev_info.dev_id = getDevId_byname(defwan_dev_name);
+			net_default_wan_proc(&defwan_dev_info);
+		} else {
+			int rt_num = pri*10 + actinfo->c_id;
+			if(actinfo->act_info.ip46flag & V4_VALID){
+				snprintf(buffer, sizeof(buffer), "ip rule add from %s table %d", actinfo->act_info.ip, rt_num);
+				system_cmd_ex(buffer);
+				snprintf(buffer, sizeof(buffer), "ip route add default dev %s table %d", wan_name, rt_num);
+				system_cmd_ex(buffer);
+				system_cmd_ex("ip route flush cache");
+			}
+			if(actinfo->act_info.ip46flag & V6_VALID){
+				snprintf(buffer, sizeof(buffer), "ip -6 rule add from %s table %d", pdp_ip6, rt_num);
+				system_cmd_ex(buffer);
+				snprintf(buffer, sizeof(buffer), "ip -6 route add default dev %s table %d", wan_name, rt_num);
+				system_cmd_ex(buffer);
+				system_cmd_ex("ip -6 route flush cache");
+			}
+		}
+		if (0 == strlen(defwan_real)) {
+			slog(NET_PRINT, SLOG_ERR, "pdp_wan_config_quick defwan_if not selected! \n");
+			net_sendmsg_2_atctl(actinfo->c_id, actinfo->act_info.ip46flag, MSG_CMD_LINKUP_END);
+			return;
+		}
+		if(actinfo->act_info.ip46flag & V4_VALID)
+			defwan4_change = strcmp(defwan_if_old, defwan_real);
+		if(actinfo->act_info.ip46flag & V6_VALID)
+			defwan6_change = strcmp(defwan6_if_old, defwan_real);
+		
+		//Êý¾ÝÏÈͨ£¬ºó×öÆäËûÅäÖã¬×¢Òâµã: ·À»ðǽ¶Ìʱ¼äÄÚ¿ÉÄÜδÉúЧ
+		if (defwan4_change && (actinfo->act_info.ip46flag & V4_VALID))
+		{
+			char nat_enable[4] = {0};
+			
+			system_cmd_ex("iptables -P INPUT ACCEPT");
+			system_cmd_ex("iptables -P OUTPUT ACCEPT");
+			system_cmd_ex("iptables -P FORWARD ACCEPT");
+			system_cmd_ex("iptables -t nat -F");
+			system_cmd_ex("iptables -t nat -X port_forward");
+			system_cmd_ex("iptables -t nat -X DMZ");
+			system_cmd_ex("iptables -t nat -X port_mapping");
+			system_cmd_ex("iptables -t nat -N port_forward");
+			system_cmd_ex("iptables -t nat -N DMZ");
+			system_cmd_ex("iptables -t nat -N port_mapping");
+			system_cmd_ex("iptables -t nat -I PREROUTING 1 -j port_forward");
+			system_cmd_ex("iptables -t nat -I PREROUTING 1 -j DMZ");
+			system_cmd_ex("iptables -t nat -I PREROUTING 1 -j port_mapping");
+			cfg_get_item("natenable", nat_enable, sizeof(nat_enable));
+			
+			if(strcmp(nat_enable, "0") != 0){
+				snprintf(buffer, sizeof(buffer), "iptables -t nat -A POSTROUTING -o %s -j MASQUERADE", defwan_real);
+				system_cmd_ex(buffer);
+			}
+			
+			net_write_file("/etc/resolv.conf", "", 0);
+			snprintf(buffer, sizeof(buffer), g_dns_conf, "127.0.0.1");
+			net_write_file("/etc/resolv.conf", buffer, strlen(buffer));
+		}
+		if(actinfo->act_info.ip46flag & V6_VALID){
+			char dhcp6s_conf[64] = {0};
+			char radvd_conf[64] = {0};
+			char radvd_pidfile[64] = {0};
+			char ndp_log[64] = {0};
+			int M_O_flag = 0;
+			char PdFlag[4] = {0};
+			char AdvManagedFlag[4] = {0};
+			char AdvOtherConfigFlag[4] = {0};
+			struct dhcp6_conf_info dhcp6_info = {0};
+			struct radvd_conf_info radvd_info = {0};
+		
+			snprintf(dhcp6s_conf, sizeof(dhcp6s_conf), "%s/dhcp6s_%s.conf", path, defwan_real); 
+			snprintf(radvd_conf, sizeof(radvd_conf), "%s/radvd_%s.conf", path, defwan_real);
+			snprintf(radvd_pidfile, sizeof(radvd_pidfile), "%s/radvd_%s.pid", path_tmp, defwan_real);
+			snprintf(ndp_log, sizeof(ndp_log), "%s/ndp_%s.log", path, defwan_real);
+		
+			net_write_file("/proc/sys/net/ipv6/conf/all/forwarding", "0", 1);
+			snprintf(buffer, sizeof(buffer), "ip -6 route add default dev %s", defwan_real);
+			system_cmd_ex(buffer);
+			snprintf(buffer, sizeof(buffer), "ip -6 addr add %s/64 dev br0", br_ip6);
+			system_cmd_ex(buffer);
+			cfg_set("ipv6_br0_addr", br_ip6);
+			net_write_file("/proc/sys/net/ipv6/conf/all/forwarding", "1", 1);
+			net_write_file("/proc/sys/net/ipv6/conf/all/proxy_ndp", "1", 1);
+			ndp_down(0);
+			snprintf(buffer, sizeof(buffer), "zte_ndp -a -s br0 -d %s -l %s &", defwan_real, ndp_log);
+			system_cmd_ex(buffer);
+			if(actinfo->act_info.ip46flag == V6_VALID){
+				cfg_get_item("xlat_enable", xlat_enable, sizeof(xlat_enable));
+				if(atoi(xlat_enable) && (default_route_check() == 0)){
+					char xlat_prefix[IPV6ADDLEN_MAX] = {0};
+					cfg_get_item("xlat_prefix", xlat_prefix, sizeof(xlat_prefix));
+					system_cmd_ex("chmod 777 /dev/net/tun");
+					if(strlen(xlat_prefix) == 0){
+						snprintf(buffer, sizeof(buffer),"clatd -i %s &", defwan_real);
+					} else {
+						snprintf(buffer, sizeof(buffer),"clatd -i %s -p %s &", defwan_real, xlat_prefix);
+					}
+					system_cmd_ex(buffer);
+					system_cmd_ex("echo 1 > /proc/sys/net/ipv4/ip_forward");
+					snprintf(buffer, sizeof(buffer),"iptables -t nat -A POSTROUTING -o v4-%s -j MASQUERADE", defwan_real);
+					system_cmd_ex(buffer);
+				}
+			}
+			
+			//dhcp set
+			dhcp6s_down(0);
+			zxic_remove(dhcp6s_conf);
+		
+			dhcp6_info.interface = lan_if;
+			dhcp6_info.link = lan_if;
+			dhcp6_info.start = dhcp_ip6_start;
+			dhcp6_info.end= dhcp_ip6_end;
+			dhcp6_info.prefix= prefix;
+			dhcp6_info.dns1 = actinfo->act_info.pri_dns6;
+			dhcp6_info.dns2 = actinfo->act_info.sec_dns6;
+			dhcp6_info.prefix_len= prefix_len;;
+			cfg_get_item("dhcpv6statePdEnabled", PdFlag, sizeof(PdFlag));
+			cfg_get_item("dhcpv6stateEnabled", AdvManagedFlag, sizeof(AdvManagedFlag));
+			cfg_get_item("dhcpv6statelessEnabled", AdvOtherConfigFlag, sizeof(AdvOtherConfigFlag));
+			if(atoi(PdFlag) == 1)
+				M_O_flag = M_O_flag|IPV6_RA_FLAG_PD;
+			if(atoi(AdvManagedFlag) == 1)
+				M_O_flag = M_O_flag|IPV6_RA_FLAG_MANAGED;
+			if(atoi(AdvOtherConfigFlag) == 1)
+				M_O_flag = M_O_flag|IPV6_RA_FLAG_OTHER_CONFIG;
+		
+			memset(buffer, 0, sizeof(buffer));
+			snprintf(buffer, sizeof(buffer), "dhcp6s -dDf -c %s %s &", dhcp6s_conf, lan_if);
+			if(config_dhcp6s(dhcp6s_conf, &dhcp6_info, M_O_flag) < 0)
+				return;
+			system_cmd_ex(buffer);
+			slog(NET_PRINT, SLOG_NORMAL, "start dhcp6s mo=%d:%s\n", M_O_flag, buffer);
+		
+			//radvd set
+			{
+				char path_tmp[16] = {0};
+				char path[32] = {0};
+				
+				cfg_get_item("path_tmp", path_tmp, sizeof(path_tmp));
+				snprintf(path, sizeof(path), "%s/radvd_%s.pid", path_tmp, defwan_real);
+				kill_pid_by_path(path);
+			}
+			zxic_remove(radvd_conf);
+			radvd_info.interface = lan_if;
+			radvd_info.prefix = br_ip6;
+			radvd_info.prefix_len = prefix_len;
+			radvd_info.dns1 = actinfo->act_info.pri_dns6;
+			radvd_info.dns2 = actinfo->act_info.sec_dns6;
+		
+			memset(buffer, 0, sizeof(buffer));
+			snprintf(buffer, sizeof(buffer), "radvd -d 3 -C %s -p %s &", radvd_conf, radvd_pidfile);
+			if(config_radvd(radvd_conf, &radvd_info, M_O_flag) < 0){
+				return;
+			}
+			zxic_remove(radvd_pidfile);
+			system_cmd_ex(buffer);	
+		}
+		system_cmd_ex("killall -9 dnsmasq");
+		snprintf(dns_path, sizeof(dns_path), "%s/dnsmasq.conf", path);	
+		net_write_file(dns_path, "", 0);
+		
+		if(actinfo->act_info.ip46flag & V4_VALID) {
+			unsigned int dns1 = 0;
+			unsigned int dns2 = 0;
+			unsigned int dns_ext = 0;
+			char dns1_s[IPV4ADDLEN_MAX] = {0};
+			char dns2_s[IPV4ADDLEN_MAX] = {0};
+			char ext_dns[IPV4ADDLEN_MAX] = {0};
+			
+			system_cmd_ex("route del default");
+			snprintf(buffer, sizeof(buffer),"route add default dev %s", defwan_real);
+			system_cmd_ex(buffer);
+			zxic_inet_pton(AF_INET, actinfo->act_info.pri_dns, &dns1);
+			zxic_inet_pton(AF_INET, actinfo->act_info.sec_dns, &dns2);
+			if(dns1)
+				snprintf(dns1_s, sizeof(dns1_s), "%s", actinfo->act_info.pri_dns);
+			else
+				snprintf(dns1_s, sizeof(dns1_s), "%s", "114.114.114.114");
+			if(dns2)
+				snprintf(dns2_s, sizeof(dns2_s), "%s", actinfo->act_info.sec_dns);
+			else
+				snprintf(dns2_s, sizeof(dns2_s), "%s", "8.8.8.8");
+			config_dns(dns_path, dns1_s, dns2_s);
+			cfg_get_item("dns_extern", ext_dns, sizeof(ext_dns));
+			zxic_inet_pton(AF_INET, ext_dns, &dns_ext);
+			if(dns_ext){
+				config_dns(dns_path, NULL, ext_dns);
+			}
+			//set ip addr for webui show
+			cfg_set("wan_ipaddr", actinfo->act_info.ip);
+			net_write_file("/proc/sys/net/ipv4/ip_forward", "1", 1);
+		}
+		if(actinfo->act_info.ip46flag & V6_VALID) {
+			char ext_dns_v6[IPV6ADDLEN_MAX] = {0};
+			struct in6_addr ipv6_dns_ext = {0};
+		
+			config_dns(dns_path, actinfo->act_info.pri_dns6, actinfo->act_info.sec_dns6);
+			cfg_get_item("ipv6_dns_extern", ext_dns_v6, sizeof(ext_dns_v6));
+			if(inet_pton(AF_INET6, pdp_ip6, &ipv6_dns_ext) > 0){
+				config_dns(dns_path, NULL, ext_dns_v6);
+			}
+			//set ipv6 addr for webui show
+			cfg_set("ipv6_wan_ipaddr", pdp_ip6);
+		}
+		if(atoi(tc_enable)){
+			snprintf(buffer, sizeof(buffer),"tc_tbf.sh up %d", actinfo->c_id);
+			system_cmd_ex(buffer);
+		}
+		snprintf(buffer, sizeof(buffer),"dnsmasq -i %s -r %s &", lan_if, dns_path);
+		system_cmd_ex(buffer);
+		slog(NET_PRINT, SLOG_NORMAL, "pdp_wan_config_quick defwan_change v4:%d v6:%d \n", defwan4_change, defwan6_change);
+		
+		//ȱʡÍâÍø¿Ú·¢Éú±ä»¯ÔòÖØÉènatºÍfilter
+		if (defwan4_change || defwan6_change) {
+			zte_router_init();
+			if(actinfo->act_info.ip46flag & V4_VALID){
+				memset(defwan_if_old, 0, ZTE_ROUTER_WAN_IF_NAME_LEN);
+				strncpy(defwan_if_old, defwan_real, strlen(defwan_real));
+			}
+			if(actinfo->act_info.ip46flag & V6_VALID){
+				memset(defwan6_if_old, 0, ZTE_ROUTER_WAN_IF_NAME_LEN);
+				strncpy(defwan6_if_old, defwan_real, strlen(defwan_real));
+			}
+		}
+		zte_unpn_set();
+		if(atoi(xlat_enable) && actinfo->act_info.ip46flag == V6_VALID){
+			snprintf(buffer, sizeof(buffer),"ip route add default dev v4-%s", defwan_real);
+			system_cmd_ex(buffer);
+		}
+		net_sendmsg_2_atctl(actinfo->c_id, actinfo->act_info.ip46flag, MSG_CMD_LINKUP_END);
+	}
+}
+
+void check_wan_change(unsigned char ip46flag)
+{
+	if (ip46flag == V4_VALID || ip46flag == V46_VALID) {
+		char nv_ethwan[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+		char nv_wifiwan[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+		char ethwan_ip[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+		char wifiwan_ip[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+
+		snprintf(nv_ethwan, sizeof(nv_ethwan), "%s_ip", eth_wan);
+		cfg_get_item(nv_ethwan, ethwan_ip, sizeof(ethwan_ip));
+		snprintf(nv_wifiwan, sizeof(nv_wifiwan), "%s_ip", wifi_wan);
+		cfg_get_item(nv_wifiwan, wifiwan_ip, sizeof(wifiwan_ip));
+		if ((0 != strcmp(ethwan_ip, "0.0.0.0") && (0 != strcmp(ethwan_ip, "")))
+			|| (0 != strcmp(wifiwan_ip, "0.0.0.0") && (0 != strcmp(wifiwan_ip, ""))))
+			proc_wan_change_v4();
+	}
+	if (ip46flag == V6_VALID || ip46flag == V46_VALID) {
+		char nv_ethwan_ipv6[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+		char nv_wifiwan_ipv6[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+		char ethwan_ipv6[ZTE_ROUTER_IPV6_ADDR_LEN] = {0};
+		char wifiwan_ipv6[ZTE_ROUTER_IPV6_ADDR_LEN] = {0};
+
+		sprintf(nv_ethwan_ipv6, "%s_ipv6_ip", eth_wan);
+		cfg_get_item(nv_ethwan_ipv6, ethwan_ipv6, sizeof(ethwan_ipv6));
+		sprintf(nv_wifiwan_ipv6, "%s_ipv6_ip", wifi_wan);
+		cfg_get_item(nv_wifiwan_ipv6, wifiwan_ipv6, sizeof(wifiwan_ipv6));
+		if (((0 != strcmp(ethwan_ipv6, "::")) && (0 != strcmp(ethwan_ipv6, ""))) 
+			|| ((0 != strcmp(wifiwan_ipv6, "::")) && (0 != strcmp(wifiwan_ipv6, ""))))
+			proc_wan_change_v6();
+	}
+}
+
+void net_wan_deact_quick(int c_id, unsigned char ip46flag)
+{
+	char cmd[128] = {0};
+	char wan_name[NV_NAME_LEN] = {0};
+	char default_wan_name[NV_NAME_LEN] = {0};
+	char default_wan6_name[NV_NAME_LEN] = {0};
+	char tc_enable[4] = {0};
+	char wan_pri[32] = {0};
+	char pdp_ip6[IPV6ADDLEN_MAX] = {0};
+	char pdp_ip[IPV4ADDLEN_MAX] = {0};
+	int pri = 0;
+	int rt_num = 0;
+
+	cfg_get_item("pswan_priority", wan_pri, sizeof(wan_pri));
+	pri = atoi(wan_pri);
+	if(pri < 0 || pri > 65535)
+		return;
+	rt_num = pri*10 + c_id;
+	cfg_get_item("tc_enable", tc_enable, sizeof(tc_enable));
+	snprintf(wan_name,NV_NAME_LEN,	"%s%d", ps_wan, c_id);
+	slog(NET_PRINT, SLOG_NORMAL, "deact ifconfig wanname:%s!\n", wan_name);
+
+	//ifconfig wan down
+	snprintf(cmd, sizeof(cmd),"ifconfig %s down", wan_name);
+	system_cmd_ex(cmd);
+	//ifconfig ip
+	snprintf(cmd, sizeof(cmd),"ifconfig %s 0.0.0.0 down", wan_name);
+	system_cmd_ex(cmd);
+
+	cfg_get_item("default_wan_name", default_wan_name, sizeof(default_wan_name));
+	cfg_get_item("default_wan6_name", default_wan6_name, sizeof(default_wan6_name));
+	
+	if (ip46flag == V4_VALID || ip46flag == V46_VALID) {
+		snprintf(cmd, sizeof(cmd), "%s_ip", wan_name);
+		cfg_get_item(cmd, pdp_ip, sizeof(pdp_ip));
+		cfg_set(cmd, "");
+		snprintf(cmd, sizeof(cmd), "%s_gw", wan_name);
+		cfg_set(cmd, "");
+		snprintf(cmd, sizeof(cmd), "%s_pridns", wan_name);
+		cfg_set(cmd, "");
+		snprintf(cmd, sizeof(cmd), "%s_secdns", wan_name);
+		cfg_set(cmd, "");
+		snprintf(cmd, sizeof(cmd), "ip rule del from %s table %d", pdp_ip, rt_num);
+		system_cmd_ex(cmd);
+		snprintf(cmd, sizeof(cmd), "ip route del default dev %s table %d", wan_name, rt_num);
+		system_cmd_ex(cmd);
+		if(strcmp(default_wan_name, wan_name) == 0){
+			//net_write_file("/proc/sys/net/ipv4/ip_forward", "0", 1);
+			snprintf(cmd, sizeof(cmd),"route del default dev %s", wan_name);
+			system_cmd_ex(cmd);
+			cfg_set("wan_ipaddr", "");
+			cfg_set("default_cid", "");
+			cfg_set("default_wan_name", "");
+			cfg_set("default_wan_rel", "");
+		}
+	}
+	if (ip46flag == V6_VALID || ip46flag == V46_VALID) {
+		snprintf(cmd, sizeof(cmd), "%s_ipv6_ip", wan_name);
+		cfg_get_item(cmd, pdp_ip6, sizeof(pdp_ip6));
+		cfg_set(cmd, "");
+		snprintf(cmd, sizeof(cmd), "%s_ipv6_interface_id", wan_name);
+		cfg_set(cmd, "");
+		snprintf(cmd, sizeof(cmd), "%s_ipv6_pridns_auto", wan_name);
+		cfg_set(cmd, "");
+		snprintf(cmd, sizeof(cmd), "%s_ipv6_secdns_auto", wan_name);
+		cfg_set(cmd, "");
+		snprintf(cmd, sizeof(cmd), "ip -6 rule del from %s table %d", pdp_ip6, rt_num);
+		system_cmd_ex(cmd);
+		snprintf(cmd, sizeof(cmd), "ip -6 route del default dev %s table %d", wan_name, rt_num);
+		system_cmd_ex(cmd);
+		if(strcmp(default_wan6_name, wan_name) == 0){
+			char br_ip6[IPV6ADDLEN_MAX] = {0};
+			
+			cfg_get_item("ipv6_br0_addr", br_ip6, sizeof(br_ip6));
+			net_write_file("/proc/sys/net/ipv6/conf/all/forwarding", "0", 1);
+			net_write_file("/proc/sys/net/ipv6/conf/all/proxy_ndp", "0", 1);
+			system_cmd_ex("ip -6 route del default");
+			snprintf(cmd, sizeof(cmd),"ip -6 addr del %s/64 dev br0", br_ip6);
+			system_cmd_ex(cmd);
+			system_cmd_ex("ip route del default");
+			system_cmd_ex("killall clatd");
+			snprintf(cmd, sizeof(cmd),"iptables -t nat -D POSTROUTING -o v4-%s -j MASQUERADE", wan_name);
+			system_cmd_ex(cmd);
+			{
+				char path_tmp[16] = {0};
+				char path[32] = {0};
+				
+				cfg_get_item("path_tmp", path_tmp, sizeof(path_tmp));
+				snprintf(path, sizeof(path), "%s/radvd_%s.pid", path_tmp, wan_name);
+				kill_pid_by_path(path);
+			}
+			dhcp6s_down(0);
+			ndp_down(0);
+			cfg_set("ipv6_br0_addr", "");
+			cfg_set("ipv6_wan_ipaddr", "");
+			cfg_set("default_cid", "");
+			cfg_set("default_wan6_name", "");
+			cfg_set("default_wan6_rel", "");
+		}
+	}
+	if(atoi(tc_enable)){
+		snprintf(cmd, sizeof(cmd),"tc_tbf.sh down %d",c_id);
+		system_cmd_ex(cmd);
+	}
+	{
+		char cid[20] = {0};
+		cfg_get_item("default_cid", cid, sizeof(cid));
+		if(c_id == atoi(cid))
+			cfg_set("default_cid", "");
+	}
+	if(strcmp(default_wan_name, wan_name) == 0 || strcmp(default_wan6_name, wan_name) == 0){
+		net_write_file("/etc/resolv.conf", "", 0);
+		check_wan_change(ip46flag);
+	}
+}
+/**************************************************************************
+* º¯ÊýÃû³Æ£º pdp_act_proc
+* ¹¦ÄÜÃèÊö£º PSÍøÂçÉ豸¼¤»î½Ó¿Ú
+* ²ÎÊý˵Ã÷£º pdp_active_info(IN):PDP¼¤»îÐÅÏ¢
+* ·µ »Ø Öµ£º ²Ù×÷³É¹¦·µ»Ø1.
+* ÆäËü˵Ã÷£º atÏà¹ØÓ¦Óýø³Ìµ÷Óã¬Èçatserver¡¢pcserver¡¢VoLTE¡¢²ÊÐŵÈÓ¦Óýø³Ì£»
+* ½Ó¿ÚÄÚ²¿ÊµÏÖ¶ÔÓÚµÄPSÉ豸µÄ¼¤»î¼°ÏàÓ¦µÄÍøÂçÅäÖÃ
+**************************************************************************/
+int net_pdp_act_proc(struct pdp_active_info *actinfo)
+{
+	char char_cid[10] = {0};
+	char cmd[100] = {0};
+	char need_jilian[NV_NAME_LEN] = {0};
+	char psext_state[NV_NAME_LEN] = {0};
+	char prefix[IPV6ADDLEN_MAX] = {0};
+	int prefix_len = 0;
+	char quick_flag[4] = {0};
+	
+	cfg_get_item("quick_dial", quick_flag, sizeof(quick_flag));
+	slog(NET_PRINT, SLOG_NORMAL, "net_pdp_act_proc\n");
+	if (!actinfo || actinfo->act_info.ip46flag == V4V6_INVALID) {
+		softap_assert("ip46flag error");//klocwork
+		return 0;
+	}
+
+	if (0 == pdp_act_check(actinfo)) {
+		softap_assert("already act.");
+	}
+	set_pdp_mode(actinfo->c_id, actinfo->pdp_type);
+
+	set_pdp_act_type(actinfo->c_id, actinfo->act_info.ip46flag);
+
+	if (actinfo->act_info.ip46flag == V6_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		prefix_len = syscall(__NR_get_ipv6_prefix,(unsigned char)actinfo->c_id, prefix);
+		slog(NET_PRINT, SLOG_NORMAL, "pdp_wan_config prefix=%s len=%d \n", prefix, prefix_len);
+		if(prefix_len > 0)
+		{
+			char nv_name[NV_NAME_LEN] = {0};
+			char len_s[4] = {0};
+
+			snprintf(nv_name, sizeof(nv_name), "%s%d_ipv6_prefix_info", ps_wan, actinfo->c_id);
+			cfg_set(nv_name, prefix);
+			snprintf(len_s, sizeof(len_s), "%d", prefix_len);
+			snprintf(nv_name, sizeof(nv_name), "%s%d_ipv6_prefix_len", ps_wan, actinfo->c_id);
+			cfg_set(nv_name, len_s);
+		}
+	}
+	//¶ÔÓÚatserver´¥·¢µÄPDP¼¤»î£¬ÊÇÓÃÓÚÆÕͨÉÏÍâÍøÒµÎñµÄ£¬´æÔÚNATת»»
+	if (actinfo->pdp_type == PDP_NORMAL) {
+		snprintf(char_cid, sizeof(char_cid), "%d", actinfo->c_id);
+		cfg_set("default_cid", char_cid);
+		if(quick_flag[0] == '1' && (actinfo->act_info.ip46flag == V4_VALID || prefix_len > 0))
+			pdp_wan_config_quick(actinfo, prefix, prefix_len);
+		else
+			pdp_wan_config(actinfo);
+		//cfg_set("ps_state", "working");
+	}
+	//¶ÔÓÚÍâºË´¥·¢µÄPDP¼¤»î£¬½øÐÐÇŽӻò¼¶Áª
+	else if (actinfo->pdp_type == PDP_EXT) {
+		//cp¼¶Áª£¬apÇŽÓ
+		if(quick_flag[0] == '1' && (actinfo->act_info.ip46flag == V4_VALID || prefix_len > 0)){
+			pdp_direct_config_quick(actinfo, prefix, prefix_len);
+		}else{
+		cfg_get_item("need_jilian", need_jilian, sizeof(need_jilian));
+		if (0 == strcmp(need_jilian, "1"))
+			pdp_direct_config(actinfo);
+		else if (0 == strcmp(need_jilian, "0")) {
+			//sprintf(cmd, "/sbin/psext_updown.sh \"linkup\" \"%d\"", actinfo->c_id);
+			sprintf(cmd, "/sbin/psext_updown.sh linkup %d", actinfo->c_id);
+			zxic_system(cmd); //kw 3
+		} else
+			softap_assert("need_jilian=%s error", need_jilian);
+		}
+		/*¸ÃÎÊÌâÓÃÓÚUSB ÈȲå°Îʱ״̬±ê¼Ç£¬½öÔÚPDP¼¤»îÖ®ºó£¬
+		²Å¶ÔÈȲå°ÎÏûÏ¢½øÐд¦Àí*/
+		sprintf(psext_state, "ps_ext%d_pdpstate", actinfo->c_id);
+		cfg_set(psext_state, "working");
+
+	}
+	//±¾µØÓ¦ÓÃÉÏÍâÍøµÄPDP¼¤»î£¬ÈçVoLTEµÈ
+	else if (actinfo->pdp_type == PDP_LOCAL) {
+		if(quick_flag[0] == '1' && (actinfo->act_info.ip46flag == V4_VALID || prefix_len > 0))
+			pdp_wan_config_quick(actinfo, prefix, prefix_len);
+		else
+			pdp_wan_config(actinfo);
+	} else if (actinfo->pdp_type == PDP_PPP) {
+		//sprintf(char_cid, "%d", actinfo->c_id);
+		//cfg_set("ppp_cid", char_cid);
+		pdp_ppp_config(actinfo);
+
+		cfg_set("ppp_pdpstate", "working");
+	} else {
+		softap_assert("pdp_type=%u error", actinfo->pdp_type);
+		return 0;
+	}
+
+	if (actinfo->pdp_type != PDP_NORMAL) 
+	{
+		net_sendmsg_2_atctl(actinfo->c_id, actinfo->act_info.ip46flag, MSG_CMD_LINKUP_END);		
+	}
+	
+	system("cat /proc/uptime 1>dev/console 2>&1");
+	slog(NET_PRINT, SLOG_NORMAL, "net_pdp_act_proc success\n");
+	
+	return 1;
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º pdp_deact_proc
+* ¹¦ÄÜÃèÊö£º PSÍøÂçÉ豸ȥ»î½Ó¿Ú
+* ²ÎÊý˵Ã÷£º c_id(IN):PDP¼¤»îc_id.
+* ·µ »Ø Öµ£º ²Ù×÷³É¹¦·µ»Ø1.
+* ÆäËü˵Ã÷£º atÏà¹ØÓ¦Óýø³Ìµ÷Óã¬Èçatserver¡¢pcserver¡¢VoLTE¡¢²ÊÐŵÈÓ¦Óýø³Ì£»
+½Ó¿ÚÄÚ²¿ÊµÏÖ¶ÔÓÚµÄPSÉ豸ȥ»î£»Ö§³Ö46µ¥Õ»È¥»î£¬ËùÒÔÈë²ÎÐèҪָʾ46Çé¿ö
+**************************************************************************/
+int net_pdp_deact_proc(int c_id, unsigned char ip46flag)
+{
+	char cmd[100] = {0};
+	char pdp_mode_nv[NV_NAME_LEN] = {0};
+	char pdp_mode[NV_NAME_LEN] = {0};
+	char psext_state[NV_NAME_LEN] = {0};
+	//char pppd_user_term[NV_NAME_LEN] = {0};
+	char quick_flag[4] = {0};
+	
+	cfg_get_item("quick_dial", quick_flag, sizeof(quick_flag));
+
+	openlog("netapi", LOG_CONS | LOG_PID, LOG_DAEMON);
+
+	if (ip46flag == V4V6_INVALID) {
+		softap_assert("ip46flag=%u error", ip46flag);
+		return 0;
+	}
+
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_pdp_deact_proc start!cid=%d,ip46flag=%u\n", c_id, ip46flag);
+
+	sprintf(pdp_mode_nv, "pdp_mode%d", c_id);
+	cfg_get_item(pdp_mode_nv, pdp_mode, sizeof(pdp_mode));
+
+	reset_pdp_mode(c_id);
+
+	closelog();
+
+	//ÍâºËpdpÈ¥»î,È¥ÇÅÈ¥¼¶Áª
+	if (0 == strcmp("bridge", pdp_mode)) {
+		if(quick_flag[0] == '1'){
+			net_br_deact_quick(c_id, ip46flag);
+		}else{
+		if (ip46flag == V4_VALID || ip46flag == V46_VALID) {
+			//sprintf(cmd, "/sbin/psext_updown.sh \"linkdown\" \"%d\"", c_id);
+			sprintf(cmd, "/sbin/psext_updown.sh linkdown %d", c_id);
+			zxic_system(cmd); //kw 3
+		}
+
+		if (ip46flag == V6_VALID || ip46flag == V46_VALID) {
+			memset(cmd, 0, sizeof(cmd));
+			//sprintf(cmd, "/sbin/psext_updown_ipv6.sh \"linkdown\" \"%d\"", c_id);
+			sprintf(cmd, "/sbin/psext_updown_ipv6.sh linkdown %d", c_id);
+			zxic_system(cmd);
+		}
+		}
+		sprintf(psext_state, "ps_ext%d_pdpstate", c_id);
+		cfg_set(psext_state, "dead");
+		slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_pdp_deact_proc success!\n");
+
+		net_sendmsg_2_atctl(c_id, ip46flag, MSG_CMD_LINKDOWN_END);	
+		
+		return 1;
+	} else if (0 == strcmp("ppp", pdp_mode)) {
+		//if (ip46flag == V4_VALID || ip46flag == V46_VALID) { for ipv6
+#if 0
+			cfg_get_item("pppd_user_term", pppd_user_term, sizeof(pppd_user_term)); //¼ì²â¸ÃpdpÈ¥¼¤»îÊÇ·ñÊÇÓÉÖն˶ϿªpppÁ´½Ó·¢ÆðµÄ
+			if (strcmp(pppd_user_term,  "terminate") != 0) {
+				cfg_set("ppp_pdpstate", "dead");
+
+			} else {
+				cfg_set("ppp_pdpstate", "user_terminate");
+				cfg_set("pppd_user_term", "");
+			}
+#endif
+			//sprintf(cmd, "/sbin/ppp_updown.sh \"linkdown\" \"%d\"", c_id);
+			sprintf(cmd, "/sbin/ppp_updown.sh linkdown %d", c_id);
+			zxic_system(cmd);
+			cfg_set("ppp_pdpstate", "dead");
+
+		//}
+		slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_pdp_deact_proc success!\n");
+
+		net_sendmsg_2_atctl(c_id, ip46flag, MSG_CMD_LINKDOWN_END);	
+		return 1;
+	}
+	//atserver pdpÈ¥»î ½«default_cidÖÿÕ
+	else if (0 == strcmp("gateway", pdp_mode)) {
+		//cfg_set("default_cid", "");
+		//cfg_set("ps_state", "dead");
+	}
+	if(quick_flag[0] == '1'){
+		net_wan_deact_quick(c_id, ip46flag);
+	}else{
+	if (ip46flag == V4_VALID || ip46flag == V46_VALID) {
+		//sprintf(cmd, "/sbin/wan_ipv4.sh \"linkdown\" \"pswan\" \"%d\"", c_id);
+		sprintf(cmd, "/sbin/wan_ipv4.sh linkdown pswan %d", c_id);
+		zxic_system(cmd);
+	}
+
+	if (ip46flag == V6_VALID || ip46flag == V46_VALID) {
+		memset(cmd, 0, sizeof(cmd));
+		//sprintf(cmd, "/sbin/wan_ipv6.sh \"linkdown\" \"pswan\" \"%d\"", c_id);
+		sprintf(cmd, "/sbin/wan_ipv6.sh linkdown pswan %d", c_id);
+		zxic_system(cmd);
+	}
+	}
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_pdp_deact_proc success!\n");
+
+	net_sendmsg_2_atctl(c_id, ip46flag, MSG_CMD_LINKDOWN_END);	
+	return 1;
+}
+
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º netdev_connect_internet
+* ¹¦ÄÜÃèÊö£º webui·¢Ë͵ÄÁ¬½ÓÇëÇó,½Ó¿ÚÄÚ²¿½øÐÐifconfig up£¬²¢Æô¶¯ÏàÓ¦µÄµØÖ··ÖÅä½ø³Ì
+* ²ÎÊý˵Ã÷£º netdev_id£ºÍøÂçÉ豸¶ÔÓ¦µÄºêÃû£¬²Î¼ûUSB_NET_DEVµÈºêÖµ
+* ·µ »Ø Öµ£º ²Ù×÷³É¹¦·µ»Ø1.
+* ÆäËü˵Ã÷£º É豸Ö÷¿ØÄ£¿éµ÷Óô˽ӿÚǰ£¬ÐèÒª¼ì²âµ±Ç°É豸ÎïÀíͨ·ÒÑͨ£¬·ñÔò²»Ó¦¸Ãµ÷Óô˽ӿڣ»
+* Ö÷¿ØÄ£¿éÐèÒªÑÏ¿ØÖظ´µÄµ÷Óøýӿڣ¬ÒòΪÿµ÷ÓÃÒ»´Î¸Ã½Ó¿Ú£¬ÄÚ²¿½Ô»áÖØÐÂÖ´ÐÐÒ»´ÎÍêÕûµÄµØÖ··ÖÅäÁ÷³Ì£»
+**************************************************************************/
+int net_netdev_connect_internet(unsigned char netdev_id)
+{
+	char eth_type[NV_NAME_LEN] = {0};
+	char work_state[NV_NAME_LEN] = {0};
+	char eth_dev[NV_NAME_LEN] = {0};
+	char sw_name[NV_NAME_LEN] = {0};
+	char swport[NV_NAME_LEN] = {0};
+	char cmd[100] = {0};
+
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_netdev_connect_internet start! netdev_id=%u\n", netdev_id);
+	if (netdev_id == RJ45_WAN_DEV) {
+		ethwan_id = netdev_id;
+		pppoe_encrypt_code();
+		eth_connect();
+	} else if (netdev_id == WIFI_WAN_DEV) {
+		wifiwan_id = netdev_id;
+		wifi_connect();
+	} else if (netdev_id == RJ45_LAN_DEV) {
+		system("landev_updown.sh \"ethlan\" \"up\"");
+		slog(NET_PRINT, SLOG_NORMAL, "rj45 as lan connect end!\n");
+	} else if (netdev_id == WIFI_LAN_DEV) {
+		system("landev_updown.sh \"wifilan\" \"up\"");
+		slog(NET_PRINT, SLOG_NORMAL, "wifi as lan connect end!\n");
+	} else {
+		softap_assert("netdev_id=%d error", netdev_id);
+		return 0;
+	}
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_netdev_connect_internet success!\n");
+	closelog();
+	return 1;
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º netdev_disconnect_internet
+* ¹¦ÄÜÃèÊö£º webui·¢Ë͵ĶϿªÁ¬½ÓÇëÇó,½Ó¿ÚÄÚ²¿½øÐÐifconfig down£¬²¢É±µôÏàÓ¦µÄµØÖ··ÖÅä½ø³Ì
+* ²ÎÊý˵Ã÷£º netdev_id£ºÍøÂçÉ豸¶ÔÓ¦µÄºêÃû£¬²Î¼ûUSB_NET_DEVµÈºêÖµ
+* ·µ »Ø Öµ£º ²Ù×÷³É¹¦·µ»Ø1.
+* ÆäËü˵Ã÷£º É豸Ö÷¿ØÄ£¿éµ÷Óô˽ӿÚ
+**************************************************************************/
+int net_netdev_disconnect_internet(unsigned char netdev_id)
+{
+	char eth_curtype[NV_NAME_LEN] = {0};
+	char eth_dev[NV_NAME_LEN] = {0};
+	char cmd[100] = {0};
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	openlog("netapi", LOG_CONS | LOG_PID, LOG_DAEMON);
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_netdev_disconnect_internet start! netdev_id=%u\n", netdev_id);
+	if (netdev_id == RJ45_WAN_DEV) {
+		ethwan_id = netdev_id;
+		//msg_timedel();
+		deletetimer(ethwan_id);
+		slog(NET_PRINT, SLOG_NORMAL, "diconnect ..... deletetimer.....");
+		cfg_get_item("eth_curtype", eth_curtype, sizeof(eth_curtype));
+		if (0 == strcmp(eth_curtype, "wan"))
+		{
+			system("wan_ipv4.sh \"linkdown\" \"ethwan\"");
+			if(atoi(wbwanv6_enable) == 1)
+				system("wan_ipv6.sh \"linkdown\" \"ethwan\"");
+		}
+		else if (0 == strcmp(eth_curtype, "lan")) {
+			system("landev_updown.sh \"ethwan\" \"down\"");
+			slog(NET_PRINT, SLOG_NORMAL, "rj45 as lan disconnect end!\n");
+		} else { //Ϊ·ÀÖ¹eth_curtypeÅжϳö´íËù×öµÄ¼æÈÝ
+			system("wan_ipv4.sh \"linkdown\" \"ethwan\"");
+			if(atoi(wbwanv6_enable) == 1)
+				system("wan_ipv6.sh \"linkdown\" \"ethwan\"");
+			system("landev_updown.sh \"ethwan\" \"down\"");
+		}
+		vlan_config(RJ45_WAN_DEV, "rem");
+		cfg_set("rj45_state", "idle");
+	} else if (netdev_id == WIFI_WAN_DEV) {
+		wifiwan_id = netdev_id;
+		deletetimer(wifiwan_id);
+		system("wan_ipv4.sh \"linkdown\" \"wifiwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"wifiwan\"");
+		cfg_set("wifi_state", "idle");
+	} else if (netdev_id == RJ45_LAN_DEV) {
+		system("landev_updown.sh \"ethlan\" \"down\"");
+		slog(NET_PRINT, SLOG_NORMAL, "rj45 as lan disconnect end!\n");
+	} else if (netdev_id == WIFI_LAN_DEV) {
+		system("landev_updown.sh \"wifilan\" \"down\"");
+		slog(NET_PRINT, SLOG_NORMAL, "wifi as lan disconnect end!\n");
+	} else {
+		softap_assert("netdev_id=%d error", netdev_id);
+		return 0;
+	}
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_netdev_disconnect_internet success!\n");
+	closelog();
+	return 1;
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º netdev_plugin_proc
+* ¹¦ÄÜÃèÊö£º ÈȲå°ÎÉ豸²åÈë,½Ó¿ÚÄÚ²¿¼ì²âÊÇ·ñÐèÒª½øÐÐ×Ô¶¯²¦ºÅ£¬ÈçÐèÒª£¬Ö´ÐеØÖ··ÖÅä¡¢×éÍøµÈÁ÷³Ì
+* ²ÎÊý˵Ã÷£º netdev_id£ºÍøÂçÉ豸¶ÔÓ¦µÄºêÃû£¬²Î¼ûUSB_NET_DEVµÈºêÖµ
+* ·µ »Ø Öµ£º ²Ù×÷³É¹¦·µ»Ø1.
+* ÆäËü˵Ã÷£º É豸Ö÷¿Øµ÷Óô˽ӿÚʱ£¬±íÃ÷¸ÃÍøÂçÉ豸ÎïÀíͨ·ÒÑͨ£¬¿ÉÒÔ½øÐÐIPÊý¾Ý°üµÄÊÕ·¢ÁË
+**************************************************************************/
+int net_netdev_plugin_proc(unsigned char netdev_id)
+{
+
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_netdev_plugin_proc start! netdev_id=%u\n", netdev_id);
+	openlog("netapi", LOG_CONS | LOG_PID, LOG_DAEMON);
+	//USB½ö´æÔÚÓÚÄÚÍøÖÐ
+	if (netdev_id == USB_LAN_DEV) {
+		system("landev_updown.sh \"usblan\" \"up\"");
+		slog(NET_PRINT, SLOG_ERR, "usb as lan plugin end!\n");
+	}
+	//ÈȲå°Î½öÐ迼ÂÇ×Ô¶¯Ä£Ê½£¬²»Ð迼ÂÇÊÖ¹¤²¦ºÅµÄÁ¬½Ó
+	//¸Ã·Ö֧ͬʱ´¦ÀíÁËlan/wan/autoÈýÖÖÇé¿ö£¬RJ45_LAN_DEVÔÝʱÎÞ·¨Ê¹ÓÃ
+	else if (netdev_id == RJ45_WAN_DEV || netdev_id == SW_WAN_DEV) {
+		ethwan_id = netdev_id;
+		ethwan_plugin();
+	} else if (netdev_id == WIFI_WAN_DEV) {
+		wifiwan_id = netdev_id;
+		wifi_plugin();
+	} else if (netdev_id == RJ45_LAN_DEV || netdev_id == SW_LAN_DEV) {
+		ethlan_plugin();
+	} else if (netdev_id == WIFI_LAN_DEV) {
+		system("landev_updown.sh \"wifilan\" \"up\"");
+		slog(NET_PRINT, SLOG_NORMAL, "wifi as lan plugin end!\n");
+	} else if (netdev_id == PS_EXT_DEV1) {
+		system("landev_updown.sh \"ps_ext1\" \"up\"");
+	} else if (netdev_id == PS_EXT_DEV2) {
+		system("landev_updown.sh \"ps_ext2\" \"up\"");
+	} else if (netdev_id == PS_EXT_DEV3) {
+		system("landev_updown.sh \"ps_ext3\" \"up\"");
+	} else if (netdev_id == PS_EXT_DEV4) {
+		system("landev_updown.sh \"ps_ext4\" \"up\"");
+	} else if (netdev_id == PS_EXT_DEV5) {
+		system("landev_updown.sh \"ps_ext5\" \"up\"");
+	} else if (netdev_id == PS_EXT_DEV6) {
+		system("landev_updown.sh \"ps_ext6\" \"up\"");
+	} else if (netdev_id == PS_EXT_DEV7) {
+		system("landev_updown.sh \"ps_ext7\" \"up\"");
+	} else if (netdev_id == PS_EXT_DEV8) {
+		system("landev_updown.sh \"ps_ext8\" \"up\"");
+	} else
+		slog(NET_PRINT, SLOG_NORMAL, "plugin netdev_id error!!! : netdev_id=%u\n", netdev_id);
+	//assert(0);
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_netdev_plugin_proc success!\n");
+	closelog();
+	return 1;
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º netdev_plugout_proc
+* ¹¦ÄÜÃèÊö£º ÈȲå°ÎÉ豸°Î³ö,½Ó¿ÚÄÚ²¿½øÐÐifconfig down£¬²¢É±µôÏàÓ¦µÄµØÖ··ÖÅä½ø³Ì
+* ²ÎÊý˵Ã÷£º netdev_id£ºÍøÂçÉ豸¶ÔÓ¦µÄºêÃû£¬²Î¼ûUSB_NET_DEVµÈºêÖµ
+* ·µ »Ø Öµ£º ²Ù×÷³É¹¦·µ»Ø1.
+* ÆäËü˵Ã÷£º É豸Ö÷¿Øµ÷Óô˽ӿÚʱ£¬±íÃ÷¸ÃÍøÂçÉ豸ÎïÀíͨ·ÒѶϣ¬²»ÒªÔÙ½øÐÐIPÊý¾Ý°üÊÕ·¢
+**************************************************************************/
+int net_netdev_plugout_proc(unsigned char netdev_id)
+{
+	char eth_curtype[NV_NAME_LEN] = {0};
+	char cmd[100] = {0};
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	openlog("netapi", LOG_CONS | LOG_PID, LOG_DAEMON);
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_netdev_plugout_proc start! netdev_id=%u\n", netdev_id);
+	//ÄÚÍøÇŵãÈ¥³ý
+	if (netdev_id == USB_LAN_DEV) {
+		system("landev_updown.sh \"usblan\" \"down\"");
+		slog(NET_PRINT, SLOG_NORMAL, "usb as lan plugout end!\n");
+		return 1;
+	}
+	//Ðè񻂿·ÖÄÚÍâÍøÄ£Ê½
+	else if (netdev_id == RJ45_WAN_DEV || netdev_id == SW_WAN_DEV) {
+		ethwan_id = netdev_id;
+		ethwan_plugout();
+	} else if (netdev_id == WIFI_WAN_DEV) {
+		wifiwan_id = netdev_id;
+		deletetimer(wifiwan_id);
+		system("wan_ipv4.sh \"linkdown\" \"wifiwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"wifiwan\"");
+		cfg_set("wifi_state", "dead");
+
+	} else if (netdev_id == RJ45_LAN_DEV || netdev_id == SW_LAN_DEV) {
+		ethlan_plugout();
+	} else if (netdev_id == WIFI_LAN_DEV) {
+		system("landev_updown.sh \"wifilan\" \"down\"");
+		slog(NET_PRINT, SLOG_NORMAL, "wifi as lan plugout end!\n");
+	} else if (netdev_id == PS_EXT_DEV1) {
+		system("landev_updown.sh \"ps_ext1\" \"down\"");
+	} else if (netdev_id == PS_EXT_DEV2) {
+		system("landev_updown.sh \"ps_ext2\" \"down\"");
+	} else if (netdev_id == PS_EXT_DEV3) {
+		system("landev_updown.sh \"ps_ext3\" \"down\"");
+	} else if (netdev_id == PS_EXT_DEV4) {
+		system("landev_updown.sh \"ps_ext4\" \"down\"");
+	} else if (netdev_id == PS_EXT_DEV5) {
+		system("landev_updown.sh \"ps_ext5\" \"down\"");
+	} else if (netdev_id == PS_EXT_DEV6) {
+		system("landev_updown.sh \"ps_ext6\" \"down\"");
+	} else if (netdev_id == PS_EXT_DEV7) {
+		system("landev_updown.sh \"ps_ext7\" \"down\"");
+	} else if (netdev_id == PS_EXT_DEV8) {
+		system("landev_updown.sh \"ps_ext8\" \"down\"");
+	} else {
+		slog(NET_PRINT, SLOG_ERR, "plugout netdev_id error!!! : netdev_id=%u\n", netdev_id);
+		//assert(0);
+		return 0;
+	}
+	//wifi ifconfig downÓÉÆäÄ£¿é¸ºÔð£¬rj45 °Î³ýÉ豸Ïûʧ£¬ÓÉÇý¶¯¸ºÔð
+	//memset(cmd, 0, sizeof(cmd));
+	//sprintf(cmd, "ifconfig %s down" , wan_if);
+	//system(cmd);
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_netdev_plugout_proc success!\n");
+	closelog();
+	return 1;
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ£º net_tc_control
+* ¹¦ÄÜÃèÊö£º Á÷Á¿¿ØÖÆ
+* ²ÎÊý˵Ã÷£º ÐèÒªÁ÷Á¿¼à¿ØµÄÉÏÏÂÐÐÁ¿£¬Êý¾Ý¿¨ÐèÒªÓÐcid£¬ufiģʽ²»ÐèÒª
+*            0±íʾ²»ÐèÒªÁ÷¿Ø
+* ·µ »Ø Öµ£º ²Ù×÷³É¹¦·µ»Ø1.
+* ÆäËü˵Ã÷£º ¸øÐèÒªÁ÷Á¿¿ØÖƵÄÓ¦Óõ÷Óã¬ÈçÉÏÐÐÐèÒªÁ÷¿Ø£¬ÇëµÈÄÜÉÏÍâÍøºóÔÙµ÷Ó㬷ñÔòÎÞ·¨»ñÈ¡ÍâÍø¿Ú½øÐÐÁ÷¿Ø
+**************************************************************************/
+int net_tc_control(struct tc_control_info *tcinfo, int src_id)
+{
+	int ret = 0;
+	char cmd[100] = {0};
+	char up[NV_NAME_LEN]   = {0};
+	char down[NV_NAME_LEN] = {0};
+	char at_str[32] = {0}; 
+	
+	slog(NET_PRINT, SLOG_NORMAL, "zte_mainctrl:net_tc_control start! c_id:%d, down:%u, up:%u\n \n", tcinfo->c_id, tcinfo->tc_downlink, tcinfo->tc_uplink);
+
+	cfg_set("tc_enable", "1");
+
+	/* Á÷Á¿Í³¼ÆÊÇÕë¶ÔByte£¬ËùÒÔÒª³ýÒÔ8 */
+	sprintf(up, "%d", (tcinfo->tc_uplink / 8));
+	cfg_set("tc_uplink", up);
+	sprintf(down, "%d", (tcinfo->tc_downlink) / 8);
+	cfg_set("tc_downlink", down);
+
+	//sprintf(cmd, "/sbin/tc_tbf.sh \"up\" \"%d\"", tcinfo->c_id);
+	sprintf(cmd, "/sbin/tc_tbf.sh up %d", tcinfo->c_id);
+	zxic_system(cmd);
+
+	if(src_id == MODULE_ID_AT_CTL)
+	{
+		sprintf(at_str, "\r\nOK\r\n");
+		send_rsp_str_to_farps(MODULE_ID_MAIN_CTRL, at_str, strlen(at_str));
+	}
+
+	return 1;
+}
+
+/*PPPÐÎ̬µÄPDP¼¤»î£¬ÔÝʱ½öÖ§³ÖIPV4*/
+int pdp_ppp_config(struct pdp_active_info *actinfo)
+{
+
+	char nv_ip[NV_NAME_LEN] = {0};
+	char nv_gw[NV_NAME_LEN] = {0};
+	char nv_pridns[NV_NAME_LEN] = {0};
+	char nv_secdns[NV_NAME_LEN] = {0};
+	char nv_ip6[NV_NAME_LEN] = {0};
+	char nv_pridns6[NV_NAME_LEN] = {0};
+	char nv_secdns6[NV_NAME_LEN] = {0};
+	char cmd[100] = {0};
+
+	if (actinfo->act_info.ip46flag == V4_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		snprintf(nv_ip, sizeof(nv_ip), "%s%d_ip", ps_wan, actinfo->c_id);
+		cfg_set(nv_ip, actinfo->act_info.ip);
+		snprintf(nv_gw, sizeof(nv_gw), "%s%d_gw", ps_wan, actinfo->c_id);
+		cfg_set(nv_gw, actinfo->act_info.ip);
+		snprintf(nv_pridns, sizeof(nv_pridns), "%s%d_pridns", ps_wan, actinfo->c_id);
+		cfg_set(nv_pridns, actinfo->act_info.pri_dns);
+		snprintf(nv_secdns, sizeof(nv_secdns), "%s%d_secdns", ps_wan, actinfo->c_id);
+		cfg_set(nv_secdns, actinfo->act_info.sec_dns);
+
+		//sprintf(cmd, "/sbin/ppp_updown.sh \"linkup\" \"%d\"", actinfo->c_id);
+		//sprintf(cmd, "/sbin/ppp_updown.sh linkup %d", actinfo->c_id);
+		//zxic_system(cmd);
+	} //else
+		//softap_assert("ip46flag=%u error", actinfo->act_info.ip46flag);
+	if (actinfo->act_info.ip46flag == V6_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		snprintf(nv_ip6, sizeof(nv_ip6), "%s%d_pppv6_ip", ps_wan, actinfo->c_id);
+		cfg_set(nv_ip6, actinfo->act_info.ip6);
+		snprintf(nv_ip6, sizeof(nv_ip6), "%s%d_ipv6_interface_id", ps_wan, actinfo->c_id);
+		save_interface_id(nv_ip6, actinfo->act_info.ip6);
+		snprintf(nv_pridns6, sizeof(nv_pridns6), "%s%d_ipv6_pridns_auto", ps_wan, actinfo->c_id);
+		cfg_set(nv_pridns6, actinfo->act_info.pri_dns6);
+		snprintf(nv_secdns6, sizeof(nv_secdns6), "%s%d_ipv6_secdns_auto", ps_wan, actinfo->c_id);
+		cfg_set(nv_secdns6, actinfo->act_info.sec_dns6);
+	}
+	sprintf(cmd, "/sbin/ppp_updown.sh linkup %d", actinfo->c_id);
+	zxic_system(cmd);
+	return 1;
+}
+
+/*NORMALÐÎ̬µÄPDP¼¤»îµÄ˫ջµØÖ·±£´æ£¬²¢´¥·¢ÍâÍø¿ÚµØÖ·ÅäÖýű¾*/
+int pdp_wan_config(struct pdp_active_info *actinfo)
+{
+	char nv_ip[NV_NAME_LEN] = {0};
+	char nv_gw[NV_NAME_LEN] = {0};
+	char nv_pridns[NV_NAME_LEN] = {0};
+	char nv_secdns[NV_NAME_LEN] = {0};
+	char nv_ip6[NV_NAME_LEN] = {0};
+	//char nv_gw6[NV_NAME_LEN] = {0};
+	char nv_pridns6[NV_NAME_LEN] = {0};
+	char nv_secdns6[NV_NAME_LEN] = {0};
+	char cmd[100] = {0};
+	FILE *fpv4 = NULL;
+	FILE *fpv6 = NULL;
+	
+	if (actinfo->act_info.ip46flag == V4_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		snprintf(nv_ip, sizeof(nv_ip), "%s%d_ip", ps_wan, actinfo->c_id);
+		cfg_set(nv_ip, actinfo->act_info.ip);
+		snprintf(nv_gw, sizeof(nv_gw), "%s%d_gw", ps_wan, actinfo->c_id);
+		cfg_set(nv_gw, actinfo->act_info.ip);
+		snprintf(nv_pridns, sizeof(nv_pridns), "%s%d_pridns", ps_wan, actinfo->c_id);
+		cfg_set(nv_pridns, actinfo->act_info.pri_dns);
+		snprintf(nv_secdns, sizeof(nv_secdns), "%s%d_secdns", ps_wan, actinfo->c_id);
+		cfg_set(nv_secdns, actinfo->act_info.sec_dns);
+
+		//sprintf(cmd, "/sbin/wan_ipv4.sh \"linkup\" \"pswan\" \"%d\"", actinfo->c_id);
+		sprintf(cmd, "/sbin/wan_ipv4.sh linkup pswan %d", actinfo->c_id);
+		//zxic_system(cmd);
+		fpv4 = popen(cmd, "r");
+	}
+
+	if (actinfo->act_info.ip46flag == V6_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		snprintf(nv_ip6, sizeof(nv_ip6), "%s%d_ipv6_interface_id", ps_wan, actinfo->c_id);
+		//cfg_set(nv_ip6, actinfo->act_info.ip6);
+		save_interface_id(nv_ip6, actinfo->act_info.ip6);
+		//snprintf(nv_gw6, sizeof(nv_gw6), "%s%d_ipv6_gw", nv_pswan, actinfo->c_id);
+		//cfg_set(nv_gw6, actinfo->act_info.gateway6);
+		snprintf(nv_pridns6, sizeof(nv_pridns6), "%s%d_ipv6_pridns_auto", ps_wan, actinfo->c_id);
+		cfg_set(nv_pridns6, actinfo->act_info.pri_dns6);
+		snprintf(nv_secdns6, sizeof(nv_secdns6), "%s%d_ipv6_secdns_auto", ps_wan, actinfo->c_id);
+		cfg_set(nv_secdns6, actinfo->act_info.sec_dns6);
+		memset(cmd, 0, sizeof(cmd));
+		//sprintf(cmd, "/sbin/wan_ipv6.sh \"linkup\" \"pswan\" \"%d\"", actinfo->c_id);
+		sprintf(cmd, "/sbin/wan_ipv6.sh linkup pswan %d", actinfo->c_id);
+		//zxic_system(cmd);
+		fpv6 = popen(cmd, "r");
+	}
+	if(fpv4 != NULL)
+		pclose(fpv4);
+	if(fpv6 != NULL)
+		pclose(fpv6);
+	return 1;
+}
+
+/*ÇŽÓÀà×éÍøÅäÖã¬CP²àÓÉÓÚPS²»ÊDZê×¢µÄlinuxÒÔÌ«Íø¿ÚÐÎ̬£¬ËùÒÔÐèÒª½øÐж¨ÖÆÂ·ÓÉ£¬ÒÔʵÏÖÍø¿Ú¹ØÁª£»AP²àÖ±½Óbr0¼´¿É*/
+int pdp_direct_config(struct pdp_active_info *actinfo)
+{
+	char nv_ip[NV_NAME_LEN] = {0};
+	char nv_gw[NV_NAME_LEN] = {0};
+	char nv_pridns[NV_NAME_LEN] = {0};
+	char nv_secdns[NV_NAME_LEN] = {0};
+	char nv_pridns6[NV_NAME_LEN] = {0};
+	char nv_secdns6[NV_NAME_LEN] = {0};
+	char nv_ip6[NV_NAME_LEN] = {0};
+	//char nv_gw6[NV_NAME_LEN] = {0};
+	char cmd[100] = {0};
+	FILE *fpv4 = NULL;
+	FILE *fpv6 = NULL;
+	
+	system("rm /etc_rw/resolv.conf");
+	
+	if (actinfo->act_info.ip46flag == V4_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		snprintf(nv_ip, sizeof(nv_ip), "%s%d_pdp_ip", ps_wan, actinfo->c_id);
+		cfg_set(nv_ip, actinfo->act_info.ip);
+		snprintf(nv_pridns, sizeof(nv_pridns), "%s%d_pridns", ps_wan, actinfo->c_id);
+		cfg_set(nv_pridns, actinfo->act_info.pri_dns);
+		snprintf(nv_secdns, sizeof(nv_secdns), "%s%d_secdns", ps_wan, actinfo->c_id);
+		cfg_set(nv_secdns, actinfo->act_info.sec_dns);
+		snprintf(nv_gw, sizeof(nv_gw), "%s%d_gw", ps_wan, actinfo->c_id);
+		//Óû§ÅäÖþ²Ì¬gw
+		if (0 != strcmp(actinfo->act_info.gateway, "")) {
+			cfg_set(nv_gw, actinfo->act_info.gateway);
+		}
+		//sprintf(cmd, "/sbin/psext_updown.sh \"linkup\" \"%d\"", actinfo->c_id);
+		sprintf(cmd, "/sbin/psext_updown.sh linkup %d", actinfo->c_id);
+		//zxic_system(cmd);
+		fpv4 = popen(cmd, "r");
+	}
+
+	if (actinfo->act_info.ip46flag == V6_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		snprintf(nv_ip6, sizeof(nv_ip6), "%s%d_ipv6_interface_id", ps_wan, actinfo->c_id);
+		//cfg_set(nv_ip6, actinfo->act_info.ip6);
+		save_interface_id(nv_ip6, actinfo->act_info.ip6);
+		//snprintf(nv_gw6, sizeof(nv_gw6), "%s%d_ipv6_gw", nv_pswan, actinfo->c_id);
+		//cfg_set(nv_gw6, actinfo->act_info.gateway6);
+		snprintf(nv_pridns6, sizeof(nv_pridns6), "%s%d_ipv6_pridns_auto", ps_wan, actinfo->c_id);
+		cfg_set(nv_pridns6, actinfo->act_info.pri_dns6);
+		snprintf(nv_secdns6, sizeof(nv_secdns6), "%s%d_ipv6_secdns_auto", ps_wan, actinfo->c_id);
+		cfg_set(nv_secdns6, actinfo->act_info.sec_dns6);
+		memset(cmd, 0, sizeof(cmd));
+		//sprintf(cmd, "/sbin/psext_updown_ipv6.sh \"linkup\" \"%d\"", actinfo->c_id);
+		sprintf(cmd, "/sbin/psext_updown_ipv6.sh linkup %d", actinfo->c_id);
+		//zxic_system(cmd);
+		fpv6 = popen(cmd, "r");
+	}
+	if(fpv4 != NULL)
+		pclose(fpv4);
+	if(fpv6 != NULL)
+		pclose(fpv6);
+	return 1;
+}
+
+//±£´æPDP¼¤»îµÄÓû§Òâͼ£¬ÒÔ±ãPDPÈ¥»îʱÄܹ»×¼È·ÊÍ·ÅÏà¹ØÍøÂç×ÊÔ´
+void set_pdp_mode(int c_id, unsigned char pdp_type)
+{
+	char pdp_mode[NV_NAME_LEN] = {0};
+
+	sprintf(pdp_mode, "pdp_mode%d", c_id);
+	if (pdp_type == PDP_NORMAL)
+		cfg_set(pdp_mode, "gateway");
+	else if (pdp_type == PDP_EXT)
+		cfg_set(pdp_mode, "bridge");
+	else if (pdp_type == PDP_LOCAL)
+		cfg_set(pdp_mode, "local");
+	else if (pdp_type == PDP_PPP)
+		cfg_set(pdp_mode, "ppp");
+	else
+		softap_assert("pdp_type=%u error", pdp_type);
+}
+
+void reset_pdp_mode(int c_id)
+{
+
+	char pdp_mode[NV_NAME_LEN] = {0};
+
+	sprintf(pdp_mode, "pdp_mode%d", c_id);
+
+	cfg_set(pdp_mode, "");
+
+}
+
+//ÉèÖÃPDP¼¤»îµÄ˫ջ֧³ÖÇé¿ö£¬ÒÔ±ãÉèÖÃNORMALÍâÍø¿ÚµÄDNSʱʹÓã»
+void set_pdp_act_type(int c_id, unsigned char ip46flag)
+{
+	char pdp_act_type[NV_NAME_LEN] = { 0 };
+	sprintf(pdp_act_type, "pdp_act_type%d", c_id);
+
+	if (ip46flag == V4_VALID)
+		cfg_set(pdp_act_type, "IPv4");
+	else if (ip46flag == V6_VALID)
+		cfg_set(pdp_act_type, "IPv6");
+	else if (ip46flag == V46_VALID)
+		cfg_set(pdp_act_type, "IPv4v6");
+	else
+		softap_assert("ip46flag=%u error", ip46flag);
+}
+
+void vlan_config(unsigned int sw_type, char* act)
+{
+	char dev_name[NV_NAME_LEN] = {0};
+	char eth_lan[NV_NAME_LEN] = {0};
+	char sw_name[NV_NAME_LEN] = {0};
+	char swport[NV_NAME_LEN] = {0};
+	char cmd[100] = {0};
+	char* str_point = NULL;
+
+	if (sw_type == RJ45_WAN_DEV) {
+		cfg_get_item("ethwan", dev_name, sizeof(dev_name));
+	} else {
+		cfg_get_item("ethlan", dev_name, sizeof(dev_name));
+	}
+	str_point = strchr(dev_name, '.');
+	if (str_point == NULL)
+		return;
+	if (0 == strcmp(act, "add")) {
+		strncpy(swport, str_point + 1, sizeof(swport)-1);
+		strncpy(sw_name, dev_name, str_point - dev_name);
+		sw_name[str_point - dev_name + 1] = '\0';
+		sprintf(cmd, "/sbin/vconfig add %s %s", sw_name, swport);
+		zxic_system(cmd);
+		memset(cmd, 0x00, sizeof(cmd));
+		sprintf(cmd, "/sbin/vconfig set_flag %s 1 1", dev_name);
+		zxic_system(cmd);
+	} else {
+		sprintf(cmd, "/sbin/vconfig rem %s", dev_name);
+		zxic_system(cmd);
+	}
+}
+void ethwan_plugin()
+{
+	char eth_dialmode[NV_NAME_LEN] = {0};
+	char eth_type[NV_NAME_LEN] = {0};
+	char ethwan_name[NV_NAME_LEN] = {0};
+	char rj45_pluginstate[NV_NAME_LEN] = {0};
+	int plugstate = 0;
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	cfg_get_item("ethwan_dialmode", eth_dialmode, sizeof(eth_dialmode));
+	cfg_get_item("eth_type", eth_type, sizeof(eth_type));
+	cfg_get_item("ethwan", ethwan_name, sizeof(ethwan_name));
+	
+	if (0 == strcmp(eth_type, "auto") || 0 == strcmp(eth_type, "")) {
+		cfg_set("rj45_state", "idle");
+		cfg_set("eth_curtype", "");
+		vlan_config(RJ45_WAN_DEV, "add");
+		if(strchr(ethwan_name, '.') == NULL)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+		{//Ö»Óе¥phy²ÅÉèÖÃ180s¶¨Ê±Æ÷£¬³¬Ê±»¹Î´»ñÈ¡ipµØÖ·Ôò½«ethwanÌí¼Óbr0ÇÅÏÂ
+			creattimer(&ethwan_id);
+		}
+		system("auto_dial.sh \"ethwan\"");
+	} else if (0 == strcmp(eth_type, "wan")) {
+		cfg_set("eth_curtype", "wan");
+		if(strchr(ethwan_name, '.') != NULL)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+		{
+			set_ethwan_port_mode(1);
+		}
+		
+		vlan_config(RJ45_WAN_DEV, "add");
+		cfg_set("rj45_state", "idle");
+		if (0 == strcmp(eth_dialmode, "auto") || 0 == strcmp(eth_dialmode, "ondemand")) {
+			cfg_set("rj45_state", "connect");
+			if(strchr(ethwan_name, '.') == NULL)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+			{//Ö»Óе¥phy²ÅÉèÖÃ180s¶¨Ê±Æ÷£¬³¬Ê±»¹Î´»ñÈ¡ipµØÖ·Ôò½«ethwanÌí¼Óbr0ÇÅÏÂ
+				creattimer(&ethwan_id);
+			}
+			system("wan_ipv4.sh \"linkup\" \"ethwan\"");
+			if(atoi(wbwanv6_enable) == 1)
+				system("wan_ipv6.sh \"linkup\" \"ethwan\"");
+		}
+	} else if (0 == strcmp(eth_type, "lan")) {
+		cfg_set("eth_curtype", "lan");
+		if(strchr(ethwan_name, '.') != NULL)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+		{
+			set_ethwan_port_mode(0);
+			cfg_get_item("rj45_pluginstate", rj45_pluginstate, sizeof(rj45_pluginstate));
+			plugstate = atoi(rj45_pluginstate);
+			if((plugstate & RJ45_LAN_IN)  == 0)
+			{
+				vlan_config(RJ45_LAN_DEV, "add");
+				system("landev_updown.sh \"ethlan\" \"up\"");
+				cfg_set("wanport3_in_lan", "1");
+			}
+		}
+		else
+		{
+			system("landev_updown.sh \"ethwan\" \"up\"");
+		}
+		slog(NET_PRINT, SLOG_NORMAL, "rj45 as lan plugin end!\n");
+	}
+
+}
+void ethlan_plugin()
+{
+	char lanflag[8] = {0};
+	char ethwan_name[NV_NAME_LEN] = {0};
+
+	cfg_get_item("ethwan", ethwan_name, sizeof(ethwan_name));
+	cfg_get_item("wanport3_in_lan", lanflag, sizeof(lanflag));
+	if(strchr(ethwan_name, '.') != NULL && strcmp(lanflag, "1") == 0)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+	{//switchÐÎ̬ÇÒwan¿Ú¶ÔÓ¦port3ÒѾ­¼ÓÈëvlan100,¼´eth0.100ÒѾ­´´½¨ÇÒ¹ÒÔÚbr0ÏÂ
+		slog(NET_PRINT, SLOG_NORMAL, "rj45 eth0.100 has been created and mounted to br0!\n");
+		return;
+	}
+	
+	vlan_config(RJ45_LAN_DEV, "add");
+	system("landev_updown.sh \"ethlan\" \"up\"");
+	slog(NET_PRINT, SLOG_NORMAL, "rj45 as lan plugin end!\n");
+}
+
+void ethwan_plugout()
+{
+	char eth_curtype[NV_NAME_LEN] = {0};
+	char cmd[100] = {0};
+	char ethwan_name[32] = {0};
+	char rj45_pluginstate[NV_NAME_LEN] = {0};
+	int plugstate = 0;
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	//msg_timedel();
+	system("killall eth_auto_connect");
+	deletetimer(ethwan_id);
+	slog(NET_PRINT, SLOG_NORMAL, "plugout ..... deletetimer.....");
+	cfg_get_item("eth_curtype", eth_curtype, sizeof(eth_curtype));
+	cfg_set("eth_curtype", "");
+	
+	cfg_get_item("ethwan", ethwan_name, sizeof(ethwan_name));
+
+	if (0 == strcmp(eth_curtype, "wan")) {
+		system("wan_ipv4.sh \"linkdown\" \"ethwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"ethwan\"");
+	} else if (0 == strcmp(eth_curtype, "lan")) {	
+		//switchÐÎ̬´ËʱûÓÐeth0.200Íø¿Ú
+		if(strchr(ethwan_name, '.') != NULL)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+		{
+			cfg_get_item("rj45_pluginstate", rj45_pluginstate, sizeof(rj45_pluginstate));
+			plugstate = atoi(rj45_pluginstate);
+			if((plugstate & RJ45_LAN_IN)  == 0)
+			{
+				system("landev_updown.sh \"ethlan\" \"down\"");
+				vlan_config(RJ45_LAN_DEV, "rem");
+				cfg_set("wanport3_in_lan", "0");
+			}
+		}
+		else
+		{
+			system("landev_updown.sh \"ethwan\" \"down\"");			
+		}
+		slog(NET_PRINT, SLOG_NORMAL, "rj45 as lan plugout end!\n");
+	} else {
+		system("wan_ipv4.sh \"linkdown\" \"ethwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"ethwan\"");
+		system("landev_updown.sh \"ethwan\" \"down\"");
+	}
+
+	cfg_set("rj45_state", "dead");
+	vlan_config(RJ45_WAN_DEV, "rem");
+	if(strchr(ethwan_name, '.') != NULL)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+	{
+		set_ethwan_port_mode(1);	//½«switchµÄwan¿Úport3»¹Ô­³Éwan£¬·ñÔòÏ´βåÈëport3¿ÉÄÜ»¹ÊÇlan¿Ú
+	}
+}
+void ethlan_plugout()
+{
+	char lanflag[8] = {0};
+	char ethwan_name[NV_NAME_LEN] = {0};
+
+	cfg_get_item("ethwan", ethwan_name, sizeof(ethwan_name));
+	cfg_get_item("wanport3_in_lan", lanflag, sizeof(lanflag));
+	if(strchr(ethwan_name, '.') != NULL && strcmp(lanflag, "1") == 0)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+	{//switchÐÎ̬ÇÒwan¿Ú¶ÔÓ¦port3ÒѾ­¼ÓÈëvlan100,¼´eth0.100Ï»¹ÓÐport3¶Ë¿Ú£¬ËùÒÔ»¹²»ÄÜɾ³ýeth0.100
+		slog(NET_PRINT, SLOG_NORMAL, "rj45 eth0.100 has been created and mounted to br0!\n");
+		return;
+	}
+	
+	system("landev_updown.sh \"ethlan\" \"down\"");
+	vlan_config(RJ45_LAN_DEV, "rem");
+	slog(NET_PRINT, SLOG_NORMAL, "rj45 as lan plugout end!\n");
+}
+
+void wifi_plugin()
+{
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	cfg_set("wifi_state", "idle");
+	creattimer(&wifiwan_id);
+	system("wan_ipv4.sh \"linkup\" \"wifiwan\"");
+	if(atoi(wbwanv6_enable) == 1)
+		system("wan_ipv6.sh \"linkup\" \"wifiwan\"");
+}
+
+
+/*rj45 ÍâÍø¿Úʱ£¬¸ù¾Ýµ±Ç°×´Ì¬£¬ÈôΪworking or init or nullÔòÏÈlinkdown£¬É±ËÀÏà¹Ø½ø³Ì£¬È»ºóÆôÓã»ÈôΪdeadÔòÖ±½ÓÆôÓÃ*/
+void eth_connect()
+{
+	char ethwan_name[NV_NAME_LEN] = {0};
+	char eth_curtype[NV_NAME_LEN] = {0};
+	char work_state[NV_NAME_LEN] = {0};
+	//rj45Ö§³Öwan/lan¹¦ÄÜ£¬¿ÉÑ¡Ôñ³ÉΪÍâÍø¿Ú»òÄÚÍø¿Ú
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	vlan_config(RJ45_WAN_DEV, "add");
+	cfg_get_item("eth_curtype", eth_curtype, sizeof(eth_curtype));
+	cfg_get_item("ethwan", ethwan_name, sizeof(ethwan_name));
+	if (0 == strcmp(eth_curtype, "lan")) {
+		system("landev_updown.sh \"ethwan\" \"up\"");
+		slog(NET_PRINT, SLOG_NORMAL, "rj45 as lan connect end!\n");
+	} else { // ĬÈÏ×÷Ϊwan¿Ú´¦Àí
+		cfg_get_item("rj45_state", work_state, sizeof(work_state));
+		//work_state=deadÔòµ±Ç°´¦ÓÚ¶Ï¿ª×´Ì¬£¬Ö±½Ólinkup£¬ÆäËû×´¿öÏÈlinkdown
+		if (0 == strcmp(work_state, "connect") || 0 == strcmp(work_state, "working")) {
+			system("wan_ipv4.sh \"linkdown\" \"ethwan\"");
+			if(atoi(wbwanv6_enable) == 1)
+				system("wan_ipv6.sh \"linkdown\" \"ethwan\"");
+			cfg_set("rj45_state", "connect");
+			if(strchr(ethwan_name, '.') == NULL)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+			{//Ö»Óе¥phy²ÅÉèÖÃ180s¶¨Ê±Æ÷£¬³¬Ê±»¹Î´»ñÈ¡ipµØÖ·Ôò½«ethwanÌí¼Óbr0ÇÅÏÂ
+				creattimer(&ethwan_id);
+			}
+			system("wan_ipv4.sh \"linkup\" \"ethwan\"");
+			if(atoi(wbwanv6_enable) == 1)
+				system("wan_ipv6.sh \"linkup\" \"ethwan\"");
+		} else if (0 == strcmp(work_state, "idle")) {
+			cfg_set("rj45_state", "connect");
+			if(strchr(ethwan_name, '.') == NULL)//¸ù¾ÝnvÏîethwanÖµÊÇ·ñÓÐ'.'À´ÅжÏÊÇswitch»¹Êǵ¥phy	
+			{//Ö»Óе¥phy²ÅÉèÖÃ180s¶¨Ê±Æ÷£¬³¬Ê±»¹Î´»ñÈ¡ipµØÖ·Ôò½«ethwanÌí¼Óbr0ÇÅÏÂ
+				creattimer(&ethwan_id);
+			}
+			system("wan_ipv4.sh \"linkup\" \"ethwan\"");
+			if(atoi(wbwanv6_enable) == 1)
+				system("wan_ipv6.sh \"linkup\" \"ethwan\"");
+		} else if (0 == strcmp(work_state, "dead") || 0 == strcmp(work_state, ""))
+			return;
+		else
+			softap_assert("rj45_state=%s error", work_state);
+
+	}
+
+}
+
+//wifi stationÍâÍø¿ÚµÄµØÖ··ÖÅäÇëÇóÁ÷³Ì£¬Èô֮ǰÒѾ­´¦ÓÚworking̬£¬ÐèÒªÏÈÇå³ýËùÓÐ×ÊÔ´
+void wifi_connect()
+{
+	char work_state[NV_NAME_LEN] = {0};
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	cfg_get_item("wifi_state", work_state, sizeof(work_state));
+	if (0 == strcmp(work_state, "connect") || 0 == strcmp(work_state, "working")) {
+		system("wan_ipv4.sh \"linkdown\" \"wifiwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"wifiwan\"");
+		cfg_set("wifi_state", "connect");
+		creattimer(&wifiwan_id);
+		system("wan_ipv4.sh \"linkup\" \"wifiwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkup\" \"wifiwan\"");
+	} else {
+		cfg_set("wifi_state", "connect");
+		creattimer(&wifiwan_id);
+		system("wan_ipv4.sh \"linkup\" \"wifiwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkup\" \"wifiwan\"");
+	}
+}
+
+int pdp_act_check(struct pdp_active_info *actinfo)
+{
+	char ps_ip[32] = {0};
+	char ps_ip6[64] = {0};
+	char nv_ip[NV_NAME_LEN] = {0};
+	char nv_ip6[NV_NAME_LEN] = {0};
+	if (actinfo->act_info.ip46flag == V4_VALID || actinfo->act_info.ip46flag == V46_VALID) {
+		snprintf(nv_ip, sizeof(nv_ip), "%s%d_ip", ps_wan, actinfo->c_id);
+		cfg_get_item(nv_ip, ps_ip, sizeof(ps_ip));
+		if (0 != strcmp(ps_ip, "0.0.0.0") && (0 != strcmp(ps_ip, ""))) {
+			slog(NET_PRINT, SLOG_ERR, "pdp_act_init: already act ip=%s", ps_ip); //cov m
+			return 0;
+		}
+	}
+	/*if (actinfo->act_info.ip46flag == V6_VALID || actinfo->act_info.ip46flag == V46_VALID)
+	{
+	    sprintf(nv_ip6,"ps%d_ipv6_ip", actinfo->c_id);
+	    cfg_get_item(nv_ip6, ps_ip6, sizeof(ps_ip6));
+	    if ((0 != strcmp(ps_ip6, "::")) && (0 != strcmp(ps_ip6, "")))
+	    {
+	        return 0;
+	    }
+	}*/
+	return 1;
+}
+
+
+void set_def_wan(char *wanif, char *wantype)
+{
+	char cmd_test[200] = {0};
+
+	cfg_set("default_wan_name", wanif);
+	cfg_set("default_wan_rel", wantype);
+	//if(0 == strncmp(wanif,"ps",2))
+	//    cfg_set("wan_name", wanif);
+
+	slog(NET_PRINT, SLOG_NORMAL, "set default_wan_name = %s \n", wanif);
+	//Èç¹ûĬÈÏÍâÍø¿ÚÊǶÔЭÒéÕ»µÄ£¬ÐèÒª½«Íø¿ÚÃû´«µÝ¸øÄÚºËʵÏÖ¿ìËÙת·¢Æ½Ì¨»°
+	if (strncmp(wanif, ps_wan, strlen(ps_wan)) == 0) {
+		memset(cmd_test, 0, sizeof(cmd_test));
+		sprintf(cmd_test, "echo %s > /proc/net/ps_name", wanif);
+		system_cmd_ex(cmd_test);
+	}
+}
+
+void set_def_wan6(char *wanif, char *wantype)
+{
+	//char cmd_test[200] = {0};
+
+	cfg_set("default_wan6_name", wanif);
+	cfg_set("default_wan6_rel", wantype);
+	//if(0 == strncmp(wanif,"ps",2))
+	//    cfg_set("wan_name6", wanif);
+	slog(NET_PRINT, SLOG_NORMAL, "set default_wan6_name = %s, default_wan6_rel = %s \n", wanif, wantype);
+	//sprintf(cmd_test,"echo test: set default_wan6_name = %s, default_wan6_rel = %s >> /mnt/jffs2/te.log ", wanif, wantype);
+	//system_cmd_ex(cmd_test);
+}
+
+/*set dns in resolv.conf */
+void defwan_set(char *wanif)
+{
+	if (0 == strcmp(wanif, eth_wan))
+		system("defwan_set.sh \"ethwan\"");
+	else if (0 == strcmp(wanif, wifi_wan))
+		system("defwan_set.sh \"wifiwan\"");
+	else
+		system("defwan_set.sh \"pswan\"");
+}
+
+void ddns_set(void)
+{
+	char ddns_enable[NV_NAME_LEN] = {0};
+	char ddns_mode[NV_NAME_LEN] = {0};
+	cfg_get_item("DDNS_Enable", ddns_enable, sizeof(ddns_enable));
+	cfg_get_item("DDNS_Mode", ddns_mode, sizeof(ddns_mode));
+
+	if (0 == strcmp(ddns_enable, "1") && 0 == strcmp(ddns_mode, "auto"))
+		system_cmd_ex("ddns.sh");
+}
+
+/*
+     deal with msg  MSG_CMD_NET_WAN4_CHANGE
+     choose the largest xxxwan_priority in wan who is up
+     set default_wan nv
+     if changed then reset firewall
+*/
+void proc_wan_change_v4(void)
+{
+	slog(NET_PRINT, SLOG_NORMAL, "proc_wan_change_v4 start!\n");
+	char wan_pri[32] = {0};
+	char cid[20] = {0};
+	int defwan_pri = 0;
+	int pri = 0;
+	char nv_pswan[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	char nv_usbwan[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	char nv_ethwan[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	char nv_wifiwan[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	char pswan_ip[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	//char usbwan_ip[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	char ethwan_ip[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	char wifiwan_ip[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	char defwan_if[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	char defwan_real[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	char defwan_dev_name[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	char ethwan_actprotl[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	int defwan_change = 0;
+	struct default_dev_info defwan_dev_info;
+	defwan_dev_info.ip46flag = V4_VALID;
+
+	//sprintf(nv_usbwan,"%s_ip", usb_wan);
+	//cfg_get_item(nv_usbwan, usbwan_ip, sizeof(usbwan_ip));
+	//¶ÔÓÚswÍø¿Ú£¬ethwanµÄÉèÖÃÊÇÔÚÈȲ岥ʱÉèÖõģ¬ÔÚzte_routerÆô¶¯£¬
+	//³õʼ»¯eth_wanʱ£¬ÓпÉÄÜÉÐδÍê³É¸ÃÉèÖã¬Òò´ËÐèÒªÖØÐ»ñÈ¡É豸Ãû
+	cfg_get_item("ethwan", eth_wan, sizeof(eth_wan));
+	snprintf(nv_ethwan, sizeof(nv_ethwan), "%s_ip", eth_wan);
+	cfg_get_item(nv_ethwan, ethwan_ip, sizeof(ethwan_ip));
+	snprintf(nv_wifiwan, sizeof(nv_wifiwan), "%s_ip", wifi_wan);
+	cfg_get_item(nv_wifiwan, wifiwan_ip, sizeof(wifiwan_ip));
+	//cfg_get_item("wlan0_ip", wifiwan_ip, sizeof(wifiwan_ip));//wlan0ÊÊÅä
+
+	cfg_get_item("default_cid", cid, sizeof(cid));
+	if (0 != strcmp(cid, "")) {
+		snprintf(nv_pswan, sizeof(nv_pswan), "%s%s_ip", ps_wan, cid);
+		cfg_get_item(nv_pswan, pswan_ip, sizeof(pswan_ip));
+		if (0 != strcmp(pswan_ip, "0.0.0.0") && (0 != strcmp(pswan_ip, ""))) {
+			memset(wan_pri, 0, sizeof(wan_pri));
+			cfg_get_item("pswan_priority", wan_pri, sizeof(wan_pri));
+			pri = atoi(wan_pri);
+			if (pri > defwan_pri) {
+				defwan_pri = pri;
+				snprintf(defwan_if, sizeof(defwan_if), "%s%s", ps_wan, cid);
+				strcpy(defwan_real, defwan_if);
+				strcpy(defwan_dev_name, ps_wan);
+			}
+		}
+	}
+	if (0 != strcmp(ethwan_ip, "0.0.0.0") && (0 != strcmp(ethwan_ip, ""))) {
+		memset(wan_pri, 0, sizeof(wan_pri));
+		cfg_get_item("ethwan_priority", wan_pri, sizeof(wan_pri));
+		pri = atoi(wan_pri);
+		if (pri > defwan_pri) {
+			defwan_pri = pri;
+			cfg_get_item("eth_curmode", ethwan_actprotl, sizeof(ethwan_actprotl));
+
+			if (0 == strcmp(ethwan_actprotl, "pppoe"))
+				strcpy(defwan_real, "ppp0");
+			else
+				strcpy(defwan_real, eth_wan);
+			strcpy(defwan_if, eth_wan);
+			strcpy(defwan_dev_name, eth_wan);
+		}
+	}
+
+	if (0 != strcmp(wifiwan_ip, "0.0.0.0") && (0 != strcmp(wifiwan_ip, ""))) {
+		memset(wan_pri, 0, sizeof(wan_pri));
+		cfg_get_item("wifiwan_priority", wan_pri, sizeof(wan_pri));
+		pri = atoi(wan_pri);
+		if (pri > defwan_pri) {
+			defwan_pri = pri;
+			strcpy(defwan_if, wifi_wan);
+			strcpy(defwan_real, wifi_wan);
+			strcpy(defwan_dev_name, wifi_wan);
+		}
+	}
+
+	//½«µ±Ç°ÓÐÐ§Íø¿ÚÖÐÓÅÏȼ¶×î¸ßµÄÉèÖÃΪȱʡÍâÍø¿Ú
+	set_def_wan(defwan_if, defwan_real);
+
+	slog(NET_PRINT, SLOG_NORMAL, "proc_wan_change_v4 old:%s, now:%s! \n", defwan_if_old, defwan_real);
+
+	//½«È±Ê¡ÍâÍø¿ÚµÄdev_id·¢Ë͸øÖ÷¿Ø
+	//if (strlen(defwan_dev_name) == 0 || 0 != strcmp(defwan_if_old, defwan_real))
+	{
+		defwan_dev_info.dev_id = getDevId_byname(defwan_dev_name);
+
+		net_default_wan_proc(&defwan_dev_info);
+
+		//char tmp_name[20]= {0};
+		//sprintf(tmp_name,"zte_blc");
+	}
+	//dns_set(defwan_if);
+
+	if (0 == strlen(defwan_real)) {
+		slog(NET_PRINT, SLOG_ERR, "proc_wan_change_v4 defwan_if not selected! \n");
+		net_sendmsg_2_atctl(atoi(cid), V4_VALID, MSG_CMD_LINKUP_END);
+		return;
+	}
+
+	if (strcmp(defwan_if_old, defwan_real) != 0)
+		defwan_change = 1;
+
+	//Êý¾ÝÏÈͨ£¬ºó×öÆäËûÅäÖã¬×¢Òâµã: ·À»ðǽ¶Ìʱ¼äÄÚ¿ÉÄÜδÉúЧ
+	if (defwan_change)
+		system_cmd_ex("nat.sh");
+	defwan_set(defwan_if);
+
+	system("cat /proc/uptime 1>dev/console 2>&1");
+	slog(NET_PRINT, SLOG_NORMAL, "proc_wan_change_v4 data ok, defwan_change:%d \n", defwan_change);
+
+	//ȱʡÍâÍø¿Ú·¢Éú±ä»¯ÔòÖØÉènatºÍfilter
+	if (defwan_change) {
+		zte_router_init();
+		//dns_set(defwan_if);
+		memset(defwan_if_old, 0, ZTE_ROUTER_WAN_IF_NAME_LEN);
+		strncpy(defwan_if_old, defwan_real, strlen(defwan_real));
+	}
+	zte_unpn_set();
+	ddns_set();
+
+	net_sendmsg_2_atctl(atoi(cid), V4_VALID, MSG_CMD_LINKUP_END);
+	
+	system("cat /proc/uptime 1>dev/console 2>&1");
+	slog(NET_PRINT, SLOG_NORMAL, "proc_wan_change_v4 end \n");
+}
+
+/*
+     deal with msg  MSG_CMD_NET_WAN6_CHANGE
+     choose the largest xxxwan_priority from the up-wans
+     set default_wan nv
+     if changed then reset firewall
+*/
+void proc_wan_change_v6(void)
+{
+	slog(NET_PRINT, SLOG_NORMAL, "proc_wan_change_v6 start!\n");
+	char cid[20] = {0};
+	char wan_pri[32] = {0};
+	int defwan_pri = 0;
+	int pri = 0;
+	char nv_pswan_ipv6[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	char nv_ethwan_ipv6[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	char nv_wifiwan_ipv6[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	char pswan_ipv6[ZTE_ROUTER_IPV6_ADDR_LEN] = {0};
+	//char usbwan_ipv6[ZTE_ROUTER_IPV6_ADDR_LEN] = {0};
+	char ethwan_ipv6[ZTE_ROUTER_IPV6_ADDR_LEN] = {0};
+	char wifiwan_ipv6[ZTE_ROUTER_IPV6_ADDR_LEN] = {0};
+	char defwan_if_ipv6[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	char defwan_real_ipv6[ZTE_ROUTER_IP_ADDR_LEN] = {0};
+	char ethwan_actprotl[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	char defwan_dev_name[ZTE_ROUTER_WAN_IF_NAME_LEN] = {0};
+	struct default_dev_info defwan_dev_info;
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	defwan_dev_info.ip46flag = V6_VALID;
+
+	cfg_get_item("ethwan", eth_wan, sizeof(eth_wan));
+	sprintf(nv_ethwan_ipv6, "%s_ipv6_ip", eth_wan);
+	//cfg_get_item("usb0_ipv6_ipaddr", usbwan_ipv6, sizeof(usbwan_ipv6));
+
+	cfg_get_item(nv_ethwan_ipv6, ethwan_ipv6, sizeof(ethwan_ipv6));
+	sprintf(nv_wifiwan_ipv6, "%s_ipv6_ip", wifi_wan);
+	cfg_get_item(nv_wifiwan_ipv6, wifiwan_ipv6, sizeof(wifiwan_ipv6));
+
+	cfg_get_item("default_cid", cid, sizeof(cid));
+	if (0 != strcmp(cid, "")) {
+		snprintf(nv_pswan_ipv6, sizeof(nv_pswan_ipv6), "%s%s_ipv6_ip", ps_wan, cid);
+		cfg_get_item(nv_pswan_ipv6, pswan_ipv6, sizeof(pswan_ipv6));
+		if ((0 != strcmp(pswan_ipv6, "::")) && (0 != strcmp(pswan_ipv6, ""))) {
+			memset(wan_pri, 0, sizeof(wan_pri));
+			cfg_get_item("pswan_priority", wan_pri, sizeof(wan_pri));
+
+			pri = atoi(wan_pri);
+			if (pri > defwan_pri) {
+				defwan_pri = pri;
+				snprintf(defwan_if_ipv6, sizeof(defwan_if_ipv6), "%s%s", ps_wan, cid);
+				strcpy(defwan_real_ipv6, defwan_if_ipv6);
+				strcpy(defwan_dev_name, ps_wan);
+			}
+		}
+	}
+	if ((0 != strcmp(ethwan_ipv6, "::")) && (0 != strcmp(ethwan_ipv6, ""))) {
+		memset(wan_pri, 0, sizeof(wan_pri));
+		cfg_get_item("ethwan_priority", wan_pri, sizeof(wan_pri));
+
+		pri = atoi(wan_pri);
+		if (pri > defwan_pri) {
+			defwan_pri = pri;
+			cfg_get_item("eth_curmode", ethwan_actprotl, sizeof(ethwan_actprotl));
+
+			if (0 == strcmp(ethwan_actprotl, "pppoe"))
+				strcpy(defwan_real_ipv6, "ppp0");
+			else
+				strcpy(defwan_real_ipv6, eth_wan);
+			strcpy(defwan_if_ipv6, eth_wan);
+			strcpy(defwan_dev_name, eth_wan);
+			cfg_set("eth_act_type", "IPv4v6");
+		}
+	}
+
+	if ((0 != strcmp(wifiwan_ipv6, "::")) && (0 != strcmp(wifiwan_ipv6, ""))) {
+		memset(wan_pri, 0, sizeof(wan_pri));
+		cfg_get_item("wifiwan_priority", wan_pri, sizeof(wan_pri));
+
+		pri = atoi(wan_pri);
+		if (pri > defwan_pri) {
+			defwan_pri = pri;
+			strcpy(defwan_if_ipv6, wifi_wan);
+			strcpy(defwan_real_ipv6, wifi_wan);
+			strcpy(defwan_dev_name, wifi_wan);
+			cfg_set("wifi_act_type", "IPv4v6");
+		}
+	}
+
+	set_def_wan6(defwan_if_ipv6, defwan_real_ipv6);
+	//½«È±Ê¡ÍâÍø¿ÚµÄdev_id·¢Ë͸øÖ÷¿Ø
+	//if (strlen(defwan_dev_name) == 0 || strcmp(defwan6_if_old, defwan_real_ipv6)!=0)
+	{
+		defwan_dev_info.dev_id = getDevId_byname(defwan_dev_name);
+
+		net_default_wan_proc(&defwan_dev_info);
+
+		//char tmp_name[20]= {0};
+		//sprintf(tmp_name,"zte_blc");
+	}
+
+	if (0 == strlen(defwan_real_ipv6)) {
+		slog(NET_PRINT, SLOG_ERR, "proc_wan_change_v6 defwan_if_ipv6 not selected! \n");
+		net_sendmsg_2_atctl(atoi(cid), V6_VALID, MSG_CMD_LINKUP_END);
+		return;
+	}
+	slog(NET_PRINT, SLOG_NORMAL, "proc_wan_change_v6 %s -> %s \n", defwan6_if_old, defwan_real_ipv6);
+	if (strcmp(defwan6_if_old, defwan_real_ipv6) != 0) {
+		int ps_wan_len = strlen(ps_wan);
+		if (0 == strcmp(defwan6_if_old, eth_wan) && atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"ethwan\"");
+		else if (0 == strcmp(defwan6_if_old, wifi_wan) && atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"wifi_wan\"");
+		else if (ps_wan_len < strlen(defwan6_if_old) && 0 == strncmp(defwan6_if_old, ps_wan, ps_wan_len)){
+			char cmd[100] = {0};
+			int cid = defwan6_if_old[ps_wan_len] - '0';
+			if(cid > 0 && cid < 9){
+				sprintf(cmd, "/sbin/wan_ipv6.sh linkdown pswan %d", cid);
+				zxic_system(cmd);
+			}
+		}
+	}
+	//Êý¾ÝÏÈͨ£¬ºó×öÆäËûÅäÖã¬×¢Òâµã: ·À»ðǽ¶Ìʱ¼äÄÚ¿ÉÄÜδÉúЧ
+	if (0 == strcmp(defwan_if_ipv6, eth_wan) && atoi(wbwanv6_enable) == 1)
+		system("wan_ipv6_config.sh \"ethwan\"");
+	else if (0 == strcmp(defwan_if_ipv6, wifi_wan) && atoi(wbwanv6_enable) == 1)
+		system("wan_ipv6_config.sh \"wifiwan\"");
+	else
+		system("wan_ipv6_config.sh \"pswan\"");
+
+	defwan_set(defwan_if_ipv6);
+
+	system("cat /proc/uptime 1>dev/console 2>&1");
+	slog(NET_PRINT, SLOG_NORMAL, "proc_wan_change_v6 data ok \n");
+
+	//Èç¹ûĬÈÏwan¿ÚÓб䣬ÐèÒªÖØÐÂÅäÖ÷ÓÉ¡¢·À»ðǽµÈÐÅÏ¢
+	if (strcmp(defwan6_if_old, defwan_real_ipv6) != 0) {
+		zte_router_init();
+		memset(defwan6_if_old, 0, ZTE_ROUTER_WAN_IF_NAME_LEN);
+		strncpy(defwan6_if_old, defwan_real_ipv6, sizeof(defwan6_if_old)-1);
+	}
+	zte_unpn_set();
+
+	net_sendmsg_2_atctl(atoi(cid), V6_VALID, MSG_CMD_LINKUP_END);
+
+	system("cat /proc/uptime 1>dev/console 2>&1");
+	slog(NET_PRINT, SLOG_NORMAL, "proc_wan_change_v6 end \n");
+}
+
+void * msg_timeout(void* arg)
+{
+	int ret = 0;
+	unsigned char netdev_id = *(unsigned char*)arg;
+
+	ret = ipc_send_message(MODULE_ID_WEB_CGI, MODULE_ID_MAIN_CTRL, MSG_CMD_NET_TIMER_OUT, sizeof(unsigned char), (UCHAR *)&netdev_id, 0);
+	if (0 != ret) {
+		softap_assert("send msg to zte_mainctrl error");
+		return NULL;//klocwork
+	}
+	return NULL;
+}
+
+void msg_timedel()
+{
+	int ret = 0;
+
+	ret = ipc_send_message(MODULE_ID_WEB_CGI, MODULE_ID_MAIN_CTRL, MSG_CMD_NET_TIMER_DEL, 0, 0, 0);
+	if (0 != ret) {
+		softap_assert("send msg to zte_mainctrl error");
+		return;
+	}
+}
+//µ±³¬Ê±ºó£¬ÍøÂçÄÚ²¿Í£Ö¹µØÖ·ÇëÇóÏà¹Ø¶¯×÷£¬²¢·¢ËÍÏûÏ¢¸øÖ÷¿Ø
+void out_of_time(unsigned char netdev_id)
+{
+	struct dialfail_dev_info dialfail_dev_info = {0};
+	dialfail_dev_info.ip46flag = V4_VALID;
+	dialfail_dev_info.dev_id = netdev_id;
+	dialfail_dev_info.dialfail_reason = TIME_OUT;
+	char tmp_name[20] = {0};
+	char rj45_pluginstate[NV_NAME_LEN] = {0};
+	int plugstate = 0;
+	char wbwanv6_enable[NV_NAME_LEN] = {0};
+	cfg_get_item("wbwanv6_enable", wbwanv6_enable, sizeof(wbwanv6_enable));
+	if (netdev_id == RJ45_WAN_DEV || netdev_id == SW_WAN_DEV) {
+		char eth_dev[NV_NAME_LEN] = {0};
+		char cmd[100] = {0};
+		system("wan_ipv4.sh \"linkdown\" \"ethwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"ethwan\"");
+		cfg_set("rj45_state", "idle");
+		cfg_get_item("ethwan", eth_dev, sizeof(eth_dev));
+		if (strchr(eth_dev, '.')) {
+			set_ethwan_port_mode(0);
+			sprintf(cmd, "/sbin/vconfig rem %s", eth_dev);
+			zxic_system(cmd);
+
+			cfg_get_item("rj45_pluginstate", rj45_pluginstate, sizeof(rj45_pluginstate));
+			plugstate = atoi(rj45_pluginstate);
+			if((plugstate & RJ45_LAN_IN) == 0)
+			{
+				system("landev_updown.sh \"ethlan\" \"down\"");
+				vlan_config(RJ45_LAN_DEV, "rem");
+				cfg_set("wanport3_in_lan", "0");
+			}
+		}
+	} else if (netdev_id == WIFI_WAN_DEV) {
+		system("wan_ipv4.sh \"linkdown\" \"wifiwan\"");
+		if(atoi(wbwanv6_enable) == 1)
+			system("wan_ipv6.sh \"linkdown\" \"wifiwan\"");
+		cfg_set("wifi_state", "idle");
+		ipc_send_message(MODULE_ID_MAIN_CTRL, MODULE_ID_WIFI, MSG_CMD_NET_WAN_DIAL_FAIL, 0, NULL, 0);
+	}
+
+	//Á¬½Ó³¬Ê±Ö®ºó·¢ËÍÏûÏ¢¸øÖ÷¿Ø
+	sprintf(tmp_name, "zte_blc");
+	slog(NET_PRINT, SLOG_ERR, "out_of_time: send MSG_CMD_NET_WAN_DIAL_FAIL msg to mainctl,netdev_id=%u\n", dialfail_dev_info.dev_id);
+
+}
+
+void creattimer(unsigned char *netdev_id)
+{
+	DeleteSoftTimer(TIMER_MainCtrl_NetID + *netdev_id);
+	CreateSoftTimer(TIMER_MainCtrl_NetID + *netdev_id, TIMER_FLAG_ONCE, ConnectWaitTime, msg_timeout, (void*)netdev_id);
+}
+
+
+
+void deletetimer(unsigned char netdev_id)
+{
+	slog(NET_PRINT, SLOG_NORMAL, "deletetimer: netdev_id=%u\n", netdev_id);
+	DeleteSoftTimer(TIMER_MainCtrl_NetID + netdev_id);
+}
+
+