static int32 _rtl865x_addNxtHop(uint32 attr, void *ref_ptr, rtl865x_netif_local_t *netif, uint32 nexthop,uint32 srcIp) { int entryIdx; rtl865x_nextHopEntry_t *entry = NULL, *entry1 = NULL; rtl865x_route_t *rt_t = NULL; /* * NOTE: * parameter description: * (1) attr: why need to add the nexthop entry? NEXTHOP_L3 or NEXTHOP_DEFREDIRECT_ACL? * (2) ref_ptr: when attr = NEXTHOP_L3, ref_ptr point to a route structure, * attr = NEXTHOP_DEFREDIRECT_ACL, ref_ptr = NULL, * attr = others, ref_ptr = NULL * (3) netif: destination network interface * (4) nexthop: * a) netif->if_type == IF_ETHER, nexthop = nexthop ip address, * b) netif->if_type == session based type, nexthop = session Id, * * following case should be NOTED now: * (1) ETHERNET type network interface: * a) If nexthop != NULL , it means the entry is added for: * nexthop ip&mac information, nextHop = arp entry of nexthop ip address. * b) If nexthop == 0, use default route's nexthop or nexthop TOCPU * * (2) PPPoE/PPTP/L2TP type network interface: * The "nexthop" will explicitly specify the PPPoE session (PPTP/L2TP session). */ if(netif == NULL) return RTL_EINVALIDINPUT; /* Allocate an empty entry for new one */ /*Note: all nexthop entry referenced by L3 must be 2 entries aligned(reference l3 Datasheet)*/ for(entryIdx = 0; entryIdx < NXTHOP_ENTRY_NUM; entryIdx++) { if(rtl865x_nxtHopTable[entryIdx].valid == 0) { switch(attr) { case NEXTHOP_L3: if( entryIdx%2 == 0 && (entryIdx + 1) < NXTHOP_ENTRY_NUM && rtl865x_nxtHopTable[entryIdx+1].valid == 0) { entry = &rtl865x_nxtHopTable[entryIdx]; goto found; } break; case NEXTHOP_DEFREDIRECT_ACL: entry = &rtl865x_nxtHopTable[entryIdx]; goto found; break; default: printk("attr(%d) is not support.....\n",attr); break; } } } /*if not found proper nextHop entry, return*/ entry = NULL; found: if(entry == NULL) return RTL_ENOFREEBUFFER; entry->valid = 1; entry->dstNetif = netif; entry->entryIndex = entryIdx; entry->nextHopType = netif->if_type; entry->srcIp = srcIp; entry->refCnt = 1; entry->flag = attr; switch(netif->if_type) { case IF_ETHER: entry->nexthop = nexthop; break; case IF_PPPOE: case IF_PPTP: case IF_L2TP: /*nexthop is sessionId*/ entry->nexthop = nexthop; break; } if(attr == NEXTHOP_L3) { entry1 = &rtl865x_nxtHopTable[entryIdx+1]; memcpy(entry1,entry,sizeof(rtl865x_nextHopEntry_t)); entry1->entryIndex = entryIdx + 1; _rtl865x_arrangeNxtHop(entryIdx, 2); /*entry1 used netif,update reference netif*/ rtl865x_referNetif(netif->name); /*entry1 used pppoe!, update reference pppoe*/ if((entry1->nextHopType == IF_PPPOE) || (entry1->nextHopType == IF_PPTP) || (entry1->nextHopType == IF_L2TP) ){ #if LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0) _rtl865x_referPpp(nexthop); #else rtl865x_referPpp(nexthop); #endif } /*FIXME_hyking:lazy, update the route information right here....*/ rt_t = (rtl865x_route_t *)ref_ptr; rt_t ->un.nxthop.nxtHopSta = entryIdx; rt_t ->un.nxthop.nxtHopEnd = entryIdx + 1; } else _rtl865x_arrangeNxtHop(entryIdx, 1); /*update reference dstnetif&pppoe arp?*/ rtl865x_referNetif(netif->name); if((entry->nextHopType == IF_PPPOE) || (entry->nextHopType == IF_PPTP) || (entry->nextHopType == IF_L2TP) ){ #if LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0) _rtl865x_referPpp(nexthop); #else rtl865x_referPpp(nexthop); #endif } return SUCCESS; }
static int32 _rtl865x_addPpp(uint8 *ifname, ether_addr_t *mac, uint32 sessionId, int32 type) { int i; rtl865x_netif_local_t *netif; rtl865x_ppp_t *entry = NULL; rtl865x_tblAsicDrv_pppoeParam_t asicPpp; rtl865x_tblAsicDrv_l2Param_t fdbEntry; rtl865x_filterDbTableEntry_t l2temp_entry; uint32 fid,column; int32 retval; uint32 fdb_type[]={ FDB_STATIC, FDB_DYNAMIC }; /*printk("%s(%d): ifname(%s),mac(%02x:%02x:%02x:%02x:%02x:%02x),sid(%d),type(%d)",__FUNCTION__,__LINE__,ifname, mac->octet[0],mac->octet[1],mac->octet[2],mac->octet[3],mac->octet[4],mac->octet[5], sessionId,type);*/ /*duplicate check*/ for(i = 0; i < PPP_NUMBER; i++) { if(rtl865x_pppTable[i].valid && rtl865x_pppTable[i].sessionId == sessionId) return RTL_EENTRYALREADYEXIST; } netif = _rtl865x_getSWNetifByName(ifname); if(netif == NULL) return RTL_ENETIFINVALID; if(netif->if_type != IF_PPPOE) return RTL_ELINKTYPESHOULDBERESET; /*found a valid entry*/ for(i = 0; i < PPP_NUMBER; i++) if(rtl865x_pppTable[i].valid == 0) { entry = &rtl865x_pppTable[i]; break; } if(entry == NULL) return RTL_ENOFREEBUFFER; /*update releated information*/ entry->valid = 1; entry->netif = netif; memcpy(&entry->server_mac,mac,sizeof(ether_addr_t)); entry->sessionId = sessionId; entry->type = type; entry->refCnt = 1; /*add this ip entry to asic*/ /* Set asic */ bzero(&asicPpp, sizeof(rtl865x_tblAsicDrv_pppoeParam_t)); asicPpp.sessionId = sessionId; asicPpp.age = 300; rtl8651_setAsicPppoe(PPP_TABLE_INDEX(entry), &asicPpp); /*FIXME_hyking:reference netif & mac*/ retval = rtl865x_referNetif(netif->name); /*add fdb entry...*/ fid = 0; column = 0; retval = rtl865x_getVlanFilterDatabaseId(netif->vid,&fid); for(i = 0; i < 2; i++) { /* printk("%s:%d\n,fid(%d),mac(%02x:%02x:%02x:%02x:%02x:%02x)\n",__FUNCTION__,__LINE__,fid,mac->octet[0],mac->octet[1], mac->octet[2],mac->octet[3],mac->octet[4],mac->octet[5]); printk("%s:%d\n",__FUNCTION__,__LINE__); */ if(rtl865x_Lookup_fdb_entry(fid, mac, fdb_type[i], &column,&fdbEntry) != SUCCESS) { continue; } /*in case of layer2 auto learn, add hardware entry to layer 2 software table*/ l2temp_entry.l2type = (fdbEntry.nhFlag==0)?RTL865x_L2_TYPEI: RTL865x_L2_TYPEII; l2temp_entry.process = FDB_TYPE_FWD; l2temp_entry.memberPortMask = fdbEntry.memberPortMask; l2temp_entry.auth = fdbEntry.auth; l2temp_entry.SrcBlk = fdbEntry.srcBlk; memcpy(&(l2temp_entry.macAddr), mac, sizeof(ether_addr_t)); rtl865x_addFilterDatabaseEntryExtension(fid, &l2temp_entry); // retval = _rtl865x_addFilterDatabaseEntry((fdbEntry.nhFlag==0)?RTL865x_L2_TYPEI: RTL865x_L2_TYPEII, fid, mac, FDB_TYPE_FWD, fdbEntry.memberPortMask, fdbEntry.auth,fdbEntry.srcBlk); rtl865x_refleshHWL2Table(mac, FDB_DYNAMIC|FDB_STATIC,fid); } /*raise event??*/ rtl865x_raiseEvent(EVENT_ADD_PPP, (void*)entry); return SUCCESS; }