1/*
2 * Copyright (c) 2012, 2015, The Linux Foundation. All rights reserved.
3 * Permission to use, copy, modify, and/or distribute this software for
4 * any purpose with or without fee is hereby granted, provided that the
5 * above copyright notice and this permission notice appear in all copies.
6 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
7 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
8 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
9 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
10 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
12 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
13 */
14
15
16#ifdef KVER32
17#include <linux/kconfig.h>
18#include <generated/autoconf.h>
19#else
20#include <linux/autoconf.h>
21#endif
22#include <linux/if_arp.h>
23#include <linux/netdevice.h>
24#include <linux/netfilter_arp.h>
25#include <linux/inetdevice.h>
26#include <linux/netfilter_ipv4/ip_tables.h>
27#include <linux/in.h>
28#include <linux/ip.h>
29#include <linux/udp.h>
30#include <linux/tcp.h>
31#include <linux/icmp.h>
32#ifdef KVER32
33#include <linux/export.h>
34#endif
35#include <net/netfilter/nf_conntrack.h>
36#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
37#include <linux/if_vlan.h>
38#endif
39#if defined (CONFIG_BRIDGE)
40#include <../net/bridge/br_private.h>
41#endif
42#include <linux/ppp_defs.h>
43#include <linux/filter.h>
44#include <linux/if_pppox.h>
45#include <linux/if_ppp.h>
46#include <linux/ppp_channel.h>
47#include <linux/ppp-comp.h>
48#include <net/sock.h>
49#include <net/route.h>
50#include <net/netevent.h>
51#include <net/ipv6.h>
52#include <net/ip_fib.h>
53#include "hsl_api.h"
54#include "fal_nat.h"
55#include "fal_ip.h"
56#include "fal_fdb.h"
57#include "hsl.h"
58#include "nat_helper.h"
59#include "napt_acl.h"
60#include "lib/nat_helper_hsl.h"
61#include "lib/nat_helper_dt.h"
62#include "hsl_shared_api.h"
63#include <net/addrconf.h>
64
65#ifdef ISISC
66#define CONFIG_IPV6_HWACCEL 1
67#else
68#undef CONFIG_IPV6_HWACCEL
69#endif
70
71#ifdef CONFIG_IPV6_HWACCEL
72#include <net/ndisc.h>
73#include <net/neighbour.h>
74#include <net/netevent.h>
75#include <net/ipv6.h>
76#include <net/ip6_route.h>
77#include <linux/ipv6.h>
78#include <linux/netfilter_ipv6.h>
79#endif
80
81//#define AP136_QCA_HEADER_EN 1
82#define MAC_LEN 6
83#define IP_LEN 4
84#define ARP_HEADER_LEN 8
85
86#define ARP_ENTRY_MAX 128
87
88#define DESS_CHIP_VER	0x14
89
90/* P6 is used by loop dev. */
91#define S17_P6PAD_MODE_REG_VALUE 0x01000000
92
93#define MULTIROUTE_WR
94
95extern struct net init_net;
96
97//char *nat_lan_dev_list = "eth0.1";
98char nat_lan_dev_list[IFNAMSIZ*4] = "br-lan eth0.1";
99char nat_wan_dev_list[IFNAMSIZ*4] = "eth0.2";
100
101char nat_wan_port = 0x20;
102
103
104#define NAT_LAN_DEV_VID 1
105#define NAT_WAN_DEV_VID 2
106
107uint32_t nat_lan_vid  = NAT_LAN_DEV_VID;
108uint32_t nat_wan_vid = NAT_WAN_DEV_VID;
109
110
111static int wan_fid = 0xffff;
112static fal_pppoe_session_t pppoetbl = {0};
113static uint32_t pppoe_gwid = 0;
114static char nat_bridge_dev[IFNAMSIZ*4] = "br-lan";
115static uint8_t lanip[4] = {0}, lanipmask[4] = {0}, wanip[4] = {0};
116static struct in6_addr wan6ip = IN6ADDR_ANY_INIT;
117static struct in6_addr lan6ip = IN6ADDR_ANY_INIT;
118
119extern int nat_chip_ver;
120
121
122#ifdef ISISC
123struct ipv6_default_route_binding
124{
125    struct in6_addr next_hop;
126    uint32_t nh_entry_id;
127};
128#endif
129
130#ifdef MULTIROUTE_WR
131#define MAX_HOST 8
132struct wan_next_hop
133{
134    u_int32_t host_ip;
135    u_int32_t entry_id;
136    u_int32_t in_acl;
137    u_int32_t in_use;
138    u_int8_t  host_mac[6];
139};
140static struct net_device *multi_route_indev = NULL;
141static struct wan_next_hop wan_nh_ent[MAX_HOST] = {{0}};
142
143#define NAT_BACKGROUND_TASK
144
145#ifdef NAT_BACKGROUND_TASK
146#define NAT_HELPER_MSG_MAX 512
147
148struct bg_ring_buf_cb {
149	unsigned int read_idx;
150	unsigned int write_idx;
151	unsigned int num;
152	unsigned int full_flag;
153	struct nat_helper_bg_msg *buf;
154};
155
156struct bg_task_cb {
157	/*struct semaphore bg_sem;  */   /*trigger thread work*/
158	spinlock_t bg_lock;           /*ring buf access protect*/
159	/*struct task_struct *bg_task;*/
160	struct workqueue_struct *nat_wq;
161	struct bg_ring_buf_cb ring;
162};
163
164enum{
165	NAT_HELPER_ARP_IN_MSG = 0,
166	NAT_HELPER_IPV6_MSG
167};
168
169struct arp_in_msg {
170	struct sk_buff *skb;
171	struct net_device *in;
172};
173
174struct ipv6_msg {
175	struct sk_buff *skb;
176	struct net_device *in;
177};
178
179
180struct nat_helper_bg_msg {
181	struct work_struct work;
182	uint32_t msg_type;
183	uint16_t sub_type;
184	uint16_t reservd;
185	union {
186		struct arp_in_msg arp_in;
187		struct ipv6_msg   ipv6;
188	};
189};
190
191
192struct bg_task_cb task_cb;
193
194int bg_ring_buf_write(struct nat_helper_bg_msg msg)
195{
196	unsigned int idx = 0;
197
198	spin_lock_bh(&task_cb.bg_lock);
199
200	if((task_cb.ring).full_flag &&
201		((task_cb.ring).read_idx == (task_cb.ring).write_idx)) {
202		HNAT_PRINTK("ring buf is full!\n");
203		spin_unlock_bh(&task_cb.bg_lock);
204		return -1;
205	}
206	msg.work = (task_cb.ring).buf[(task_cb.ring).write_idx].work;
207	(task_cb.ring).buf[(task_cb.ring).write_idx] = msg;
208	idx = (task_cb.ring).write_idx;
209
210	(task_cb.ring).write_idx = ((task_cb.ring).write_idx+1)%NAT_HELPER_MSG_MAX;
211	if(task_cb.ring.read_idx == task_cb.ring.write_idx)
212		task_cb.ring.full_flag = 1;
213
214	spin_unlock_bh(&task_cb.bg_lock);
215	queue_work(task_cb.nat_wq, &(task_cb.ring).buf[idx].work);
216
217	return 0;
218}
219
220int bg_ring_buf_read(struct nat_helper_bg_msg *msg)
221{
222	spin_lock_bh(&task_cb.bg_lock);
223	task_cb.ring.read_idx = (task_cb.ring.read_idx+1)%NAT_HELPER_MSG_MAX;
224	task_cb.ring.full_flag = 0;
225	spin_unlock_bh(&task_cb.bg_lock);
226
227	return 0;
228}
229
230
231
232#endif
233
234static int wan_nh_get(u_int32_t host_ip)
235{
236    int i;
237
238    host_ip = htonl(host_ip);
239
240    for (i=0; i<MAX_HOST; i++)
241    {
242        if ((wan_nh_ent[i].host_ip != 0) && !memcmp(&wan_nh_ent[i].host_ip, &host_ip, 4))
243        {
244            // printk("%s %d\n", __FUNCTION__, __LINE__);
245            // if ((wan_nh_ent[i].entry_id != 0) && (wan_nh_ent[i].in_acl != 1))
246            if (wan_nh_ent[i].in_acl != 1)
247            {
248                wan_nh_ent[i].in_acl = 1;
249
250                return i;
251            }
252            // printk("%s %d\n", __FUNCTION__, __LINE__);
253        }
254        printk("%s %d wan_nh_ent 0x%08x host_ip 0x%08x\n", __FUNCTION__, __LINE__, wan_nh_ent[i].host_ip, host_ip);
255    }
256
257    return -1;
258}
259
260static void wan_nh_add(u_int8_t *host_ip , u_int8_t *host_mac, u_int32_t id)
261{
262    int i;
263
264    for( i = 0 ; i < MAX_HOST ; i++ )
265    {
266        if((wan_nh_ent[i].host_ip != 0) && !memcmp(&wan_nh_ent[i].host_ip, host_ip, 4))
267        {
268            if (host_mac == NULL) break;
269
270            if(!memcmp(&wan_nh_ent[i].host_mac, host_mac,6))
271                return;
272            else
273                break ;
274        }
275
276        if(wan_nh_ent[i].host_ip == 0)
277            break;
278    }
279
280    if (i < MAX_HOST)
281    {
282        if ((wan_nh_ent[i].in_use) && (wan_nh_ent[i].in_acl)) return;
283
284        memcpy(&wan_nh_ent[i].host_ip, host_ip, 4);
285        if (host_mac != NULL)
286        {
287            memcpy(wan_nh_ent[i].host_mac, host_mac, 6);
288            wan_nh_ent[i].entry_id = id;
289            if ((wan_nh_ent[i].in_use) && !(wan_nh_ent[i].in_acl))
290            {
291                droute_add_acl_rules(*(uint32_t *)&lanip, *(uint32_t *)&lanipmask, id);
292                /* set the in_acl flag */
293                wan_nh_ent[i].in_acl = 1;
294            }
295        }
296        else
297        {
298            /* set the in_use flag */
299            wan_nh_ent[i].in_use = 1;
300        }
301        aos_printk("%s: ip %08x (%d)\n" ,__func__, wan_nh_ent[i].host_ip, i);
302    }
303}
304
305static uint32_t get_next_hop( uint32_t daddr , uint32_t saddr )
306{
307    struct fib_result res;
308#ifdef KVER32
309    struct flowi4 fl =
310    {
311        .flowi4_iif =  multi_route_indev->ifindex,
312        .flowi4_mark = 0,
313        .flowi4_tos = 0,
314        .flowi4_scope = RT_SCOPE_UNIVERSE,
315        .daddr = htonl(daddr),
316        .saddr = htonl(saddr),
317    };
318#else
319    struct flowi fl = { .nl_u = { .ip4_u =
320            {
321                .daddr = daddr,
322                .saddr = saddr,
323                .tos = 0,
324                .scope = RT_SCOPE_UNIVERSE,
325            }
326        },
327        .mark = 0,
328        .iif = multi_route_indev->ifindex
329    };
330#endif
331    struct net    * net = dev_net(multi_route_indev);
332    struct fib_nh *mrnh = NULL;
333
334    if (fib_lookup(net, &fl, &res) != 0)
335    {
336        return 0;
337    }
338    else
339    {
340        mrnh = res.fi->fib_nh;
341        if (NULL == mrnh)
342        {
343            return 0;
344        }
345    }
346
347    return ntohl(mrnh->nh_gw);
348}
349
350uint32_t napt_set_default_route(fal_ip4_addr_t dst_addr, fal_ip4_addr_t src_addr)
351{
352    sw_error_t rv;
353
354    /* search for the next hop (s) */
355    if (!(get_aclrulemask() & (1 << S17_ACL_LIST_DROUTE)))
356    {
357        if (multi_route_indev && \
358                (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOE) &&
359                (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOES0))
360        {
361            uint32_t next_hop = get_next_hop(dst_addr, src_addr);
362
363            HNAT_PRINTK("Next hop: %08x\n", next_hop);
364            if (next_hop != 0)
365            {
366                fal_host_entry_t arp_entry;
367
368                memset(&arp_entry, 0, sizeof(arp_entry));
369                arp_entry.ip4_addr = next_hop;
370                arp_entry.flags = FAL_IP_IP4_ADDR;
371                rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &arp_entry);
372                if (rv != SW_OK)
373                {
374                    printk("%s: IP_HOST_GET error... (non-existed host: %08x?) \n", __func__, next_hop);
375                    /* add into the nh_ent */
376                    wan_nh_add((u_int8_t *)&next_hop, (u_int8_t *)NULL, 0);
377                }
378                else
379                {
380                    if (wan_nh_get(next_hop) != -1)
381                        droute_add_acl_rules(*(uint32_t *)&lanip, *(uint32_t *)&lanipmask, arp_entry.entry_id);
382                    else
383                        printk("%s %d\n", __FUNCTION__, __LINE__);
384                }
385            }
386            else
387            {
388                HNAT_PRINTK("no need to set the default route... \n");
389                // set_aclrulemask (S17_ACL_LIST_DROUTE);
390            }
391        }
392        else
393        {
394            printk("multi_route_indev %p nf_athrs17_hnat_wan_type %d\n", multi_route_indev, nf_athrs17_hnat_wan_type);
395        }
396    }
397    /* end next hop (s) */
398
399    return SW_OK;
400}
401#endif /* MULTIROUTE_WR */
402
403static void qcaswitch_hostentry_flush(void)
404{
405    fal_host_entry_t hostentry;
406    sw_error_t ret;
407
408    do
409    {
410        memset(&hostentry, 0, sizeof(fal_host_entry_t));
411        hostentry.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
412        ret = IP_HOST_NEXT (0, FAL_IP_ENTRY_ID_EN, &hostentry);
413        if (SW_OK == ret)
414        {
415            IP_HOST_DEL(0, FAL_IP_ENTRY_IPADDR_EN, &hostentry);
416        }
417    }while (SW_OK == ret);
418
419    return;
420}
421
422#ifdef CONFIG_IPV6_HWACCEL /* only for S17c */
423static struct in6_addr* get_ipv6_default_gateway(void)
424{
425    /* ip_route_output_key can't return correct default nexhop
426     * routes are less than 4 and it only searches in route
427     * hash, not in fib, so use fib_lookup.
428     */
429    struct in6_addr *ip6addr = NULL;
430    struct in6_addr des_addr = IN6ADDR_ANY_INIT;
431    struct rt6_info *rt = rt6_lookup(&init_net, &des_addr, NULL, 0, 0);
432
433    if (rt)
434    {
435        ip6addr = &rt->rt6i_gateway;
436    }
437
438    return ip6addr;
439}
440
441static int add_pppoev6_host_entry(void)
442{
443    struct in6_addr local_lan6ip = IN6ADDR_ANY_INIT;
444    unsigned long  flags;
445    int ppp_sid, ppp_sid2;
446    unsigned char ppp_peer_mac[ETH_ALEN];
447    unsigned char ppp_peer_mac2[ETH_ALEN];
448    a_uint32_t ppp_peer_ip = 0;
449    int wvid;
450    fal_host_entry_t nh_arp_entry;
451    sw_error_t rv;
452    a_uint32_t droute_entry_id = 0;
453    a_bool_t ena;
454    static fal_pppoe_session_t pppoev6_sid_table = {0};
455    struct  in6_addr *next_hop;
456
457    local_irq_save(flags);
458    memcpy(&local_lan6ip, &lan6ip, sizeof(struct in6_addr));
459    ppp_sid2 = nf_athrs17_hnat_ppp_id2;
460    ppp_sid = nf_athrs17_hnat_ppp_id;
461    ppp_peer_ip = nf_athrs17_hnat_ppp_peer_ip;
462    memcpy(ppp_peer_mac, nf_athrs17_hnat_ppp_peer_mac, ETH_ALEN);
463    memcpy(ppp_peer_mac2, nf_athrs17_hnat_ppp_peer_mac2, ETH_ALEN);
464    wvid = wan_fid;
465    local_irq_restore(flags);
466
467    if (NF_S17_WAN_TYPE_PPPOE != nf_athrs17_hnat_wan_type)
468    {
469        return SW_BAD_STATE;
470    }
471
472    if (__ipv6_addr_type(&local_lan6ip) == IPV6_ADDR_ANY)
473    {
474        /* Cannot get lanip6 successfully. */
475        return SW_BAD_STATE;
476    }
477    if (0xffff == wvid)
478    {
479        printk("%s: Cannot get WAN vid!\n", __FUNCTION__);
480        return SW_FAIL;
481    }
482
483    if (0 == nf_athrs17_hnat_ppp_peer_ip)
484    {
485        return SW_FAIL;
486    }
487
488    next_hop = get_ipv6_default_gateway();
489    if (NULL == next_hop)
490    {
491        printk("No IPv6 Gateway!\n");
492        return SW_BAD_STATE;
493    }
494
495    if (0 != ppp_sid)
496    {
497        if ((ppp_sid == ppp_sid2)||(0 == ppp_sid2)) /* v4 and v6 have the same session id */
498        {
499            memset(&nh_arp_entry, 0, sizeof(nh_arp_entry));
500            nh_arp_entry.ip4_addr = ppp_peer_ip;
501            nh_arp_entry.flags = FAL_IP_IP4_ADDR;
502            rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &nh_arp_entry);
503            if (rv != SW_OK)
504            {
505                printk("%s: IP_HOST_GET error (0x%08x)\n", __func__, ppp_peer_ip);
506                if (PPPOE_STATUS_GET(0, &ena) != SW_OK)
507                {
508                    if (!ena)
509                    {
510                        if (PPPOE_STATUS_SET(0, A_TRUE) != SW_OK)
511                        {
512                            aos_printk("Cannot enable the PPPoE mode\n");
513                            return SW_FAIL;
514                        }
515                    }
516                }
517                pppoev6_sid_table.session_id = ppp_sid;
518                pppoev6_sid_table.multi_session = 1;
519                pppoev6_sid_table.uni_session = 1;
520                pppoev6_sid_table.entry_id = 0;
521                /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */
522                rv = PPPOE_SESSION_TABLE_ADD(0, &pppoev6_sid_table);
523                if (rv == SW_OK)
524                {
525                    a_int32_t a_entry_id = -1;
526
527                    PPPOE_SESSION_ID_SET(0, pppoev6_sid_table.entry_id, pppoev6_sid_table.session_id);
528                    aos_printk("pppoe session: %d, entry_id: %d\n",
529                               pppoev6_sid_table.session_id, pppoev6_sid_table.entry_id);
530                    /* create the peer host ARP entry */
531                    a_entry_id = arp_hw_add(S17_WAN_PORT, wan_fid, (void *)&ppp_peer_ip, (void *)ppp_peer_mac, 0);
532                    if (a_entry_id >= 0) /* hostentry creation okay */
533                    {
534                        rv = IP_HOST_PPPOE_BIND(0, a_entry_id, pppoev6_sid_table.entry_id, A_TRUE);
535                        if ( rv != SW_OK)
536                        {
537                            aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n",
538                                       a_entry_id, rv);
539                            PPPOE_SESSION_TABLE_DEL(0, &pppoev6_sid_table);
540                            return SW_FAIL;
541                        }
542                        droute_entry_id = a_entry_id;
543                    }
544                    else
545                    {
546                        PPPOE_SESSION_TABLE_DEL(0, &pppoev6_sid_table);
547                        return SW_FAIL;
548                    }
549                }
550                else
551                {
552                    aos_printk("PPPoE session add failed.. (id: %d)\n",
553                               pppoev6_sid_table.session_id);
554                    aos_printk("rv: %d\n", rv);
555                    return SW_FAIL;
556                }
557            }
558            else
559            {
560                droute_entry_id = nh_arp_entry.entry_id;
561            }
562            ipv6_droute_add_acl_rules(&local_lan6ip, droute_entry_id);
563        }
564        else /* Not the same session id */
565        {
566            if (PPPOE_STATUS_GET(0, &ena) != SW_OK)
567            {
568                if (!ena)
569                {
570                    if (PPPOE_STATUS_SET(0, A_TRUE) != SW_OK)
571                    {
572                        aos_printk("Cannot enable the PPPoE mode\n");
573                        return SW_FAIL;
574                    }
575                }
576            }
577            memset(&nh_arp_entry, 0, sizeof(nh_arp_entry));
578            memcpy((void *)&nh_arp_entry.ip6_addr, (void *)next_hop, sizeof(nh_arp_entry.ip6_addr));
579            nh_arp_entry.flags = FAL_IP_IP6_ADDR;
580            rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &nh_arp_entry);
581            if (rv != SW_OK)
582            {
583                /* ARP alread setup. */
584                return SW_OK;
585            }
586            pppoev6_sid_table.session_id = ppp_sid2;
587            pppoev6_sid_table.multi_session = 1;
588            pppoev6_sid_table.uni_session = 1;
589            pppoev6_sid_table.entry_id = 0;
590            /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */
591            rv = PPPOE_SESSION_TABLE_ADD(0, &pppoev6_sid_table);
592            if (rv == SW_OK)
593            {
594                a_int32_t a_entry_id = -1;
595
596                PPPOE_SESSION_ID_SET(0, pppoev6_sid_table.entry_id, pppoev6_sid_table.session_id);
597                aos_printk("pppoe session: %d, entry_id: %d\n",
598                           pppoev6_sid_table.session_id, pppoev6_sid_table.entry_id);
599                /* create the peer host ARP entry */
600                a_entry_id = arp_hw_add(S17_WAN_PORT, wan_fid, (void *)next_hop, ppp_peer_mac2, 1);
601                if (a_entry_id >= 0) /* hostentry creation okay */
602                {
603                    rv = IP_HOST_PPPOE_BIND(0, a_entry_id, pppoev6_sid_table.entry_id, A_TRUE);
604                    if ( rv != SW_OK)
605                    {
606                        aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n",
607                                   a_entry_id, rv);
608                        PPPOE_SESSION_TABLE_DEL(0, &pppoev6_sid_table);
609                        return SW_FAIL;
610                    }
611                    droute_entry_id = a_entry_id;
612                }
613                else
614                {
615                    PPPOE_SESSION_TABLE_DEL(0, &pppoev6_sid_table);
616                    return SW_FAIL;
617                }
618            }
619            else
620            {
621                aos_printk("PPPoE session add failed.. (id: %d)\n",
622                           pppoev6_sid_table.session_id);
623                aos_printk("rv: %d\n", rv);
624                return SW_FAIL;
625            }
626            ipv6_droute_add_acl_rules(&local_lan6ip, droute_entry_id);
627        }
628    }
629
630    return SW_OK;
631}
632
633uint32_t napt_set_ipv6_default_route(void)
634{
635    sw_error_t rv;
636    static a_bool_t ipv6_droute_setup = A_FALSE;
637    static struct ipv6_default_route_binding ipv6_droute_bind = {IN6ADDR_ANY_INIT,0};
638    struct in6_addr local_lan6ip = IN6ADDR_ANY_INIT;
639    unsigned long  flags;
640
641	if (((nat_chip_ver&0xffff)>>8) == DESS_CHIP_VER)
642		return SW_OK;
643
644    /* search for the next hop (s)*/
645    if (NF_S17_WAN_TYPE_IP == nf_athrs17_hnat_wan_type)
646    {
647        struct  in6_addr *next_hop = get_ipv6_default_gateway();
648
649        // printk("IPv6 next hop: %pI6\n", next_hop);
650
651        if (next_hop != NULL)
652        {
653            fal_host_entry_t ipv6_neigh_entry;
654
655            if (__ipv6_addr_type(next_hop) == IPV6_ADDR_LINKLOCAL)
656                return SW_OK;
657
658            local_irq_save(flags);
659            memcpy(&local_lan6ip, &lan6ip, sizeof(struct in6_addr));
660            local_irq_restore(flags);
661
662            memset(&ipv6_neigh_entry, 0, sizeof(ipv6_neigh_entry));
663            memcpy(&ipv6_neigh_entry.ip6_addr, next_hop, 16);
664            ipv6_neigh_entry.flags = FAL_IP_IP6_ADDR;
665            rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &ipv6_neigh_entry);
666            if ((rv != SW_OK)||(__ipv6_addr_type(&local_lan6ip) == IPV6_ADDR_ANY))
667            {
668                if (ipv6_droute_setup)
669                {
670                    ipv6_droute_del_acl_rules();
671                    memset(&ipv6_droute_bind, 0, sizeof(ipv6_droute_bind));
672                    ipv6_droute_setup = A_FALSE;
673                }
674            }
675            else
676            {
677                if (ipv6_droute_setup)
678                {
679                    if (!ipv6_addr_equal(&ipv6_droute_bind.next_hop, next_hop) ||
680                            ipv6_droute_bind.nh_entry_id != ipv6_neigh_entry.entry_id)
681                    {
682                        ipv6_droute_del_acl_rules();
683                    }
684                }
685                ipv6_droute_bind.next_hop = *next_hop;
686                ipv6_droute_bind.nh_entry_id = ipv6_neigh_entry.entry_id;
687
688                ipv6_droute_add_acl_rules(&local_lan6ip, ipv6_neigh_entry.entry_id);
689                ipv6_droute_setup = A_TRUE;
690            }
691        }
692        else
693        {
694            if (ipv6_droute_setup)
695            {
696                ipv6_droute_del_acl_rules();
697                memset(&ipv6_droute_bind, 0, sizeof(ipv6_droute_bind));
698                ipv6_droute_setup = A_FALSE;
699            }
700        }
701    }
702    else if (NF_S17_WAN_TYPE_IP == nf_athrs17_hnat_wan_type)
703    {
704        add_pppoev6_host_entry();
705    }
706
707    return SW_OK;
708}
709#endif /* ifdef CONFIG_IPV6_HWACCEL */
710
711static sw_error_t setup_interface_entry(char *list_if, int is_wan)
712{
713    char temp[IFNAMSIZ*4]; /* Max 4 interface entries right now. */
714    char *dev_name, *list_all;
715    struct net_device *nat_dev;
716    struct in_device *in_device_lan = NULL, *in_device_wan = NULL;
717    uint8_t *devmac, if_mac_addr[MAC_LEN];
718    char *br_name;
719    uint32_t vid = 0;
720    sw_error_t setup_error;
721    uint32_t ipv6 = 0;
722    static int setup_lan_if=0;
723
724    memcpy(temp, list_if, strlen(list_if)+1);
725    list_all = temp;
726
727    setup_error = SW_FAIL;
728    while ((dev_name = strsep(&list_all, " ")) != NULL)
729    {
730        nat_dev = dev_get_by_name(&init_net, dev_name);
731        if (NULL == nat_dev)
732        {
733            // printk("%s: Cannot get device %s by name!\n", __FUNCTION__, dev_name);
734            setup_error = SW_FAIL;
735            continue;
736        }
737#if defined (CONFIG_BRIDGE)
738#ifdef KVER32
739        if (NULL != br_port_get_rcu(nat_dev)) /* under bridge interface. */
740        {
741            /* Get bridge interface name */
742            br_name = (char *)(br_port_get_rcu(nat_dev)->br->dev->name);
743            //memcpy (nat_bridge_dev, br_name, sizeof(br_name));
744            strcat (nat_lan_dev_list, " ");
745            strcat (nat_lan_dev_list, br_name);
746            /* Get dmac */
747            devmac = (uint8_t *)(br_port_get_rcu(nat_dev)->br->dev->dev_addr);
748        }
749#else
750        if (NULL != nat_dev->br_port) /* under bridge interface. */
751        {
752            /* Get bridge interface name */
753            br_name = (char *)nat_dev->br_port->br->dev->name;
754            //memcpy (nat_bridge_dev, br_name, sizeof(br_name));
755            strcat (nat_lan_dev_list, " ");
756            strcat (nat_lan_dev_list, br_name);
757            /* Get dmac */
758            devmac = (uint8_t *)nat_dev->br_port->br->dev->dev_addr;
759        }
760#endif
761        else
762#endif /* CONFIG_BRIDGE */
763        {
764            devmac = (uint8_t *)nat_dev->dev_addr;
765        }
766        /* get vid */
767#if 0
768#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
769        vid = vlan_dev_vlan_id(nat_dev);
770#else
771        vid = 0;
772#endif
773#endif
774		if(is_wan)
775			vid = nat_wan_vid;
776		else
777			vid = nat_lan_vid;
778#ifdef CONFIG_IPV6_HWACCEL
779        ipv6 = 1;
780        if (is_wan)
781        {
782            wan_fid = vid;
783        }
784#else
785        ipv6 = 0;
786        if (is_wan)
787        {
788            if (NF_S17_WAN_TYPE_PPPOEV6 == nf_athrs17_hnat_wan_type)
789                ipv6 = 1;
790            wan_fid = vid;
791        }
792#endif
793#ifdef ISISC
794        if (0 == is_wan) /* Not WAN -> LAN */
795        {
796            /* Setup private and netmask as soon as possible */
797            if (br_port_get_rcu(nat_dev)) /* under bridge interface. */
798            {
799                in_device_lan = (struct in_device *) (br_port_get_rcu(nat_dev)->br->dev->ip_ptr);
800            }
801            else
802            {
803                in_device_lan = (struct in_device *) nat_dev->ip_ptr;
804            }
805
806            if ((in_device_lan) && (in_device_lan->ifa_list))
807            {
808                nat_hw_prv_mask_set((a_uint32_t)(in_device_lan->ifa_list->ifa_mask));
809                nat_hw_prv_base_set((a_uint32_t)(in_device_lan->ifa_list->ifa_address));
810#ifndef KVER32
811                printk("Set private base 0x%08x for %s\n", (a_uint32_t)(in_device_lan->ifa_list->ifa_address), nat_dev->br_port->br->dev->name);
812#endif
813                memcpy(&lanip, (void *)&(in_device_lan->ifa_list->ifa_address), 4); /* copy Lan port IP. */
814		memcpy(&lanipmask, (void *)&(in_device_lan->ifa_list->ifa_mask), 4);
815#ifndef ISISC
816                redirect_internal_ip_packets_to_cpu_on_wan_add_acl_rules((a_uint32_t)(in_device_lan->ifa_list->ifa_address),
817                                                                            (a_uint32_t)(in_device_lan->ifa_list->ifa_mask));
818#endif
819            }
820
821            if(setup_lan_if) {
822                return SW_OK;
823            } else {
824                setup_lan_if = 1;
825            }
826        }
827#endif
828		if (1 == is_wan) {
829			in_device_wan = (struct in_device *) nat_dev->ip_ptr;
830			if((in_device_wan) && (in_device_wan->ifa_list))
831			{
832				a_uint32_t index;
833				nat_hw_pub_ip_add(ntohl((a_uint32_t)(in_device_wan->ifa_list->ifa_address)), &index);
834				HNAT_PRINTK("pubip add 0x%x\n", (a_uint32_t)(in_device_wan->ifa_list->ifa_address));
835			}
836		}
837        memcpy(if_mac_addr, devmac, MAC_LEN);
838        devmac = if_mac_addr;
839        dev_put(nat_dev);
840
841        if(if_mac_add(devmac, vid, ipv6) != 0)
842        {
843            setup_error = SW_FAIL;
844            continue;
845        }
846        else
847        {
848            setup_error = SW_OK;
849        }
850    }
851
852    return setup_error;
853}
854
855static void setup_dev_list(void)
856{
857	fal_vlan_t entry;
858	uint32_t tmp_vid = 0xffffffff;
859
860	/*get the vlan entry*/
861	while(1) {
862		if(SW_OK != VLAN_NEXT(0, tmp_vid, &entry))
863			break;
864		tmp_vid = entry.vid;
865		if(tmp_vid != 0) {
866			if(entry.mem_ports & nat_wan_port) {
867				/*wan port*/
868				HNAT_PRINTK("wan port vid:%d\n", tmp_vid);
869				nat_wan_vid = tmp_vid;
870				snprintf(nat_wan_dev_list, IFNAMSIZ, "eth0.%d eth0 pppoe-wan", tmp_vid);
871			} else {
872				/*lan port*/
873				HNAT_PRINTK("lan port vid:%d\n", tmp_vid);
874				nat_lan_vid = tmp_vid;
875				snprintf(nat_lan_dev_list, IFNAMSIZ, "eth0.%d eth1", tmp_vid);
876			}
877		}
878	}
879}
880
881static int setup_all_interface_entry(void)
882{
883    static int setup_wan_if = 0;
884    //static int setup_lan_if=0;
885    static int setup_default_vid = 0;
886    int i = 0;
887
888	setup_dev_list();
889
890    if (0 == setup_default_vid)
891    {
892        for (i=0; i<7; i++) /* For AR8327/AR8337, only 7 port */
893        {
894#if NAT_TODO /* need to implement here */
895            PORTVLAN_ROUTE_DEFV_SET(0, i);
896#endif
897        }
898        setup_default_vid = 1;
899    }
900
901    //if (0 == setup_lan_if)
902    {
903#ifdef ISISC
904        //MISC_ARP_CMD_SET(0, FAL_MAC_FRWRD); /* Should be put in init function. */
905#if 0
906        MISC_ARP_SP_NOT_FOUND_SET(0, FAL_MAC_RDT_TO_CPU);
907#endif
908#endif
909        if (SW_OK == setup_interface_entry(nat_lan_dev_list, 0))
910        {
911            //setup_lan_if = 1; /* setup LAN interface entry success */
912            //printk("Setup LAN interface entry done!\n");
913        }
914    }
915
916    if (0 == setup_wan_if)
917    {
918        if (SW_OK == setup_interface_entry(nat_wan_dev_list, 1))
919        {
920            setup_wan_if = 1; /* setup WAN interface entry success */
921        }
922    }
923#ifndef ISISC /* For S17c only */
924    if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) ||
925            (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6))
926    {
927        uint8_t buf[6];
928
929        memcpy(buf, nf_athrs17_hnat_ppp_peer_mac, ETH_ALEN);
930        HNAT_PRINTK("Peer MAC: %s ", buf);
931        /* add the peer interface with VID */
932        if_mac_add(buf, wan_fid, 0);
933        HNAT_PRINTK(" --> (%.2x-%.2x-%.2x-%.2x-%.2x-%.2x)\n", \
934                    buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
935        memcpy(&wanip, (void *)&nf_athrs17_hnat_wan_ip, 4);
936    }
937#endif
938
939    return 1;
940}
941
942/* check for pppoe session change */
943static void isis_pppoe_check_for_redial(void)
944{
945    if (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_IP)
946        return;
947
948    if(((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) \
949            || (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6)) \
950            && (pppoetbl.session_id != 0))
951    {
952        if(pppoetbl.session_id != nf_athrs17_hnat_ppp_id)
953        {
954            aos_printk("%s: PPPoE session ID changed... \n", __func__);
955            if (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOEV6)
956            {
957                if (PPPOE_SESSION_TABLE_DEL(0, &pppoetbl) != SW_OK)
958                {
959                    aos_printk("delete old pppoe session %d entry_id %d failed.. \n", pppoetbl.session_id, pppoetbl.entry_id);
960                    return;
961                }
962
963                /* force PPPoE parser for multi- and uni-cast packets; for v1.0.7+ */
964                pppoetbl.session_id = nf_athrs17_hnat_ppp_id;
965                pppoetbl.multi_session = 1;
966                pppoetbl.uni_session = 0;
967                pppoetbl.entry_id = 0;
968                /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */
969                if (PPPOE_SESSION_TABLE_ADD(0, &pppoetbl) == SW_OK)
970                {
971                    PPPOE_SESSION_ID_SET(0, pppoetbl.entry_id, pppoetbl.session_id);
972                    printk("%s: new pppoe session id: %x, entry_id: %x\n", __func__, pppoetbl.session_id, pppoetbl.entry_id);
973                }
974            }
975            else  /* nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6 */
976            {
977                /* reset the session Id only */
978                aos_printk("IPV6 PPPOE mode... \n");
979                pppoetbl.session_id = nf_athrs17_hnat_ppp_id;
980                PPPOE_SESSION_ID_SET(0, pppoetbl.entry_id, pppoetbl.session_id);
981                printk("%s: new pppoe session id: %x, entry_id: %x\n", __func__, pppoetbl.session_id, pppoetbl.entry_id);
982            }
983            /* read back the WAN IP */
984            memcpy(&wanip, (void *)&nf_athrs17_hnat_wan_ip, 4);
985            aos_printk("Read the WAN IP back... %.8x\n", *(uint32_t *)&wanip);
986            /* change the PPPoE ACL to ensure the packet is correctly forwarded by the HNAT engine */
987            pppoe_add_acl_rules(*(uint32_t *)&wanip, *(uint32_t *)&lanip,
988            						*(uint32_t *)&lanipmask, pppoe_gwid);
989        }
990    }
991}
992
993#ifdef ISIS /* only for S17 */
994static void pppoev6_mac6_loop_dev(void)
995{
996#define PPPOEV6_SESSION_ID  0xfffe
997    fal_pppoe_session_t ptbl;
998	sw_error_t rv;
999	a_uint32_t entry;
1000
1001    memset(&ptbl, 0, sizeof(fal_pppoe_session_t));
1002
1003    aos_printk("%s: set MAC6 as loopback device\n", __func__);
1004
1005    ptbl.session_id = PPPOEV6_SESSION_ID;
1006    ptbl.multi_session = 1;
1007    ptbl.uni_session = 1;
1008    ptbl.entry_id = 0xe;
1009
1010    /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */
1011    if (PPPOE_SESSION_TABLE_ADD(0, &ptbl) == SW_OK)
1012    {
1013        PPPOE_SESSION_ID_SET(0, ptbl.entry_id, ptbl.session_id);
1014        aos_printk("%s: pppoe session id: %d added into entry: %d \n", __func__, ptbl.session_id, ptbl.entry_id);
1015    }
1016    else
1017    {
1018        aos_printk("%s: failed on adding pppoe session id: %d\n", __func__, ptbl.session_id);
1019    }
1020
1021    /* PPPoE entry 0 */
1022	entry = PPPOEV6_SESSION_ID;
1023	HSL_REG_ENTRY_SET(rv, 0, PPPOE_EDIT, 0, (a_uint8_t *) (&entry), sizeof (a_uint32_t));
1024
1025    aos_printk("%s: end of function... \n", __func__);
1026}
1027
1028static void pppoev6_remove_parser(uint32_t entry_id)
1029{
1030	sw_error_t rv;
1031	a_uint32_t entry;
1032
1033    aos_printk("%s: clear entry id: %d\n", __func__, entry_id);
1034    /* clear the session id in the PPPoE parser engine */
1035	entry = 0;
1036	HSL_REG_ENTRY_SET(rv, 0, PPPOE_SESSION,
1037					entry_id, (a_uint8_t *) (&entry), sizeof (a_uint32_t));
1038}
1039
1040static void pppoev6_mac6_stop_learning(void)
1041{
1042    /* do not disable this port if some other registers are already filled in
1043       to prevent setting conflict */
1044    int val = S17_P6PAD_MODE_REG_VALUE;
1045	sw_error_t rv;
1046	a_uint32_t entry;
1047
1048    if ( val != (1<<24))
1049    {
1050        aos_printk("%s: MAC 6 already being used!\n", __FUNCTION__);
1051        return;
1052    }
1053
1054
1055    /* clear the MAC6 learning bit */
1056	HSL_REG_ENTRY_GET(rv, 0, PORT_LOOKUP_CTL, 6, (a_uint8_t *) (&entry), sizeof (a_uint32_t));
1057	entry = entry & ~(1<<20);
1058	HSL_REG_ENTRY_SET(rv, 0, PORT_LOOKUP_CTL, 6, (a_uint8_t *) (&entry), sizeof (a_uint32_t));
1059
1060    /* force loopback mode */
1061	entry = 0x7e;
1062	HSL_REG_ENTRY_SET(rv, 0, PORT_STATUS, 6, (a_uint8_t *) (&entry), sizeof (a_uint32_t));
1063	entry = 0x10;
1064	HSL_REG_ENTRY_SET(rv, 0, PORT_HDR_CTL, 6, (a_uint8_t *) (&entry), sizeof (a_uint32_t));
1065}
1066#endif // ifdef ISIS
1067
1068static int add_pppoe_host_entry(uint32_t sport, a_int32_t arp_entry_id)
1069{
1070    a_bool_t ena;
1071    int rv = SW_OK;
1072    fal_host_entry_t nh_arp_entry;
1073
1074    if (0xffff == wan_fid)
1075    {
1076        printk("%s: Cannot get WAN vid!\n", __FUNCTION__);
1077        return SW_FAIL;
1078    }
1079
1080    if (PPPOE_STATUS_GET(0, &ena) != SW_OK)
1081    {
1082        aos_printk("Cannot get the PPPoE mode\n");
1083        ena = 0;
1084    }
1085
1086    memset(&nh_arp_entry, 0, sizeof(nh_arp_entry));
1087    nh_arp_entry.ip4_addr = ntohl(nf_athrs17_hnat_ppp_peer_ip);
1088    nh_arp_entry.flags = FAL_IP_IP4_ADDR;
1089    rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &nh_arp_entry);
1090    if (SW_OK != rv || pppoetbl.session_id != nf_athrs17_hnat_ppp_id)
1091    {
1092        if ((!ena) && (PPPOE_STATUS_SET(0, A_TRUE) != SW_OK))
1093            aos_printk("Cannot enable the PPPoE mode\n");
1094
1095        aos_printk("PPPoE enable mode: %d\n", ena);
1096
1097        pppoetbl.session_id = nf_athrs17_hnat_ppp_id;
1098        pppoetbl.multi_session = 1;
1099        pppoetbl.uni_session = 0;
1100        pppoetbl.entry_id = 0;
1101
1102        /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */
1103        rv = PPPOE_SESSION_TABLE_ADD(0, &pppoetbl);
1104        if (rv == SW_OK)
1105        {
1106            uint8_t mbuf[6], ibuf[4];
1107            a_int32_t a_entry_id = -1;
1108			a_uint32_t index;
1109
1110            PPPOE_SESSION_ID_SET(0, pppoetbl.entry_id, pppoetbl.session_id);
1111            aos_printk("pppoe session: %d, entry_id: %d\n", pppoetbl.session_id, pppoetbl.entry_id);
1112
1113            /* create the peer host ARP entry */
1114            memcpy(ibuf, (void *)&nf_athrs17_hnat_ppp_peer_ip, 4);
1115            memcpy(mbuf, nf_athrs17_hnat_ppp_peer_mac, ETH_ALEN);
1116
1117            a_entry_id = arp_hw_add(S17_WAN_PORT, wan_fid, ibuf, mbuf, 0);
1118            if (a_entry_id >= 0) /* hostentry creation okay */
1119            {
1120                aos_printk("(1)Bind PPPoE session ID: %d, entry_id: %d to host entry: %d\n", \
1121                           pppoetbl.session_id, pppoetbl.entry_id, a_entry_id);
1122
1123                rv = IP_HOST_PPPOE_BIND(0, a_entry_id, pppoetbl.entry_id, A_TRUE);
1124                if ( rv != SW_OK)
1125                {
1126                    aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n", a_entry_id, rv);
1127                }
1128
1129                aos_printk("adding ACLs \n");
1130                pppoe_gwid = a_entry_id;
1131			pppoe_add_acl_rules(nf_athrs17_hnat_wan_ip, *(uint32_t *)&lanip,
1132								*(uint32_t *)&lanipmask, a_entry_id);
1133			nat_hw_pub_ip_add(ntohl(nf_athrs17_hnat_wan_ip), &index);
1134                aos_printk("ACL creation okay... \n");
1135            } else {
1136			HNAT_PRINTK("pppoe arp add fail!\n");
1137            }
1138        }
1139        else
1140        {
1141            aos_printk("PPPoE session add failed.. (id: %d)\n", pppoetbl.session_id);
1142            aos_printk("rv: %d\n", rv);
1143        }
1144
1145#ifdef ISIS
1146        if (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6)
1147        {
1148            aos_printk("IPV6 PPPOE mode... (share the same ID with IPV4's)\n");
1149            pppoev6_mac6_loop_dev();
1150            pppoev6_remove_parser(pppoetbl.entry_id);
1151
1152            /* bind the first LAN host to the pseudo PPPoE ID */
1153            rv = IP_HOST_PPPOE_BIND(0, arp_entry_id, 0, A_TRUE);
1154            if ( rv != SW_OK)
1155            {
1156                aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n", arp_entry_id, rv);
1157            }
1158        }
1159#endif // ifdef ISIS
1160    }
1161#ifdef ISIS
1162    else  /* ena */
1163    {
1164        if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6) &&
1165                (sport != S17_WAN_PORT)&& (arp_entry_id != 0))
1166        {
1167            aos_printk("IPV6 PPPoE mode\n");
1168            /* bind LAN hosts to the pseudo PPPoE ID */
1169            rv = IP_HOST_PPPOE_BIND(0, arp_entry_id, 0, A_TRUE);
1170            if ( rv != SW_OK)
1171            {
1172                aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n", arp_entry_id, rv);
1173            }
1174        }
1175    }
1176#endif // ifdef ISIS
1177
1178    return SW_OK;
1179}
1180
1181static int
1182arp_is_reply(struct sk_buff *skb)
1183{
1184    struct arphdr *arp = arp_hdr(skb);
1185
1186    if (!arp)
1187    {
1188        HNAT_PRINTK("%s: Packet has no ARP data\n", __func__);
1189        return 0;
1190    }
1191
1192    if (skb->len < sizeof(struct arphdr))
1193    {
1194        HNAT_PRINTK("%s: Packet is too small to be an ARP\n", __func__);
1195        return 0;
1196    }
1197
1198    if (arp->ar_op != htons(ARPOP_REPLY))
1199    {
1200        return 0;
1201    }
1202    return 1;
1203}
1204
1205static int
1206dev_check(char *in_dev, char *dev_list)
1207{
1208    char *list_dev;
1209    char temp[100] = {0};
1210    char *list;
1211
1212    if(!in_dev || !dev_list)
1213    {
1214        return 0;
1215    }
1216
1217    strcpy(temp, dev_list);
1218    list = temp;
1219
1220    while ((list_dev = strsep(&list, " ")) != NULL)
1221    {
1222        HNAT_PRINTK("%s: strlen:%d list_dev:%s in_dev:%s\n",
1223                    __func__, strlen(list_dev), list_dev, in_dev);
1224
1225        if (!strncmp(list_dev, in_dev, strlen(list_dev)))
1226        {
1227            HNAT_PRINTK("%s: %s\n", __FUNCTION__, list_dev);
1228            return 1;
1229        }
1230    }
1231
1232    return 0;
1233}
1234
1235#ifndef ISISC
1236static uint32_t get_netmask_from_netdevice(const struct net_device *in_net_dev)
1237{
1238    struct in_device *my_in_device = NULL;
1239    uint32_t result = 0xffffff00;
1240
1241    if((in_net_dev) && (in_net_dev->ip_ptr != NULL))
1242    {
1243        my_in_device = (struct in_device *)(in_net_dev->ip_ptr);
1244        if(my_in_device->ifa_list != NULL)
1245        {
1246            result = my_in_device->ifa_list->ifa_mask;
1247        }
1248    }
1249
1250    return result;
1251}
1252#endif
1253
1254static unsigned int
1255arp_in(unsigned int hook,
1256       struct sk_buff *skb,
1257       const struct net_device *in,
1258       const struct net_device *out,
1259       int (*okfn) (struct sk_buff *))
1260{
1261	struct sk_buff *new_skb = NULL;
1262	struct nat_helper_bg_msg msg;
1263	/*unsigned long flags = 0;*/
1264
1265	new_skb = skb_clone(skb, GFP_ATOMIC);
1266	if(new_skb) {
1267		memset(&msg, 0, sizeof(msg));
1268		msg.msg_type = NAT_HELPER_ARP_IN_MSG;
1269		msg.arp_in.skb = new_skb;
1270		msg.arp_in.in = in;
1271
1272		/*send msg to background task*/
1273		/*spin_lock_irqsave(&task_cb.bg_lock, flags);*/
1274		if(bg_ring_buf_write(msg))
1275			kfree_skb(new_skb);
1276		/*spin_unlock_irqrestore(&task_cb.bg_lock, flags);*/
1277		/*up(&task_cb.bg_sem);*/
1278	}
1279
1280	return NF_ACCEPT;
1281
1282}
1283
1284
1285#ifdef NAT_BACKGROUND_TASK
1286static unsigned int
1287arp_in_bg_handle(struct nat_helper_bg_msg *msg)
1288{
1289    struct arphdr *arp = NULL;
1290    uint8_t *sip, *dip, *smac, *dmac;
1291    uint8_t dev_is_lan = 0;
1292    uint32_t sport = 0, vid = 0;
1293#ifdef ISIS
1294    uint32_t lan_netmask = 0;
1295    a_bool_t prvbasemode = 1;
1296#endif
1297    a_int32_t arp_entry_id = -1;
1298	struct net_device *in = msg->arp_in.in;
1299	struct sk_buff *skb = msg->arp_in.skb;
1300
1301
1302    /* check for PPPoE redial here, to reduce overheads */
1303    isis_pppoe_check_for_redial();
1304
1305    /* do not write out host table if HNAT is disabled */
1306    if (!nf_athrs17_hnat)
1307        return 0;
1308
1309    setup_all_interface_entry();
1310
1311    if(dev_check((char *)in->name, (char *)nat_wan_dev_list))
1312    {
1313
1314    }
1315    else if (dev_check((char *)in->name, (char *)nat_lan_dev_list))
1316    {
1317        dev_is_lan = 1;
1318    }
1319    else
1320    {
1321        HNAT_INFO_PRINTK("Not Support device: %s\n",  (char *)in->name);
1322        return 0;
1323    }
1324
1325    if(!arp_is_reply(skb))
1326    {
1327        return 0;
1328    }
1329#ifdef AP136_QCA_HEADER_EN
1330    if(arp_if_info_get((void *)(skb->head), &sport, &vid) != 0)
1331    {
1332        printk("Cannot get header info!!\n");
1333        return 0;
1334    }
1335#else
1336    if(dev_is_lan) {
1337         vid = nat_lan_vid;
1338    } else {
1339         vid = nat_wan_vid;
1340    }
1341
1342    fal_fdb_entry_t entry = {0};
1343
1344    entry.fid = vid;
1345
1346	smac = skb_mac_header(skb) + MAC_LEN;
1347    aos_mem_copy(&(entry.addr), smac, sizeof(fal_mac_addr_t));
1348    if(fal_fdb_find(0, &entry) == SW_OK) {
1349        vid  = entry.fid;
1350        sport = 0;
1351        while (sport < 32) {
1352            if(entry.port.map & (1 << sport)) {
1353                break;
1354            }
1355            sport++;
1356        }
1357    } else {
1358        printk("not find the FDB entry\n");
1359    }
1360#endif
1361
1362    arp = arp_hdr(skb);
1363    smac = ((uint8_t *) arp) + ARP_HEADER_LEN;
1364    sip = smac + MAC_LEN;
1365    dmac = sip + IP_LEN;
1366    dip = dmac + MAC_LEN;
1367
1368    arp_entry_id = arp_hw_add(sport, vid, sip, smac, 0);
1369    if(arp_entry_id < 0)
1370    {
1371        printk("ARP entry error!!\n");
1372        return 0;
1373    }
1374
1375    if (0 == dev_is_lan)
1376    {
1377        memcpy(&wanip, dip, 4);
1378#ifdef MULTIROUTE_WR
1379        wan_nh_add(sip, smac, arp_entry_id);
1380#endif
1381    }
1382
1383    if(dev_is_lan && nat_hw_prv_base_can_update())
1384    {
1385        nat_hw_flush();
1386        nat_hw_prv_base_update_disable();
1387#ifdef MULTIROUTE_WR
1388        //multi_route_indev = in;
1389#endif
1390    }
1391    multi_route_indev = in;
1392
1393    if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) ||
1394            (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6))
1395    {
1396        add_pppoe_host_entry(sport, arp_entry_id);
1397    }
1398
1399#ifdef ISIS
1400    /* check for SIP and DIP range */
1401    if ((lanip[0] != 0) && (wanip[0] != 0))
1402    {
1403		if(!NAT_PRV_ADDR_MODE_GET)
1404			return 1;
1405
1406        if (NAT_PRV_ADDR_MODE_GET(0, &prvbasemode) != SW_OK)
1407        {
1408            aos_printk("Private IP base mode check failed: %d\n", prvbasemode);
1409        }
1410
1411        if (!prvbasemode) /* mode 0 */
1412        {
1413            if ((lanip[0] == wanip[0]) && (lanip[1] == wanip[1]))
1414            {
1415                if ((lanip[2] & 0xf0) == (wanip[2] & 0xf0))
1416                {
1417                    if (get_aclrulemask()& (1 << S17_ACL_LIST_IPCONF))
1418                        return 0;
1419
1420                    aos_printk("LAN IP and WAN IP conflict... \n");
1421                    /* set h/w acl to filter out this case */
1422#ifdef MULTIROUTE_WR
1423                    // if ( (wan_nh_ent[0].host_ip != 0) && (wan_nh_ent[0].entry_id != 0))
1424                    if ( (wan_nh_ent[0].host_ip != 0))
1425                        ip_conflict_add_acl_rules(*(uint32_t *)&wanip, *(uint32_t *)&lanip, wan_nh_ent[0].entry_id);
1426#endif
1427                    return 0;
1428                }
1429            }
1430        }
1431        else  /* mode 1*/
1432        {
1433            ;; /* do nothing */
1434        }
1435    }
1436#endif /* ifdef ISIS */
1437
1438    return 1;
1439}
1440#endif
1441
1442
1443static struct
1444        nf_hook_ops arpinhook =
1445{
1446    .hook = arp_in,
1447    .hooknum = NF_ARP_IN,
1448    .owner = THIS_MODULE,
1449    .pf = NFPROTO_ARP,
1450    .priority = NF_IP_PRI_FILTER,
1451};
1452
1453#ifdef AUTO_UPDATE_PPPOE_INFO
1454static int qcaswitch_pppoe_ip_event(struct notifier_block *this,
1455                                    unsigned long event, void *ptr)
1456{
1457    struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
1458    struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev;
1459    struct list_head *list;
1460    struct channel *pch;
1461    struct sock *sk;
1462    struct pppox_sock *po;
1463    unsigned long  flags;
1464    static int connection_count = 0;
1465    fal_pppoe_session_t del_pppoetbl;
1466	int channel_count;
1467	struct ppp_channel *ppp_chan[1];
1468	int channel_protocol;
1469
1470    if (!((dev->type == ARPHRD_PPP) && (dev->flags & IFF_POINTOPOINT)))
1471        return NOTIFY_DONE;
1472
1473    if (dev_net(dev) != &init_net)
1474        return NOTIFY_DONE;
1475
1476    setup_all_interface_entry();
1477
1478    switch (event)
1479    {
1480        case NETDEV_UP:
1481            if (ppp_is_multilink(dev) == 0) {
1482                /* not doing multilink: send it down the first channel */
1483			channel_count = ppp_hold_channels(dev, ppp_chan, 1);
1484			if (channel_count != 1)
1485				return NOTIFY_DONE;
1486
1487			channel_protocol = ppp_channel_get_protocol(ppp_chan[0]);
1488			if (channel_protocol == PX_PROTO_OE)
1489			{
1490				if (ppp_chan[0]->private)
1491				{
1492					/* the NETDEV_UP event will be sent many times
1493					* because of ifa operation ifa->ifa_local != ifa->ifa_address
1494					* means that remote ip is really added.
1495					*/
1496					if (ifa->ifa_local == ifa->ifa_address)
1497					{
1498						ppp_release_channels(ppp_chan, 1);
1499						return NOTIFY_DONE;
1500					}
1501					sk = (struct sock *)(ppp_chan[0]->private);
1502					po = (struct pppox_sock*)sk;
1503					connection_count++;
1504					if (((NF_S17_WAN_TYPE_PPPOE == nf_athrs17_hnat_wan_type) &&
1505					(0 != nf_athrs17_hnat_ppp_id))) /* another session for IPv6 */
1506					{
1507						nf_athrs17_hnat_ppp_id2 = ntohs(po->proto.pppoe.pa.sid);
1508						memcpy(nf_athrs17_hnat_ppp_peer_mac2,
1509							po->proto.pppoe.pa.remote, ETH_ALEN);
1510					} else {
1511						nf_athrs17_hnat_wan_type = NF_S17_WAN_TYPE_PPPOE;
1512						nf_athrs17_hnat_wan_ip = ifa->ifa_local;
1513						nf_athrs17_hnat_ppp_peer_ip = ifa->ifa_address;
1514						memcpy(nf_athrs17_hnat_ppp_peer_mac,
1515							po->pppoe_pa.remote, ETH_ALEN);
1516						nf_athrs17_hnat_ppp_id = ntohs(po->pppoe_pa.sid);
1517					}
1518					ppp_release_channels(ppp_chan, 1);
1519				} else {
1520					ppp_release_channels(ppp_chan, 1);
1521					/* channel got unregistered */
1522					return NOTIFY_DONE;
1523				}
1524			} else {
1525				ppp_release_channels(ppp_chan, 1);
1526				/* channel got unregistered */
1527				return NOTIFY_DONE;
1528			}
1529		}
1530		break;
1531
1532        case NETDEV_DOWN:
1533            if (NF_S17_WAN_TYPE_PPPOE != nf_athrs17_hnat_wan_type)
1534            {
1535                return NOTIFY_DONE;
1536            }
1537            connection_count--;
1538            if (ifa->ifa_local == nf_athrs17_hnat_wan_ip)
1539            {
1540                /* PPPoE Interface really down */
1541                ipv6_droute_del_acl_rules();
1542                del_pppoetbl.session_id = nf_athrs17_hnat_ppp_id;
1543                del_pppoetbl.multi_session = 1;
1544                del_pppoetbl.uni_session = 0;
1545                del_pppoetbl.entry_id = 0;
1546                PPPOE_SESSION_TABLE_DEL(0, &del_pppoetbl);
1547		memset(&pppoetbl, 0, sizeof(pppoetbl));
1548                nf_athrs17_hnat_wan_type = NF_S17_WAN_TYPE_IP;
1549                nf_athrs17_hnat_wan_ip = 0;
1550                nf_athrs17_hnat_ppp_peer_ip = 0;
1551                nf_athrs17_hnat_ppp_id = 0;
1552                memset(&nf_athrs17_hnat_ppp_peer_mac, 0, ETH_ALEN);
1553            }
1554            else
1555            {
1556                if (0 != nf_athrs17_hnat_ppp_id2)
1557                {
1558                    del_pppoetbl.session_id = nf_athrs17_hnat_ppp_id2;
1559                    del_pppoetbl.multi_session = 1;
1560                    del_pppoetbl.uni_session = 0;
1561                    del_pppoetbl.entry_id = 0;
1562                    PPPOE_SESSION_TABLE_DEL(0, &del_pppoetbl);
1563			memset(&pppoetbl, 0, sizeof(pppoetbl));
1564                }
1565                nf_athrs17_hnat_ppp_id2 = 0;
1566                memset(&nf_athrs17_hnat_ppp_peer_mac2, 0, ETH_ALEN);
1567            }
1568            qcaswitch_hostentry_flush();
1569            break;
1570
1571        default:
1572            break;
1573    }
1574    return NOTIFY_DONE;
1575}
1576
1577/* a linux interface is configured with ipaddr, then
1578 * it becomes a L3 routing interface
1579 * add the router mac of this interface to the table
1580 */
1581/* FIXME: only hande pppoe event right now. */
1582static int qcaswitch_ip_event(struct notifier_block *this,
1583                              unsigned long event, void *ptr)
1584{
1585    struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
1586    struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev;
1587
1588    if ((dev->type == ARPHRD_PPP) && (dev->flags & IFF_POINTOPOINT))
1589    {
1590        return qcaswitch_pppoe_ip_event(this, event, ptr);
1591    }
1592
1593    return NOTIFY_DONE;
1594}
1595
1596
1597static struct notifier_block qcaswitch_ip_notifier =
1598{
1599    .notifier_call = qcaswitch_ip_event,
1600    .priority = 100,
1601};
1602#endif // ifdef AUTO_UPDATE_PPPOE_INFO
1603
1604#define HOST_AGEOUT_STATUS 1
1605void host_check_aging(void)
1606{
1607    fal_host_entry_t *host_entry_p, host_entry= {0};
1608    sw_error_t rv;
1609    int cnt = 0;
1610    unsigned long flags;
1611    fal_napt_entry_t src_napt = {0}, pub_napt = {0};
1612
1613    host_entry_p = &host_entry;
1614    host_entry_p->entry_id = FAL_NEXT_ENTRY_FIRST_ID;
1615
1616	/*check host is not neccessary, check napt is enough*/
1617	return;
1618
1619    local_irq_save(flags);
1620    while (1)
1621    {
1622        host_entry_p->status = HOST_AGEOUT_STATUS;
1623        /* FIXME: now device id is set to 0. */
1624        rv = IP_HOST_NEXT (0, FAL_IP_ENTRY_STATUS_EN, host_entry_p);
1625        // rv = IP_HOST_NEXT (0, 0, host_entry_p);
1626        if (SW_OK != rv)
1627            break;
1628        if (cnt >= ARP_ENTRY_MAX) // arp entry number
1629            break;
1630
1631        if (ARP_AGE_NEVER == host_entry_p->status)
1632            continue;
1633
1634        if ((S17_WAN_PORT == host_entry_p->port_id) &&
1635                (host_entry_p->counter_en))
1636        {
1637            if (0 != host_entry_p->packet)
1638            {
1639                // arp entry is using, update it.
1640                host_entry.status = ARP_AGE;
1641                printk("Update WAN port hostentry!\n");
1642                IP_HOST_ADD(0, host_entry_p);
1643            }
1644            else
1645            {
1646                printk("Del WAN port hostentry!\n");
1647                IP_HOST_DEL(0, FAL_IP_ENTRY_IPADDR_EN, host_entry_p);
1648            }
1649            continue;
1650        }
1651
1652        src_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
1653        memcpy(&src_napt.src_addr, &host_entry_p->ip4_addr, sizeof(fal_ip4_addr_t));
1654        pub_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID;
1655        memcpy(&pub_napt.trans_addr, &host_entry_p->ip4_addr, sizeof(fal_ip4_addr_t));
1656        if((NAPT_NEXT(0, FAL_NAT_ENTRY_SOURCE_IP_EN ,&src_napt) !=0) && \
1657                (NAPT_NEXT(0, FAL_NAT_ENTRY_PUBLIC_IP_EN ,&pub_napt) != 0))
1658        {
1659            /* Cannot find naptentry */
1660            printk("ARP id 0x%x: Cannot find NAPT entry!\n", host_entry_p->entry_id);
1661            IP_HOST_DEL(0, FAL_IP_ENTRY_IPADDR_EN, host_entry_p);
1662            continue;
1663        }
1664        // arp entry is using, update it.
1665        host_entry_p->status = ARP_AGE;
1666        IP_HOST_ADD(0, host_entry_p);
1667        printk("update entry 0x%x port %d\n", host_entry_p->entry_id, host_entry_p->port_id);
1668        cnt++;
1669    }
1670    local_irq_restore(flags);
1671}
1672
1673#ifdef CONFIG_IPV6_HWACCEL
1674#define IPV6_LEN 16
1675#define MAC_LEN 6
1676#define PROTO_ICMPV6 0x3a
1677#define NEIGHBOUR_SOL 135
1678#define NEIGHBOUR_AD 136
1679
1680struct icmpv6_option
1681{
1682    __u8 type;
1683    __u8 len;
1684    __u8 mac[MAC_LEN];
1685};
1686
1687static unsigned int ipv6_handle(unsigned   int   hooknum,
1688                                struct   sk_buff   *skb,
1689                                const   struct   net_device   *in,
1690                                const   struct   net_device   *out,
1691                                int   (*okfn)(struct   sk_buff   *))
1692{
1693	struct sk_buff *new_skb = NULL;
1694	struct nat_helper_bg_msg msg;
1695	/*unsigned long flags = 0;*/
1696
1697	if (!nf_athrs17_hnat)
1698        return NF_ACCEPT;
1699
1700	new_skb = skb_clone(skb, GFP_ATOMIC);
1701	if(new_skb) {
1702		memset(&msg, 0, sizeof(msg));
1703		msg.msg_type = NAT_HELPER_IPV6_MSG;
1704		msg.ipv6.skb = new_skb;
1705		msg.ipv6.in = in;
1706
1707		/*send msgto background task*/
1708		/*spin_lock_irqsave(&task_cb.bg_lock, flags);*/
1709		if(bg_ring_buf_write(msg))
1710			kfree_skb(new_skb);
1711		/*spin_unlock_irqrestore(&task_cb.bg_lock, flags);*/
1712	}
1713
1714	return NF_ACCEPT;
1715
1716}
1717
1718
1719#ifdef NAT_BACKGROUND_TASK
1720
1721static unsigned int ipv6_bg_handle(struct nat_helper_bg_msg *msg)
1722{
1723	struct net_device *in = msg->arp_in.in;
1724	struct sk_buff *skb = msg->arp_in.skb;
1725
1726    struct ipv6hdr *iph6 = ipv6_hdr(skb);
1727    struct icmp6hdr *icmp6 = icmp6_hdr(skb);
1728    __u8 *sip = ((__u8 *)icmp6)+sizeof(struct icmp6hdr);
1729    struct icmpv6_option *icmpv6_opt = (struct icmpv6_option *)(sip+IPV6_LEN);
1730    __u8 *sa = icmpv6_opt->mac;
1731
1732    uint32_t sport = 0, vid = 0;
1733    struct inet6_ifaddr *in_device_addr = NULL;
1734    uint8_t dev_is_lan = 0;
1735    uint8_t *smac;
1736
1737
1738    /* do not write out host table if HNAT is disabled */
1739    if (!nf_athrs17_hnat)
1740        return 0;
1741
1742    setup_all_interface_entry();
1743
1744    if(dev_check((char *)in->name, (char *)nat_wan_dev_list))
1745    {
1746        dev_is_lan = 0;
1747    }
1748    else if (dev_check((char *)in->name, (char *)nat_lan_dev_list))
1749    {
1750        dev_is_lan = 1;
1751    }
1752    else
1753    {
1754        HNAT_PRINTK("Not Support device: %s\n",  (char *)in->name);
1755        return 0;
1756    }
1757
1758    if(PROTO_ICMPV6 == iph6->nexthdr)
1759    {
1760        if(NEIGHBOUR_AD == icmp6->icmp6_type)
1761        {
1762            if (__ipv6_addr_type((struct in6_addr*)sip) & IPV6_ADDR_LINKLOCAL)
1763                return 0;
1764
1765#ifdef AP136_QCA_HEADER_EN
1766            if(arp_if_info_get((void *)(skb->head), &sport, &vid) != 0)
1767            {
1768                return 0;
1769            }
1770
1771            if ((0 == vid)||(0 == sport))
1772            {
1773                printk("Error: Null sport or vid!!\n");
1774                return 0;
1775            }
1776#else
1777            if(dev_is_lan) {
1778                 vid = NAT_LAN_DEV_VID;
1779            } else {
1780                 vid = NAT_WAN_DEV_VID;
1781            }
1782
1783            fal_fdb_entry_t entry = {0};
1784
1785            entry.fid = vid;
1786            smac = skb_mac_header(skb) + MAC_LEN;
1787            aos_mem_copy(&(entry.addr), smac, sizeof(fal_mac_addr_t));
1788
1789            if(fal_fdb_find(0, &entry) == SW_OK) {
1790                vid  = entry.fid;
1791                sport = 0;
1792                while (sport < 32) {
1793                    if(entry.port.map & (1 << sport)) {
1794                        break;
1795                    }
1796                    sport++;
1797                }
1798            } else {
1799                printk("not find the FDB entry\n");
1800            }
1801#endif
1802            if ((0 == dev_is_lan) && (S17_WAN_PORT != sport))
1803            {
1804                printk("Error: WAN port %d\n", sport);
1805                return 0;
1806            }
1807
1808            HNAT_PRINTK("ND Reply %x %x\n",icmpv6_opt->type,icmpv6_opt->len);
1809            HNAT_PRINTK("isis_v6: incoming packet, sip = %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n"
1810                        ,sip[0],sip[1],sip[2],sip[3],sip[4],sip[5],sip[6],sip[7]
1811                        ,sip[8],sip[9],sip[10],sip[11],sip[12],sip[13],sip[14],sip[15]
1812                       );
1813            HNAT_PRINTK("isis_v6: incoming packet, sa  = %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n", sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1814            HNAT_PRINTK("isis_v6: vid = %d sport = %d\n", vid, sport);
1815
1816            //add nd entry
1817            if((2 == icmpv6_opt->type) && (1 == icmpv6_opt->len))
1818            {
1819                arp_hw_add(sport, vid, sip, sa, 1);
1820            }
1821            else /* ND AD packets without option filed? Fix Me!! */
1822            {
1823		sa = skb_mac_header(skb) + MAC_LEN;
1824                HNAT_PRINTK("isis_v6 Changed sa  = %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n", sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1825                arp_hw_add(sport, vid, sip, sa, 1);
1826            }
1827
1828#if NAT_TODO /* should be ok */
1829            if ((NULL != in->ip6_ptr) && (NULL != ((struct inet6_dev *)in->ip6_ptr)->addr_list))
1830#else
1831            if (NULL != in->ip6_ptr)
1832#endif
1833            {
1834                //list_for_each_entry(in_device_addr, &(in->ip6_ptr)->addr_list, if_list);
1835                struct inet6_dev *idev = __in6_dev_get(in);
1836                list_for_each_entry(in_device_addr, &idev->addr_list, if_list) {
1837            		if (in_device_addr->scope == 0 &&
1838            		    !(in_device_addr->flags & IFA_F_TENTATIVE)) {
1839            			break;
1840            		}
1841        	    }
1842
1843                if (0 == dev_is_lan)
1844                {
1845                    /* WAN ipv6 address*/
1846                    memcpy(&wan6ip, (__u8 *)&in_device_addr->addr, sizeof(struct in6_addr));
1847                    HNAT_PRINTK("%s: ipv6 wanip %pI6\n", in->name, &wan6ip);
1848                }
1849                else
1850                {
1851                    /* LAN ipv6 address*/
1852                    memcpy(&lan6ip, (__u8 *)&in_device_addr->addr, sizeof(struct in6_addr));
1853                    HNAT_PRINTK("%s: ipv6 lanip %pI6\n", in->name, &lan6ip);
1854                }
1855            }
1856        }
1857    }
1858
1859    return 1;
1860}
1861#endif
1862
1863static struct nf_hook_ops ipv6_inhook =
1864{
1865    .hook = ipv6_handle,
1866    .owner = THIS_MODULE,
1867    .pf = PF_INET6,
1868    .hooknum = NF_INET_PRE_ROUTING,
1869    .priority = NF_IP6_PRI_CONNTRACK,
1870};
1871#endif /* CONFIG_IPV6_HWACCEL */
1872
1873#ifdef NAT_BACKGROUND_TASK
1874
1875static void nat_task_entry(struct work_struct *wq)
1876{
1877	struct nat_helper_bg_msg msg;
1878	/*unsigned long flags = 0;*/
1879	unsigned int result = 0;
1880
1881	msg = *(struct nat_helper_bg_msg *)wq;
1882
1883	/*spin_lock_irqsave(&task_cb.bg_lock, flags);*/
1884	bg_ring_buf_read(NULL);
1885	/*spin_unlock_irqrestore(&task_cb.bg_lock, flags);*/
1886
1887	HNAT_PRINTK("handle msg: %d\n", msg.msg_type);
1888
1889	if(msg.msg_type == NAT_HELPER_ARP_IN_MSG) {
1890		result =  arp_in_bg_handle(&msg);
1891		kfree_skb(msg.arp_in.skb);
1892	}
1893	#ifdef CONFIG_IPV6_HWACCEL
1894	else if(msg.msg_type == NAT_HELPER_IPV6_MSG) {
1895		result = ipv6_bg_handle(&msg);
1896		kfree_skb(msg.ipv6.skb);
1897	}
1898	#endif
1899
1900}
1901
1902void nat_helper_bg_task_init()
1903{
1904	unsigned int i = 0;
1905	struct nat_helper_bg_msg *msg;
1906	/*create the thread and alloc ring buffer*/
1907
1908	memset(&task_cb, 0, sizeof(task_cb));
1909
1910	task_cb.nat_wq = create_singlethread_workqueue("nat_wq");
1911
1912    if(!task_cb.nat_wq)
1913    {
1914        aos_printk("create nat workqueuefail\n");
1915        return;
1916    }
1917
1918	/*init lock and alloc the ring buffer*/
1919
1920	/*sema_init(&task_cb.bg_sem, 0);*/
1921	spin_lock_init(&task_cb.bg_lock);
1922
1923	task_cb.ring.num = NAT_HELPER_MSG_MAX;
1924	task_cb.ring.buf = kzalloc(NAT_HELPER_MSG_MAX * sizeof(struct nat_helper_bg_msg), GFP_ATOMIC);
1925	if(!task_cb.ring.buf) {
1926		aos_printk("ring buf alloc fail!\n");
1927		return;
1928	}
1929	msg = (struct nat_helper_bg_msg*)task_cb.ring.buf;
1930	for(i = 0; i < task_cb.ring.num; i++)
1931	{
1932		INIT_WORK(&msg[i].work, nat_task_entry);
1933	}
1934
1935	aos_printk("bg task init successfull!\n");
1936
1937}
1938
1939void nat_helper_bg_task_exit()
1940{
1941	/*stop the workqueue and release the ring buffer*/
1942	if(task_cb.nat_wq)
1943		destroy_workqueue(task_cb.nat_wq);
1944	if(task_cb.ring.buf)
1945		kfree(task_cb.ring.buf);
1946}
1947#endif
1948
1949
1950extern int napt_procfs_init(void);
1951extern void napt_procfs_exit(void);
1952extern a_uint32_t hsl_dev_wan_port_get(a_uint32_t dev_id);
1953
1954void host_helper_wan_port_init()
1955{
1956	nat_wan_port = hsl_dev_wan_port_get(0);
1957	printk("nat wan port is %d\n", nat_wan_port);
1958}
1959
1960void host_helper_init(void)
1961{
1962    int i;
1963    sw_error_t rv;
1964    a_uint32_t entry;
1965
1966    /* header len 4 with type 0xaaaa */
1967    HEADER_TYPE_SET(0, A_TRUE, 0xaaaa);
1968#ifdef ISISC
1969    /* For S17c (ISISC), it is not necessary to make all frame with header */
1970    printk("host_helper_init start\n");
1971    //PORT_TXHDR_MODE_SET(0, 0, FAL_ONLY_MANAGE_FRAME_EN);
1972    /* Fix tag disappear problem, set TO_CPU_VID_CHG_EN, 0xc00 bit1 */
1973    CPU_VID_EN_SET(0, A_TRUE);
1974    /* set RM_RTD_PPPOE_EN, 0xc00 bit0 */
1975    RTD_PPPOE_EN_SET(0, A_TRUE);
1976    /* Enable ARP ack frame as management frame. */
1977    for (i=1; i<6; i++)
1978    {
1979        PORT_ARP_ACK_STATUS_SET(0, i, A_TRUE);
1980    }
1981    MISC_ARP_CMD_SET(0, FAL_MAC_FRWRD);
1982    /* Avoid ARP response storm for HUB, now this fix only apply on PORT5 */
1983#if 0
1984    MISC_ARP_SP_NOT_FOUND_SET(0, FAL_MAC_RDT_TO_CPU);
1985    MISC_ARP_GUARD_SET(0, S17_WAN_PORT, FAL_MAC_IP_PORT_GUARD);
1986#endif
1987    /* set VLAN_TRANS_TEST register bit, to block packets from WAN port has private dip */
1988    NETISOLATE_SET(0, A_TRUE);
1989#else
1990    PORT_TXHDR_MODE_SET(0, 0, FAL_ALL_TYPE_FRAME_EN);
1991#endif
1992    CPU_PORT_STATUS_SET(0, A_TRUE);
1993    IP_ROUTE_STATUS_SET(0, A_TRUE);
1994
1995    /* CPU port with VLAN tag, others w/o VLAN */
1996    entry = 0x01111112;
1997    HSL_REG_ENTRY_SET(rv, 0, ROUTER_EG, 0, (a_uint8_t *) (&entry), sizeof (a_uint32_t));
1998
1999    napt_procfs_init();
2000    memcpy(nat_bridge_dev, nat_lan_dev_list, strlen(nat_lan_dev_list)+1);
2001
2002    nf_register_hook(&arpinhook);
2003/*hnat not upport ipv6*/
2004#if 0
2005#ifdef CONFIG_IPV6_HWACCEL
2006    aos_printk("Registering IPv6 hooks... \n");
2007    nf_register_hook(&ipv6_inhook);
2008#endif
2009#endif
2010
2011#ifdef AUTO_UPDATE_PPPOE_INFO
2012    register_inetaddr_notifier(&qcaswitch_ip_notifier);
2013#endif // ifdef AUTO_UPDATE_PPPOE_INFO
2014
2015    /* Enable ACLs to handle MLD packets */
2016    upnp_ssdp_add_acl_rules();
2017    ipv6_snooping_solicted_node_add_acl_rules();
2018    ipv6_snooping_sextuple0_group_add_acl_rules();
2019    ipv6_snooping_quintruple0_1_group_add_acl_rules();
2020
2021	REG_GET(0, 0, &nat_chip_ver, 4);
2022	napt_helper_hsl_init();
2023	host_helper_wan_port_init();
2024}
2025
2026void host_helper_exit(void)
2027{
2028    napt_procfs_exit();
2029
2030    nf_unregister_hook(&arpinhook);
2031#if 0
2032#ifdef CONFIG_IPV6_HWACCEL
2033    nf_unregister_hook(&ipv6_inhook);
2034#endif
2035#endif
2036
2037	#ifdef AUTO_UPDATE_PPPOE_INFO
2038	unregister_inetaddr_notifier(&qcaswitch_ip_notifier);
2039	#endif
2040}
2041
2042