int _netdev_open(struct net_device *pnetdev) { uint status; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - dev_open\n")); DBG_88E("+88eu_drv - drv_open, bup =%d\n", padapter->bup); if (pwrctrlpriv->ps_flag) { padapter->net_closed = false; goto netdev_open_normal_process; } if (!padapter->bup) { padapter->bDriverStopped = false; padapter->bSurpriseRemoved = false; padapter->bCardDisableWOHSM = false; status = rtw_hal_init(padapter); if (status == _FAIL) { RT_TRACE(_module_os_intfs_c_, _drv_err_, ("rtl88eu_hal_init(): Can't init h/w!\n")); goto netdev_open_error; } pr_info("MAC Address = %pM\n", pnetdev->dev_addr); status = rtw_start_drv_threads(padapter); if (status == _FAIL) { pr_info("Initialize driver software resource Failed!\n"); goto netdev_open_error; } if (init_hw_mlme_ext(padapter) == _FAIL) { pr_info("can't init mlme_ext_priv\n"); goto netdev_open_error; } if (padapter->intf_start) padapter->intf_start(padapter); rtw_proc_init_one(pnetdev); rtw_led_control(padapter, LED_CTL_NO_LINK); padapter->bup = true; } padapter->net_closed = false; _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); padapter->pwrctrlpriv.bips_processing = false; rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); if (!rtw_netif_queue_stopped(pnetdev)) rtw_netif_start_queue(pnetdev); else rtw_netif_wake_queue(pnetdev); netdev_br_init(pnetdev); netdev_open_normal_process: RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-88eu_drv - dev_open\n")); DBG_88E("-88eu_drv - drv_open, bup =%d\n", padapter->bup); return 0; netdev_open_error: padapter->bup = false; netif_carrier_off(pnetdev); rtw_netif_stop_queue(pnetdev); RT_TRACE(_module_os_intfs_c_, _drv_err_, ("-88eu_drv - dev_open, fail!\n")); DBG_88E("-88eu_drv - drv_open fail, bup =%d\n", padapter->bup); return -1; }
int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method) { unsigned short protocol; unsigned char networkAddr[MAX_NETWORK_ADDR_LEN]; unsigned int tmp; if (skb == NULL) return -1; if ((method <= NAT25_MIN) || (method >= NAT25_MAX)) return -1; protocol = be16_to_cpu(*((__be16 *)(skb->data + 2 * ETH_ALEN))); /*---------------------------------------------------*/ /* Handle IP frame */ /*---------------------------------------------------*/ if (protocol == ETH_P_IP) { struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN); if (((unsigned char*)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) { DEBUG_WARN("NAT25: malformed IP packet !\n"); return -1; } switch (method) { case NAT25_CHECK: return -1; case NAT25_INSERT: { /* some muticast with source IP is all zero, maybe other case is illegal */ /* in class A, B, C, host address is all zero or all one is illegal */ if (iph->saddr == 0) return 0; tmp = be32_to_cpu(iph->saddr); DEBUG_INFO("NAT25: Insert IP, SA=%08x, DA=%08x\n", tmp, iph->daddr); __nat25_generate_ipv4_network_addr(networkAddr, &tmp); /* record source IP address and , source mac address into db */ __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); __nat25_db_print(priv); } return 0; case NAT25_LOOKUP: { DEBUG_INFO("NAT25: Lookup IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr); tmp = be32_to_cpu(iph->daddr); __nat25_generate_ipv4_network_addr(networkAddr, &tmp); if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) { if (*((unsigned char *)&iph->daddr + 3) == 0xff) { /* L2 is unicast but L3 is broadcast, make L2 bacome broadcast */ DEBUG_INFO("NAT25: Set DA as boardcast\n"); memset(skb->data, 0xff, ETH_ALEN); } else { /* forward unknow IP packet to upper TCP/IP */ DEBUG_INFO("NAT25: Replace DA with BR's MAC\n"); if ( (*(u32 *)priv->br_mac) == 0 && (*(u16 *)(priv->br_mac+4)) == 0 ) { printk("Re-init netdev_br_init() due to br_mac==0!\n"); netdev_br_init(priv->pnetdev); } memcpy(skb->data, priv->br_mac, ETH_ALEN); } } } return 0; default: return -1; } } /*---------------------------------------------------*/ /* Handle ARP frame */ /*---------------------------------------------------*/ else if (protocol == ETH_P_ARP) { struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN); unsigned char *arp_ptr = (unsigned char *)(arp + 1); unsigned int *sender, *target; if (arp->ar_pro != __constant_htons(ETH_P_IP)) { DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", be16_to_cpu(arp->ar_pro)); return -1; } switch (method) { case NAT25_CHECK: return 0; /* skb_copy for all ARP frame */ case NAT25_INSERT: { DEBUG_INFO("NAT25: Insert ARP, MAC=%02x%02x%02x%02x%02x%02x\n", arp_ptr[0], arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]); /* change to ARP sender mac address to wlan STA address */ memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN); arp_ptr += arp->ar_hln; sender = (unsigned int *)arp_ptr; __nat25_generate_ipv4_network_addr(networkAddr, sender); __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); __nat25_db_print(priv); } return 0; case NAT25_LOOKUP: { DEBUG_INFO("NAT25: Lookup ARP\n"); arp_ptr += arp->ar_hln; sender = (unsigned int *)arp_ptr; arp_ptr += (arp->ar_hln + arp->ar_pln); target = (unsigned int *)arp_ptr; __nat25_generate_ipv4_network_addr(networkAddr, target); __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); /* change to ARP target mac address to Lookup result */ arp_ptr = (unsigned char *)(arp + 1); arp_ptr += (arp->ar_hln + arp->ar_pln); memcpy(arp_ptr, skb->data, ETH_ALEN); } return 0; default: return -1; } } /*---------------------------------------------------*/ /* Handle IPX and Apple Talk frame */ /*---------------------------------------------------*/ else if ((protocol == ETH_P_IPX) || (protocol <= ETH_FRAME_LEN)) { unsigned char ipx_header[2] = {0xFF, 0xFF}; struct ipxhdr *ipx = NULL; struct elapaarp *ea = NULL; struct ddpehdr *ddp = NULL; unsigned char *framePtr = skb->data + ETH_HLEN; if (protocol == ETH_P_IPX) { DEBUG_INFO("NAT25: Protocol=IPX (Ethernet II)\n"); ipx = (struct ipxhdr *)framePtr; } else if (protocol <= ETH_FRAME_LEN) { if (!memcmp(ipx_header, framePtr, 2)) { DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.3)\n"); ipx = (struct ipxhdr *)framePtr; } else { unsigned char ipx_8022_type = 0xE0; unsigned char snap_8022_type = 0xAA; if (*framePtr == snap_8022_type) { unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37}; /* IPX SNAP ID */ unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3}; /* Apple Talk AARP SNAP ID */ unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */ framePtr += 3; /* eliminate the 802.2 header */ if (!memcmp(ipx_snap_id, framePtr, 5)) { framePtr += 5; /* eliminate the SNAP header */ DEBUG_INFO("NAT25: Protocol=IPX (Ethernet SNAP)\n"); ipx = (struct ipxhdr *)framePtr; } else if (!memcmp(aarp_snap_id, framePtr, 5)) { framePtr += 5; /* eliminate the SNAP header */ ea = (struct elapaarp *)framePtr; } else if (!memcmp(ddp_snap_id, framePtr, 5)) { framePtr += 5; /* eliminate the SNAP header */ ddp = (struct ddpehdr *)framePtr; } else { DEBUG_WARN("NAT25: Protocol=Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0], framePtr[1], framePtr[2], framePtr[3], framePtr[4]); return -1; } } else if (*framePtr == ipx_8022_type) { framePtr += 3; /* eliminate the 802.2 header */ if (!memcmp(ipx_header, framePtr, 2)) { DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.2)\n"); ipx = (struct ipxhdr *)framePtr; } else return -1; } else return -1; } } else return -1; /* IPX */ if (ipx != NULL) { switch (method) { case NAT25_CHECK: if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { DEBUG_INFO("NAT25: Check IPX skb_copy\n"); return 0; } return -1; case NAT25_INSERT: { DEBUG_INFO("NAT25: Insert IPX, Dest=%08x,%02x%02x%02x%02x%02x%02x,%04x Source=%08x,%02x%02x%02x%02x%02x%02x,%04x\n", ipx->ipx_dest.net, ipx->ipx_dest.node[0], ipx->ipx_dest.node[1], ipx->ipx_dest.node[2], ipx->ipx_dest.node[3], ipx->ipx_dest.node[4], ipx->ipx_dest.node[5], ipx->ipx_dest.sock, ipx->ipx_source.net, ipx->ipx_source.node[0], ipx->ipx_source.node[1], ipx->ipx_source.node[2], ipx->ipx_source.node[3], ipx->ipx_source.node[4], ipx->ipx_source.node[5], ipx->ipx_source.sock); if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { DEBUG_INFO("NAT25: Use IPX Net, and Socket as network addr\n"); __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock); /* change IPX source node addr to wlan STA address */ memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN); } else { __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node); } __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); __nat25_db_print(priv); } return 0; case NAT25_LOOKUP: { if (!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) { DEBUG_INFO("NAT25: Lookup IPX, Modify Destination IPX Node addr\n"); __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock); __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); /* replace IPX destination node addr with Lookup destination MAC addr */ memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN); } else { __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node); __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); } } return 0; default: return -1; } } /* AARP */ else if (ea != NULL) { /* Sanity check fields. */ if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) { DEBUG_WARN("NAT25: Appletalk AARP Sanity check fail!\n"); return -1; } switch (method) { case NAT25_CHECK: return 0; case NAT25_INSERT: { /* change to AARP source mac address to wlan STA address */ memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN); DEBUG_INFO("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n", ea->pa_src_net, ea->pa_src_node, ea->pa_dst_net, ea->pa_dst_node); __nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node); __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); __nat25_db_print(priv); } return 0; case NAT25_LOOKUP: { DEBUG_INFO("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n", ea->pa_src_net, ea->pa_src_node, ea->pa_dst_net, ea->pa_dst_node); __nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node); __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); /* change to AARP destination mac address to Lookup result */ memcpy(ea->hw_dst, skb->data, ETH_ALEN); } return 0; default: return -1; } } /* DDP */ else if (ddp != NULL) { switch (method) { case NAT25_CHECK: return -1; case NAT25_INSERT: { DEBUG_INFO("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n", ddp->deh_snet, ddp->deh_snode, ddp->deh_dnet, ddp->deh_dnode); __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode); __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); __nat25_db_print(priv); } return 0; case NAT25_LOOKUP: { DEBUG_INFO("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n", ddp->deh_snet, ddp->deh_snode, ddp->deh_dnet, ddp->deh_dnode); __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode); __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); } return 0; default: return -1; } } return -1; } /*---------------------------------------------------*/ /* Handle PPPoE frame */ /*---------------------------------------------------*/ else if ((protocol == ETH_P_PPP_DISC) || (protocol == ETH_P_PPP_SES)) { struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); unsigned short *pMagic; switch (method) { case NAT25_CHECK: if (ph->sid == 0) return 0; return 1; case NAT25_INSERT: if (ph->sid == 0) /* Discovery phase according to tag */ { if (ph->code == PADI_CODE || ph->code == PADR_CODE) { if (priv->ethBrExtInfo.addPPPoETag) { struct pppoe_tag *tag, *pOldTag; unsigned char tag_buf[40]; int old_tag_len=0; tag = (struct pppoe_tag *)tag_buf; pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); if (pOldTag) { /* if SID existed, copy old value and delete it */ old_tag_len = ntohs(pOldTag->tag_len); if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) { DEBUG_ERR("SID tag length too long!\n"); return -1; } memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN, pOldTag->tag_data, old_tag_len); if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) { DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n"); return -1; } ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len); } tag->tag_type = PTT_RELAY_SID; tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len); /* insert the magic_code+client mac in relay tag */ pMagic = (unsigned short *)tag->tag_data; *pMagic = htons(MAGIC_CODE); memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN); /* Add relay tag */ if (__nat25_add_pppoe_tag(skb, tag) < 0) return -1; DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n", (ph->code == PADI_CODE ? "PADI" : "PADR")); } else { /* not add relay tag */ if (priv->pppoe_connection_in_progress && memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) { DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n"); return -2; } if (priv->pppoe_connection_in_progress == 0) memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN); priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; } } else return -1; } else /* session phase */ { DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid)); __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); __nat25_db_print(priv); if (!priv->ethBrExtInfo.addPPPoETag && priv->pppoe_connection_in_progress && !memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) priv->pppoe_connection_in_progress = 0; } return 0; case NAT25_LOOKUP: if (ph->code == PADO_CODE || ph->code == PADS_CODE) { if (priv->ethBrExtInfo.addPPPoETag) { struct pppoe_tag *tag; unsigned char *ptr; unsigned short tagType, tagLen; int offset=0; if ((ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID))) == NULL) { DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n"); return -1; } tag = (struct pppoe_tag *)ptr; tagType = (unsigned short)((ptr[0] << 8) + ptr[1]); tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]); if ((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN))) { DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen); return -1; } pMagic = (unsigned short *)tag->tag_data; if (ntohs(*pMagic) != MAGIC_CODE) { DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n", (ph->code == PADO_CODE ? "PADO" : "PADS")); return -1; } memcpy(skb->data, tag->tag_data+MAGIC_CODE_LEN, ETH_ALEN); if (tagLen > MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN) offset = TAG_HDR_LEN; if (skb_pull_and_merge(skb, ptr+offset, TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset) < 0) { DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n"); return -1; } ph->length = htons(ntohs(ph->length)-(TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset)); if (offset > 0) tag->tag_len = htons(tagLen-MAGIC_CODE_LEN-RTL_RELAY_TAG_LEN); DEBUG_INFO("NAT25: Lookup PPPoE, forward %s Packet from %s\n", (ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name); } else { /* not add relay tag */ if (!priv->pppoe_connection_in_progress) { DEBUG_ERR("Discard PPPoE packet due to no connection in progresss!\n"); return -1; } memcpy(skb->data, priv->pppoe_addr, ETH_ALEN); priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; } } else { if (ph->sid != 0) { DEBUG_INFO("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name); __nat25_generate_pppoe_network_addr(networkAddr, skb->data+ETH_ALEN, &(ph->sid)); __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); __nat25_db_print(priv); } else return -1; } return 0; default: return -1; } } /*---------------------------------------------------*/ /* Handle EAP frame */ /*---------------------------------------------------*/ else if (protocol == 0x888e) { switch (method) { case NAT25_CHECK: return -1; case NAT25_INSERT: return 0; case NAT25_LOOKUP: return 0; default: return -1; } } /*---------------------------------------------------*/ /* Handle C-Media proprietary frame */ /*---------------------------------------------------*/ else if ((protocol == 0xe2ae) || (protocol == 0xe2af)) { switch (method) { case NAT25_CHECK: return -1; case NAT25_INSERT: return 0; case NAT25_LOOKUP: return 0; default: return -1; } } /*---------------------------------------------------*/ /* Handle IPV6 frame */ /*---------------------------------------------------*/ else if (protocol == ETH_P_IPV6) { struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); if (sizeof(*iph) >= (skb->len - ETH_HLEN)) { DEBUG_WARN("NAT25: malformed IPv6 packet !\n"); return -1; } switch (method) { case NAT25_CHECK: if (skb->data[0] & 1) return 0; return -1; case NAT25_INSERT: { DEBUG_INFO("NAT25: Insert IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," " DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", iph->saddr.s6_addr16[0],iph->saddr.s6_addr16[1],iph->saddr.s6_addr16[2],iph->saddr.s6_addr16[3], iph->saddr.s6_addr16[4],iph->saddr.s6_addr16[5],iph->saddr.s6_addr16[6],iph->saddr.s6_addr16[7], iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3], iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]); if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); __nat25_db_print(priv); if (iph->nexthdr == IPPROTO_ICMPV6 && skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph), skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) { struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph)); hdr->icmp6_cksum = 0; hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr, iph->payload_len, IPPROTO_ICMPV6, csum_partial((__u8 *)hdr, iph->payload_len, 0)); } } } } return 0; case NAT25_LOOKUP: DEBUG_INFO("NAT25: Lookup IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," " DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", iph->saddr.s6_addr16[0],iph->saddr.s6_addr16[1],iph->saddr.s6_addr16[2],iph->saddr.s6_addr16[3], iph->saddr.s6_addr16[4],iph->saddr.s6_addr16[5],iph->saddr.s6_addr16[6],iph->saddr.s6_addr16[7], iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3], iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]); __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr); __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); return 0; default: return -1; } } return -1; }
void netdev_br_init(struct net_device *netdev) { struct adapter *adapter = (struct adapter *)rtw_netdev_priv(netdev); rcu_read_lock(); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) if (rcu_dereference(adapter->pnetdev->rx_handler_data)) { #else if (rcu_dereference(adapter->pnetdev->br_port)) { #endif struct net_device *br_netdev; struct net *devnet = NULL; devnet = dev_net(netdev); br_netdev = dev_get_by_name(devnet, CONFIG_BR_EXT_BRNAME); if (br_netdev) { memcpy(adapter->br_mac, br_netdev->dev_addr, ETH_ALEN); dev_put(br_netdev); } else { pr_info("%s()-%d: dev_get_by_name(%s) failed!", __func__, __LINE__, CONFIG_BR_EXT_BRNAME); } } adapter->ethBrExtInfo.addPPPoETag = 1; rcu_read_unlock(); } int _netdev_open(struct net_device *pnetdev) { uint status; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - dev_open\n")); DBG_88E("+88eu_drv - drv_open, bup =%d\n", padapter->bup); if (pwrctrlpriv->ps_flag) { padapter->net_closed = false; goto netdev_open_normal_process; } if (!padapter->bup) { padapter->bDriverStopped = false; padapter->bSurpriseRemoved = false; padapter->bCardDisableWOHSM = false; status = rtw_hal_init(padapter); if (status == _FAIL) { RT_TRACE(_module_os_intfs_c_, _drv_err_, ("rtl88eu_hal_init(): Can't init h/w!\n")); goto netdev_open_error; } pr_info("MAC Address = %pM\n", pnetdev->dev_addr); status = rtw_start_drv_threads(padapter); if (status == _FAIL) { pr_info("Initialize driver software resource Failed!\n"); goto netdev_open_error; } if (init_hw_mlme_ext(padapter) == _FAIL) { pr_info("can't init mlme_ext_priv\n"); goto netdev_open_error; } if (padapter->intf_start) padapter->intf_start(padapter); rtw_proc_init_one(pnetdev); rtw_led_control(padapter, LED_CTL_NO_LINK); padapter->bup = true; } padapter->net_closed = false; _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); padapter->pwrctrlpriv.bips_processing = false; rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv); if (!rtw_netif_queue_stopped(pnetdev)) rtw_netif_start_queue(pnetdev); else rtw_netif_wake_queue(pnetdev); netdev_br_init(pnetdev); netdev_open_normal_process: RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-88eu_drv - dev_open\n")); DBG_88E("-88eu_drv - drv_open, bup =%d\n", padapter->bup); return 0; netdev_open_error: padapter->bup = false; netif_carrier_off(pnetdev); rtw_netif_stop_queue(pnetdev); RT_TRACE(_module_os_intfs_c_, _drv_err_, ("-88eu_drv - dev_open, fail!\n")); DBG_88E("-88eu_drv - drv_open fail, bup =%d\n", padapter->bup); return -1; }