static void pppoev6_mac6_loop_dev(void) { #define PPPOEV6_SESSION_ID 0xfffe fal_pppoe_session_t ptbl; memset(&ptbl, 0, sizeof(fal_pppoe_session_t)); aos_printk("%s: set MAC6 as loopback device\n", __func__); ptbl.session_id = PPPOEV6_SESSION_ID; ptbl.multi_session = 1; ptbl.uni_session = 1; ptbl.entry_id = 0xe; /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */ if (isis_pppoe_session_table_add(0, &ptbl) == SW_OK) { isis_pppoe_session_id_set(0, ptbl.entry_id, ptbl.session_id); aos_printk("%s: pppoe session id: %d added into entry: %d \n", __func__, ptbl.session_id, ptbl.entry_id); } else { aos_printk("%s: failed on adding pppoe session id: %d\n", __func__, ptbl.session_id); } /* PPPoE entry 0 */ athrs17_reg_write(0x2200, PPPOEV6_SESSION_ID); aos_printk("%s: end of function... \n", __func__); }
static void _isis_acl_sw_rule_dump(char *info, isis_acl_rule_t * sw_rule) { #ifdef ISIS_ACL_DEBUG a_uint32_t flt_idx, i; aos_printk("\n%s", info); for (flt_idx = 0; flt_idx < ISIS_MAX_FILTER; flt_idx++) { aos_printk("\n%d software filter:", flt_idx); aos_printk("\nact:"); for (i = 0; i < 3; i++) { aos_printk("%08x ", sw_rule[flt_idx].filter.act[i]); } aos_printk("\nvlu:"); for (i = 0; i < 5; i++) { aos_printk("%08x ", sw_rule[flt_idx].filter.vlu[i]); } aos_printk("\nmsk:"); for (i = 0; i < 5; i++) { aos_printk("%08x ", sw_rule[flt_idx].filter.msk[i]); } aos_printk("\nctl:status[%02d] list_id[%02d] rule_id[%02d]", sw_rule[flt_idx].status, sw_rule[flt_idx].list_id, sw_rule[flt_idx].rule_id); aos_printk("\n\n"); } #else return; #endif }
/* check for pppoe session change */ static void isis_pppoe_check_for_redial(void) { if (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_IP) return; if(((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) \ || (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6)) \ && (pppoetbl.session_id != 0)) { if(pppoetbl.session_id != nf_athrs17_hnat_ppp_id) { aos_printk("%s: PPPoE session ID changed... \n", __func__); if (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOEV6) { if (isis_pppoe_session_table_del(0, &pppoetbl) != SW_OK) { aos_printk("delete old pppoe session %d entry_id %d failed.. \n", pppoetbl.session_id, pppoetbl.entry_id); return; } /* force PPPoE parser for multi- and uni-cast packets; for v1.0.7+ */ pppoetbl.session_id = nf_athrs17_hnat_ppp_id; pppoetbl.multi_session = 1; pppoetbl.uni_session = 1; pppoetbl.entry_id = 0; /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */ if (isis_pppoe_session_table_add(0, &pppoetbl) == SW_OK) { isis_pppoe_session_id_set(0, pppoetbl.entry_id, pppoetbl.session_id); printk("%s: new pppoe session id: %x, entry_id: %x\n", __func__, pppoetbl.session_id, pppoetbl.entry_id); } } else /* nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6 */ { /* reset the session Id only */ aos_printk("IPV6 PPPOE mode... \n"); pppoetbl.session_id = nf_athrs17_hnat_ppp_id; isis_pppoe_session_id_set(0, pppoetbl.entry_id, pppoetbl.session_id); printk("%s: new pppoe session id: %x, entry_id: %x\n", __func__, pppoetbl.session_id, pppoetbl.entry_id); } /* read back the WAN IP */ uint8_t buf[4]; simple_strtohex(buf, nf_athrs17_hnat_wan_ip, 4); memcpy(&wanip, buf, 4); aos_printk("Read the WAN IP back... %.8x\n", *(uint32_t *)&wanip); /* change the PPPoE ACL to ensure the packet is correctly forwarded by the HNAT engine */ pppoe_add_acl_rules(*(uint32_t *)&wanip, *(uint32_t *)&lanip, pppoe_gwid); } } }
uint32_t napt_set_default_route(fal_ip4_addr_t dst_addr, fal_ip4_addr_t src_addr) { sw_error_t rv; /* search for the next hop (s) */ if (!(get_aclrulemask() & (1 << S17_ACL_LIST_DROUTE))) { if (multi_route_indev && \ (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOE) && (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOES0)) { uint32_t next_hop = get_next_hop(dst_addr, src_addr); aos_printk("Next hop: %08x\n", next_hop); if (next_hop != 0) { fal_host_entry_t arp_entry; memset(&arp_entry, 0, sizeof(arp_entry)); arp_entry.ip4_addr = next_hop; arp_entry.flags = FAL_IP_IP4_ADDR; rv = isis_ip_host_get(0, FAL_IP_ENTRY_IPADDR_EN, &arp_entry); if (rv != SW_OK) { printk("%s: isis_ip_host_get error... (non-existed host: %08x?) \n", __func__, next_hop); /* add into the nh_ent */ wan_nh_add((u_int8_t *)&next_hop, (u_int8_t *)NULL, 0); } else { printk("%s %d\n", __FUNCTION__, __LINE__); if (wan_nh_get(next_hop) != -1) droute_add_acl_rules(*(uint32_t *)&lanip, arp_entry.entry_id); else printk("%s %d\n", __FUNCTION__, __LINE__); } } else { aos_printk("no need to set the default route... \n"); set_aclrulemask (S17_ACL_LIST_DROUTE); } } } /* end next hop (s) */ return SW_OK; }
static void _isis_acl_list_dump(a_uint32_t dev_id) { a_uint32_t i; isis_acl_list_t *sw_list; aos_printk("\ndev_id=%d list control infomation:", dev_id); for (i = 0; i < ISIS_MAX_FILTER; i++) { sw_list = &(sw_list_ent[dev_id][i]); if (ENT_USED & sw_list->status) { aos_printk ("\nlist_id=%02d list_pri=%02d rule_nr=%02d [pts_map]:0x%02x idx=%02d ", sw_list->list_id, sw_list->list_pri, sw_list->rule_nr, sw_list->bind_pts, i); } } aos_printk("\n"); }
void host_helper_init(void) { int i; sw_error_t rv; a_uint32_t entry; /* header len 4 with type 0xaaaa */ isis_header_type_set(0, A_TRUE, 0xaaaa); #ifdef ISISC /* For S17c (ISISC), it is not necessary to make all frame with header */ isis_port_txhdr_mode_set(0, 0, FAL_ONLY_MANAGE_FRAME_EN); /* Fix tag disappear problem, set TO_CPU_VID_CHG_EN, 0xc00 bit1 */ isis_cpu_vid_en_set(0, A_TRUE); /* set RM_RTD_PPPOE_EN, 0xc00 bit0 */ isis_rtd_pppoe_en_set(0, A_TRUE); /* Enable ARP ack frame as management frame. */ for (i=1; i<6; i++) { isis_port_arp_ack_status_set(0, i, A_TRUE); } isis_arp_cmd_set(0, FAL_MAC_FRWRD); /* set VLAN_TRANS_TEST register bit, to block packets from WAN port has private dip */ isis_netisolate_set(0, A_TRUE); #else isis_port_txhdr_mode_set(0, 0, FAL_ALL_TYPE_FRAME_EN); #endif isis_cpu_port_status_set(0, A_TRUE); isis_ip_route_status_set(0, A_TRUE); /* CPU port with VLAN tag, others w/o VLAN */ entry = 0x01111112; HSL_REG_ENTRY_SET(rv, 0, ROUTER_EG, 0, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); napt_procfs_init(); nf_register_hook(&arpinhook); #ifdef CONFIG_IPV6_HWACCEL aos_printk("Registering IPv6 hooks... \n"); nf_register_hook(&ipv6_inhook); #endif /* Enable ACLs to handle MLD packets */ upnp_ssdp_add_acl_rules(); ipv6_snooping_solicted_node_add_acl_rules(); ipv6_snooping_sextuple0_group_add_acl_rules(); ipv6_snooping_quintruple0_1_group_add_acl_rules(); }
static void wan_nh_add(u_int8_t *host_ip , u_int8_t *host_mac, u_int32_t id) { int i; for( i = 0 ; i < MAX_HOST ; i++ ) { if((wan_nh_ent[i].host_ip != 0) && !memcmp(&wan_nh_ent[i].host_ip, host_ip, 4)) { if (host_mac == NULL) break; if(!memcmp(&wan_nh_ent[i].host_mac, host_mac,6)) return; else break ; } if(wan_nh_ent[i].host_ip == 0) break; } if (i < MAX_HOST) { if ((wan_nh_ent[i].in_use) && (wan_nh_ent[i].in_acl)) return; memcpy(&wan_nh_ent[i].host_ip, host_ip, 4); if (host_mac != NULL) { memcpy(wan_nh_ent[i].host_mac, host_mac, 6); wan_nh_ent[i].entry_id = id; if ((wan_nh_ent[i].in_use) && !(wan_nh_ent[i].in_acl)) { droute_add_acl_rules(*(uint32_t *)&lanip, id); /* set the in_acl flag */ wan_nh_ent[i].in_acl = 1; } } else { /* set the in_use flag */ wan_nh_ent[i].in_use = 1; } aos_printk("%s: ip %08x (%d)\n" ,__func__, wan_nh_ent[i].host_ip, i); } }
static void pppoev6_mac6_stop_learning(void) { /* do not disable this port if some other registers are already filled in to prevent setting conflict */ int val = S17_P6PAD_MODE_REG_VALUE; if ( val != (1<<24)) { aos_printk("%s: MAC 6 already being used!\n", __FUNCTION__); return; } /* clear the MAC6 learning bit */ athrs17_reg_write(0x6a8, athrs17_reg_read(0x6a8) & ~(1<<20)); /* force loopback mode */ athrs17_reg_write(0x94, 0x7e); athrs17_reg_write(0xb4, 0x10); }
HSL_LOCAL sw_error_t isis_acl_rule_dump(a_uint32_t dev_id) { a_uint32_t flt_idx, i; sw_error_t rv; hw_filter_t filter; aos_printk("\nisis_acl_rule_dump:\n"); for (flt_idx = 0; flt_idx < ISIS_MAX_FILTER; flt_idx++) { aos_mem_zero(&filter, sizeof (hw_filter_t)); rv = _isis_filter_up_to_sw(dev_id, &filter, flt_idx); if (SW_OK != rv) { continue; } aos_printk("\n%d filter dump:", flt_idx); aos_printk("\nhardware content:"); aos_printk("\nact:"); for (i = 0; i < (sizeof (filter.act) / sizeof (a_uint32_t)); i++) { aos_printk("%08x ", filter.act[i]); } aos_printk("\nvlu:"); for (i = 0; i < (sizeof (filter.vlu) / sizeof (a_uint32_t)); i++) { aos_printk("%08x ", filter.vlu[i]); } aos_printk("\nmsk:"); for (i = 0; i < (sizeof (filter.msk) / sizeof (a_uint32_t)); i++) { aos_printk("%08x ", filter.msk[i]); } aos_printk("\nsoftware content:"); aos_printk("\nact:"); for (i = 0; i < (sizeof (filter.act) / sizeof (a_uint32_t)); i++) { aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.act[i]); } aos_printk("\nvlu:"); for (i = 0; i < (sizeof (filter.vlu) / sizeof (a_uint32_t)); i++) { aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.vlu[i]); } aos_printk("\nmsk:"); for (i = 0; i < (sizeof (filter.msk) / sizeof (a_uint32_t)); i++) { aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.msk[i]); } aos_printk("\nctl:status[%02d] list_id[%02d] rule_id[%02d]", sw_rule_ent[dev_id][flt_idx].status, sw_rule_ent[dev_id][flt_idx].list_id, sw_rule_ent[dev_id][flt_idx].rule_id); aos_printk("\n\n"); } return SW_OK; }
static unsigned int arp_in(unsigned int hook, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn) (struct sk_buff *)) { struct arphdr *arp = NULL; uint8_t *sip, *dip, *smac, *dmac; uint8_t dev_is_lan = 0; uint32_t sport = 0, vid = 0; #ifdef ISIS uint32_t lan_netmask = 0; a_bool_t prvbasemode = 1; #endif a_int32_t arp_entry_id = -1; /* check for PPPoE redial here, to reduce overheads */ isis_pppoe_check_for_redial(); /* do not write out host table if HNAT is disabled */ if (!nf_athrs17_hnat) return NF_ACCEPT; setup_all_interface_entry(); if(dev_check((char *)in->name, (char *)nat_wan_dev_list)) { } else if (dev_check((char *)in->name, (char *)nat_bridge_dev)) { dev_is_lan = 1; } else { printk("Not Support device: %s\n", nat_bridge_dev); return NF_ACCEPT; } if(!arp_is_reply(skb)) { return NF_ACCEPT; } if(arp_if_info_get((void *)(skb->head), &sport, &vid) != 0) { return NF_ACCEPT; } arp = arp_hdr(skb); smac = ((uint8_t *) arp) + ARP_HEADER_LEN; sip = smac + MAC_LEN; dmac = sip + IP_LEN; dip = dmac + MAC_LEN; arp_entry_id = arp_hw_add(sport, vid, sip, smac, 0); if(arp_entry_id < 0) { return NF_ACCEPT; } if (0 == dev_is_lan) { memcpy(&wanip, dip, 4); #ifdef MULTIROUTE_WR wan_nh_add(sip, smac, arp_entry_id); #endif } if(dev_is_lan && nat_hw_prv_base_can_update()) { nat_hw_flush(); nat_hw_prv_base_set(*((uint32_t*)dip)); nat_hw_prv_base_update_disable(); memcpy(&lanip, dip, 4); /* copy Lan port IP. */ #ifndef ISISC lan_netmask = get_netmask_from_netdevice(in); redirect_internal_ip_packets_to_cpu_on_wan_add_acl_rules(*(uint32_t *)&lanip, lan_netmask); #endif #ifdef MULTIROUTE_WR multi_route_indev = in; #endif } if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) || (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6)) { add_pppoe_host_entry(sport, arp_entry_id); } #ifdef ISIS /* check for SIP and DIP range */ if ((lanip[0] != 0) && (wanip[0] != 0)) { if (isis_nat_prv_addr_mode_get(0, &prvbasemode) != SW_OK) { aos_printk("Private IP base mode check failed: %d\n", prvbasemode); } if (!prvbasemode) /* mode 0 */ { if ((lanip[0] == wanip[0]) && (lanip[1] == wanip[1])) { if ((lanip[2] & 0xf0) == (wanip[2] & 0xf0)) { if (get_aclrulemask()& (1 << S17_ACL_LIST_IPCONF)) return NF_ACCEPT; aos_printk("LAN IP and WAN IP conflict... \n"); /* set h/w acl to filter out this case */ #ifdef MULTIROUTE_WR // if ( (wan_nh_ent[0].host_ip != 0) && (wan_nh_ent[0].entry_id != 0)) if ( (wan_nh_ent[0].host_ip != 0)) ip_conflict_add_acl_rules(*(uint32_t *)&wanip, *(uint32_t *)&lanip, wan_nh_ent[0].entry_id); #endif return NF_ACCEPT; } } } else /* mode 1*/ { ;; /* do nothing */ } } #endif /* ifdef ISIS */ return NF_ACCEPT; }
static int add_pppoe_host_entry(uint32_t sport, a_int32_t arp_entry_id) { a_bool_t ena; int rv = SW_OK; // int wport = 0xff; if (0xffff == wan_fid) { printk("%s: Cannot get WAN vid!\n", __FUNCTION__); return SW_FAIL; } aos_printk("Wan type: PPPoE, session: %d\n", nf_athrs17_hnat_ppp_id); aos_printk("Peer MAC: %s Peer IP: %s\n", nf_athrs17_hnat_ppp_peer_mac, nf_athrs17_hnat_ppp_peer_ip); if (isis_pppoe_status_get(0, &ena) != SW_OK) { aos_printk("Cannot get the PPPoE mode\n"); ena = 0; } if (!ena) { if (isis_pppoe_status_set(0, A_TRUE) != SW_OK) aos_printk("Cannot enable the PPPoE mode\n"); aos_printk("PPPoE enable mode: %d\n", ena); pppoetbl.session_id = nf_athrs17_hnat_ppp_id; pppoetbl.multi_session = 1; pppoetbl.uni_session = 1; pppoetbl.entry_id = 0; /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */ rv = isis_pppoe_session_table_add(0, &pppoetbl); if (rv == SW_OK) { uint8_t mbuf[6], ibuf[4]; a_int32_t a_entry_id = -1; isis_pppoe_session_id_set(0, pppoetbl.entry_id, pppoetbl.session_id); aos_printk("pppoe session: %d, entry_id: %d\n", pppoetbl.session_id, pppoetbl.entry_id); /* create the peer host ARP entry */ simple_strtohex(ibuf, nf_athrs17_hnat_ppp_peer_ip, 4); simple_strtohex(mbuf, nf_athrs17_hnat_ppp_peer_mac, 6); a_entry_id = arp_hw_add(S17_WAN_PORT, wan_fid, ibuf, mbuf, 0); if (a_entry_id >= 0) /* hostentry creation okay */ { aos_printk("(1)Bind PPPoE session ID: %d, entry_id: %d to host entry: %d\n", \ pppoetbl.session_id, pppoetbl.entry_id, a_entry_id); rv = isis_ip_host_pppoe_bind(0, a_entry_id, pppoetbl.entry_id, A_TRUE); if ( rv != SW_OK) { aos_printk("isis_ip_host_pppoe_bind failed (entry: %d, rv: %d)... \n", a_entry_id, rv); } aos_printk("adding ACLs \n"); pppoe_gwid = a_entry_id; pppoe_add_acl_rules(*(uint32_t *)&wanip, *(uint32_t *)&lanip, a_entry_id); aos_printk("ACL creation okay... \n"); } } else { aos_printk("PPPoE session add failed.. (id: %d)\n", pppoetbl.session_id); aos_printk("rv: %d\n", rv); } #ifdef ISIS if (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6) { aos_printk("IPV6 PPPOE mode... (share the same ID with IPV4's)\n"); pppoev6_mac6_loop_dev(); pppoev6_remove_parser(pppoetbl.entry_id); /* bind the first LAN host to the pseudo PPPoE ID */ rv = isis_ip_host_pppoe_bind(0, arp_entry_id, 0, A_TRUE); if ( rv != SW_OK) { aos_printk("isis_ip_host_pppoe_bind failed (entry: %d, rv: %d)... \n", arp_entry_id, rv); } } #endif } else /* ena */ { #ifdef ISIS if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6) && (sport != S17_WAN_PORT)&& (arp_entry_id != 0)) { aos_printk("IPV6 PPPoE mode\n"); /* bind LAN hosts to the pseudo PPPoE ID */ rv = isis_ip_host_pppoe_bind(0, arp_entry_id, 0, A_TRUE); if ( rv != SW_OK) { aos_printk("isis_ip_host_pppoe_bind failed (entry: %d, rv: %d)... \n", arp_entry_id, rv); } } #endif } return SW_OK; }
static void pppoev6_remove_parser(uint32_t entry_id) { aos_printk("%s: clear entry id: %d\n", __func__, entry_id); /* clear the session id in the PPPoE parser engine */ athrs17_reg_write(PPPOE_SESSION_OFFSET + PPPOE_SESSION_E_OFFSET * entry_id, 0); }
sw_error_t hsl_dev_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) { sw_error_t rv = SW_OK; /* debug, jhung */ aos_printk("hsl_dev_init... "); if (SW_MAX_NR_DEV <= dev_id) { return SW_BAD_PARAM; } aos_mem_set(&dev_table[dev_id], 0, sizeof (hsl_dev_t)); SW_RTN_ON_ERROR(sd_init(dev_id,cfg)); #ifdef UK_IF SW_RTN_ON_ERROR(sw_uk_init(cfg->nl_prot)); #endif #if defined API_LOCK SW_RTN_ON_ERROR(hsl_api_lock_init()); #endif rv = SW_INIT_ERROR; switch (cfg->chip_type) { case CHIP_ATHENA: #if defined ATHENA rv = athena_init(dev_id, cfg); #endif break; case CHIP_GARUDA: #if defined GARUDA rv = garuda_init(dev_id, cfg); #endif break; case CHIP_SHIVA: #if defined SHIVA rv = shiva_init(dev_id, cfg); #endif break; case CHIP_HORUS: #if defined HORUS rv = horus_init(dev_id, cfg); #endif break; case CHIP_ISIS: #if defined ISIS rv = isis_init(dev_id, cfg); #endif break; case CHIP_UNSPECIFIED: #if defined ATHENA rv = athena_init(dev_id, cfg); #elif defined GARUDA rv = garuda_init(dev_id, cfg); #elif defined SHIVA rv = shiva_init(dev_id, cfg); #elif defined HORUS rv = horus_init(dev_id, cfg); #elif defined ISIS rv = isis_init(dev_id, cfg); #endif break; default: return SW_BAD_PARAM; } SW_RTN_ON_ERROR(rv); if (NULL == dev_ssdk_cfg[dev_id]) { dev_ssdk_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); } if (NULL == dev_ssdk_cfg[dev_id]) { return SW_OUT_OF_MEM; } aos_mem_copy(dev_ssdk_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); return rv; }