Beispiel #1
0
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;
	
}