1/*
2
3	Copyright 2005, Broadcom Corporation
4	All Rights Reserved.
5
6	THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
7	KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
8	SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
9	FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
10
11*/
12/*
13
14	wificonf, OpenWRT
15	Copyright (C) 2005 Felix Fietkau <nbd@vd-s.ath.cx>
16
17*/
18/*
19
20	Modified for Tomato Firmware
21	Portions, Copyright (C) 2006-2009 Jonathan Zarate
22
23*/
24
25#include <rc.h>
26
27#ifndef UU_INT
28typedef u_int64_t u64;
29typedef u_int32_t u32;
30typedef u_int16_t u16;
31typedef u_int8_t u8;
32#endif
33
34#include <linux/types.h>
35#include <linux/sockios.h>
36#include <linux/ethtool.h>
37#include <sys/ioctl.h>
38#include <net/if_arp.h>
39#include <arpa/inet.h>
40#include <dirent.h>
41
42#include <wlutils.h>
43#ifdef CONFIG_BCMWL5
44#include <bcmparams.h>
45#include <wlioctl.h>
46#include <security_ipc.h>
47
48#ifndef WL_BSS_INFO_VERSION
49#error WL_BSS_INFO_VERSION
50#endif
51#if WL_BSS_INFO_VERSION >= 108
52#include <etioctl.h>
53#else
54#include <etsockio.h>
55#endif
56#endif /* CONFIG_BCMWL5 */
57
58#ifdef RTCONFIG_RALINK
59#include <ralink.h>
60#endif
61
62#ifdef RTCONFIG_QCA
63#include <qca.h>
64#endif
65
66#ifdef RTCONFIG_USB_MODEM
67#include <usb_info.h>
68#endif
69#ifdef RTCONFIG_DPSTA
70#include <dpsta_linux.h>
71#endif
72
73const int ifup_vap =
74#if defined(RTCONFIG_QCA)
75	0;
76#else
77	1;
78#endif
79
80#define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr)
81
82static time_t s_last_lan_port_stopped_ts = 0;
83
84void update_lan_state(int state, int reason)
85{
86	char prefix[32];
87	char tmp[100], tmp1[100], *ptr;
88
89	snprintf(prefix, sizeof(prefix), "lan_");
90
91	_dprintf("%s(%s, %d, %d)\n", __FUNCTION__, prefix, state, reason);
92
93#ifdef RTCONFIG_QTN	/* AP and Repeater mode, workaround to infosvr, RT-AC87U bug#38, bug#44, bug#46 */
94	_dprintf("%s(workaround to infosvr)\n", __FUNCTION__);
95	eval("ifconfig", "br0:0", "169.254.39.3", "netmask", "255.255.255.0");
96	if(*nvram_safe_get("QTN_RPC_CLIENT"))
97		eval("ifconfig", "br0:0", nvram_safe_get("QTN_RPC_CLIENT"), "netmask", "255.255.255.0");
98	else
99		eval("ifconfig", "br0:0", "169.254.39.1", "netmask", "255.255.255.0");
100#endif
101
102	nvram_set_int(strcat_r(prefix, "state_t", tmp), state);
103	nvram_set_int(strcat_r(prefix, "sbstate_t", tmp), 0);
104
105	if(state==LAN_STATE_INITIALIZING)
106	{
107		if(nvram_match(strcat_r(prefix, "proto", tmp), "dhcp")) {
108			// always keep in default ip before getting ip
109			nvram_set(strcat_r(prefix, "dns", tmp), nvram_default_get("lan_ipaddr"));
110		}
111
112		if (!nvram_get_int(strcat_r(prefix, "dnsenable_x", tmp))) {
113			strcpy(tmp1, "");
114			ptr = nvram_safe_get(strcat_r(prefix, "dns1_x", tmp));
115			if (*ptr && inet_addr_(ptr) != INADDR_ANY)
116				sprintf(tmp1, "%s", ptr);
117			ptr = nvram_safe_get(strcat_r(prefix, "dns2_x", tmp));
118			if (*ptr && inet_addr_(ptr) != INADDR_ANY)
119				sprintf(tmp1 + strlen(tmp1), "%s%s", *tmp1 ? " " : "", ptr);
120			nvram_set(strcat_r(prefix, "dns", tmp), tmp1);
121		}
122		// why not keeping default ip set above?
123		else nvram_set(strcat_r(prefix, "dns", tmp), "");
124	}
125	else if(state==LAN_STATE_STOPPED) {
126		// Save Stopped Reason
127		// keep ip info if it is stopped from connected
128		nvram_set_int(strcat_r(prefix, "sbstate_t", tmp), reason);
129	}
130
131}
132
133#ifdef RTCONFIG_BCMWL6
134/* workaround for BCMWL6 only */
135static void set_mrate(const char* ifname, const char* prefix)
136{
137	float mrate = 0;
138	char tmp[100];
139
140	switch (nvram_get_int(strcat_r(prefix, "mrate_x", tmp))) {
141	case 0: /* Auto */
142		mrate = 0;
143		break;
144	case 1: /* Legacy CCK 1Mbps */
145		mrate = 1;
146		break;
147	case 2: /* Legacy CCK 2Mbps */
148		mrate = 2;
149		break;
150	case 3: /* Legacy CCK 5.5Mbps */
151		mrate = 5.5;
152		break;
153	case 4: /* Legacy OFDM 6Mbps */
154		mrate = 6;
155		break;
156	case 5: /* Legacy OFDM 9Mbps */
157		mrate = 9;
158		break;
159	case 6: /* Legacy CCK 11Mbps */
160		mrate = 11;
161		break;
162	case 7: /* Legacy OFDM 12Mbps */
163		mrate = 12;
164		break;
165	case 8: /* Legacy OFDM 18Mbps */
166		mrate = 18;
167		break;
168	case 9: /* Legacy OFDM 24Mbps */
169		mrate = 24;
170		break;
171	case 10: /* Legacy OFDM 36Mbps */
172		mrate = 36;
173		break;
174	case 11: /* Legacy OFDM 48Mbps */
175		mrate = 48;
176		break;
177	case 12: /* Legacy OFDM 54Mbps */
178		mrate = 54;
179		break;
180	default: /* Auto */
181		mrate = 0;
182		break;
183	}
184
185	sprintf(tmp, "wl -i %s mrate %.1f", ifname, mrate);
186	system(tmp);
187}
188#endif
189
190#ifdef CONFIG_BCMWL5
191static int wlconf(char *ifname, int unit, int subunit)
192{
193	int r;
194	char wl[24];
195	int txpower;
196	int model = get_model();
197	char tmp[100], prefix[] = "wlXXXXXXXXXXXXXX";
198
199#ifdef RTCONFIG_QTN
200	if (!strcmp(ifname, "wifi0"))
201		unit = 1;
202#endif
203	if (unit < 0) return -1;
204
205	if (subunit < 0)
206	{
207#ifdef RTCONFIG_QTN
208		if (unit == 1)
209			goto GEN_CONF;
210#endif
211		snprintf(prefix, sizeof(prefix), "wl%d_", unit);
212
213#if 0
214#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA)
215		if (psta_exist_except(unit) || psr_exist_except(unit))
216		{
217			eval("wlconf", ifname, "down");
218			eval("wl", "-i", ifname, "radio", "off");
219			return -1;
220		}
221#endif
222#endif
223
224#ifdef RTCONFIG_QTN
225GEN_CONF:
226#endif
227#ifdef RTCONFIG_BCMWL6
228		wl_check_chanspec();
229#endif
230		generate_wl_para(unit, subunit);
231
232		for (r = 1; r < MAX_NO_MSSID; r++)	// early convert for wlx.y
233			generate_wl_para(unit, r);
234
235		if (nvram_match(strcat_r(prefix, "radio", tmp), "0"))
236		{
237			eval("wlconf", ifname, "down");
238			eval("wl", "-i", ifname, "radio", "off");
239			return -1;
240		}
241	}
242
243#if 0
244	if (/* !wl_probe(ifname) && */ unit >= 0) {
245		// validate nvram settings foa wireless i/f
246		snprintf(wl, sizeof(wl), "--wl%d", unit);
247		eval("nvram", "validate", wl);
248	}
249#endif
250
251#ifdef RTCONFIG_QTN
252	if (unit == 1)
253		return -1;
254#endif
255
256	if (unit >= 0 && subunit < 0)
257	{
258#ifdef RTCONFIG_OPTIMIZE_XBOX
259		if (nvram_match(strcat_r(prefix, "optimizexbox", tmp), "1"))
260			eval("wl", "-i", ifname, "ldpc_cap", "0");
261		else
262			eval("wl", "-i", ifname, "ldpc_cap", "1");	// driver default setting
263#endif
264#ifdef RTCONFIG_BCMWL6
265#if !defined(RTCONFIG_BCM7) && !defined(RTCONFIG_BCM_7114)
266		if (nvram_match(strcat_r(prefix, "ack_ratio", tmp), "1"))
267			eval("wl", "-i", ifname, "ack_ratio", "4");
268		else
269			eval("wl", "-i", ifname, "ack_ratio", "2");	// driver default setting
270#endif
271		if (nvram_match(strcat_r(prefix, "ampdu_mpdu", tmp), "1"))
272			eval("wl", "-i", ifname, "ampdu_mpdu", "64");
273		else
274#if !defined(RTCONFIG_BCM7)
275			eval("wl", "-i", ifname, "ampdu_mpdu", "-1");	// driver default setting
276#else
277			eval("wl", "-i", ifname, "ampdu_mpdu", "32");	// driver default setting
278#endif
279#ifdef RTCONFIG_BCMARM
280		if (nvram_match(strcat_r(prefix, "ampdu_rts", tmp), "1"))
281			eval("wl", "-i", ifname, "ampdu_rts", "1");	// driver default setting
282		else
283			eval("wl", "-i", ifname, "ampdu_rts", "0");
284#if 0
285		if (nvram_match(strcat_r(prefix, "itxbf", tmp), "1"))
286			eval("wl", "-i", ifname, "txbf_imp", "1");	// driver default setting
287		else
288			eval("wl", "-i", ifname, "txbf_imp", "0");
289#endif
290#endif /* RTCONFIG_BCMARM */
291#else
292		eval("wl", "-i", ifname, "ampdu_density", "6");		// resolve IOT with Intel STA for BRCM SDK 5.110.27.20012
293#endif /* RTCONFIG_BCMWL6 */
294	}
295
296	r = eval("wlconf", ifname, "up");
297	if (r == 0) {
298		if (unit >= 0 && subunit < 0) {
299#ifdef REMOVE
300			// setup primary wl interface
301			nvram_set("rrules_radio", "-1");
302			eval("wl", "-i", ifname, "antdiv", nvram_safe_get(wl_nvname("antdiv", unit, 0)));
303			eval("wl", "-i", ifname, "txant", nvram_safe_get(wl_nvname("txant", unit, 0)));
304			eval("wl", "-i", ifname, "txpwr1", "-o", "-m", nvram_get_int(wl_nvname("txpwr", unit, 0)) ? nvram_safe_get(wl_nvname("txpwr", unit, 0)) : "-1");
305			eval("wl", "-i", ifname, "interference", nvram_safe_get(wl_nvname("interfmode", unit, 0)));
306#endif
307#ifndef RTCONFIG_BCMWL6
308			switch (model) {
309				default:
310					if ((unit == 0) &&
311						nvram_match(strcat_r(prefix, "noisemitigation", tmp), "1"))
312					{
313						eval("wl", "-i", ifname, "interference_override", "4");
314						eval("wl", "-i", ifname, "phyreg", "0x547", "0x4444");
315						eval("wl", "-i", ifname, "phyreg", "0xc33", "0x280");
316					}
317					break;
318			}
319#else
320#ifdef RTCONFIG_PROXYSTA
321			if (psta_exist_except(unit)/* || psr_exist_except(unit)*/)
322			{
323				eval("wl", "-i", ifname, "closed", "1");
324				eval("wl", "-i", ifname, "maxassoc", "0");
325			}
326#endif
327			set_mrate(ifname, prefix);
328#ifdef RTCONFIG_BCMARM
329			if (nvram_match(strcat_r(prefix, "ampdu_rts", tmp), "0") &&
330				nvram_match(strcat_r(prefix, "nmode", tmp), "-1"))
331				eval("wl", "-i", ifname, "rtsthresh", "65535");
332#endif
333
334			wl_dfs_radarthrs_config(ifname, unit);
335
336#endif /* RTCONFIG_BCMWL6 */
337			txpower = nvram_get_int(wl_nvname("txpower", unit, 0));
338
339			dbG("unit: %d, txpower: %d%\n", unit, txpower);
340
341			switch (model) {
342				default:
343
344					eval("wl", "-i", ifname, "txpwr1", "-1");
345
346					break;
347			}
348		}
349
350		if (wl_client(unit, subunit)) {
351			if (nvram_match(wl_nvname("mode", unit, subunit), "wet")) {
352				ifconfig(ifname, IFUP | IFF_ALLMULTI, NULL, NULL);
353			}
354			if (nvram_get_int(wl_nvname("radio", unit, 0))) {
355				snprintf(wl, sizeof(wl), "%d", unit);
356				xstart("radio", "join", wl);
357			}
358		}
359	}
360	return r;
361}
362
363// -----------------------------------------------------------------------------
364
365/*
366 * Carry out a socket request including openning and closing the socket
367 * Return -1 if failed to open socket (and perror); otherwise return
368 * result of ioctl
369 */
370static int
371soc_req(const char *name, int action, struct ifreq *ifr)
372{
373	int s;
374	int rv = 0;
375
376	if (name == NULL) return -1;
377
378	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
379		perror("socket");
380		return -1;
381	}
382	strncpy(ifr->ifr_name, name, IFNAMSIZ);
383	ifr->ifr_name[IFNAMSIZ-1] = '\0';
384	rv = ioctl(s, action, ifr);
385	close(s);
386
387	return rv;
388}
389#endif
390
391/* Check NVRam to see if "name" is explicitly enabled */
392static inline int
393wl_vif_enabled(const char *name, char *tmp)
394{
395	if (name == NULL) return 0;
396
397	return (nvram_get_int(strcat_r(name, "_bss_enabled", tmp)));
398}
399
400#if defined(CONFIG_BCMWL5)
401/* Set the HW address for interface "name" if present in NVRam */
402static void
403wl_vif_hwaddr_set(const char *name)
404{
405	int rc;
406	char *ea;
407	char hwaddr[20];
408	struct ifreq ifr;
409	int retry = 0;
410	unsigned char comp_mac_address[ETHER_ADDR_LEN];
411	snprintf(hwaddr, sizeof(hwaddr), "%s_hwaddr", name);
412	ea = nvram_get(hwaddr);
413	if (ea == NULL) {
414		fprintf(stderr, "NET: No hw addr found for %s\n", name);
415		return;
416	}
417
418#ifdef RTCONFIG_QTN
419	if(strcmp(name, "wl1.1") == 0 ||
420		strcmp(name, "wl1.2") == 0 ||
421		strcmp(name, "wl1.3") == 0)
422		return;
423#endif
424	fprintf(stderr, "NET: Setting %s hw addr to %s\n", name, ea);
425	ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
426	ether_atoe(ea, (unsigned char *)ifr.ifr_hwaddr.sa_data);
427	ether_atoe(ea, comp_mac_address);
428	if ((rc = soc_req(name, SIOCSIFHWADDR, &ifr)) < 0) {
429		fprintf(stderr, "NET: Error setting hw for %s; returned %d\n", name, rc);
430	}
431	memset(&ifr, 0, sizeof(ifr));
432	while (retry < 100) { /* maximum 100 millisecond waiting */
433		usleep(1000); /* 1 ms sleep */
434		if ((rc = soc_req(name, SIOCGIFHWADDR, &ifr)) < 0) {
435			fprintf(stderr, "NET: Error Getting hw for %s; returned %d\n", name, rc);
436		}
437		if (memcmp(comp_mac_address, (unsigned char *)ifr.ifr_hwaddr.sa_data,
438			ETHER_ADDR_LEN) == 0) {
439			break;
440		}
441		retry++;
442	}
443	if (retry >= 100) {
444		fprintf(stderr, "Unable to check if mac was set properly for %s\n", name);
445	}
446}
447#endif
448
449#ifdef RTCONFIG_EMF
450void
451emf_mfdb_update(char *lan_ifname, char *lan_port_ifname, bool add)
452{
453	char word[256], *next;
454	char *mgrp, *ifname;
455
456	/* Add/Delete MFDB entries corresponding to new interface */
457	foreach(word, nvram_safe_get("emf_entry"), next) {
458		ifname = word;
459		mgrp = strsep(&ifname, ":");
460
461		if ((mgrp == 0) || (ifname == 0))
462			continue;
463
464		/* Add/Delete MFDB entry using the group addr and interface */
465		if (strcmp(lan_port_ifname, ifname) == 0) {
466			eval("emf", ((add) ? "add" : "del"),
467			     "mfdb", lan_ifname, mgrp, ifname);
468		}
469	}
470
471	return;
472}
473
474void
475emf_uffp_update(char *lan_ifname, char *lan_port_ifname, bool add)
476{
477	char word[256], *next;
478	char *ifname;
479
480	/* Add/Delete UFFP entries corresponding to new interface */
481	foreach(word, nvram_safe_get("emf_uffp_entry"), next) {
482		ifname = word;
483
484		if (ifname == 0)
485			continue;
486
487		/* Add/Delete UFFP entry for the interface */
488		if (strcmp(lan_port_ifname, ifname) == 0) {
489			eval("emf", ((add) ? "add" : "del"),
490			     "uffp", lan_ifname, ifname);
491		}
492	}
493
494	return;
495}
496
497void
498emf_rtport_update(char *lan_ifname, char *lan_port_ifname, bool add)
499{
500	char word[256], *next;
501	char *ifname;
502
503	/* Add/Delete RTPORT entries corresponding to new interface */
504	foreach(word, nvram_safe_get("emf_rtport_entry"), next) {
505		ifname = word;
506
507		if (ifname == 0)
508			continue;
509
510		/* Add/Delete RTPORT entry for the interface */
511		if (strcmp(lan_port_ifname, ifname) == 0) {
512			eval("emf", ((add) ? "add" : "del"),
513			     "rtport", lan_ifname, ifname);
514		}
515	}
516
517	return;
518}
519
520void
521start_emf(char *lan_ifname)
522{
523	char word[256], *next;
524	char *mgrp, *ifname;
525
526	if (!nvram_match("emf_enable", "1"))
527		return;
528
529	/* Start EMF */
530	eval("emf", "start", lan_ifname);
531
532	/* Add the static MFDB entries */
533	foreach(word, nvram_safe_get("emf_entry"), next) {
534		ifname = word;
535		mgrp = strsep(&ifname, ":");
536
537		if ((mgrp == 0) || (ifname == 0))
538			continue;
539
540		/* Add MFDB entry using the group addr and interface */
541		eval("emf", "add", "mfdb", lan_ifname, mgrp, ifname);
542	}
543
544	/* Add the UFFP entries */
545	foreach(word, nvram_safe_get("emf_uffp_entry"), next) {
546		ifname = word;
547		if (ifname == 0)
548			continue;
549
550		/* Add UFFP entry for the interface */
551		eval("emf", "add", "uffp", lan_ifname, ifname);
552	}
553
554	/* Add the RTPORT entries */
555	foreach(word, nvram_safe_get("emf_rtport_entry"), next) {
556		ifname = word;
557		if (ifname == 0)
558			continue;
559
560		/* Add RTPORT entry for the interface */
561		eval("emf", "add", "rtport", lan_ifname, ifname);
562	}
563
564	return;
565}
566
567static void stop_emf(char *lan_ifname)
568{
569	/* Stop the EMF for this LAN */
570	eval("emf", "stop", lan_ifname);
571	/* Remove Bridge from igs */
572	eval("igs", "del", "bridge", lan_ifname);
573	eval("emf", "del", "bridge", lan_ifname);
574}
575#endif
576
577static void start_snooper(char *lan_ifname)
578{
579#ifdef CONFIG_BCMWL5
580	char word[64], *next;
581
582	if (!nvram_match("emf_enable", "1"))
583		return;
584
585	foreach (word, nvram_safe_get("lan_ifnames"), next) {
586		if (eval("/usr/sbin/snooper", "-b", lan_ifname, "-s", word) == 0);
587			break;
588	}
589#endif
590}
591
592static void stop_snooper(void)
593{
594	killall_tk("snooper");
595}
596
597// -----------------------------------------------------------------------------
598
599/* Set initial QoS mode for all et interfaces that are up. */
600#ifdef CONFIG_BCMWL5
601void
602set_et_qos_mode(void)
603{
604	int i, s, qos;
605	struct ifreq ifr;
606	struct ethtool_drvinfo info;
607
608	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
609		return;
610
611	qos = (strcmp(nvram_safe_get("wl_wme"), "off") != 0);
612
613	for (i = 1; i <= DEV_NUMIFS; i ++) {
614		ifr.ifr_ifindex = i;
615		if (ioctl(s, SIOCGIFNAME, &ifr))
616			continue;
617		if (ioctl(s, SIOCGIFHWADDR, &ifr))
618			continue;
619		if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
620			continue;
621		if (ioctl(s, SIOCGIFFLAGS, &ifr))
622			continue;
623		if (!(ifr.ifr_flags & IFF_UP))
624			continue;
625		/* Set QoS for et & bcm57xx devices */
626		memset(&info, 0, sizeof(info));
627		info.cmd = ETHTOOL_GDRVINFO;
628		ifr.ifr_data = (caddr_t)&info;
629		if (ioctl(s, SIOCETHTOOL, &ifr) < 0)
630			continue;
631		if ((strncmp(info.driver, "et", 2) != 0) &&
632		    (strncmp(info.driver, "bcm57", 5) != 0))
633			continue;
634		ifr.ifr_data = (caddr_t)&qos;
635		ioctl(s, SIOCSETCQOS, &ifr);
636	}
637
638	close(s);
639}
640#endif /* CONFIG_BCMWL5 */
641
642#if defined(RTCONFIG_QCA)
643void stavap_start(void)
644{
645	dbG("qca sta start\n");
646}
647#endif
648
649#if defined(RTCONFIG_RALINK) && defined(RTCONFIG_WIRELESSREPEATER)
650void apcli_start(void)
651{
652//repeater mode :sitesurvey channel and apclienable=1
653	int ch;
654	char *aif;
655	int ht_ext;
656
657	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER)
658	{
659		int wlc_band = nvram_get_int("wlc_band");
660		if (wlc_band == 0)
661			aif=nvram_safe_get("wl0_ifname");
662		else
663			aif=nvram_safe_get("wl1_ifname");
664		ch = site_survey_for_channel(0,aif, &ht_ext);
665		if(ch!=-1)
666		{
667			if (wlc_band == 1)
668			{
669				doSystem("iwpriv %s set Channel=%d", APCLI_5G, ch);
670				doSystem("iwpriv %s set ApCliEnable=1", APCLI_5G);
671			}
672			else
673			{
674				doSystem("iwpriv %s set Channel=%d", APCLI_2G, ch);
675				doSystem("iwpriv %s set ApCliEnable=1", APCLI_2G);
676			}
677			fprintf(stderr,"##set channel=%d, enable apcli ..#\n",ch);
678		}
679		else
680			fprintf(stderr,"## Can not find pap's ssid ##\n");
681	}
682}
683#endif	/* RTCONFIG_RALINK && RTCONFIG_WIRELESSREPEATER */
684
685void start_wl(void)
686{
687#ifdef CONFIG_BCMWL5
688	char *lan_ifname, *lan_ifnames, *ifname, *p;
689	int unit, subunit;
690	int is_client = 0;
691	char tmp[100], tmp2[100], prefix[] = "wlXXXXXXXXXXXXXX";
692
693	lan_ifname = nvram_safe_get("lan_ifname");
694	if (strncmp(lan_ifname, "br", 2) == 0) {
695		if ((lan_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL) {
696			p = lan_ifnames;
697			while ((ifname = strsep(&p, " ")) != NULL) {
698				while (*ifname == ' ') ++ifname;
699				if (*ifname == 0) break;
700
701				unit = -1; subunit = -1;
702
703				// ignore disabled wl vifs
704				if (strncmp(ifname, "wl", 2) == 0 && strchr(ifname, '.')) {
705					char nv[40];
706					snprintf(nv, sizeof(nv) - 1, "%s_bss_enabled", wif_to_vif(ifname));
707					if (!nvram_get_int(nv))
708						continue;
709					if (get_ifname_unit(ifname, &unit, &subunit) < 0)
710						continue;
711				}
712				// get the instance number of the wl i/f
713				else if (wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit)))
714					continue;
715
716				is_client |= wl_client(unit, subunit) && nvram_get_int(wl_nvname("radio", unit, 0));
717
718#ifdef CONFIG_BCMWL5
719				snprintf(prefix, sizeof(prefix), "wl%d_", unit);
720				if (nvram_match(strcat_r(prefix, "radio", tmp), "0"))
721				{
722					nvram_set_int(strcat_r(prefix, "timesched", tmp2), 0);	// disable wifi time-scheduler
723#ifdef RTCONFIG_QTN
724					if (strcmp(ifname, "wifi0"))
725#endif
726					{
727						eval("wlconf", ifname, "down");
728						eval("wl", "-i", ifname, "radio", "off");
729					}
730				}
731				else
732#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA)
733				if (!psta_exist_except(unit)/* && !psr_exist_except(unit)*/)
734#endif
735				{
736#ifdef RTCONFIG_QTN
737					if (strcmp(ifname, "wifi0"))
738#endif
739					eval("wlconf", ifname, "start"); /* start wl iface */
740				}
741				wlconf_post(ifname);
742#endif	// CONFIG_BCMWL5
743			}
744			free(lan_ifnames);
745		}
746	}
747#ifdef CONFIG_BCMWL5
748	else if (strcmp(lan_ifname, "")) {
749		/* specific non-bridged lan iface */
750		eval("wlconf", lan_ifname, "start");
751	}
752#endif	// CONFIG_BCMWL5
753
754#if 0
755	killall("wldist", SIGTERM);
756	eval("wldist");
757#endif
758
759	if (is_client)
760		xstart("radio", "join");
761
762#ifdef RTCONFIG_PORT_BASED_VLAN
763	start_vlan_wl();
764#endif
765
766	/* manual turn on 5g led for some gpio-ctrl-5g-led */
767#ifdef RTCONFIG_BCMWL6
768#if defined(RTAC66U) || defined(BCM4352)
769	if (nvram_match("wl1_radio", "1"))
770	{
771#ifndef RTCONFIG_LED_BTN
772		if (!(nvram_get_int("sw_mode")==SW_MODE_AP && nvram_get_int("wlc_psta") && nvram_get_int("wlc_band")==0)) {
773			nvram_set("led_5g", "1");
774			led_control(LED_5G, LED_ON);
775		}
776#else
777		nvram_set("led_5g", "1");
778		if (nvram_get_int("AllLED"))
779			led_control(LED_5G, LED_ON);
780#endif
781	}
782	else
783	{
784		nvram_set("led_5g", "0");
785		led_control(LED_5G, LED_OFF);
786	}
787
788#ifdef RTCONFIG_TURBO
789	if ((nvram_match("wl0_radio", "1") || nvram_match("wl1_radio", "1")
790#if defined(RTAC3200) || defined(RTAC5300) || defined(RTAC5300R)
791		|| nvram_match("wl2_radio", "1")
792#endif
793	)
794#ifdef RTCONFIG_LED_BTN
795		&& nvram_get_int("AllLED")
796#endif
797	)
798		led_control(LED_TURBO, LED_ON);
799	else
800		led_control(LED_TURBO, LED_OFF);
801#endif
802#endif
803#endif
804#endif /* CONFIG_BCMWL5 */
805
806
807#if defined(RTCONFIG_USER_LOW_RSSI) && !defined(RTCONFIG_BCMARM)
808	init_wllc();
809#endif
810
811
812#ifdef RTCONFIG_QTN
813	start_qtn_monitor();
814#endif
815}
816
817void stop_wl(void)
818{
819}
820
821#ifdef CONFIG_BCMWL5
822static int set_wlmac(int idx, int unit, int subunit, void *param)
823{
824	char *ifname;
825
826	ifname = nvram_safe_get(wl_nvname("ifname", unit, subunit));
827
828	// skip disabled wl vifs
829	if (strncmp(ifname, "wl", 2) == 0 && strchr(ifname, '.') &&
830		!nvram_get_int(wl_nvname("bss_enabled", unit, subunit)))
831		return 0;
832
833	set_mac(ifname, wl_nvname("macaddr", unit, subunit),
834		2 + unit + ((subunit > 0) ? ((unit + 1) * 0x10 + subunit) : 0));
835
836	return 1;
837}
838#endif
839
840static int
841add_lan_routes(char *lan_ifname)
842{
843	return add_routes("lan_", "route", lan_ifname);
844}
845
846static int
847del_lan_routes(char *lan_ifname)
848{
849	return del_routes("lan_", "route", lan_ifname);
850}
851
852#if defined(RTCONFIG_QCA)||defined(RTCONFIG_RALINK)
853char *get_hwaddr(const char *ifname)
854{
855	int s = -1;
856	struct ifreq ifr;
857	char eabuf[32];
858	char *p = NULL;
859
860	if (ifname == NULL) return NULL;
861
862	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) return NULL;
863
864	strcpy(ifr.ifr_name, ifname);
865	if (ioctl(s, SIOCGIFHWADDR, &ifr)) goto error;
866
867	p = strdup(ether_etoa((const unsigned char *)ifr.ifr_hwaddr.sa_data, eabuf));
868
869error:
870	close(s);
871	return p;
872}
873#endif
874
875#ifdef RTCONFIG_QCA
876void
877qca_wif_up(const char* wif)
878{
879#ifdef RTCONFIG_WIRELESSREPEATER
880	if ((nvram_get_int("sw_mode") == SW_MODE_REPEATER && !strncmp(wif,"sta",3)))
881		ifconfig(wif, IFUP, NULL, NULL);
882#endif
883}
884
885
886void
887gen_qca_wifi_cfgs(void)
888{
889	pid_t pid;
890	char *argv[]={"/sbin/delay_exec","1","/tmp/postwifi.sh",NULL};
891	char wi2_gn[10],wi5_gn[10];
892	char *p1, path2[50];
893	char wif[256], *next;
894	FILE *fp,*fp2;
895	char tmp[100], prefix[]="wlXXXXXXX_";
896	int led_onoff[2] = { LED_ON, LED_ON }, unit = -1, sunit = 0;
897	int sidx = 0;
898	unsigned int m, wl_mask = 0;	/* bit0~3: 2G, bit4~7: 5G */
899	char conf_path[] = "/etc/Wireless/conf/hostapd_athXXX.confYYYYYY";
900	char pid_path[] = "/var/run/hostapd_athXXX.pidYYYYYY";
901	char entropy_path[] = "/var/run/entropy_athXXX.binYYYYYY";
902	char path[] = "/sys/class/net/ath001XXXXXX";
903	char path1[sizeof(NAWDS_SH_FMT) + 6];
904	int i;
905#ifdef RTCONFIG_WIRELESSREPEATER
906	char cmd[200];
907#if 0 // ARPNAT is obsolete
908	char ebtable[3][40]={"PREROUTING --in-interface","POSTROUTING --out-interface","ebtables -t nat -F"};
909#endif
910	memset(cmd,0,sizeof(cmd));
911#endif
912	sprintf(wi2_gn,"%s0",WIF_2G);
913	sprintf(wi5_gn,"%s0",WIF_5G);
914	if (!(fp = fopen("/tmp/prewifi.sh", "w+")))
915		return;
916	if (!(fp2 = fopen("/tmp/postwifi.sh", "w+")))
917		return;
918
919	foreach (wif, nvram_safe_get("lan_ifnames"), next) {
920
921		extern int get_wlsubnet(int band, const char *ifname);
922		if (!guest_wlif(wif) && (unit = get_wifi_unit(wif)) >= 0 && unit < sizeof(led_onoff)) {
923			snprintf(prefix, sizeof(prefix), "wl%d_", unit);
924			if (nvram_match(strcat_r(prefix, "radio", tmp), "0"))
925				led_onoff[unit] = LED_OFF;
926		}
927		if (!strcmp(wif, WIF_2G)) {			// 2.4G
928			wl_mask |= 1;
929			gen_ath_config(0, 0, 0);
930		}
931		else if (!strncmp(wif,wi2_gn,strlen(wi2_gn)))	// 2.4G guest
932		{
933			p1=strstr(wif,wi2_gn);
934			sunit = get_wlsubnet(0, wif);
935			if (p1 && sunit > 0) {
936				sidx = atoi(p1 + strlen(wi2_gn));
937				wl_mask |= 1 << sunit;
938				gen_ath_config(0, 0, sidx);
939			}
940		}
941		else if (!strcmp(wif, WIF_5G)) {		// 5G
942			wl_mask |= (1 << 4);
943			gen_ath_config(1, 1, 0);
944		}
945		else if (!strncmp(wif,wi5_gn,strlen(wi5_gn)))	// 5G guest
946		{
947			p1=strstr(wif,wi5_gn);
948			sunit = get_wlsubnet(1, wif);
949			if (p1 && sunit > 0) {
950				sidx = atoi(p1 + strlen(wi5_gn));
951				wl_mask |= 1 << (sunit + 4);
952				gen_ath_config(1, 1, sidx);
953			}
954		}
955
956#ifdef RTCONFIG_WIRELESSREPEATER
957		else if (!strcmp(wif, STA_2G) || !strcmp(wif, STA_5G))
958		{
959			if(nvram_get_int("sw_mode") == SW_MODE_REPEATER){
960				sprintf(cmd,"wpa_supplicant -B -P /var/run/wifi-%s.pid -D athr -i %s -b br0 -c /etc/Wireless/conf/wpa_supplicant-%s.conf",wif,wif,wif);
961			}
962		}
963#endif
964		else
965			continue;
966
967#ifdef RTCONFIG_WIRELESSREPEATER
968		if (strcmp(wif,"sta0")&&strcmp(wif,"sta1"))
969#endif
970		{
971			fprintf(fp, "/etc/Wireless/sh/prewifi_%s.sh\n",wif);
972			fprintf(fp2, "/etc/Wireless/sh/postwifi_%s.sh\n",wif);
973		}
974	}
975
976#if defined(PLN12)
977	//fprintf(fp2, "led_ctrl %d %d\n", LED_2G_GREEN, led_onoff[0]);
978	//fprintf(fp2, "led_ctrl %d %d\n", LED_2G_ORANGE, led_onoff[0]);
979	fprintf(fp2, "led_ctrl %d %d\n", LED_2G_RED, led_onoff[0]);
980	set_wifiled(1);
981#elif defined(PLAC56)
982	fprintf(fp2, "led_ctrl %d %d\n", LED_2G_GREEN, led_onoff[0]);
983	//fprintf(fp2, "led_ctrl %d %d\n", LED_2G_RED, led_onoff[0]);
984	fprintf(fp2, "led_ctrl %d %d\n", LED_5G_GREEN, led_onoff[0]);
985	//fprintf(fp2, "led_ctrl %d %d\n", LED_5G_RED, led_onoff[0]);
986	set_wifiled(1);
987#else
988	fprintf(fp2, "led_ctrl %d %d\n", LED_2G, led_onoff[0]);
989#endif
990#if defined(RTCONFIG_HAS_5G)
991	fprintf(fp2, "led_ctrl %d %d\n", LED_5G, led_onoff[1]);
992#endif
993	fprintf(fp2, "nvram set wlready=1\n");
994
995	fclose(fp);
996	fclose(fp2);
997	chmod("/tmp/prewifi.sh",0777);
998	chmod("/tmp/postwifi.sh",0777);
999
1000	for (i = 0, unit = 0, sunit = 0, sidx = 0, m = 0xFF; m > 0; ++i, ++sunit, ++sidx, m >>= 1) {
1001		if (i == 4) {
1002			unit = 1;
1003			sunit = 0;
1004			sidx = 0;
1005		}
1006		__get_wlifname(unit, sidx, wif);
1007		sprintf(path, "/sys/class/net/%s", wif);
1008		if (d_exists(path))
1009			ifconfig(wif, 0, NULL, NULL);
1010		sprintf(pid_path, "/var/run/hostapd_%s.pid", wif);
1011		if (!f_exists(pid_path))
1012			continue;
1013
1014		kill_pidfile_tk(pid_path);
1015	}
1016
1017	doSystem("/tmp/prewifi.sh");
1018#ifdef RTCONFIG_WIRELESSREPEATER
1019	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER){
1020		doSystem(cmd);
1021#if 0 // ARPNAT is obsolete
1022		sleep(1);
1023		doSystem(ebtable[2]);
1024		for(i=0;i<2;i++)
1025		{
1026			if(nvram_get_int("wlc_band")==0)
1027				sprintf(cmd,"ebtables -t nat -A %s %s -j arpnat --arpnat-target ACCEPT",ebtable[i], STA_2G);
1028			else
1029				sprintf(cmd,"ebtables -t nat -A %s %s -j arpnat --arpnat-target ACCEPT",ebtable[i], STA_5G);
1030			doSystem(cmd);
1031		}
1032#else
1033		doSystem("iwpriv %s extap 1", get_staifname(nvram_get_int("wlc_band")));
1034#endif
1035		doSystem("ifconfig %s up", get_staifname(nvram_get_int("wlc_band")));
1036	}
1037#endif
1038#ifdef RTCONFIG_PROXYSTA
1039	if (nvram_get_int("wlc_psta") == 0) {
1040#endif
1041	m = wl_mask & 0xFF;
1042	for (i = 0, unit = 0, sunit = 0, sidx = 0; m > 0; ++i, ++sunit, ++sidx, m >>= 1) {
1043		char *str;
1044		if (i == 4) {
1045			unit = 1;
1046			sunit = 0;
1047			sidx = 0;
1048		}
1049		if (!nvram_match(wl_nvname("bss_enabled", unit, sunit), "1"))
1050		{
1051			sidx--;
1052			continue;
1053		}
1054
1055		__get_wlifname(unit, sidx, wif);
1056		tweak_wifi_ps(wif);
1057
1058#ifdef RTCONFIG_WIRELESSREPEATER
1059		if(nvram_get_int("sw_mode") == SW_MODE_REPEATER)
1060			doSystem("iwpriv %s athnewind 1", wif);
1061#endif
1062
1063		sprintf(path2, "/etc/Wireless/sh/postwifi_%s.sh", wif);
1064		if (!(fp = fopen(path2, "a")))
1065			continue;
1066
1067		/* hostapd is not required if
1068		 * 1. Open system and WPS is disabled.
1069		 *    a. primary 2G/5G and WPS is disabled
1070		 *    b. guest 2G/5G
1071		 * 2. WEP
1072		 */
1073		if (!strcmp(nvram_safe_get(wl_nvname("auth_mode_x", unit, sunit)), "open") &&
1074		    ((!sunit && !nvram_get_int("wps_enable")) || sunit)) {
1075			fclose(fp);
1076			continue;
1077		} else if (!strcmp(nvram_safe_get(wl_nvname("auth_mode_x", unit, sunit)), "shared")) {
1078			fclose(fp);
1079			continue;
1080		}
1081
1082		sprintf(conf_path, "/etc/Wireless/conf/hostapd_%s.conf", wif);
1083		sprintf(pid_path, "/var/run/hostapd_%s.pid", wif);
1084		sprintf(entropy_path, "/var/run/entropy_%s.bin", wif);
1085		fprintf(fp, "hostapd -d -B %s -P %s -e %s\n", conf_path, pid_path, entropy_path);
1086
1087		str = nvram_safe_get(wl_nvname("radio", unit, 0));
1088		if (str && strlen(str)) {
1089			char vphy[10];
1090			char *updown = atoi(str)? "up" : "down";
1091			strcpy(vphy, get_vphyifname(unit));
1092			fprintf(fp, "ifconfig %s %s\n", vphy, updown);
1093			fprintf(fp, "ifconfig %s %s\n", wif, updown);
1094
1095			/* Connect to peer WDS AP after VAP up */
1096			sprintf(path1, NAWDS_SH_FMT, wif);
1097			if (!sunit && atoi(str) && f_exists(path1)) {
1098				fprintf(fp, "%s\n", path1);
1099			}
1100		}
1101
1102		fclose(fp);
1103	}
1104
1105	argv[1]="4";
1106	_eval(argv, NULL, 0, &pid);
1107	//system("/tmp/postwifi.sh");
1108	//sleep(1);
1109#ifdef RTCONFIG_PROXYSTA
1110	}
1111#endif
1112}
1113
1114static void
1115set_wlpara_qca(const char* wif, int band)
1116{
1117/* TBD.fill some eraly init here
1118	char tmp[100], prefix[]="wlXXXXXXX_";
1119
1120	snprintf(prefix, sizeof(prefix), "wl%d_", band);
1121
1122	if (nvram_match(strcat_r(prefix, "radio", tmp), "0"))
1123		radio_ra(wif, band, 0);
1124	else
1125	{
1126		int txpower = atoi(nvram_safe_get(strcat_r(prefix, "TxPower", tmp)));
1127		if ((txpower >= 0) && (txpower <= 100))
1128			doSystem("iwpriv %s set TxPower=%d",wif, txpower);
1129	}
1130	eval("iwpriv", (char *)wif, "set", "IgmpAdd=01:00:5e:7f:ff:fa");
1131	eval("iwpriv", (char *)wif, "set", "IgmpAdd=01:00:5e:00:00:09");
1132	eval("iwpriv", (char *)wif, "set", "IgmpAdd=01:00:5e:00:00:fb");
1133*/
1134}
1135
1136
1137static int
1138wlconf_qca(const char* wif)
1139{
1140	int unit = 0;
1141	char word[256], *next;
1142	char tmp[128], prefix[] = "wlXXXXXXXXXX_";
1143	char *p;
1144
1145	foreach (word, nvram_safe_get("wl_ifnames"), next) {
1146		snprintf(prefix, sizeof(prefix), "wl%d_", unit);
1147
1148		if (!strcmp(word, wif))
1149		{
1150			p = get_hwaddr(wif);
1151			if (p)
1152			{
1153				nvram_set(strcat_r(prefix, "hwaddr", tmp), p);
1154				free(p);
1155			}
1156			if (!strcmp(word, WIF_2G))
1157				set_wlpara_qca(wif, 0);
1158			else if (!strcmp(word, WIF_5G))
1159				set_wlpara_qca(wif, 1);
1160		}
1161
1162		unit++;
1163	}
1164	return 0;
1165}
1166
1167#endif
1168#ifdef RTCONFIG_RALINK
1169static void
1170gen_ra_config(const char* wif)
1171{
1172	char word[256], *next;
1173
1174	foreach (word, nvram_safe_get("wl_ifnames"), next) {
1175		if (!strcmp(word, wif))
1176		{
1177			if (!strcmp(word, nvram_safe_get("wl0_ifname"))) // 2.4G
1178			{
1179				if (!strncmp(word, "rai", 3))	// iNIC
1180					gen_ralink_config(0, 1);
1181				else
1182					gen_ralink_config(0, 0);
1183			}
1184			else if (!strcmp(word, nvram_safe_get("wl1_ifname"))) // 5G
1185			{
1186				if (!strncmp(word, "rai", 3))	// iNIC
1187					gen_ralink_config(1, 1);
1188				else
1189					gen_ralink_config(1, 0);
1190			}
1191		}
1192	}
1193}
1194
1195static int
1196radio_ra(const char *wif, int band, int ctrl)
1197{
1198	char tmp[100], prefix[]="wlXXXXXXX_";
1199
1200	snprintf(prefix, sizeof(prefix), "wl%d_", band);
1201
1202	if (wif == NULL) return -1;
1203
1204	if (!ctrl)
1205	{
1206		doSystem("iwpriv %s set RadioOn=0", wif);
1207	}
1208	else
1209	{
1210		if (nvram_match(strcat_r(prefix, "radio", tmp), "1"))
1211			doSystem("iwpriv %s set RadioOn=1", wif);
1212	}
1213
1214	return 0;
1215}
1216
1217static void
1218set_wlpara_ra(const char* wif, int band)
1219{
1220	char tmp[100], prefix[]="wlXXXXXXX_";
1221
1222	snprintf(prefix, sizeof(prefix), "wl%d_", band);
1223
1224	if (nvram_match(strcat_r(prefix, "radio", tmp), "0"))
1225		radio_ra(wif, band, 0);
1226	else
1227	{
1228		int txpower = nvram_get_int(strcat_r(prefix, "txpower", tmp));
1229		if ((txpower >= 0) && (txpower <= 100))
1230			doSystem("iwpriv %s set TxPower=%d",wif, txpower);
1231	}
1232#if 0
1233	if (nvram_match(strcat_r(prefix, "bw", tmp), "2"))
1234	{
1235		int channel = get_channel(band);
1236
1237		if (channel)
1238			eval("iwpriv", (char *)wif, "set", "HtBw=1");
1239	}
1240#endif
1241#if 0 //defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)	/* set RT3352 iNIC in kernel driver to avoid loss setting after reset */
1242	if(strcmp(wif, "rai0") == 0)
1243	{
1244		int i;
1245		char buf[32];
1246		eval("iwpriv", (char *)wif, "set", "asiccheck=1");
1247		for(i = 0; i < 3; i++)
1248		{
1249			sprintf(buf, "setVlanId=%d,%d", i + INIC_VLAN_IDX_START, i + INIC_VLAN_ID_START);
1250			eval("iwpriv", (char *)wif, "switch", buf);	//set vlan id can pass through the switch insided the RT3352.
1251								//set this before wl connection linu up. Or the traffic would be blocked by siwtch and need to reconnect.
1252		}
1253		for(i = 0; i < 5; i++)
1254		{
1255			sprintf(buf, "setPortPowerDown=%d,%d", i, 1);
1256			eval("iwpriv", (char *)wif, "switch", buf);	//power down the Ethernet PHY of RT3352 internal switch.
1257		}
1258	}
1259#endif // RTCONFIG_WLMODULE_RT3352_INIC_MII
1260	eval("iwpriv", (char *)wif, "set", "IgmpAdd=01:00:5e:7f:ff:fa");
1261	eval("iwpriv", (char *)wif, "set", "IgmpAdd=01:00:5e:00:00:09");
1262	eval("iwpriv", (char *)wif, "set", "IgmpAdd=01:00:5e:00:00:fb");
1263}
1264
1265static int
1266wlconf_ra(const char* wif)
1267{
1268	int unit = 0;
1269	char word[256], *next;
1270	char tmp[128], prefix[] = "wlXXXXXXXXXX_";
1271	char *p;
1272
1273	foreach (word, nvram_safe_get("wl_ifnames"), next) {
1274		snprintf(prefix, sizeof(prefix), "wl%d_", unit);
1275
1276		if (!strcmp(word, wif))
1277		{
1278			p = get_hwaddr(wif);
1279			if (p)
1280			{
1281				nvram_set(strcat_r(prefix, "hwaddr", tmp), p);
1282				free(p);
1283			}
1284
1285			if (!strcmp(word, WIF_2G))
1286				set_wlpara_ra(wif, 0);
1287#if defined(RTCONFIG_HAS_5G)
1288			else if (!strcmp(word, WIF_5G))
1289				set_wlpara_ra(wif, 1);
1290#endif	/* RTCONFIG_HAS_5G */
1291		}
1292
1293		unit++;
1294	}
1295	return 0;
1296}
1297#endif
1298
1299#ifdef RTCONFIG_IPV6
1300void ipv6_sysconf(const char *ifname, const char *name, int value)
1301{
1302	char path[PATH_MAX], sval[16];
1303
1304	if (ifname == NULL || name == NULL)
1305		return;
1306
1307	snprintf(path, sizeof(path), "/proc/sys/net/ipv6/conf/%s/%s", ifname, name);
1308	snprintf(sval, sizeof(sval), "%d", value);
1309	f_write_string(path, sval, 0, 0);
1310}
1311
1312int ipv6_getconf(const char *ifname, const char *name)
1313{
1314	char path[PATH_MAX], sval[16];
1315
1316	if (ifname == NULL || name == NULL)
1317		return 0;
1318
1319	snprintf(path, sizeof(path), "/proc/sys/net/ipv6/conf/%s/%s", ifname, name);
1320	if (f_read_string(path, sval, sizeof(sval)) <= 0)
1321		return 0;
1322
1323	return atoi(sval);
1324}
1325
1326void set_default_accept_ra(int flag)
1327{
1328	ipv6_sysconf("all", "accept_ra", flag ? 1 : 0);
1329	ipv6_sysconf("default", "accept_ra", flag ? 1 : 0);
1330}
1331
1332void set_default_forwarding(int flag)
1333{
1334	ipv6_sysconf("all", "forwarding", flag ? 1 : 0);
1335	ipv6_sysconf("default", "forwarding", flag ? 1 : 0);
1336}
1337
1338void set_intf_ipv6_dad(const char *ifname, int addbr, int flag)
1339{
1340	if (ifname == NULL) return;
1341
1342	ipv6_sysconf(ifname, "accept_dad", flag ? 2 : 0);
1343	if (flag)
1344		ipv6_sysconf(ifname, "dad_transmits", addbr ? 2 : 1);
1345}
1346
1347void enable_ipv6(const char *ifname)
1348{
1349	if (ifname == NULL) return;
1350
1351	ipv6_sysconf(ifname, "disable_ipv6", 0);
1352}
1353
1354void disable_ipv6(const char *ifname)
1355{
1356	if (ifname == NULL) return;
1357
1358	ipv6_sysconf(ifname, "disable_ipv6", 1);
1359}
1360
1361void config_ipv6(int enable, int incl_wan)
1362{
1363	DIR *dir;
1364	struct dirent *dirent;
1365	int service;
1366	int match;
1367	char word[256], *next;
1368
1369	if ((dir = opendir("/proc/sys/net/ipv6/conf")) != NULL) {
1370		while ((dirent = readdir(dir)) != NULL) {
1371			if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
1372				continue;
1373			if (incl_wan)
1374				goto ALL;
1375			match = 0;
1376			foreach (word, nvram_safe_get("wan_ifnames"), next) {
1377				if (!strcmp(dirent->d_name, word))
1378				{
1379					match = 1;
1380					break;
1381				}
1382			}
1383			if (match) continue;
1384ALL:
1385			if (enable)
1386				enable_ipv6(dirent->d_name);
1387			else
1388				disable_ipv6(dirent->d_name);
1389
1390			if (enable && strcmp(dirent->d_name, "all") &&
1391				strcmp(dirent->d_name, "default") &&
1392				!with_ipv6_linklocal_addr(dirent->d_name))
1393				reset_ipv6_linklocal_addr(dirent->d_name, 0);
1394		}
1395		closedir(dir);
1396	}
1397
1398	if (is_routing_enabled())
1399	{
1400		service = get_ipv6_service();
1401		switch (service) {
1402		case IPV6_NATIVE_DHCP:
1403#ifdef RTCONFIG_6RELAYD
1404		case IPV6_PASSTHROUGH:
1405#endif
1406			set_default_accept_ra(1);
1407		case IPV6_6IN4:
1408		case IPV6_6TO4:
1409		case IPV6_6RD:
1410		case IPV6_MANUAL:
1411		default:
1412			set_default_accept_ra(0);
1413			break;
1414		}
1415
1416		set_default_forwarding(1);
1417	}
1418	else set_default_accept_ra(0);
1419}
1420
1421#ifdef RTCONFIG_DUALWAN
1422void start_lan_ipv6(void)
1423{
1424	char *lan_ifname = strdup(nvram_safe_get("lan_ifname"));
1425	char *dualwan_wans = nvram_safe_get("wans_dualwan");
1426	char *dualwan_mode = nvram_safe_get("wans_mode");
1427	int unit, ipv6_service = 0;
1428
1429	if (!(!strstr(dualwan_wans, "none") &&
1430		(!strcmp(dualwan_mode, "fo") || !strcmp(dualwan_mode, "fb"))))
1431		return;
1432
1433	for (unit = WAN_UNIT_FIRST; unit < WAN_UNIT_MAX; ++unit)
1434		if (get_ipv6_service_by_unit(unit) != IPV6_DISABLED) {
1435			ipv6_service = 1;
1436			break;
1437		}
1438	if (!ipv6_service)
1439		return;
1440
1441	set_intf_ipv6_dad(lan_ifname, 0, 1);
1442	config_ipv6(ipv6_enabled() && is_routing_enabled(), 0);
1443	start_ipv6();
1444}
1445
1446void stop_lan_ipv6(void)
1447{
1448	char *lan_ifname = strdup(nvram_safe_get("lan_ifname"));
1449	char *dualwan_wans = nvram_safe_get("wans_dualwan");
1450	char *dualwan_mode = nvram_safe_get("wans_mode");
1451
1452	if (!(!strstr(dualwan_wans, "none") &&
1453		(!strcmp(dualwan_mode, "fo") || !strcmp(dualwan_mode, "fb"))))
1454		return;
1455
1456	stop_ipv6();
1457	set_intf_ipv6_dad(lan_ifname, 0, 0);
1458	config_ipv6(0, 1);
1459}
1460
1461void restart_dnsmasq_ipv6(void)
1462{
1463	char *dualwan_wans = nvram_safe_get("wans_dualwan");
1464	char *dualwan_mode = nvram_safe_get("wans_mode");
1465
1466	if (!(!strstr(dualwan_wans, "none") &&
1467		(!strcmp(dualwan_mode, "fo") || !strcmp(dualwan_mode, "fb"))))
1468		return;
1469
1470	if (!ipv6_enabled())
1471		return;
1472
1473	start_dnsmasq();
1474}
1475#endif
1476#endif
1477
1478#ifdef RTCONFIG_DPSTA
1479static int
1480dpsta_ioctl(char *name, void *buf, int len)
1481{
1482	struct ifreq ifr;
1483	int ret = 0;
1484	int s;
1485
1486	/* open socket to kernel */
1487	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1488		perror("socket");
1489		return errno;
1490	}
1491
1492	strncpy(ifr.ifr_name, name, IFNAMSIZ);
1493	ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
1494	ifr.ifr_data = (caddr_t)buf;
1495	if ((ret = ioctl(s, SIOCDEVPRIVATE, &ifr)) < 0)
1496		perror(ifr.ifr_name);
1497
1498	/* cleanup */
1499	close(s);
1500	return ret;
1501}
1502#endif
1503
1504void start_lan(void)
1505{
1506	char *lan_ifname;
1507	struct ifreq ifr;
1508	char *lan_ifnames, *ifname, *p;
1509	int sfd;
1510	uint32 ip;
1511	int hwaddrset;
1512	char eabuf[32];
1513	char word[256], *next;
1514	int match;
1515	char tmp[100], prefix[] = "wlXXXXXXXXXXXXXX";
1516	int i;
1517#ifdef RTCONFIG_WIRELESSREPEATER
1518	char domain_mapping[64];
1519#endif
1520#ifdef CONFIG_BCMWL5
1521	int unit, subunit, sta = 0;
1522#endif
1523#ifdef RTCONFIG_DPSTA
1524	char hwaddr[ETHER_ADDR_LEN];
1525	char macaddr[18];
1526	int s=0;
1527	int dpsta=0;
1528	dpsta_enable_info_t info = { 0 };
1529#endif
1530#ifdef RTCONFIG_GMAC3
1531	char name[80];
1532#endif
1533#ifdef __CONFIG_DHDAP__
1534	int is_dhd;
1535#endif /* __CONFIG_DHDAP__ */
1536
1537	update_lan_state(LAN_STATE_INITIALIZING, 0);
1538
1539	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER) {
1540		nvram_set("wlc_mode", "0");
1541		nvram_set("btn_ez_radiotoggle", "0"); // reset to default
1542	}
1543
1544	convert_routes();
1545
1546#if defined(RTCONFIG_RALINK) || defined(RTCONFIG_QCA)
1547	init_wl();
1548#endif
1549
1550#ifdef RTCONFIG_LED_ALL
1551	led_control(LED_ALL, LED_ON);
1552#if defined(RTAC1200HP) || defined(RTN56UB1) || defined(RTN56UB2)
1553	led_control(LED_5G, LED_ON);
1554	led_control(LED_2G, LED_ON);
1555#endif
1556#endif
1557
1558#ifdef CONFIG_BCMWL5
1559	init_wl_compact();
1560	wlconf_pre();
1561
1562	if (0)
1563	{
1564		foreach_wif(1, NULL, set_wlmac);
1565		check_afterburner();
1566	}
1567#endif
1568
1569	if (no_need_to_start_wps() ||
1570	    wps_band_radio_off(get_radio_band(nvram_get_int("wps_band"))) ||
1571	    wps_band_ssid_broadcast_off(get_radio_band(nvram_get_int("wps_band"))))
1572		nvram_set("wps_enable", "0");
1573	/* recover wps enable option back to original state */
1574	else if(!nvram_match("wps_enable", nvram_safe_get("wps_enable_old"))){
1575		nvram_set("wps_enable", nvram_safe_get("wps_enable_old"));
1576	}
1577
1578	if ((sfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) return;
1579
1580#ifdef RTCONFIG_GMAC3
1581	/* In 3GMAC mode, bring up the GMAC forwarding interfaces.
1582	 * Then bringup the primary wl interfaces that avail of hw switching.
1583	 */
1584	if (nvram_match("gmac3_enable", "1")) { /* __CONFIG_GMAC3__ */
1585
1586		/* Bring up GMAC#0 and GMAC#1 forwarder(s) */
1587		foreach(name, nvram_safe_get("fwddevs"), next) {
1588			ifconfig(name, 0, NULL, NULL);
1589			ifconfig(name, IFUP | IFF_ALLMULTI | IFF_PROMISC, NULL, NULL);
1590		}
1591	}
1592#endif
1593	lan_ifname = strdup(nvram_safe_get("lan_ifname"));
1594	if (strncmp(lan_ifname, "br", 2) == 0) {
1595		_dprintf("%s: setting up the bridge %s\n", __FUNCTION__, lan_ifname);
1596
1597		eval("brctl", "addbr", lan_ifname);
1598		eval("brctl", "setfd", lan_ifname, "0");
1599#ifdef RTAC87U
1600		eval("brctl", "stp", lan_ifname, nvram_safe_get("lan_stp"));
1601#else
1602		if (is_routing_enabled())
1603			eval("brctl", "stp", lan_ifname, nvram_safe_get("lan_stp"));
1604		else
1605			eval("brctl", "stp", lan_ifname, "0");
1606#endif
1607
1608#ifdef RTCONFIG_IPV6
1609		if (get_ipv6_service() != IPV6_DISABLED) {
1610			ipv6_sysconf(lan_ifname, "accept_ra", 0);
1611			ipv6_sysconf(lan_ifname, "forwarding", 0);
1612		}
1613		set_intf_ipv6_dad(lan_ifname, 1, 1);
1614#endif
1615#ifdef RTCONFIG_EMF
1616		if (nvram_match("emf_enable", "1")) {
1617			eval("emf", "add", "bridge", lan_ifname);
1618			eval("igs", "add", "bridge", lan_ifname);
1619		}
1620#endif
1621		inet_aton(nvram_safe_get("lan_ipaddr"), (struct in_addr *)&ip);
1622
1623		hwaddrset = 0;
1624		if ((lan_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL) {
1625			p = lan_ifnames;
1626
1627			while ((ifname = strsep(&p, " ")) != NULL) {
1628				while (*ifname == ' ') ++ifname;
1629				if (*ifname == 0) break;
1630#ifdef CONFIG_BCMWL5
1631				if (strncmp(ifname, "wl", 2) == 0) {
1632					if (!wl_vif_enabled(ifname, tmp)) {
1633						continue; /* Ignore disabled WL VIF */
1634					}
1635					wl_vif_hwaddr_set(ifname);
1636				}
1637				unit = -1; subunit = -1;
1638#endif
1639
1640				// ignore disabled wl vifs
1641				if (guest_wlif(ifname)) {
1642					char nv[40];
1643					char nv2[40];
1644					snprintf(nv, sizeof(nv) - 1, "%s_bss_enabled", wif_to_vif(ifname));
1645					snprintf(nv2, sizeof(nv2) - 1, "%s_expire", wif_to_vif(ifname));
1646					if(nvram_get_int("sw_mode")==SW_MODE_REPEATER)
1647					{
1648						nvram_set(nv,"1");	/*wl0.x_bss_enable=1*/
1649						nvram_unset(nv2);	/*remove wl0.x_expire*/
1650					}
1651					if (nvram_get_int(nv2) && nvram_get_int("success_start_service")==0)
1652					{
1653						nvram_set(nv, "0");
1654					}
1655
1656					if (!nvram_get_int(nv))
1657						continue;
1658#ifdef CONFIG_BCMWL5
1659					if (get_ifname_unit(ifname, &unit, &subunit) < 0)
1660						continue;
1661#endif
1662				}
1663#ifdef CONFIG_BCMWL5
1664				else
1665					wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
1666#endif
1667
1668#ifdef RTCONFIG_QCA
1669				qca_wif_up(ifname);
1670#endif
1671#ifdef RTCONFIG_RALINK
1672				gen_ra_config(ifname);
1673#endif
1674#if defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)
1675				{ // add interface for iNIC packets
1676					char *nic_if, *nic_ifs, *nic_lan_ifnames;
1677					if((nic_lan_ifnames = strdup(nvram_safe_get("nic_lan_ifnames"))))
1678					{
1679						nic_ifs = nic_lan_ifnames;
1680						while ((nic_if = strsep(&nic_ifs, " ")) != NULL) {
1681							while (*nic_if == ' ')
1682								nic_if++;
1683							if (*nic_if == 0)
1684								break;
1685							if(strcmp(ifname, nic_if) == 0)
1686							{
1687								int vlan_id;
1688								if((vlan_id = atoi(ifname + 4)) > 0)
1689								{
1690									char id[8];
1691									sprintf(id, "%d", vlan_id);
1692									eval("vconfig", "add", "eth2", id);
1693								}
1694								break;
1695							}
1696						}
1697						free(nic_lan_ifnames);
1698					}
1699				}
1700#endif
1701#if defined(RTCONFIG_QCA)
1702				if (!ifup_vap &&
1703				    (!strncmp(ifname, WIF_2G, strlen(WIF_2G)) ||
1704				     !strncmp(ifname, WIF_5G, strlen(WIF_5G))))
1705				{
1706					/* Don't up VAP interface here. */
1707				} else {
1708#endif
1709					// bring up interface
1710					if (ifconfig(ifname, IFUP | IFF_ALLMULTI, NULL, NULL) != 0) {
1711#if defined(RTAC56U) || defined(RTAC56S)
1712						if(strncmp(ifname, "eth2", 4)==0)
1713							nvram_set("5g_fail", "1");	// gpio led
1714#endif
1715#ifdef RTCONFIG_QTN
1716						if (strcmp(ifname, "wifi0"))
1717#endif
1718						continue;
1719					}
1720#if defined(RTAC56U) || defined(RTAC56S)
1721					else if(strncmp(ifname, "eth2", 4)==0)
1722						nvram_unset("5g_fail");			// gpio led
1723#endif
1724#if defined(RTCONFIG_QCA)
1725				}
1726#endif
1727
1728#ifdef RTCONFIG_RALINK
1729				wlconf_ra(ifname);
1730#elif defined(RTCONFIG_QCA)
1731				wlconf_qca(ifname);
1732#endif
1733
1734				// set the logical bridge address to that of the first interface
1735				strlcpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
1736				if ((!hwaddrset) ||
1737				    (ioctl(sfd, SIOCGIFHWADDR, &ifr) == 0 &&
1738				    memcmp(ifr.ifr_hwaddr.sa_data, "\0\0\0\0\0\0", ETHER_ADDR_LEN) == 0)) {
1739					strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
1740					if (ioctl(sfd, SIOCGIFHWADDR, &ifr) == 0) {
1741						strlcpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
1742						ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
1743
1744#ifdef RTCONFIG_QCA
1745#ifdef RTCONFIG_WIRELESSREPEATER
1746						if(nvram_get_int("sw_mode") == SW_MODE_REPEATER) {
1747							char *stamac;
1748							if((stamac=getStaMAC())!=NULL)
1749								ether_atoe(stamac,ifr.ifr_hwaddr.sa_data);
1750						}
1751#endif
1752#endif
1753
1754#ifdef RTCONFIG_DPSTA
1755						memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
1756#endif
1757						_dprintf("%s: setting MAC of %s bridge to %s\n", __FUNCTION__,
1758							ifr.ifr_name, ether_etoa((const unsigned char *) ifr.ifr_hwaddr.sa_data, eabuf));
1759						ioctl(sfd, SIOCSIFHWADDR, &ifr);
1760						hwaddrset = 1;
1761					}
1762				}
1763#ifdef CONFIG_BCMWL5
1764				if (wlconf(ifname, unit, subunit) == 0) {
1765					const char *mode = nvram_safe_get(wl_nvname("mode", unit, subunit));
1766
1767					if (strcmp(mode, "wet") == 0) {
1768						// Enable host DHCP relay
1769						if (nvram_match("lan_proto", "static")) {
1770#ifdef __CONFIG_DHDAP__
1771							is_dhd = !dhd_probe(ifname);
1772							if(is_dhd) {
1773								char macbuf[sizeof("wet_host_mac") + 1 + ETHER_ADDR_LEN];
1774								dhd_iovar_setbuf(ifname, "wet_host_mac", ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN , macbuf, sizeof(macbuf));
1775							}
1776							else
1777#endif /* __CONFIG_DHDAP__ */
1778							wl_iovar_set(ifname, "wet_host_mac", ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
1779						}
1780					}
1781
1782					sta |= (strcmp(mode, "sta") == 0);
1783					if ((strcmp(mode, "ap") != 0) && (strcmp(mode, "wet") != 0)
1784						&& (strcmp(mode, "psta") != 0) && (strcmp(mode, "psr") != 0))
1785						continue;
1786				}
1787#endif
1788#ifdef RTCONFIG_QTN
1789				if (!strcmp(ifname, "wifi0"))
1790					continue;
1791#endif
1792				/* Don't attach the main wl i/f in wds mode */
1793				match = 0, i = 0;
1794				foreach (word, nvram_safe_get("wl_ifnames"), next) {
1795					if (!strcmp(ifname, word))
1796					{
1797						snprintf(prefix, sizeof(prefix), "wl%d_", i);
1798						if (nvram_match(strcat_r(prefix, "mode_x", tmp), "1"))
1799#ifdef RTCONFIG_QCA
1800							match = 0;
1801#else
1802							match = 1;
1803#endif
1804
1805#ifdef RTCONFIG_PROXYSTA
1806#ifdef RTCONFIG_RALINK
1807						if (mediabridge_mode()) {
1808							ifconfig(ifname, 0, NULL, NULL);
1809							match = 1;
1810						}
1811#endif
1812#endif
1813
1814						break;
1815					}
1816
1817					i++;
1818				}
1819#if defined(RTCONFIG_PROXYSTA) && defined(RTCONFIG_DPSTA)
1820				/* Dont add main wl i/f when proxy sta is
1821			 	 * enabled in both bands. Instead add the
1822			 	 * dpsta interface.
1823			 	 */
1824				if (strstr(nvram_safe_get("dpsta_ifnames"), ifname)) {
1825					ifname = !dpsta ? "dpsta" : "";
1826					dpsta++;
1827
1828					/* Assign hw address */
1829					if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
1830						strncpy(ifr.ifr_name, "dpsta", IFNAMSIZ);
1831					if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0 &&
1832						memcmp(ifr.ifr_hwaddr.sa_data, "\0\0\0\0\0\0",
1833						ETHER_ADDR_LEN) == 0) {
1834							ether_etoa((const unsigned char *) hwaddr, macaddr);
1835							ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
1836							memcpy(ifr.ifr_hwaddr.sa_data, hwaddr,
1837								ETHER_ADDR_LEN);
1838							if (ioctl(s, SIOCSIFHWADDR, &ifr)) {
1839								close(s);
1840								return;
1841							}
1842						}
1843					}
1844					close(s);
1845				}
1846#endif
1847#ifdef RTCONFIG_GMAC3
1848				/* In 3GMAC mode, skip wl interfaces that avail of hw switching.
1849				 *
1850				 * Do not add these wl interfaces to the LAN bridge as they avail of
1851				 * HW switching. Misses in the HW switch's ARL will be forwarded via vlan1
1852				 * to br0 (i.e. via the network GMAC#2).
1853				 */
1854				if (nvram_match("gmac3_enable", "1") &&
1855					find_in_list(nvram_get("fwd_wlandevs"), ifname))
1856						goto gmac3_no_swbr;
1857#endif
1858#ifdef RTCONFIG_PORT_BASED_VLAN
1859				if (vlan_enable() && check_if_exist_vlan_ifnames(ifname))
1860					match = 1;
1861#endif
1862				if (!match)
1863				{
1864					eval("brctl", "addif", lan_ifname, ifname);
1865#ifdef RTCONFIG_GMAC3
1866gmac3_no_swbr:
1867#endif
1868#ifdef RTCONFIG_EMF
1869					if (nvram_match("emf_enable", "1"))
1870						eval("emf", "add", "iface", lan_ifname, ifname);
1871#endif
1872				}
1873				enable_wifi_bled(ifname);
1874			}
1875
1876			free(lan_ifnames);
1877		}
1878	}
1879	// --- this shouldn't happen ---
1880	else if (*lan_ifname) {
1881		ifconfig(lan_ifname, IFUP | IFF_ALLMULTI, NULL, NULL);
1882#ifdef CONFIG_BCMWL5
1883		wlconf(lan_ifname, -1, -1);
1884#endif
1885	}
1886	else {
1887		close(sfd);
1888		free(lan_ifname);
1889		return;
1890	}
1891
1892	// Get current LAN hardware address
1893	strlcpy(ifr.ifr_name, lan_ifname, IFNAMSIZ);
1894	if (ioctl(sfd, SIOCGIFHWADDR, &ifr) == 0) nvram_set("lan_hwaddr", ether_etoa((const unsigned char *) ifr.ifr_hwaddr.sa_data, eabuf));
1895
1896	close(sfd);
1897	/* Set initial QoS mode for LAN ports. */
1898#ifdef CONFIG_BCMWL5
1899	set_et_qos_mode();
1900#endif
1901
1902#ifdef RTCONFIG_DPSTA
1903	/* Configure dpsta module */
1904	if (dpsta) {
1905		int di = 0;
1906
1907		/* Enable and set the policy to in-band and cross-band
1908		 * forwarding policy.
1909		 */
1910		info.enable = 1;
1911		info.policy = atoi(nvram_safe_get("dpsta_policy"));
1912		info.lan_uif = atoi(nvram_safe_get("dpsta_lan_uif"));
1913		foreach(name, nvram_safe_get("dpsta_ifnames"), next) {
1914			strcpy((char *)info.upstream_if[di], name);
1915			di++;
1916		}
1917		dpsta_ioctl("dpsta", &info, sizeof(dpsta_enable_info_t));
1918
1919		/* Bring up dpsta interface */
1920		ifconfig("dpsta", IFUP, NULL, NULL);
1921	}
1922#endif
1923
1924	// bring up and configure LAN interface
1925#ifdef RTCONFIG_DHCP_OVERRIDE
1926	if(nvram_match("lan_proto", "static") || nvram_get_int("sw_mode") == SW_MODE_AP)
1927#else
1928	if(nvram_match("lan_proto", "static"))
1929#endif
1930		ifconfig(lan_ifname, IFUP | IFF_ALLMULTI, nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
1931	else
1932		ifconfig(lan_ifname, IFUP | IFF_ALLMULTI, nvram_default_get("lan_ipaddr"), nvram_default_get("lan_netmask"));
1933
1934#ifdef RTCONFIG_QCA
1935	gen_qca_wifi_cfgs();
1936#endif
1937
1938
1939#if defined(RTCONFIG_CFEZ) && defined(RTCONFIG_BCMARM)
1940	//move to ate-broadcom.c
1941#else
1942	config_loopback();
1943#endif
1944
1945#ifdef RTCONFIG_PORT_BASED_VLAN
1946	start_vlan_ifnames();
1947#endif
1948
1949#ifdef RTCONFIG_IPV6
1950	set_intf_ipv6_dad(lan_ifname, 0, 1);
1951	config_ipv6(ipv6_enabled() && is_routing_enabled(), 0);
1952	start_ipv6();
1953#endif
1954
1955#ifdef RTCONFIG_EMF
1956	start_emf(lan_ifname);
1957#endif
1958	start_snooper(lan_ifname);
1959
1960	if (nvram_match("lan_proto", "dhcp")
1961#ifdef RTCONFIG_DEFAULT_AP_MODE
1962			&& !nvram_match("ate_flag", "1")
1963#endif
1964	) {
1965		// only none routing mode need lan_proto=dhcp
1966		if (pids("udhcpc"))
1967		{
1968			killall("udhcpc", SIGUSR2);
1969			killall("udhcpc", SIGTERM);
1970			unlink("/tmp/udhcpc_lan");
1971		}
1972
1973		char *dhcp_argv[] = { "udhcpc",
1974					"-i", "br0",
1975					"-p", "/var/run/udhcpc_lan.pid",
1976					"-s", "/tmp/udhcpc_lan",
1977					NULL };
1978		pid_t pid;
1979
1980		symlink("/sbin/rc", "/tmp/udhcpc_lan");
1981		_eval(dhcp_argv, NULL, 0, &pid);
1982
1983		update_lan_state(LAN_STATE_CONNECTING, 0);
1984	}
1985	else {
1986		if(is_routing_enabled())
1987		{
1988			update_lan_state(LAN_STATE_CONNECTED, 0);
1989			add_lan_routes(lan_ifname);
1990			start_default_filter(0);
1991		}
1992		else lan_up(lan_ifname);
1993	}
1994
1995	free(lan_ifname);
1996
1997#ifdef RTCONFIG_SHP
1998	if(nvram_get_int("lfp_disable")==0) {
1999		restart_lfp();
2000	}
2001#endif
2002
2003#ifdef WEB_REDIRECT
2004#ifdef RTCONFIG_WIRELESSREPEATER
2005	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER) {
2006		// Drop the DHCP server from PAP.
2007		repeater_pap_disable();
2008
2009		// When CONNECTED, need to redirect 10.0.0.1(from the browser's cache) to DUT's home page.
2010		repeater_nat_setting();
2011	}
2012#endif
2013
2014	if(nvram_get_int("sw_mode") != SW_MODE_AP) {
2015		redirect_setting();
2016_dprintf("nat_rule: stop_nat_rules 1.\n");
2017		stop_nat_rules();
2018	}
2019
2020	start_wanduck();
2021#endif
2022
2023#ifdef RTCONFIG_BCMWL6
2024	set_acs_ifnames();
2025#endif
2026
2027#ifdef RTCONFIG_WIRELESSREPEATER
2028	if(nvram_get_int("sw_mode")==SW_MODE_REPEATER) {
2029		start_wlcconnect();
2030	}
2031
2032	if(get_model() == MODEL_APN12HP &&
2033		nvram_get_int("sw_mode") == SW_MODE_AP) {
2034		// When CONNECTED, need to redirect 10.0.0.1
2035		// (from the browser's cache) to DUT's home page.
2036		repeater_nat_setting();
2037		eval("ebtables", "-t", "broute", "-F");
2038		eval("ebtables", "-t", "filter", "-F");
2039		eval("ebtables", "-t", "broute", "-I", "BROUTING", "-d", "00:E0:11:22:33:44", "-j", "redirect", "--redirect-target", "DROP");
2040		sprintf(domain_mapping, "%x %s", inet_addr(nvram_safe_get("lan_ipaddr")), DUT_DOMAIN_NAME);
2041		f_write_string("/proc/net/dnsmqctrl", domain_mapping, 0, 0);
2042		start_nat_rules();
2043	}
2044#endif
2045
2046#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA)
2047	if ((is_psta(nvram_get_int("wlc_band")) || is_psr(nvram_get_int("wlc_band")))
2048#if defined(RTCONFIG_BCM7) || defined(RTCONFIG_BCM_7114)
2049#ifdef RTCONFIG_GMAC3
2050		&& !nvram_match("gmac3_enable", "1")
2051#endif
2052		&& nvram_match("ctf_disable", "1")
2053#endif
2054	) setup_dnsmq(1);
2055#endif
2056
2057#ifdef RTCONFIG_QTN
2058	if(*nvram_safe_get("QTN_RPC_CLIENT"))
2059		eval("ifconfig", "br0:0", nvram_safe_get("QTN_RPC_CLIENT"), "netmask", "255.255.255.0");
2060	else
2061		eval("ifconfig", "br0:0", "169.254.39.1", "netmask", "255.255.255.0");
2062#endif
2063	nvram_set("reload_svc_radio", "1");
2064
2065	_dprintf("%s %d\n", __FUNCTION__, __LINE__);
2066}
2067
2068#ifdef RTCONFIG_RALINK
2069static void
2070stop_wds_ra(const char* lan_ifname, const char* wif)
2071{
2072	char prefix[32];
2073	char wdsif[32];
2074	int i;
2075
2076	if (strcmp(wif, WIF_2G) && strcmp(wif, WIF_5G))
2077		return;
2078
2079	if (!strncmp(wif, "rai", 3))
2080		snprintf(prefix, sizeof(prefix), "wdsi");
2081	else
2082		snprintf(prefix, sizeof(prefix), "wds");
2083
2084	for (i = 0; i < 4; i++)
2085	{
2086		sprintf(wdsif, "%s%d", prefix, i);
2087		doSystem("brctl delif %s %s 1>/dev/null 2>&1", lan_ifname, wdsif);
2088		ifconfig(wdsif, 0, NULL, NULL);
2089	}
2090}
2091#endif
2092
2093void stop_lan(void)
2094{
2095	_dprintf("%s %d\n", __FUNCTION__, __LINE__);
2096
2097	char *lan_ifname;
2098	char *lan_ifnames, *p, *ifname;
2099
2100	lan_ifname = nvram_safe_get("lan_ifname");
2101
2102	if(is_routing_enabled())
2103	{
2104		stop_wanduck();
2105		del_lan_routes(lan_ifname);
2106	}
2107#ifdef RTCONFIG_WIRELESSREPEATER
2108	else if(nvram_get_int("sw_mode") == SW_MODE_REPEATER) {
2109		stop_wlcconnect();
2110
2111		stop_wanduck();
2112	}
2113#endif
2114#ifdef WEB_REDIRECT
2115	else if (is_apmode_enabled())
2116		stop_wanduck();
2117#endif
2118
2119#ifdef RTCONFIG_IPV6
2120	stop_ipv6();
2121	set_intf_ipv6_dad(lan_ifname, 0, 0);
2122	config_ipv6(0, 1);
2123#endif
2124
2125	ifconfig("lo", 0, NULL, NULL);
2126
2127	ifconfig(lan_ifname, 0, NULL, NULL);
2128
2129#ifdef RTCONFIG_GMAC3
2130	char name[20], *next;
2131	if (nvram_match("gmac3_enable", "1")) { /* __CONFIG_GMAC3__ */
2132
2133		/* Bring down GMAC#0 and GMAC#1 forwarder(s) */
2134		foreach(name, nvram_safe_get("fwddevs"), next) {
2135			ifconfig(name, 0, NULL, NULL);
2136		}
2137	}
2138#endif
2139
2140	if (module_loaded("ebtables")) {
2141		eval("ebtables", "-F");
2142		eval("ebtables", "-t", "broute", "-F");
2143	}
2144
2145	if (strncmp(lan_ifname, "br", 2) == 0) {
2146		if ((lan_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL) {
2147			p = lan_ifnames;
2148			while ((ifname = strsep(&p, " ")) != NULL) {
2149				while (*ifname == ' ') ++ifname;
2150				if (*ifname == 0) break;
2151				disable_wifi_bled(ifname);
2152#ifdef RTCONFIG_DPSTA
2153				if (!strcmp(ifname, "dpsta")) {
2154					char dp_uif[80], *dpnext;
2155					foreach(dp_uif, nvram_safe_get("dpsta_ifnames"),
2156						dpnext) {
2157						eval("wlconf", dp_uif, "down");
2158						ifconfig(dp_uif, 0, NULL, NULL);
2159					}
2160				}
2161#endif
2162#ifdef CONFIG_BCMWL5
2163#ifdef RTCONFIG_QTN
2164				if (strcmp(ifname, "wifi0"))
2165#endif
2166				{
2167					eval("wlconf", ifname, "down");
2168					eval("wl", "-i", ifname, "radio", "off");
2169					ifconfig(ifname, 0, NULL, NULL);
2170				}
2171#elif defined RTCONFIG_RALINK
2172				if (!strncmp(ifname, "ra", 2))
2173					stop_wds_ra(lan_ifname, ifname);
2174#elif defined(RTCONFIG_QCA)
2175				/* do nothing */
2176#endif	// BCMWL5
2177
2178#ifdef RTCONFIG_GMAC3
2179				/* List of primary WLAN interfaces that avail of HW switching. */
2180				/* In 3GMAC mode, each wl interfaces in "fwd_wlandevs" don't
2181				 * attach to the bridge.
2182				 */
2183				if (nvram_match("gmac3_enable", "1") &&
2184					find_in_list(nvram_get("fwd_wlandevs"), ifname))
2185					goto gmac3_no_swbr;
2186#endif
2187				eval("brctl", "delif", lan_ifname, ifname);
2188#ifdef RTCONFIG_GMAC3
2189gmac3_no_swbr:
2190#endif
2191#ifdef RTCONFIG_EMF
2192				if (nvram_match("emf_enable", "1"))
2193					eval("emf", "del", "iface", lan_ifname, ifname);
2194#endif
2195#if defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)
2196				{ // remove interface for iNIC packets
2197					char *nic_if, *nic_ifs, *nic_lan_ifnames;
2198					if((nic_lan_ifnames = strdup(nvram_safe_get("nic_lan_ifnames"))))
2199					{
2200						nic_ifs = nic_lan_ifnames;
2201						while ((nic_if = strsep(&nic_ifs, " ")) != NULL) {
2202							while (*nic_if == ' ')
2203								nic_if++;
2204							if (*nic_if == 0)
2205								break;
2206							if(strcmp(ifname, nic_if) == 0)
2207							{
2208								eval("vconfig", "rem", ifname);
2209								break;
2210							}
2211						}
2212						free(nic_lan_ifnames);
2213					}
2214				}
2215#endif
2216			}
2217			free(lan_ifnames);
2218		}
2219#ifdef RTCONFIG_EMF
2220		stop_emf(lan_ifname);
2221#endif
2222		stop_snooper();
2223		eval("brctl", "delbr", lan_ifname);
2224	}
2225	else if (*lan_ifname) {
2226#ifdef CONFIG_BCMWL5
2227		eval("wlconf", lan_ifname, "down");
2228		eval("wl", "-i", lan_ifname, "radio", "off");
2229#endif
2230	}
2231
2232#ifdef RTCONFIG_PORT_BASED_VLAN
2233	stop_vlan_ifnames();
2234#endif
2235
2236#ifdef RTCONFIG_BCMWL6
2237#if defined(RTAC66U) || defined(BCM4352)
2238	nvram_set("led_5g", "0");
2239	led_control(LED_5G, LED_OFF);
2240#ifdef RTCONFIG_TURBO
2241	led_control(LED_TURBO, LED_OFF);
2242#endif
2243#endif
2244#endif
2245
2246	// inform watchdog to stop WPS LED
2247	kill_pidfile_s("/var/run/watchdog.pid", SIGUSR2);
2248
2249	fini_wl();
2250
2251	init_nvram();	// init nvram lan_ifnames
2252	wl_defaults();	// init nvram wlx_ifnames & lan_ifnames
2253
2254	update_lan_state(LAN_STATE_STOPPED, 0);
2255
2256	killall("udhcpc", SIGUSR2);
2257	killall("udhcpc", SIGTERM);
2258	unlink("/tmp/udhcpc_lan");
2259
2260#ifdef RTCONFIG_QTN
2261	nvram_unset("qtn_ready");
2262#endif
2263
2264	_dprintf("%s %d\n", __FUNCTION__, __LINE__);
2265}
2266
2267void do_static_routes(int add)
2268{
2269	char *buf;
2270	char *p, *q;
2271	char *dest, *mask, *gateway, *metric, *ifname;
2272	int r;
2273
2274	if ((buf = strdup(nvram_safe_get(add ? "routes_static" : "routes_static_saved"))) == NULL) return;
2275	if (add) nvram_set("routes_static_saved", buf);
2276		else nvram_unset("routes_static_saved");
2277	p = buf;
2278	while ((q = strsep(&p, ">")) != NULL) {
2279		if (vstrsep(q, "<", &dest, &gateway, &mask, &metric, &ifname) != 5) continue;
2280		ifname = nvram_safe_get((*ifname == 'L') ? "lan_ifname" :
2281					((*ifname == 'W') ? "wan_iface" : "wan_ifname"));
2282		if (add) {
2283			for (r = 3; r >= 0; --r) {
2284				if (route_add(ifname, atoi(metric) + 1, dest, gateway, mask) == 0) break;
2285				sleep(1);
2286			}
2287		}
2288		else {
2289			route_del(ifname, atoi(metric) + 1, dest, gateway, mask);
2290		}
2291	}
2292	free(buf);
2293}
2294
2295#ifdef CONFIG_BCMWL5
2296
2297/*
2298 * EAP module
2299 */
2300
2301static int
2302wl_send_dif_event(const char *ifname, uint32 event)
2303{
2304	static int s = -1;
2305	int len, n;
2306	struct sockaddr_in to;
2307	char data[IFNAMSIZ + sizeof(uint32)];
2308
2309	if (ifname == NULL) return -1;
2310
2311	/* create a socket to receive dynamic i/f events */
2312	if (s < 0) {
2313		s = socket(AF_INET, SOCK_DGRAM, 0);
2314		if (s < 0) {
2315			perror("socket");
2316			return -1;
2317		}
2318	}
2319
2320	/* Init the message contents to send to eapd. Specify the interface
2321	 * and the event that occured on the interface.
2322	 */
2323	strncpy(data, ifname, IFNAMSIZ);
2324	*(uint32 *)(data + IFNAMSIZ) = event;
2325	len = IFNAMSIZ + sizeof(uint32);
2326
2327	/* send to eapd */
2328	to.sin_addr.s_addr = inet_addr(EAPD_WKSP_UDP_ADDR);
2329	to.sin_family = AF_INET;
2330	to.sin_port = htons(EAPD_WKSP_DIF_UDP_PORT);
2331
2332	n = sendto(s, data, len, 0, (struct sockaddr *)&to,
2333		sizeof(struct sockaddr_in));
2334
2335	if (n != len) {
2336		perror("udp send failed\n");
2337		return -1;
2338	}
2339
2340	_dprintf("hotplug_net(): sent event %d\n", event);
2341
2342	return n;
2343}
2344#endif
2345
2346void hotplug_net(void)
2347{
2348	char *lan_ifname = nvram_safe_get("lan_ifname");
2349	char *interface, *action;
2350	bool psta_if, dyn_if, add_event, remove_event;
2351	int unit;
2352	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
2353#ifdef RTCONFIG_USB_MODEM
2354	char device_path[128], usb_path[PATH_MAX], usb_node[32], port_path[8];
2355	char nvram_name[32];
2356	char word[PATH_MAX], *next;
2357	char modem_type[8];
2358#endif
2359
2360	if (!(interface = getenv("INTERFACE")) ||
2361	    !(action = getenv("ACTION")))
2362		return;
2363
2364	_dprintf("hotplug net INTERFACE=%s ACTION=%s\n", interface, action);
2365
2366#ifdef LINUX26
2367	add_event = !strcmp(action, "add");
2368#else
2369	add_event = !strcmp(action, "register");
2370#endif
2371
2372#ifdef LINUX26
2373	remove_event = !strcmp(action, "remove");
2374#else
2375	remove_event = !strcmp(action, "unregister");
2376#endif
2377
2378#ifdef RTCONFIG_BCMWL6
2379	psta_if = wl_wlif_is_psta(interface);
2380#else
2381	psta_if = 0;
2382#endif
2383
2384	dyn_if = !strncmp(interface, "wds", 3) || psta_if;
2385
2386	if (!dyn_if && !remove_event)
2387		goto NEITHER_WDS_OR_PSTA;
2388
2389	if (dyn_if && add_event) {
2390#ifdef RTCONFIG_RALINK
2391		if (nvram_match("sw_mode", "2"))
2392			return;
2393
2394		if (strncmp(interface, WDSIF_5G, strlen(WDSIF_5G)) == 0 && isdigit(interface[strlen(WDSIF_5G)]))
2395		{
2396			if (nvram_match("wl1_mode_x", "0")) return;
2397		}
2398		else
2399		{
2400			if (nvram_match("wl0_mode_x", "0")) return;
2401		}
2402#endif
2403
2404		/* Bring up the interface and add to the bridge */
2405		ifconfig(interface, IFUP, NULL, NULL);
2406
2407#ifdef RTCONFIG_EMF
2408		if (nvram_match("emf_enable", "1")) {
2409			eval("emf", "add", "iface", lan_ifname, interface);
2410			emf_mfdb_update(lan_ifname, interface, TRUE);
2411			emf_uffp_update(lan_ifname, interface, TRUE);
2412			emf_rtport_update(lan_ifname, interface, TRUE);
2413		}
2414#endif
2415#ifdef CONFIG_BCMWL5
2416		/* Indicate interface create event to eapd */
2417		if (psta_if) {
2418			_dprintf("hotplug_net(): send dif event to %s\n", interface);
2419			wl_send_dif_event(interface, 0);
2420			return;
2421		}
2422#endif
2423		if (!strncmp(lan_ifname, "br", 2)) {
2424			eval("brctl", "addif", lan_ifname, interface);
2425#ifdef CONFIG_BCMWL5
2426			/* Inform driver to send up new WDS link event */
2427			if (wl_iovar_setint(interface, "wds_enable", 1)) {
2428				_dprintf("%s set wds_enable failed\n", interface);
2429				return;
2430			}
2431#endif
2432		}
2433
2434		return;
2435	}
2436
2437#ifdef CONFIG_BCMWL5
2438	if (remove_event) {
2439		/* Indicate interface delete event to eapd */
2440		wl_send_dif_event(interface, 1);
2441
2442#ifdef RTCONFIG_EMF
2443		if (nvram_match("emf_enable", "1"))
2444			eval("emf", "del", "iface", lan_ifname, interface);
2445#endif /* RTCONFIG_EMF */
2446	}
2447#endif
2448
2449#if defined(RTCONFIG_QCA)
2450	if (remove_event) { // TBD
2451		f_write_string("/dev/sfe", "clear", 0, 0);
2452	}
2453#endif
2454
2455NEITHER_WDS_OR_PSTA:
2456	/* PPP interface removed */
2457	if (strncmp(interface, "ppp", 3) == 0 && remove_event) {
2458		while ((unit = ppp_ifunit(interface)) >= 0) {
2459			snprintf(prefix, sizeof(prefix), "wan%d_", unit);
2460			nvram_set(strcat_r(prefix, "pppoe_ifname", tmp), "");
2461		}
2462	}
2463#ifdef RTCONFIG_USB_MODEM
2464	// Android phone, RNDIS interface, NCM, qmi_wwan.
2465	else if(!strncmp(interface, "usb", 3)) {
2466		if(nvram_get_int("sw_mode") != SW_MODE_ROUTER)
2467			return;
2468
2469		if ((unit = get_usbif_dualwan_unit()) < 0) {
2470			usb_dbg("(%s): in the current dual wan mode, didn't support the USB modem.\n", interface);
2471			return;
2472		}
2473
2474		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
2475
2476		if(!strcmp(action, "add")) {
2477			unsigned int vid, pid;
2478			char buf[32];
2479			int i = 0;
2480
2481			logmessage("hotplug", "add net %s.", interface);
2482			_dprintf("hotplug net: add net %s.\n", interface);
2483
2484			snprintf(device_path, 128, "%s/%s/device", SYS_NET, interface);
2485
2486			memset(usb_path, 0, PATH_MAX);
2487			if(realpath(device_path, usb_path) == NULL){
2488				_dprintf("hotplug net(%s): skip 1. device_path %s.\n", interface, device_path);
2489				return;
2490			}
2491
2492			if(get_usb_node_by_string(usb_path, usb_node, 32) == NULL){
2493				_dprintf("hotplug net(%s): skip 2. usb_path %s.\n", interface, usb_path);
2494				return;
2495			}
2496
2497			if(get_path_by_node(usb_node, port_path, 8) == NULL){
2498				_dprintf("hotplug net(%s): skip 3. usb_node %s.\n", interface, usb_node);
2499				return;
2500			}
2501
2502#ifdef RTCONFIG_INTERNAL_GOBI
2503			if((nvram_get_int("usb_gobi") == 1 && strcmp(port_path, "2"))
2504					|| (nvram_get_int("usb_gobi") != 1 && !strcmp(port_path, "2"))
2505					)
2506				return;
2507#endif
2508
2509			snprintf(buf, 32, "%s", nvram_safe_get("usb_modem_act_path"));
2510			if(strcmp(buf, "") && strcmp(buf, usb_node)){
2511				_dprintf("hotplug net(%s): skip 4. port_path %s.\n", interface, port_path);
2512				return;
2513			}
2514
2515			if(!strcmp(buf, ""))
2516				nvram_set("usb_modem_act_path", usb_node); // needed by find_modem_type.sh.
2517
2518			while(!strcmp(nvram_safe_get("usb_modem_act_type"), "") && i++ < 3){
2519				_dprintf("hotplug net(%s): wait for the modem driver at %d second...\n", interface, i);
2520				eval("find_modem_type.sh");
2521				sleep(1);
2522			}
2523
2524			snprintf(modem_type, 8, "%s", nvram_safe_get("usb_modem_act_type"));
2525			_dprintf("hotplug net: usb_modem_act_type=%s.\n", modem_type);
2526			if(!strcmp(modem_type, "mbim")){
2527				_dprintf("hotplug net(%s): skip the MBIM interface.\n", interface);
2528				return;
2529			}
2530
2531			vid = get_usb_vid(usb_node);
2532			pid = get_usb_pid(usb_node);
2533			logmessage("hotplug", "Got net %s, vid 0x%x, pid 0x%x.", interface, vid, pid);
2534			_dprintf("hotplug net: Got net %s, vid 0x%x, pid 0x%x.\n", interface, vid, pid);
2535
2536			if(!strcmp(interface, "usb0")){
2537				_dprintf("hotplug net(%s): let usb0 wait for usb1.\n", interface);
2538				sleep(1);
2539			}
2540
2541			snprintf(nvram_name, 32, "usb_path%s_act", port_path);
2542			snprintf(word, PATH_MAX, "%s", nvram_safe_get(nvram_name));
2543			_dprintf("hotplug net(%s): %s %s.\n", interface, nvram_name, word);
2544
2545			//if(!strcmp(word, "usb1") && strcmp(interface, "usb1")){
2546			if(!strcmp(word, "usb1")){
2547				// If there are 2 usbX, use QMI:usb1 to connect.
2548				logmessage("hotplug", "skip to set net %s.", interface);
2549				_dprintf("hotplug net: skip to set net %s.\n", interface);
2550				return;
2551			}
2552			else{
2553				logmessage("hotplug", "set net %s.", interface);
2554				_dprintf("hotplug net: set net %s.\n", interface);
2555				nvram_set(nvram_name, interface);
2556				snprintf(buf, 32, "%u", vid);
2557				nvram_set("usb_modem_act_vid", buf);
2558				snprintf(buf, 32, "%u", pid);
2559				nvram_set("usb_modem_act_pid", buf);
2560				nvram_set("usb_modem_act_dev", interface);
2561				nvram_set(strcat_r(prefix, "ifname", tmp), interface);
2562			}
2563
2564			// won't wait at the busy time of every start_wan when booting.
2565			if(!strcmp(nvram_safe_get("success_start_service"), "1")){
2566				// wait for Andorid phones.
2567				_dprintf("hotplug net INTERFACE=%s ACTION=%s: wait 2 seconds...\n", interface, action);
2568				sleep(2);
2569			}
2570			else{
2571				// wait that the modem nvrams are ready during booting.
2572				// e.q. Huawei E398.
2573				int i = 0;
2574				snprintf(nvram_name, 32, "usb_path%s", port_path);
2575				while(strcmp(nvram_safe_get(nvram_name), "modem") && i++ < 3){
2576					_dprintf("%s: waiting %d second for the modem nvrams...", __FUNCTION__, i);
2577					sleep(1);
2578				}
2579			}
2580
2581			if(nvram_get_int("usb_modem_act_reset") != 0){
2582				logmessage("hotplug", "Modem had been reset and woken up net %s.", interface);
2583				_dprintf("hotplug net(%s) had been reset and woken up.\n", interface);
2584				nvram_set("usb_modem_act_reset", "2");
2585				return;
2586			}
2587
2588#ifdef RTCONFIG_DUALWAN
2589			// avoid the busy time of every start_wan when booting.
2590			if(!strcmp(nvram_safe_get("success_start_service"), "0")
2591					&& strcmp(modem_type, "rndis") // rndis modem can't get IP when booting.
2592					&& strcmp(modem_type, "qmi") // qmi modem often be blocked when booting.
2593					&& (unit == WAN_UNIT_FIRST || nvram_match("wans_mode", "lb"))
2594					){
2595				_dprintf("%s: start_wan_if(%d)!\n", __FUNCTION__, unit);
2596				start_wan_if(unit);
2597			}
2598#endif
2599		}
2600		else{
2601			logmessage("hotplug", "remove net %s.", interface);
2602			_dprintf("hotplug net: remove net %s.\n", interface);
2603
2604			snprintf(usb_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
2605			if(strlen(usb_node) <= 0)
2606				return;
2607
2608			if(get_path_by_node(usb_node, port_path, 8) == NULL)
2609				return;
2610
2611			snprintf(nvram_name, 32, "usb_path%s_act", port_path);
2612			if(strcmp(nvram_safe_get(nvram_name), interface))
2613				return;
2614
2615			nvram_unset(nvram_name);
2616
2617			clean_modem_state(1);
2618
2619			nvram_set(strcat_r(prefix, "ifname", tmp), "");
2620
2621			/* Stop dhcp client */
2622			stop_udhcpc(unit);
2623		}
2624	}
2625	// Beceem dongle, ASIX USB to RJ45 converter, ECM, rndis(LU-150: ethX with RNDIS).
2626	else if(!strncmp(interface, "eth", 3)) {
2627		if(nvram_get_int("sw_mode") != SW_MODE_ROUTER)
2628			return;
2629
2630#ifdef RTCONFIG_RALINK
2631		// In the Ralink platform eth2 isn't defined at wan_ifnames or other nvrams,
2632		// so it need to deny additionally.
2633		if(!strncmp(interface, "eth2", 4))
2634			return;
2635
2636#if defined(RTN67U) || defined(RTN36U3) || defined(RTN56U) || defined(RTN56UB1) || defined(RTN56UB2)
2637		/* eth3 may be used as WAN on some Ralink/MTK platform. */
2638		if(!strncmp(interface, "eth3", 4))
2639			return;
2640#endif
2641
2642#elif defined(RTCONFIG_QCA)
2643		/* All models use eth0/eth1 as LAN or WAN. */
2644		if (!strncmp(interface, "eth0", 4) || !strncmp(interface, "eth1", 4))
2645			return;
2646#if defined(RTCONFIG_SWITCH_RTL8370M_PHY_QCA8033_X2) || defined(RTCONFIG_SWITCH_RTL8370MB_PHY_QCA8033_X2)
2647		/* BRT-AC828M2 SR1~SR3: eth2/eth3 are WAN1/WAN2.
2648		 * BRT-AC828M2 SR4+   : eth2/eth3 are LAN2/WAN2.
2649		 */
2650		if (!strncmp(interface, "eth2", 4) || !strncmp(interface, "eth3", 4))
2651			return;
2652#endif
2653
2654#else
2655		// for all models, ethernet's physical interface.
2656		if(!strcmp(interface, "eth0"))
2657			return;
2658#endif
2659
2660		// Not wired ethernet.
2661		foreach(word, nvram_safe_get("wan_ifnames"), next)
2662			if(!strcmp(interface, word))
2663				return;
2664
2665		// Not wired ethernet.
2666		foreach(word, nvram_safe_get("lan_ifnames"), next)
2667			if(!strcmp(interface, word))
2668				return;
2669
2670		// Not wireless ethernet.
2671		foreach(word, nvram_safe_get("wl_ifnames"), next)
2672			if(!strcmp(interface, word))
2673				return;
2674
2675		if ((unit = get_usbif_dualwan_unit()) < 0) {
2676			usb_dbg("(%s): in the current dual wan mode, didn't support the USB modem.\n", interface);
2677			return;
2678		}
2679
2680		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
2681
2682		if(!strcmp(action, "add")) {
2683			nvram_set(strcat_r(prefix, "ifname", tmp), interface);
2684
2685			_dprintf("hotplug net INTERFACE=%s ACTION=%s: wait 2 seconds...\n", interface, action);
2686			sleep(2);
2687
2688			snprintf(device_path, 128, "%s/%s/device", SYS_NET, interface);
2689
2690			// Huawei E353.
2691			if(check_if_dir_exist(device_path)) {
2692				memset(usb_path, 0, PATH_MAX);
2693				if(realpath(device_path, usb_path) == NULL)
2694					return;
2695
2696				if(get_usb_node_by_string(usb_path, usb_node, 32) == NULL)
2697					return;
2698
2699				if(get_path_by_node(usb_node, port_path, 8) == NULL)
2700					return;
2701
2702				snprintf(nvram_name, 32, "usb_path%s_act", port_path);
2703
2704				nvram_set(nvram_name, interface);
2705				nvram_set("usb_modem_act_path", usb_node);
2706				nvram_set("usb_modem_act_dev", interface);
2707			}
2708			// Beceem dongle.
2709			else{
2710				// do nothing.
2711			}
2712
2713#ifdef RTCONFIG_DUALWAN
2714			// avoid the busy time of every start_wan when booting.
2715			if(!strcmp(nvram_safe_get("success_start_service"), "0")
2716					&& (unit == WAN_UNIT_FIRST || nvram_match("wans_mode", "lb"))
2717					){
2718				_dprintf("%s: start_wan_if(%d)!\n", __FUNCTION__, unit);
2719				start_wan_if(unit);
2720			}
2721#endif
2722		}
2723		else{
2724			nvram_set(strcat_r(prefix, "ifname", tmp), "");
2725
2726			stop_wan_if(unit);
2727
2728			snprintf(usb_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
2729			if(strlen(usb_node) <= 0)
2730				return;
2731
2732			if(get_path_by_node(usb_node, port_path, 8) == NULL)
2733				return;
2734
2735			snprintf(nvram_name, 32, "usb_path%s_act", port_path);
2736
2737			if(!strcmp(nvram_safe_get(nvram_name), interface)) {
2738				nvram_unset(nvram_name);
2739
2740				clean_modem_state(1);
2741			}
2742
2743			/* Stop dhcp client */
2744			stop_udhcpc(unit);
2745
2746#ifdef RTCONFIG_USB_BECEEM
2747			if(strlen(port_path) <= 0)
2748				system("asus_usbbcm usbbcm remove");
2749#endif
2750		}
2751	}
2752#ifdef RTCONFIG_USB_BECEEM
2753	// WiMAX: madwimax, gctwimax.
2754	else if(!strncmp(interface, "wimax", 5)){
2755		if(nvram_get_int("sw_mode") != SW_MODE_ROUTER)
2756			return;
2757
2758		if((unit = get_usbif_dualwan_unit()) < 0){
2759			usb_dbg("(%s): in the current dual wan mode, didn't support the USB modem.\n", interface);
2760			return;
2761		}
2762
2763		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
2764
2765		if(!strcmp(action, "add")){
2766			snprintf(usb_node, 32, "%s", nvram_safe_get("usb_modem_act_path"));
2767			if(strlen(usb_node) <= 0)
2768				return;
2769			if(get_path_by_node(usb_node, port_path, 8) == NULL)
2770				return;
2771
2772			nvram_set(strcat_r(prefix, "ifname", tmp), interface);
2773
2774			snprintf(nvram_name, 32, "usb_path%s_act", port_path);
2775			nvram_set(nvram_name, interface);
2776
2777			_dprintf("hotplug net INTERFACE=%s ACTION=%s: wait 2 seconds...\n", interface, action);
2778			sleep(2);
2779
2780			// This is the second step of start_wan_if().
2781			// First start_wan_if(): call the WiMAX process up.
2782			// Second start_wan_if(): call the udhcpc up.
2783			_dprintf("%s: start_wan_if(%d)!\n", __FUNCTION__, unit);
2784			start_wan_if(unit);
2785		}
2786		else // remove: do nothing.
2787			;
2788	}
2789#endif
2790#endif
2791}
2792
2793#ifdef CONFIG_BCMWL5
2794static int is_same_addr(struct ether_addr *addr1, struct ether_addr *addr2)
2795{
2796	int i;
2797	for (i = 0; i < 6; i++) {
2798		if (addr1->octet[i] != addr2->octet[i])
2799			return 0;
2800	}
2801	return 1;
2802}
2803
2804#define WL_MAX_ASSOC	128
2805static int check_wl_client(char *ifname, int unit, int subunit)
2806{
2807	struct ether_addr bssid;
2808	wl_bss_info_t *bi;
2809	char buf[WLC_IOCTL_MAXLEN];
2810	struct maclist *mlist;
2811	int mlsize, i;
2812	int associated, authorized;
2813
2814	*(uint32 *)buf = WLC_IOCTL_MAXLEN;
2815	if (wl_ioctl(ifname, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN) < 0 ||
2816	    wl_ioctl(ifname, WLC_GET_BSS_INFO, buf, WLC_IOCTL_MAXLEN) < 0)
2817		return 0;
2818
2819	bi = (wl_bss_info_t *)(buf + 4);
2820	if ((bi->SSID_len == 0) ||
2821	    (bi->BSSID.octet[0] + bi->BSSID.octet[1] + bi->BSSID.octet[2] +
2822	     bi->BSSID.octet[3] + bi->BSSID.octet[4] + bi->BSSID.octet[5] == 0))
2823		return 0;
2824
2825	associated = 0;
2826	authorized = strstr(nvram_safe_get(wl_nvname("akm", unit, subunit)), "psk") == 0;
2827
2828	mlsize = sizeof(struct maclist) + (WL_MAX_ASSOC * sizeof(struct ether_addr));
2829	if ((mlist = malloc(mlsize)) != NULL) {
2830		mlist->count = WL_MAX_ASSOC;
2831		if (wl_ioctl(ifname, WLC_GET_ASSOCLIST, mlist, mlsize) == 0) {
2832			for (i = 0; i < mlist->count; ++i) {
2833				if (is_same_addr(&mlist->ea[i], &bi->BSSID)) {
2834					associated = 1;
2835					break;
2836				}
2837			}
2838		}
2839
2840		if (associated && !authorized) {
2841			memset(mlist, 0, mlsize);
2842			mlist->count = WL_MAX_ASSOC;
2843			strcpy((char*)mlist, "autho_sta_list");
2844			if (wl_ioctl(ifname, WLC_GET_VAR, mlist, mlsize) == 0) {
2845				for (i = 0; i < mlist->count; ++i) {
2846					if (is_same_addr(&mlist->ea[i], &bi->BSSID)) {
2847						authorized = 1;
2848						break;
2849					}
2850				}
2851			}
2852		}
2853		free(mlist);
2854	}
2855	return (associated && authorized);
2856}
2857#else /* ! CONFIG_BCMWL5 */
2858static int check_wl_client(char *ifname, int unit, int subunit)
2859{
2860// add ralink client check code here
2861	return 0;
2862}
2863#endif /* CONFIG_BCMWL5 */
2864
2865#define STACHECK_CONNECT	30
2866#define STACHECK_DISCONNECT	5
2867
2868static int radio_join(int idx, int unit, int subunit, void *param)
2869{
2870	int i;
2871	char s[32], f[64];
2872	char *ifname;
2873
2874	int *unit_filter = param;
2875	if (*unit_filter >= 0 && *unit_filter != unit) return 0;
2876
2877	if (!nvram_get_int(wl_nvname("radio", unit, 0)) || !wl_client(unit, subunit)) return 0;
2878
2879	ifname = nvram_safe_get(wl_nvname("ifname", unit, subunit));
2880
2881	// skip disabled wl vifs
2882	if (strncmp(ifname, "wl", 2) == 0 && strchr(ifname, '.') &&
2883		!nvram_get_int(wl_nvname("bss_enabled", unit, subunit)))
2884		return 0;
2885
2886	sprintf(f, "/var/run/radio.%d.%d.pid", unit, subunit < 0 ? 0 : subunit);
2887	if (f_read_string(f, s, sizeof(s)) > 0) {
2888		if ((i = atoi(s)) > 1) {
2889			kill(i, SIGTERM);
2890			sleep(1);
2891		}
2892	}
2893
2894	if (fork() == 0) {
2895		sprintf(s, "%d", getpid());
2896		f_write(f, s, sizeof(s), 0, 0644);
2897
2898		int stacheck_connect = nvram_get_int("sta_chkint");
2899		if (stacheck_connect <= 0)
2900			stacheck_connect = STACHECK_CONNECT;
2901		int stacheck;
2902
2903		while (get_radio(unit, 0) && wl_client(unit, subunit)) {
2904
2905			if (check_wl_client(ifname, unit, subunit)) {
2906				stacheck = stacheck_connect;
2907			}
2908			else {
2909#ifdef RTCONFIG_RALINK
2910// add ralink client mode code here.
2911#elif defined(RTCONFIG_QCA)
2912// add QCA client mode code here.
2913#else
2914				eval("wl", "-i", ifname, "disassoc");
2915#ifdef CONFIG_BCMWL5
2916				char *amode, *sec = nvram_safe_get(wl_nvname("akm", unit, subunit));
2917
2918				if (strstr(sec, "psk2")) amode = "wpa2psk";
2919				else if (strstr(sec, "psk")) amode = "wpapsk";
2920				else if (strstr(sec, "wpa2")) amode = "wpa2";
2921				else if (strstr(sec, "wpa")) amode = "wpa";
2922				else if (nvram_get_int(wl_nvname("auth", unit, subunit))) amode = "shared";
2923				else amode = "open";
2924
2925				eval("wl", "-i", ifname, "join", nvram_safe_get(wl_nvname("ssid", unit, subunit)),
2926					"imode", "bss", "amode", amode);
2927#else
2928				eval("wl", "-i", ifname, "join", nvram_safe_get(wl_nvname("ssid", unit, subunit)));
2929#endif
2930#endif
2931				stacheck = STACHECK_DISCONNECT;
2932			}
2933			sleep(stacheck);
2934		}
2935		unlink(f);
2936	}
2937
2938	return 1;
2939}
2940
2941enum {
2942	RADIO_OFF = 0,
2943	RADIO_ON = 1,
2944	RADIO_TOGGLE = 2,
2945	RADIO_SWITCH = 3
2946};
2947
2948static int radio_toggle(int idx, int unit, int subunit, void *param)
2949{
2950	if (!nvram_get_int(wl_nvname("radio", unit, 0))) return 0;
2951
2952	int *op = param;
2953
2954	if (*op == RADIO_TOGGLE) {
2955		*op = get_radio(unit, subunit) ? RADIO_OFF : RADIO_ON;
2956	}
2957
2958	set_radio(*op, unit, subunit);
2959	return *op;
2960}
2961
2962#ifdef RTCONFIG_BCMWL6
2963static void led_bh_prep(int post)
2964{
2965	int wlon_unit = -1, i = 0, maxi = 1;
2966	char ifbuf[5];
2967
2968	switch (get_model()) {
2969		case MODEL_RTAC56S:
2970		case MODEL_RTAC56U:
2971			if(post)
2972			{
2973				eval("wl", "ledbh", "3", "7");
2974				eval("wl", "-i", "eth2", "ledbh", "10", "7");
2975			}
2976			else
2977			{
2978				eval("wl", "ledbh", "3", "1");
2979				eval("wl", "-i", "eth2", "ledbh", "10", "1");
2980				led_control(LED_5G, LED_ON);
2981				eval("wlconf", "eth1", "up");
2982				eval("wl", "maxassoc", "0");
2983				eval("wlconf", "eth2", "up");
2984				eval("wl", "-i", "eth2", "maxassoc", "0");
2985			}
2986			break;
2987		case MODEL_RTAC5300:
2988		case MODEL_RTAC5300R:
2989		case MODEL_RTAC88U:
2990		case MODEL_RTAC3100:
2991
2992			if(post)
2993			{
2994				wlon_unit = nvram_get_int("wlc_band");
2995
2996				if(!mediabridge_mode()) {
2997					eval("wl", "ledbh", "9", "7");
2998					eval("wl", "-i", "eth2", "ledbh", "9", "7");
2999#if defined(RTAC5300) || defined(RTAC5300R)
3000					eval("wl", "-i", "eth3", "ledbh", "9", "7");
3001#endif
3002				} else { /* turn off other bands led */
3003#if defined(RTAC5300) || defined(RTAC5300R)
3004					maxi = 2;
3005#endif
3006					for(i=0; i<=maxi; ++i) {
3007						if( i == wlon_unit )
3008							continue;
3009						memset(ifbuf, 0, sizeof(ifbuf));
3010						sprintf(ifbuf, "eth%d", i+1);
3011						eval("wl", "-i", ifbuf, "ledbh", "9", "0");
3012					}
3013				}
3014			}
3015			else
3016			{
3017
3018				eval("wl", "ledbh", "9", "1");
3019				eval("wl", "-i", "eth2", "ledbh", "9", "1");
3020#if defined(RTAC5300) || defined(RTAC5300R)
3021				eval("wl", "-i", "eth3", "ledbh", "9", "1");
3022#endif
3023				eval("wlconf", "eth1", "up");
3024				eval("wl", "maxassoc", "0");
3025				eval("wlconf", "eth2", "up");
3026				eval("wl", "-i", "eth2", "maxassoc", "0");
3027#if defined(RTAC5300) || defined(RTAC5300R)
3028				eval("wlconf", "eth3", "up");
3029				eval("wl", "-i", "eth3", "maxassoc", "0");
3030#endif
3031			}
3032			break;
3033		case MODEL_RTAC3200:
3034		case MODEL_DSLAC68U:
3035		case MODEL_RPAC68U:
3036		case MODEL_RTAC68U:
3037		case MODEL_RTAC87U:
3038			if(post)
3039			{
3040				eval("wl", "ledbh", "10", "7");
3041				eval("wl", "-i", "eth2", "ledbh", "10", "7");
3042
3043#ifdef RTCONFIG_LEDARRAY
3044				eval("wl", "ledbh", "9", "7");
3045				eval("wl", "ledbh", "0", "7");
3046				eval("wl", "-i", "eth2", "ledbh", "9", "7");
3047				eval("wl", "-i", "eth2", "ledbh", "0", "7");
3048#endif
3049#if defined(RTAC3200)
3050				eval("wl", "-i", "eth3", "ledbh", "10", "7");
3051#endif
3052			}
3053			else
3054			{
3055				eval("wl", "ledbh", "10", "1");
3056				eval("wl", "-i", "eth2", "ledbh", "10", "1");
3057
3058#ifdef RTCONFIG_LEDARRAY
3059				eval("wl", "ledbh", "9", "1");
3060				eval("wl", "ledbh", "0", "1");
3061				eval("wl", "-i", "eth2", "ledbh", "9", "1");
3062				eval("wl", "-i", "eth2", "ledbh", "0", "1");
3063#endif
3064#if defined(RTAC3200)
3065				eval("wl", "-i", "eth3", "ledbh", "10", "1");
3066#endif
3067#ifdef BCM4352
3068				led_control(LED_5G, LED_ON);
3069#endif
3070#ifdef RTCONFIG_TURBO
3071				led_control(LED_TURBO, LED_ON);
3072#endif
3073				eval("wlconf", "eth1", "up");
3074				eval("wl", "maxassoc", "0");
3075				eval("wlconf", "eth2", "up");
3076				eval("wl", "-i", "eth2", "maxassoc", "0");
3077#if defined(RTAC3200)
3078				eval("wlconf", "eth3", "up");
3079				eval("wl", "-i", "eth3", "maxassoc", "0");
3080#endif
3081			}
3082			break;
3083		case MODEL_RTAC53U:
3084			if(post)
3085			{
3086				eval("wl", "-i", "eth1", "ledbh", "3", "7");
3087				eval("wl", "-i", "eth2", "ledbh", "9", "7");
3088			}
3089			else
3090			{
3091				eval("wl", "-i", "eth1", "ledbh", "3", "1");
3092				eval("wl", "-i", "eth2", "ledbh", "9", "1");
3093				eval("wlconf", "eth1", "up");
3094				eval("wl", "maxassoc", "0");
3095				eval("wlconf", "eth2", "up");
3096				eval("wl", "-i", "eth2", "maxassoc", "0");
3097			}
3098			break;
3099		default:
3100			break;
3101	}
3102}
3103#endif
3104
3105int radio_switch(int subunit)
3106{
3107	char tmp[100], tmp2[100], prefix[] = "wlXXXXXXXXXXXXXX";
3108	char *p;
3109	int i;		// unit
3110	int sw = 1;	// record get_radio status
3111	int MAX = 0;	// if MAX = 1: single band, 2: dual band
3112
3113#ifdef RTCONFIG_WIRELESSREPEATER
3114	// repeater mode not support HW radio
3115	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER) {
3116		dbG("[radio switch] repeater mode not support HW radio\n");
3117		return -1;
3118	}
3119#endif
3120
3121	foreach(tmp, nvram_safe_get("wl_ifnames"), p)
3122		MAX++;
3123
3124	for(i = 0; i < MAX; i++) {
3125		sw &= get_radio(i, subunit);
3126	}
3127
3128	sw = !sw;
3129
3130	for(i = 0; i < MAX; i++) {
3131		// set wlx_radio
3132		snprintf(prefix, sizeof(prefix), "wl%d_", i);
3133		nvram_set_int(strcat_r(prefix, "radio", tmp), sw);
3134		//dbG("[radio switch] %s=%d, MAX=%d\n", tmp, sw, MAX); // radio switch
3135		set_radio(sw, i, subunit); 	// set wifi radio
3136
3137		// trigger wifi via WPS/HW toggle, no matter disable or enable wifi, must disable wifi time-scheduler
3138		// prio : HW switch > WPS/HW toggle > time-scheduler
3139		nvram_set_int(strcat_r(prefix, "timesched", tmp2), 0);	// disable wifi time-scheduler
3140		//dbG("[radio switch] %s=%s\n", tmp2, nvram_safe_get(tmp2));
3141	}
3142
3143	// commit to flash once */
3144	nvram_commit();
3145#ifdef RTCONFIG_BCMWL6
3146	if (sw) led_bh_prep(0);	// early turn wl led on
3147#endif
3148	// make sure all interfaces work well
3149	restart_wireless();
3150#ifdef RTCONFIG_BCMWL6
3151	if (sw) led_bh_prep(1); // restore ledbh if needed
3152#endif
3153	return 0;
3154}
3155
3156int delay_main(int argc, char *argv[])
3157{
3158	char buff[100];
3159	int i;
3160	if(argc>1)
3161	{
3162		sleep(atoi(argv[1]));
3163		memset(buff,0,sizeof(buff));
3164		i=2;
3165		while(i<argc)
3166		{
3167			strcat(buff,argv[i]);
3168			strcat(buff," ");
3169			i++;
3170		}
3171		doSystem(buff);
3172	}
3173	else
3174		dbG("delay_exec: args error!\n");
3175
3176	return 0;
3177}
3178
3179int radio_main(int argc, char *argv[])
3180{
3181	int op = RADIO_OFF;
3182	int unit;
3183	int subunit;
3184
3185	if (argc < 2) {
3186HELP:
3187		usage_exit(argv[0], "on|off|toggle|switch|join [N]\n");
3188	}
3189	unit = (argc >= 3) ? atoi(argv[2]) : -1;
3190	subunit = (argc >= 4) ? atoi(argv[3]) : 0;
3191
3192	if (strcmp(argv[1], "toggle") == 0)
3193		op = RADIO_TOGGLE;
3194	else if (strcmp(argv[1], "off") == 0)
3195		op = RADIO_OFF;
3196	else if (strcmp(argv[1], "on") == 0)
3197		op = RADIO_ON;
3198	else if (strcmp(argv[1], "switch") == 0) {
3199		op = RADIO_SWITCH;
3200		goto SWITCH;
3201	}
3202	else if (strcmp(argv[1], "join") == 0)
3203		goto JOIN;
3204	else
3205		goto HELP;
3206
3207	if (unit >= 0)
3208		op = radio_toggle(0, unit, subunit, &op);
3209	else
3210		op = foreach_wif(0, &op, radio_toggle);
3211
3212	if (!op) {
3213		//led(LED_DIAG, 0);
3214		return 0;
3215	}
3216JOIN:
3217	foreach_wif(1, &unit, radio_join);
3218SWITCH:
3219	if(op == RADIO_SWITCH) {
3220		radio_switch(subunit);
3221	}
3222
3223	return 0;
3224}
3225
3226#if 0
3227/*
3228int wdist_main(int argc, char *argv[])
3229{
3230	int n;
3231	rw_reg_t r;
3232	int v;
3233
3234	if (argc != 2) {
3235		r.byteoff = 0x684;
3236		r.size = 2;
3237		if (wl_ioctl(nvram_safe_get("wl_ifname"), 101, &r, sizeof(r)) == 0) {
3238			v = r.val - 510;
3239			if (v <= 9) v = 0;
3240				else v = (v - (9 + 1)) * 150;
3241			printf("Current: %d-%dm (0x%02x)\n\n", v + (v ? 1 : 0), v + 150, r.val);
3242		}
3243		usage_exit(argv[0], "<meters>");
3244	}
3245	if ((n = atoi(argv[1])) <= 0) setup_wldistance();
3246		else set_wldistance(n);
3247	return 0;
3248}
3249*/
3250static int get_wldist(int idx, int unit, int subunit, void *param)
3251{
3252	int n;
3253
3254	char *p = nvram_safe_get(wl_nvname("distance", unit, 0));
3255	if ((*p == 0) || ((n = atoi(p)) < 0)) return 0;
3256
3257	return (9 + (n / 150) + ((n % 150) ? 1 : 0));
3258}
3259
3260static int wldist(int idx, int unit, int subunit, void *param)
3261{
3262	rw_reg_t r;
3263	uint32 s;
3264	char *p;
3265	int n;
3266
3267	n = get_wldist(idx, unit, subunit, param);
3268	if (n > 0) {
3269		s = 0x10 | (n << 16);
3270		p = nvram_safe_get(wl_nvname("ifname", unit, 0));
3271		wl_ioctl(p, 197, &s, sizeof(s));
3272
3273		r.byteoff = 0x684;
3274		r.val = n + 510;
3275		r.size = 2;
3276		wl_ioctl(p, 102, &r, sizeof(r));
3277	}
3278	return 0;
3279}
3280
3281// ref: wificonf.c
3282int wldist_main(int argc, char *argv[])
3283{
3284	if (fork() == 0) {
3285		if (foreach_wif(0, NULL, get_wldist) == 0) return 0;
3286
3287		while (1) {
3288			foreach_wif(0, NULL, wldist);
3289			sleep(2);
3290		}
3291	}
3292
3293	return 0;
3294}
3295#endif
3296int
3297update_lan_resolvconf(void)
3298{
3299	FILE *fp;
3300	char word[256], *next;
3301	int lock, dup_dns = 0;
3302	char *lan_dns, *lan_gateway;
3303
3304	lock = file_lock("resolv");
3305
3306	if (!(fp = fopen("/tmp/resolv.conf", "w+"))) {
3307		perror("/tmp/resolv.conf");
3308		file_unlock(lock);
3309		return errno;
3310	}
3311
3312	lan_dns = nvram_safe_get("lan_dns");
3313	lan_gateway = nvram_safe_get("lan_gateway");
3314#ifdef RTCONFIG_WIRELESSREPEATER
3315	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER && nvram_get_int("wlc_state") != WLC_STATE_CONNECTED)
3316		fprintf(fp, "nameserver %s\n", nvram_default_get("lan_ipaddr"));
3317	else
3318#endif
3319	{
3320		foreach(word, lan_dns, next) {
3321			if (!strcmp(word, lan_gateway))
3322				dup_dns = 1;
3323			fprintf(fp, "nameserver %s\n", word);
3324		}
3325	}
3326
3327	if (*lan_gateway != '\0' && !dup_dns)
3328		fprintf(fp, "nameserver %s\n", lan_gateway);
3329
3330	fclose(fp);
3331
3332	file_unlock(lock);
3333	return 0;
3334}
3335
3336
3337void
3338lan_up(char *lan_ifname)
3339{
3340#ifdef CONFIG_BCMWL5
3341	int32 ip;
3342	char tmp[100], prefix[]="wlXXXXXXX_";
3343#ifdef __CONFIG_DHDAP__
3344	int is_dhd;
3345#endif
3346#endif
3347#ifdef RTCONFIG_WIRELESSREPEATER
3348	char domain_mapping[64];
3349#endif
3350
3351	_dprintf("%s(%s)\n", __FUNCTION__, lan_ifname);
3352
3353#ifdef CONFIG_BCMWL5
3354#if defined(RTCONFIG_WIRELESSREPEATER) || defined(RTCONFIG_PROXYSTA)
3355	if (nvram_match("lan_proto", "dhcp")) {
3356		if (nvram_get_int("sw_mode") == SW_MODE_REPEATER
3357		) {
3358			snprintf(prefix, sizeof(prefix), "wl%d_", nvram_get_int("wlc_band"));
3359			inet_aton(nvram_safe_get("lan_ipaddr"), (struct in_addr *)&ip);
3360#ifdef __CONFIG_DHDAP__
3361			is_dhd = !dhd_probe(nvram_safe_get(strcat_r(prefix, "ifname", tmp)));
3362			if (is_dhd) {
3363				dhd_iovar_setint(nvram_safe_get(strcat_r(prefix, "ifname", tmp)), "wet_host_ipv4", ip);
3364			} else
3365#endif /* __CONFIG_DHDAP__ */
3366			wl_iovar_setint(nvram_safe_get(strcat_r(prefix, "ifname", tmp)), "wet_host_ipv4", ip);
3367		}
3368	}
3369#endif
3370#endif /* CONFIG_BCMWL5 */
3371
3372	start_dnsmasq();
3373
3374	update_lan_resolvconf();
3375
3376	/* Set default route to gateway if specified */
3377	if(nvram_get_int("sw_mode") != SW_MODE_REPEATER
3378#ifdef RTCONFIG_WIRELESSREPEATER
3379			|| (nvram_get_int("sw_mode") == SW_MODE_REPEATER && nvram_get_int("wlc_state") == WLC_STATE_CONNECTED)
3380#endif
3381			) {
3382		route_add(lan_ifname, 0, "0.0.0.0", nvram_safe_get("lan_gateway"), "0.0.0.0");
3383
3384		/* Sync time */
3385		if (!pids("ntp"))
3386		{
3387			stop_ntpc();
3388			start_ntpc();
3389		}
3390		else
3391			kill_pidfile_s("/var/run/ntp.pid", SIGALRM);
3392	}
3393
3394	/* Scan new subnetwork */
3395	stop_networkmap();
3396	start_networkmap(0);
3397	update_lan_state(LAN_STATE_CONNECTED, 0);
3398
3399#ifdef RTCONFIG_WIRELESSREPEATER
3400	// when wlc_mode = 0 & wlc_state = WLC_STATE_CONNECTED, don't notify wanduck yet.
3401	// when wlc_mode = 1 & wlc_state = WLC_STATE_CONNECTED, need to notify wanduck.
3402	// When wlc_mode = 1 & lan_up, need to set wlc_state be WLC_STATE_CONNECTED always.
3403	// wlcconnect often set the wlc_state too late.
3404	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER && nvram_get_int("wlc_mode") == 1) {
3405		repeater_nat_setting();
3406		nvram_set_int("wlc_state", WLC_STATE_CONNECTED);
3407
3408		logmessage("notify wanduck", "wlc_state change!");
3409		_dprintf("%s: notify wanduck: wlc_state=%d.\n", __FUNCTION__, nvram_get_int("wlc_state"));
3410		// notify the change to wanduck.
3411		kill_pidfile_s("/var/run/wanduck.pid", SIGUSR1);
3412	}
3413
3414	if(get_model() == MODEL_APN12HP &&
3415		nvram_get_int("sw_mode") == SW_MODE_AP) {
3416		repeater_nat_setting();
3417		eval("ebtables", "-t", "broute", "-F");
3418		eval("ebtables", "-t", "filter", "-F");
3419		eval("ebtables", "-t", "broute", "-I", "BROUTING", "-d", "00:E0:11:22:33:44", "-j", "redirect", "--redirect-target", "DROP");
3420		sprintf(domain_mapping, "%x %s", inet_addr(nvram_safe_get("lan_ipaddr")), DUT_DOMAIN_NAME);
3421		f_write_string("/proc/net/dnsmqctrl", domain_mapping, 0, 0);
3422		start_nat_rules();
3423	}
3424#endif
3425
3426#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA)
3427	if ((is_psta(nvram_get_int("wlc_band")) || is_psr(nvram_get_int("wlc_band")))
3428#if defined(RTCONFIG_BCM7) || defined(RTCONFIG_BCM_7114)
3429#ifdef RTCONFIG_GMAC3
3430		&& !nvram_match("gmac3_enable", "1")
3431#endif
3432		&& nvram_match("ctf_disable", "1")
3433#endif
3434	) setup_dnsmq(1);
3435#endif
3436
3437#ifdef RTCONFIG_USB
3438#ifdef RTCONFIG_MEDIA_SERVER
3439	if(get_invoke_later()&INVOKELATER_DMS)
3440		notify_rc("restart_dms");
3441#endif
3442#endif
3443}
3444
3445void
3446lan_down(char *lan_ifname)
3447{
3448	_dprintf("%s(%s)\n", __FUNCTION__, lan_ifname);
3449
3450	/* Remove default route to gateway if specified */
3451	route_del(lan_ifname, 0, "0.0.0.0",
3452			nvram_safe_get("lan_gateway"),
3453			"0.0.0.0");
3454
3455	/* Clear resolv.conf */
3456	f_write("/tmp/resolv.conf", NULL, 0, 0, 0);
3457
3458	update_lan_state(LAN_STATE_STOPPED, 0);
3459}
3460
3461void stop_lan_wl(void)
3462{
3463	char *p, *ifname;
3464	char *wl_ifnames;
3465	char *lan_ifname;
3466#ifdef CONFIG_BCMWL5
3467	int unit, subunit;
3468#endif
3469
3470	if (module_loaded("ebtables")) {
3471		eval("ebtables", "-F");
3472		eval("ebtables", "-t", "broute", "-F");
3473	}
3474
3475	lan_ifname = nvram_safe_get("lan_ifname");
3476	if ((wl_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL) {
3477		p = wl_ifnames;
3478		while ((ifname = strsep(&p, " ")) != NULL) {
3479			while (*ifname == ' ') ++ifname;
3480			if (*ifname == 0) break;
3481			disable_wifi_bled(ifname);
3482#ifdef CONFIG_BCMWL5
3483#ifdef RTCONFIG_QTN
3484			if (!strcmp(ifname, "wifi0")) continue;
3485#endif
3486			if (strncmp(ifname, "wl", 2) == 0 && strchr(ifname, '.')) {
3487				if (get_ifname_unit(ifname, &unit, &subunit) < 0)
3488					continue;
3489			}
3490			else if (wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit)))
3491			{
3492#ifdef RTCONFIG_EMF
3493				if (nvram_match("emf_enable", "1"))
3494					eval("emf", "del", "iface", lan_ifname, ifname);
3495#endif
3496				continue;
3497			}
3498
3499			eval("wlconf", ifname, "down");
3500			eval("wl", "-i", ifname, "radio", "off");
3501#elif defined RTCONFIG_RALINK
3502			if (!strncmp(ifname, "ra", 2))
3503				stop_wds_ra(lan_ifname, ifname);
3504#elif defined(RTCONFIG_QCA)
3505				/* do nothing */
3506#endif
3507			ifconfig(ifname, 0, NULL, NULL);
3508#ifdef RTCONFIG_GMAC3
3509			if (nvram_match("gmac3_enable", "1") && find_in_list(nvram_get("fwd_wlandevs"), ifname))
3510				goto gmac3_no_swbr;
3511#endif
3512			eval("brctl", "delif", lan_ifname, ifname);
3513#ifdef RTCONFIG_GMAC3
3514gmac3_no_swbr:
3515#endif
3516#ifdef RTCONFIG_EMF
3517			if (nvram_match("emf_enable", "1"))
3518				eval("emf", "del", "iface", lan_ifname, ifname);
3519#endif
3520
3521#if defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)
3522			{ // remove interface for iNIC packets
3523				char *nic_if, *nic_ifs, *nic_lan_ifnames;
3524				if((nic_lan_ifnames = strdup(nvram_safe_get("nic_lan_ifnames"))))
3525				{
3526					nic_ifs = nic_lan_ifnames;
3527					while ((nic_if = strsep(&nic_ifs, " ")) != NULL) {
3528						while (*nic_if == ' ')
3529							nic_if++;
3530						if (*nic_if == 0)
3531							break;
3532						if(strcmp(ifname, nic_if) == 0)
3533						{
3534							eval("vconfig", "rem", ifname);
3535							break;
3536						}
3537					}
3538					free(nic_lan_ifnames);
3539				}
3540			}
3541#endif
3542		}
3543
3544		free(wl_ifnames);
3545	}
3546#ifdef RTCONFIG_EMF
3547	stop_emf(lan_ifname);
3548#endif
3549	stop_snooper();
3550
3551#ifdef RTCONFIG_PORT_BASED_VLAN
3552	stop_vlan_wl_ifnames();
3553#endif
3554
3555#ifdef RTCONFIG_BCMWL6
3556#if defined(RTAC66U) || defined(BCM4352)
3557	nvram_set("led_5g", "0");
3558	led_control(LED_5G, LED_OFF);
3559#ifdef RTCONFIG_TURBO
3560	led_control(LED_TURBO, LED_OFF);
3561#endif
3562#endif
3563#endif
3564
3565	// inform watchdog to stop WPS LED
3566	kill_pidfile_s("/var/run/watchdog.pid", SIGUSR2);
3567
3568	fini_wl();
3569}
3570
3571#if defined(RTCONFIG_RALINK) || defined(RTCONFIG_QCA)
3572pid_t pid_from_file(char *pidfile)
3573{
3574	FILE *fp;
3575	char buf[256];
3576	pid_t pid = 0;
3577
3578	if ((fp = fopen(pidfile, "r")) != NULL) {
3579		if (fgets(buf, sizeof(buf), fp))
3580			pid = strtoul(buf, NULL, 0);
3581
3582		fclose(fp);
3583	}
3584
3585	return pid;
3586}
3587#endif
3588
3589void start_lan_wl(void)
3590{
3591	char *lan_ifname;
3592	char *wl_ifnames, *ifname, *p;
3593	uint32 ip;
3594	char tmp[100], prefix[] = "wlXXXXXXXXXXXXXX";
3595	char word[256], *next;
3596	int match;
3597	int i;
3598#ifdef CONFIG_BCMWL5
3599	struct ifreq ifr;
3600	int unit, subunit, sta = 0;
3601#endif
3602#ifdef __CONFIG_DHDAP__
3603	int is_dhd;
3604#endif /* __CONFIG_DHDAP__ */
3605
3606#if defined(RTCONFIG_RALINK) || defined(RTCONFIG_QCA)
3607	init_wl();
3608#endif
3609
3610#ifdef CONFIG_BCMWL5
3611	init_wl_compact();
3612	wlconf_pre();
3613
3614	if (0)
3615	{
3616		foreach_wif(1, NULL, set_wlmac);
3617		check_afterburner();
3618	}
3619#endif
3620
3621	if (no_need_to_start_wps() ||
3622	    wps_band_radio_off(get_radio_band(nvram_get_int("wps_band"))) ||
3623	    wps_band_ssid_broadcast_off(get_radio_band(nvram_get_int("wps_band"))))
3624		nvram_set("wps_enable", "0");
3625	/* recover wps enable option back to original state */
3626	else if(!nvram_match("wps_enable", nvram_safe_get("wps_enable_old"))){
3627		nvram_set("wps_enable", nvram_safe_get("wps_enable_old"));
3628	}
3629
3630	lan_ifname = strdup(nvram_safe_get("lan_ifname"));
3631#ifdef RTCONFIG_EMF
3632	if (nvram_match("emf_enable", "1")) {
3633		eval("emf", "add", "bridge", lan_ifname);
3634		eval("igs", "add", "bridge", lan_ifname);
3635	}
3636#endif
3637	if (strncmp(lan_ifname, "br", 2) == 0) {
3638		inet_aton(nvram_safe_get("lan_ipaddr"), (struct in_addr *)&ip);
3639
3640		if ((wl_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL) {
3641			p = wl_ifnames;
3642			while ((ifname = strsep(&p, " ")) != NULL) {
3643				while (*ifname == ' ') ++ifname;
3644				if (*ifname == 0) break;
3645#ifdef CONFIG_BCMWL5
3646				if (strncmp(ifname, "wl", 2) == 0) {
3647					if (!wl_vif_enabled(ifname, tmp)) {
3648						continue; /* Ignore disabled WL VIF */
3649					}
3650					wl_vif_hwaddr_set(ifname);
3651				}
3652				unit = -1; subunit = -1;
3653#endif
3654
3655				// ignore disabled wl vifs
3656
3657				if (guest_wlif(ifname)) {
3658					char nv[40];
3659					char nv2[40];
3660					char nv3[40];
3661					snprintf(nv, sizeof(nv) - 1, "%s_bss_enabled", wif_to_vif(ifname));
3662					if (!nvram_get_int(nv))
3663					{
3664						continue;
3665					}
3666					else
3667					{
3668						if (!nvram_get(strcat_r(prefix, "lanaccess", tmp)))
3669							nvram_set(strcat_r(prefix, "lanaccess", tmp), "off");
3670
3671						if ((nvram_get_int("wl_unit") >= 0) && (nvram_get_int("wl_subunit") > 0))
3672						{
3673							snprintf(nv, sizeof(nv) - 1, "%s_expire", wif_to_vif(ifname));
3674							snprintf(nv2, sizeof(nv2) - 1, "%s_expire_tmp", wif_to_vif(ifname));
3675							snprintf(nv3, sizeof(nv3) - 1, "wl%d.%d", nvram_get_int("wl_unit"), nvram_get_int("wl_subunit"));
3676							if (!strcmp(nv3, wif_to_vif(ifname)))
3677							{
3678								nvram_set(nv2, nvram_safe_get(nv));
3679								nvram_set("wl_unit", "-1");
3680								nvram_set("wl_subunit", "-1");
3681							}
3682						}
3683					}
3684#ifdef CONFIG_BCMWL5
3685					if (get_ifname_unit(ifname, &unit, &subunit) < 0)
3686						continue;
3687#endif
3688				}
3689#ifdef CONFIG_BCMWL5
3690				else
3691					wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit));
3692#endif
3693
3694#ifdef RTCONFIG_QCA
3695				qca_wif_up(ifname);
3696#endif
3697#ifdef RTCONFIG_RALINK
3698				gen_ra_config(ifname);
3699#endif
3700#if defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)
3701				{ // add interface for iNIC packets
3702					char *nic_if, *nic_ifs, *nic_lan_ifnames;
3703					if((nic_lan_ifnames = strdup(nvram_safe_get("nic_lan_ifnames"))))
3704					{
3705						nic_ifs = nic_lan_ifnames;
3706						while ((nic_if = strsep(&nic_ifs, " ")) != NULL) {
3707							while (*nic_if == ' ')
3708								nic_if++;
3709							if (*nic_if == 0)
3710								break;
3711							if(strcmp(ifname, nic_if) == 0)
3712							{
3713								int vlan_id;
3714								if((vlan_id = atoi(ifname + 4)) > 0)
3715								{
3716									char id[8];
3717									sprintf(id, "%d", vlan_id);
3718									eval("vconfig", "add", "eth2", id);
3719								}
3720								break;
3721							}
3722						}
3723						free(nic_lan_ifnames);
3724					}
3725				}
3726#endif
3727#if defined(RTCONFIG_QCA)
3728				if (!ifup_vap &&
3729				    (!strncmp(ifname, WIF_2G, strlen(WIF_2G)) ||
3730				     !strncmp(ifname, WIF_5G, strlen(WIF_5G))))
3731				{
3732					/* Don't up VAP interface here. */
3733				} else {
3734#endif
3735					// bring up interface
3736					if (ifconfig(ifname, IFUP | IFF_ALLMULTI, NULL, NULL) != 0) {
3737#ifdef RTCONFIG_QTN
3738						if (strcmp(ifname, "wifi0"))
3739#endif
3740							continue;
3741					}
3742#if defined(RTCONFIG_QCA)
3743				}
3744#endif
3745
3746#ifdef RTCONFIG_RALINK
3747				wlconf_ra(ifname);
3748#elif defined(RTCONFIG_QCA)
3749				/* do nothing */
3750#elif defined CONFIG_BCMWL5
3751				if (wlconf(ifname, unit, subunit) == 0) {
3752					const char *mode = nvram_safe_get(wl_nvname("mode", unit, subunit));
3753
3754					if (strcmp(mode, "wet") == 0) {
3755						// Enable host DHCP relay
3756						if (nvram_match("lan_proto", "static")) {
3757#ifdef __CONFIG_DHDAP__
3758							is_dhd = !dhd_probe(ifname);
3759							if(is_dhd) {
3760								char macbuf[sizeof("wet_host_mac") + 1 + ETHER_ADDR_LEN];
3761								dhd_iovar_setbuf(ifname, "wet_host_mac", ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN , macbuf, sizeof(macbuf));
3762							}
3763							else
3764#endif /* __CONFIG_DHDAP__ */
3765							wl_iovar_set(ifname, "wet_host_mac", ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
3766						}
3767					}
3768
3769					sta |= (strcmp(mode, "sta") == 0);
3770					if ((strcmp(mode, "ap") != 0) && (strcmp(mode, "wet") != 0)
3771						&& (strcmp(mode, "psta") != 0) && (strcmp(mode, "psr") != 0))
3772						continue;
3773				} else {
3774#ifdef RTCONFIG_EMF
3775					if (nvram_match("emf_enable", "1"))
3776						eval("emf", "add", "iface", lan_ifname, ifname);
3777#endif
3778					continue;
3779				}
3780#endif
3781				/* Don't attach the main wl i/f in wds mode */
3782				match = 0, i = 0;
3783				foreach (word, nvram_safe_get("wl_ifnames"), next) {
3784					if (!strcmp(ifname, word))
3785					{
3786						snprintf(prefix, sizeof(prefix), "wl%d_", i);
3787						if (nvram_match(strcat_r(prefix, "mode_x", tmp), "1"))
3788#ifdef RTCONFIG_QCA
3789							match = 0;
3790#else
3791							match = 1;
3792#endif
3793
3794#ifdef RTCONFIG_PROXYSTA
3795#ifdef RTCONFIG_RALINK
3796						if (mediabridge_mode()) {
3797							ifconfig(ifname, 0, NULL, NULL);
3798							match = 1;
3799						}
3800#endif
3801#endif
3802
3803						break;
3804					}
3805
3806					i++;
3807				}
3808#ifdef RTCONFIG_GMAC3
3809				/* In 3GMAC mode, skip wl interfaces that avail of hw switching.
3810				 *
3811				 * Do not add these wl interfaces to the LAN bridge as they avail of
3812				 * HW switching. Misses in the HW switch's ARL will be forwarded via vlan1
3813				 * to br0 (i.e. via the network GMAC#2).
3814				 */
3815				if (nvram_match("gmac3_enable", "1") &&
3816					find_in_list(nvram_get("fwd_wlandevs"), ifname))
3817						goto gmac3_no_swbr;
3818#endif
3819#if defined(RTCONFIG_PORT_BASED_VLAN)
3820				if (vlan_enable() && check_if_exist_vlan_ifnames(ifname))
3821					match = 1;
3822#endif
3823				if (!match)
3824				{
3825					eval("brctl", "addif", lan_ifname, ifname);
3826#ifdef RTCONFIG_GMAC3
3827gmac3_no_swbr:
3828#endif
3829#ifdef RTCONFIG_EMF
3830					if (nvram_match("emf_enable", "1"))
3831						eval("emf", "add", "iface", lan_ifname, ifname);
3832#endif
3833				}
3834				enable_wifi_bled(ifname);
3835			}
3836			free(wl_ifnames);
3837		}
3838	}
3839
3840#ifdef RTCONFIG_EMF
3841	start_emf(lan_ifname);
3842#endif
3843	start_snooper(lan_ifname);
3844
3845#ifdef RTCONFIG_PORT_BASED_VLAN
3846	start_vlan_wl_ifnames();
3847#endif
3848
3849#ifdef RTCONFIG_BCMWL6
3850	set_acs_ifnames();
3851#endif
3852
3853	free(lan_ifname);
3854
3855	nvram_set("reload_svc_radio", "1");
3856}
3857
3858void restart_wl(void)
3859{
3860#ifdef CONFIG_BCMWL5
3861	char *wl_ifnames, *ifname, *p;
3862	int unit, subunit;
3863	int is_client = 0;
3864	char tmp[100], tmp2[100], prefix[] = "wlXXXXXXXXXXXXXX";
3865
3866	if ((wl_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL) {
3867		p = wl_ifnames;
3868		while ((ifname = strsep(&p, " ")) != NULL) {
3869			while (*ifname == ' ') ++ifname;
3870			if (*ifname == 0) break;
3871
3872			unit = -1; subunit = -1;
3873
3874			// ignore disabled wl vifs
3875			if (strncmp(ifname, "wl", 2) == 0 && strchr(ifname, '.')) {
3876				char nv[40];
3877				snprintf(nv, sizeof(nv) - 1, "%s_bss_enabled", wif_to_vif(ifname));
3878				if (!nvram_get_int(nv))
3879					continue;
3880				if (get_ifname_unit(ifname, &unit, &subunit) < 0)
3881					continue;
3882			}
3883			// get the instance number of the wl i/f
3884			else if (wl_ioctl(ifname, WLC_GET_INSTANCE, &unit, sizeof(unit)))
3885				continue;
3886
3887			is_client |= wl_client(unit, subunit) && nvram_get_int(wl_nvname("radio", unit, 0));
3888
3889#ifdef CONFIG_BCMWL5
3890			snprintf(prefix, sizeof(prefix), "wl%d_", unit);
3891			if (nvram_match(strcat_r(prefix, "radio", tmp), "0"))
3892			{
3893				nvram_set_int(strcat_r(prefix, "timesched", tmp2), 0);	// disable wifi time-scheduler
3894#ifdef RTCONFIG_QTN
3895				if (strcmp(ifname, "wifi0"))
3896#endif
3897				{
3898					eval("wlconf", ifname, "down");
3899					eval("wl", "-i", ifname, "radio", "off");
3900				}
3901			}
3902			else
3903#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA)
3904			if (!psta_exist_except(unit)/* || !psr_exist_except(unit)*/)
3905#endif
3906			{
3907#ifdef RTCONFIG_QTN
3908				if (strcmp(ifname, "wifi0"))
3909#endif
3910				eval("wlconf", ifname, "start"); /* start wl iface */
3911			}
3912			wlconf_post(ifname);
3913#endif	// CONFIG_BCMWL5
3914		}
3915		free(wl_ifnames);
3916	}
3917
3918#if 0
3919	killall("wldist", SIGTERM);
3920	eval("wldist");
3921#endif
3922
3923	if (is_client)
3924		xstart("radio", "join");
3925
3926#ifdef RTCONFIG_PORT_BASED_VLAN
3927	restart_vlan_wl();
3928#endif
3929
3930#ifdef RTCONFIG_BCMWL6
3931#if defined(RTAC66U) || defined(BCM4352)
3932	if (nvram_match("wl1_radio", "1"))
3933	{
3934#ifndef RTCONFIG_LED_BTN
3935		if (!(nvram_get_int("sw_mode")==SW_MODE_AP && nvram_get_int("wlc_psta") && nvram_get_int("wlc_band")==0)) {
3936			nvram_set("led_5g", "1");
3937			led_control(LED_5G, LED_ON);
3938		}
3939#else
3940		nvram_set("led_5g", "1");
3941		if (nvram_get_int("AllLED"))
3942			led_control(LED_5G, LED_ON);
3943#endif
3944	}
3945	else
3946	{
3947		nvram_set("led_5g", "0");
3948		led_control(LED_5G, LED_OFF);
3949	}
3950#ifdef RTCONFIG_TURBO
3951	if ((nvram_match("wl0_radio", "1") || nvram_match("wl1_radio", "1")
3952#if defined(RTAC3200) || defined(RTAC5300) || defined(RTAC5300R)
3953		|| nvram_match("wl2_radio", "1")
3954#endif
3955	)
3956#ifdef RTCONFIG_LED_BTN
3957		&& nvram_get_int("AllLED")
3958#endif
3959	)
3960		led_control(LED_TURBO, LED_ON);
3961	else
3962		led_control(LED_TURBO, LED_OFF);
3963#endif
3964#endif
3965#endif
3966#endif /* CONFIG_BCMWL5 */
3967
3968
3969#if defined(RTCONFIG_USER_LOW_RSSI) && !defined(RTCONFIG_BCMARM)
3970	init_wllc();
3971#endif
3972
3973
3974}
3975
3976void lanaccess_mssid_ban(const char *limited_ifname)
3977{
3978	char lan_subnet[32];
3979#ifdef RTAC87U
3980	char limited_ifname_real[32] = {0};
3981#endif
3982
3983	if (limited_ifname == NULL) return;
3984
3985	if (nvram_get_int("sw_mode") != SW_MODE_ROUTER) return;
3986
3987#ifdef RTAC87U
3988	/* #565: Access Intranet off */
3989	/* workaround: use vlan4000, 4001, 4002 as QTN guest network VID */
3990
3991	if(strcmp(limited_ifname, "wl1.1") == 0)
3992		snprintf(limited_ifname_real, sizeof(limited_ifname_real), "vlan4000");
3993	else if(strcmp(limited_ifname, "wl1.2") == 0)
3994		snprintf(limited_ifname_real, sizeof(limited_ifname_real), "vlan4001");
3995	else if(strcmp(limited_ifname, "wl1.3") == 0)
3996		snprintf(limited_ifname_real, sizeof(limited_ifname_real), "vlan4002");
3997	else
3998		snprintf(limited_ifname_real, "%s", limited_ifname);
3999
4000	eval("ebtables", "-A", "FORWARD", "-i", (char*)limited_ifname_real, "-j", "DROP"); //ebtables FORWARD: "for frames being forwarded by the bridge"
4001	eval("ebtables", "-A", "FORWARD", "-o", (char*)limited_ifname_real, "-j", "DROP"); // so that traffic via host and nat is passed
4002
4003	snprintf(lan_subnet, sizeof(lan_subnet), "%s/%s", nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
4004	eval("ebtables", "-t", "broute", "-A", "BROUTING", "-i", (char*)limited_ifname_real, "-p", "ipv4", "--ip-dst", lan_subnet, "--ip-proto", "tcp", "-j", "DROP");
4005#else
4006	eval("ebtables", "-A", "FORWARD", "-i", (char*)limited_ifname, "-j", "DROP"); //ebtables FORWARD: "for frames being forwarded by the bridge"
4007	eval("ebtables", "-A", "FORWARD", "-o", (char*)limited_ifname, "-j", "DROP"); // so that traffic via host and nat is passed
4008
4009	snprintf(lan_subnet, sizeof(lan_subnet), "%s/%s", nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
4010	eval("ebtables", "-t", "broute", "-A", "BROUTING", "-i", (char*)limited_ifname, "-p", "ipv4", "--ip-dst", lan_subnet, "--ip-proto", "tcp", "-j", "DROP");
4011#endif
4012}
4013
4014void lanaccess_wl(void)
4015{
4016	char *p, *ifname;
4017	char *wl_ifnames;
4018#ifdef CONFIG_BCMWL5
4019	int unit, subunit;
4020#endif
4021
4022	if ((wl_ifnames = strdup(nvram_safe_get("lan_ifnames"))) != NULL) {
4023		p = wl_ifnames;
4024		while ((ifname = strsep(&p, " ")) != NULL) {
4025			while (*ifname == ' ') ++ifname;
4026			if (*ifname == 0) break;
4027#ifdef CONFIG_BCMWL5
4028			if (guest_wlif(ifname)) {
4029				if (get_ifname_unit(ifname, &unit, &subunit) < 0)
4030					continue;
4031			}
4032			else continue;
4033
4034#ifdef RTCONFIG_WIRELESSREPEATER
4035			if(nvram_get_int("sw_mode")==SW_MODE_REPEATER && unit==nvram_get_int("wlc_band") && subunit==1) continue;
4036#endif
4037#elif defined RTCONFIG_RALINK
4038			if (guest_wlif(ifname))
4039				;
4040			else
4041				continue;
4042#elif defined(RTCONFIG_QCA)
4043			if (guest_wlif(ifname))
4044				;
4045			else
4046				continue;
4047#endif
4048#if defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)
4049			if (strncmp(ifname, "rai", 3) == 0)
4050				continue;
4051#endif
4052
4053#if defined(CONFIG_BCMWL5) && defined(RTCONFIG_PORT_BASED_VLAN)
4054			if (vlan_enable() && check_if_exist_vlan_ifnames(ifname))
4055				continue;
4056#endif
4057
4058			char nv[40];
4059			snprintf(nv, sizeof(nv) - 1, "%s_lanaccess", wif_to_vif(ifname));
4060			if (!strcmp(nvram_safe_get(nv), "off"))
4061				lanaccess_mssid_ban(ifname);
4062		}
4063		free(wl_ifnames);
4064	}
4065#if defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)
4066	if ((wl_ifnames = strdup(nvram_safe_get("nic_lan_ifnames"))) != NULL) {
4067		p = wl_ifnames;
4068		while ((ifname = strsep(&p, " ")) != NULL) {
4069			while (*ifname == ' ') ++ifname;
4070			if (*ifname == 0) break;
4071
4072			lanaccess_mssid_ban(ifname);
4073		}
4074		free(wl_ifnames);
4075	}
4076#endif
4077
4078#ifdef RTCONFIG_PORT_BASED_VLAN
4079	vlan_lanaccess_wl();
4080#endif
4081}
4082
4083void restart_wireless(void)
4084{
4085#ifdef RTCONFIG_WIRELESSREPEATER
4086	char domain_mapping[64];
4087#endif
4088	int lock = file_lock("wireless");
4089
4090	nvram_set_int("wlready", 0);
4091
4092#ifdef RTCONFIG_BCMWL6
4093#ifdef RTCONFIG_PROXYSTA
4094	stop_psta_monitor();
4095#endif
4096	stop_acsd();
4097#ifdef BCM_BSD
4098	stop_bsd();
4099#endif
4100#ifdef BCM_SSD
4101	stop_ssd();
4102#endif
4103	stop_igmp_proxy();
4104#ifdef RTCONFIG_HSPOT
4105	stop_hspotap();
4106#endif
4107#endif
4108	stop_wps();
4109#ifdef CONFIG_BCMWL5
4110	stop_nas();
4111	stop_eapd();
4112#elif defined RTCONFIG_RALINK
4113	stop_8021x();
4114#endif
4115
4116#if ((defined(RTCONFIG_USER_LOW_RSSI) && defined(RTCONFIG_BCMARM)) || defined(RTCONFIG_NEW_USER_LOW_RSSI))
4117	stop_roamast();
4118#endif
4119	stop_lan_wl();
4120
4121	init_nvram();	// init nvram lan_ifnames
4122	wl_defaults();	// init nvram wlx_ifnames & lan_ifnames
4123#ifndef CONFIG_BCMWL5
4124	sleep(2);	// delay to avoid start interface on stoping.
4125#endif
4126
4127#ifdef RTCONFIG_PORT_BASED_VLAN
4128	set_port_based_vlan_config(NULL);
4129#endif
4130	start_lan_wl();
4131
4132	reinit_hwnat(-1);
4133
4134#ifdef CONFIG_BCMWL5
4135	start_eapd();
4136	start_nas();
4137#elif defined RTCONFIG_RALINK
4138	start_8021x();
4139#endif
4140	start_wps();
4141#ifdef RTCONFIG_BCMWL6
4142#ifdef RTCONFIG_HSPOT
4143	start_hspotap();
4144#endif
4145	start_igmp_proxy();
4146#ifdef BCM_BSD
4147	start_bsd();
4148#endif
4149#ifdef BCM_SSD
4150	start_ssd();
4151#endif
4152	start_acsd();
4153#ifdef RTCONFIG_PROXYSTA
4154	start_psta_monitor();
4155#endif
4156#endif
4157#ifndef RTCONFIG_BCMWL6
4158#ifdef RTCONFIG_WL_AUTO_CHANNEL
4159	if(nvram_match("AUTO_CHANNEL", "1")) {
4160		nvram_set("wl_channel", "6");
4161		nvram_set("wl0_channel", "6");
4162	}
4163#endif
4164#endif
4165	restart_wl();
4166	lanaccess_wl();
4167
4168#ifdef CONFIG_BCMWL5
4169	/* for MultiSSID */
4170	if(nvram_get_int("qos_enable") == 1) {
4171		del_EbtablesRules(); // flush ebtables nat table
4172		add_EbtablesRules();
4173	}
4174#endif
4175
4176#ifdef RTCONFIG_WIRELESSREPEATER
4177	// when wlc_mode = 0 & wlc_state = WLC_STATE_CONNECTED, don't notify wanduck yet.
4178	// when wlc_mode = 1 & wlc_state = WLC_STATE_CONNECTED, need to notify wanduck.
4179	// When wlc_mode = 1 & lan_up, need to set wlc_state be WLC_STATE_CONNECTED always.
4180	// wlcconnect often set the wlc_state too late.
4181	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER && nvram_get_int("wlc_mode") == 1) {
4182		repeater_nat_setting();
4183		nvram_set_int("wlc_state", WLC_STATE_CONNECTED);
4184
4185		logmessage("notify wanduck", "wlc_state change!");
4186		_dprintf("%s: notify wanduck: wlc_state=%d.\n", __FUNCTION__, nvram_get_int("wlc_state"));
4187		// notify the change to wanduck.
4188		kill_pidfile_s("/var/run/wanduck.pid", SIGUSR1);
4189	}
4190
4191	if(get_model() == MODEL_APN12HP &&
4192		nvram_get_int("sw_mode") == SW_MODE_AP) {
4193		repeater_nat_setting();
4194		eval("ebtables", "-t", "broute", "-F");
4195		eval("ebtables", "-t", "filter", "-F");
4196		eval("ebtables", "-t", "broute", "-I", "BROUTING", "-d", "00:E0:11:22:33:44", "-j", "redirect", "--redirect-target", "DROP");
4197		sprintf(domain_mapping, "%x %s", inet_addr(nvram_safe_get("lan_ipaddr")), DUT_DOMAIN_NAME);
4198		f_write_string("/proc/net/dnsmqctrl", domain_mapping, 0, 0);
4199		start_nat_rules();
4200	}
4201#endif
4202
4203#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA)
4204	if ((is_psta(nvram_get_int("wlc_band")) || is_psr(nvram_get_int("wlc_band")))
4205#if defined(RTCONFIG_BCM7) || defined(RTCONFIG_BCM_7114)
4206#ifdef RTCONFIG_GMAC3
4207		&& !nvram_match("gmac3_enable", "1")
4208#endif
4209		&& nvram_match("ctf_disable", "1")
4210#endif
4211	) setup_dnsmq(1);
4212#endif
4213
4214#ifdef RTCONFIG_QCA
4215	gen_qca_wifi_cfgs();
4216#endif
4217	nvram_set_int("wlready", 1);
4218
4219#ifdef RTAC87U
4220	if(nvram_get_int("AllLED") == 0) setAllLedOff();
4221#endif
4222
4223#if ((defined(RTCONFIG_USER_LOW_RSSI) && defined(RTCONFIG_BCMARM)) || defined(RTCONFIG_NEW_USER_LOW_RSSI))
4224	start_roamast();
4225#endif
4226
4227	file_unlock(lock);
4228}
4229
4230/* for WPS Reset */
4231void restart_wireless_wps(void)
4232{
4233	int lock = file_lock("wireless");
4234#ifdef RTCONFIG_WIRELESSREPEATER
4235	char domain_mapping[64];
4236#endif
4237
4238	nvram_set_int("wlready", 0);
4239
4240#ifdef RTCONFIG_BCMWL6
4241#ifdef RTCONFIG_PROXYSTA
4242	stop_psta_monitor();
4243#endif
4244	stop_acsd();
4245#ifdef BCM_BSD
4246	stop_bsd();
4247#endif
4248#ifdef BCM_SSD
4249	stop_ssd();
4250#endif
4251	stop_igmp_proxy();
4252#ifdef RTCONFIG_HSPOT
4253	stop_hspotap();
4254#endif
4255#endif
4256	stop_wps();
4257#ifdef CONFIG_BCMWL5
4258	stop_nas();
4259	stop_eapd();
4260#elif defined RTCONFIG_RALINK
4261	stop_8021x();
4262#endif
4263	stop_lan_wl();
4264	wl_defaults_wps();
4265#ifndef CONFIG_BCMWL5
4266	sleep(2);	// delay to avoid start interface on stoping.
4267#endif
4268
4269	start_lan_wl();
4270
4271	reinit_hwnat(-1);
4272
4273#ifdef CONFIG_BCMWL5
4274	start_eapd();
4275	start_nas();
4276#elif defined RTCONFIG_RALINK
4277	start_8021x();
4278#endif
4279	start_wps();
4280#ifdef RTCONFIG_BCMWL6
4281#ifdef RTCONFIG_HSPOT
4282	start_hspotap();
4283#endif
4284	start_igmp_proxy();
4285#ifdef BCM_BSD
4286	start_bsd();
4287#endif
4288#ifdef BCM_SSD
4289	start_ssd();
4290#endif
4291	start_acsd();
4292#ifdef RTCONFIG_PROXYSTA
4293	start_psta_monitor();
4294#endif
4295#endif
4296#ifndef RTCONFIG_BCMWL6
4297#ifdef RTCONFIG_WL_AUTO_CHANNEL
4298	if(nvram_match("AUTO_CHANNEL", "1")) {
4299		nvram_set("wl_channel", "6");
4300		nvram_set("wl0_channel", "6");
4301	}
4302#endif
4303#endif
4304	restart_wl();
4305	lanaccess_wl();
4306
4307#ifdef CONFIG_BCMWL5
4308	/* for MultiSSID */
4309	if(nvram_get_int("qos_enable") == 1) {
4310		del_EbtablesRules(); // flush ebtables nat table
4311		add_EbtablesRules();
4312	}
4313#endif
4314
4315#ifdef RTCONFIG_WIRELESSREPEATER
4316	// when wlc_mode = 0 & wlc_state = WLC_STATE_CONNECTED, don't notify wanduck yet.
4317	// when wlc_mode = 1 & wlc_state = WLC_STATE_CONNECTED, need to notify wanduck.
4318	// When wlc_mode = 1 & lan_up, need to set wlc_state be WLC_STATE_CONNECTED always.
4319	// wlcconnect often set the wlc_state too late.
4320	if(nvram_get_int("sw_mode") == SW_MODE_REPEATER && nvram_get_int("wlc_mode") == 1) {
4321		repeater_nat_setting();
4322		nvram_set_int("wlc_state", WLC_STATE_CONNECTED);
4323
4324		logmessage("notify wanduck", "wlc_state change!");
4325		_dprintf("%s: notify wanduck: wlc_state=%d.\n", __FUNCTION__, nvram_get_int("wlc_state"));
4326		// notify the change to wanduck.
4327		kill_pidfile_s("/var/run/wanduck.pid", SIGUSR1);
4328	}
4329
4330	if(get_model() == MODEL_APN12HP &&
4331		nvram_get_int("sw_mode") == SW_MODE_AP) {
4332		repeater_nat_setting();
4333		eval("ebtables", "-t", "broute", "-F");
4334		eval("ebtables", "-t", "filter", "-F");
4335		eval("ebtables", "-t", "broute", "-I", "BROUTING", "-d", "00:E0:11:22:33:44", "-j", "redirect", "--redirect-target", "DROP");
4336		sprintf(domain_mapping, "%x %s", inet_addr(nvram_safe_get("lan_ipaddr")), DUT_DOMAIN_NAME);
4337		f_write_string("/proc/net/dnsmqctrl", domain_mapping, 0, 0);
4338		start_nat_rules();
4339	}
4340#endif
4341
4342#if defined(RTCONFIG_BCMWL6) && defined(RTCONFIG_PROXYSTA)
4343	if ((is_psta(nvram_get_int("wlc_band")) || is_psr(nvram_get_int("wlc_band")))
4344#if defined(RTCONFIG_BCM7) || defined(RTCONFIG_BCM_7114)
4345#ifdef RTCONFIG_GMAC3
4346		&& !nvram_match("gmac3_enable", "1")
4347#endif
4348		&& nvram_match("ctf_disable", "1")
4349#endif
4350	) setup_dnsmq(1);
4351#endif
4352
4353	nvram_set_int("wlready", 1);
4354
4355	file_unlock(lock);
4356}
4357
4358#ifdef RTCONFIG_BCM_7114
4359void stop_wl_bcm(void)
4360{
4361#ifdef RTCONFIG_WIRELESSREPEATER
4362	if (nvram_get_int("sw_mode") == SW_MODE_REPEATER)
4363		stop_wlcconnect();
4364#endif
4365
4366#ifdef RTCONFIG_BCMWL6
4367#ifdef RTCONFIG_PROXYSTA
4368	stop_psta_monitor();
4369#endif
4370	stop_acsd();
4371#ifdef BCM_BSD
4372	stop_bsd();
4373#endif
4374#ifdef BCM_SSD
4375	stop_ssd();
4376#endif
4377	stop_igmp_proxy();
4378#ifdef RTCONFIG_HSPOT
4379	stop_hspotap();
4380#endif
4381#endif
4382	stop_wps();
4383#ifdef CONFIG_BCMWL5
4384	stop_nas();
4385	stop_eapd();
4386#elif defined RTCONFIG_RALINK
4387	stop_8021x();
4388#endif
4389
4390#if ((defined(RTCONFIG_USER_LOW_RSSI) && defined(RTCONFIG_BCMARM)) || defined(RTCONFIG_NEW_USER_LOW_RSSI))
4391	stop_roamast();
4392#endif
4393	stop_lan_wl();
4394}
4395#endif
4396
4397//FIXME: add sysdep wrapper
4398
4399void start_wan_port(void)
4400{
4401	wanport_ctrl(1);
4402}
4403
4404void stop_wan_port(void)
4405{
4406	wanport_ctrl(0);
4407}
4408
4409void restart_lan_port(int dt)
4410{
4411	stop_lan_port();
4412	start_lan_port(dt);
4413}
4414
4415void start_lan_port(int dt)
4416{
4417	int now = 0;
4418
4419	if (dt <= 0)
4420		now = 1;
4421
4422	_dprintf("%s(%d) %d\n", __func__, dt, now);
4423	if (!s_last_lan_port_stopped_ts) {
4424		s_last_lan_port_stopped_ts = uptime();
4425		now = 1;
4426	}
4427
4428	while (!now && (uptime() - s_last_lan_port_stopped_ts < dt)) {
4429		_dprintf("sleep 1\n");
4430		sleep(1);
4431	}
4432
4433#ifdef RTCONFIG_QTN
4434	if (nvram_get_int("qtn_ready") == 1)
4435		dbG("do not start lan port due to QTN not ready\n");
4436	else
4437		lanport_ctrl(1);
4438#else
4439	lanport_ctrl(1);
4440#endif
4441}
4442
4443void stop_lan_port(void)
4444{
4445	lanport_ctrl(0);
4446	s_last_lan_port_stopped_ts = uptime();
4447	_dprintf("%s() stop lan port. ts %ld\n", __func__, s_last_lan_port_stopped_ts);
4448}
4449
4450void start_lan_wlport(void)
4451{
4452	char word[256], *next;
4453	int unit, subunit;
4454
4455#ifdef RTCONFIG_PROXYSTA
4456#if defined(RTCONFIG_RALINK) || defined(RTCONFIG_QCA)
4457	if (mediabridge_mode())
4458		return;
4459#endif
4460#endif
4461
4462	unit=0;
4463	foreach (word, nvram_safe_get("wl_ifnames"), next) {
4464		if(unit!=nvram_get_int("wlc_band")) set_radio(1, unit, 0);
4465		for (subunit = 1; subunit < 4; subunit++)
4466		{
4467			set_radio(1, unit, subunit);
4468		}
4469		unit++;
4470	}
4471}
4472
4473void stop_lan_wlport(void)
4474{
4475	char word[256], *next;
4476	int unit, subunit;
4477
4478#ifdef RTCONFIG_PROXYSTA
4479#if defined(RTCONFIG_RALINK) || defined(RTCONFIG_QCA)
4480	if (mediabridge_mode())
4481		return;
4482#endif
4483#endif
4484
4485	unit=0;
4486	foreach (word, nvram_safe_get("wl_ifnames"), next) {
4487		if(unit!=nvram_get_int("wlc_band")) set_radio(0, unit, 0);
4488		for (subunit = 1; subunit < 4; subunit++)
4489		{
4490			set_radio(0, unit, subunit);
4491		}
4492		unit++;
4493	}
4494}
4495#if 0
4496static int
4497net_dev_exist(const char *ifname)
4498{
4499	DIR *dir_to_open = NULL;
4500	char tmpstr[128];
4501
4502	if (ifname == NULL) return 0;
4503
4504	sprintf(tmpstr, "/sys/class/net/%s", ifname);
4505	dir_to_open = opendir(tmpstr);
4506	if (dir_to_open)
4507	{
4508		closedir(dir_to_open);
4509		return 1;
4510	}
4511		return 0;
4512}
4513
4514int
4515wl_dev_exist(void)
4516{
4517	char word[256], *next;
4518	int val = 1;
4519
4520	foreach (word, nvram_safe_get("wl_ifnames"), next) {
4521		if (!net_dev_exist(word))
4522		{
4523			val = 0;
4524			break;
4525		}
4526	}
4527
4528	return val;
4529}
4530#endif
4531#ifdef RTCONFIG_WIRELESSREPEATER
4532void start_lan_wlc(void)
4533{
4534	_dprintf("%s %d\n", __FUNCTION__, __LINE__);
4535
4536	char *lan_ifname;
4537
4538	lan_ifname = nvram_safe_get("lan_ifname");
4539	update_lan_state(LAN_STATE_INITIALIZING, 0);
4540
4541	// bring up and configure LAN interface
4542	if(nvram_match("lan_proto", "static"))
4543		ifconfig(lan_ifname, IFUP | IFF_ALLMULTI, nvram_safe_get("lan_ipaddr"), nvram_safe_get("lan_netmask"));
4544	else
4545		ifconfig(lan_ifname, IFUP | IFF_ALLMULTI, nvram_default_get("lan_ipaddr"), nvram_default_get("lan_netmask"));
4546
4547	if(nvram_match("lan_proto", "dhcp"))
4548	{
4549		// only none routing mode need lan_proto=dhcp
4550		if (pids("udhcpc"))
4551		{
4552			killall("udhcpc", SIGUSR2);
4553			killall("udhcpc", SIGTERM);
4554			unlink("/tmp/udhcpc_lan");
4555		}
4556		char *dhcp_argv[] = { "udhcpc",
4557					"-i", "br0",
4558					"-p", "/var/run/udhcpc_lan.pid",
4559					"-s", "/tmp/udhcpc_lan",
4560					NULL };
4561		pid_t pid;
4562
4563		symlink("/sbin/rc", "/tmp/udhcpc_lan");
4564		_eval(dhcp_argv, NULL, 0, &pid);
4565
4566		update_lan_state(LAN_STATE_CONNECTING, 0);
4567	}
4568	else {
4569		lan_up(lan_ifname);
4570	}
4571
4572	_dprintf("%s %d\n", __FUNCTION__, __LINE__);
4573}
4574
4575void stop_lan_wlc(void)
4576{
4577	_dprintf("%s %d\n", __FUNCTION__, __LINE__);
4578
4579	char *lan_ifname;
4580
4581	lan_ifname = nvram_safe_get("lan_ifname");
4582
4583	ifconfig(lan_ifname, 0, NULL, NULL);
4584
4585	update_lan_state(LAN_STATE_STOPPED, 0);
4586
4587	killall("udhcpc", SIGUSR2);
4588	killall("udhcpc", SIGTERM);
4589	unlink("/tmp/udhcpc_lan");
4590
4591	_dprintf("%s %d\n", __FUNCTION__, __LINE__);
4592}
4593#endif //RTCONFIG_WIRELESSREPEATER
4594
4595#ifdef RTCONFIG_QTN
4596int reset_qtn(int restart)
4597{
4598	int wait_loop;
4599	gen_stateless_conf();
4600	system("cp -p /rom/qtn/* /tmp/");
4601	if( restart == 0){
4602		lanport_ctrl(0);
4603#if 1	/* replaced by raw Ethernet frame */
4604		if(*nvram_safe_get("QTN_RPC_CLIENT"))
4605			eval("ifconfig", "br0:0", nvram_safe_get("QTN_RPC_CLIENT"), "netmask", "255.255.255.0");
4606		else
4607			eval("ifconfig", "br0:0", "169.254.39.1", "netmask", "255.255.255.0");
4608#endif
4609		eval("ifconfig", "br0:1", "1.1.1.1", "netmask", "255.255.255.0");
4610		eval("tftpd");
4611	}
4612	led_control(BTN_QTN_RESET, LED_ON);
4613	led_control(BTN_QTN_RESET, LED_OFF);
4614	if(nvram_match("lan_proto", "dhcp")){
4615		if(nvram_get_int("sw_mode") == SW_MODE_REPEATER ||
4616			nvram_get_int("sw_mode") == SW_MODE_AP)
4617		{
4618			if (pids("udhcpc"))
4619			{
4620				killall("udhcpc", SIGUSR2);
4621				killall("udhcpc", SIGTERM);
4622				unlink("/tmp/udhcpc_lan");
4623			}
4624
4625			wait_loop = 3;
4626			while(wait_loop > 0) {
4627				dbG("[reset_qtn] *** kill udhcpc to waiting tftp loading ***\n");
4628				sleep(15);	/* waiting tftp loading */
4629				wait_loop--;
4630			}
4631			dbG("[reset_qtn] *** finish tftp loading, restart udhcpc ***\n");
4632
4633			char *dhcp_argv[] = { "udhcpc",
4634						"-i", "br0",
4635						"-p", "/var/run/udhcpc_lan.pid",
4636						"-s", "/tmp/udhcpc_lan",
4637						NULL };
4638			pid_t pid;
4639
4640			symlink("/sbin/rc", "/tmp/udhcpc_lan");
4641			_eval(dhcp_argv, NULL, 0, &pid);
4642		}
4643	}
4644
4645	return 0;
4646}
4647
4648int start_qtn(void)
4649{
4650	gen_rpc_qcsapi_ip();
4651	reset_qtn(0);
4652
4653	return 0;
4654}
4655
4656#endif
4657