Exemplo n.º 1
0
/*
========================================================================
Routine Description:
	Forward the received packet.

Arguments:
	pPacket			- the received packet

Return Value:
	None

Note:
========================================================================
*/
UINT32 BG_FTPH_PacketFromApHandle(
	IN		PNDIS_PACKET	pPacket)
{
	struct net_device	*pNetDev;
	struct sk_buff		*pRxPkt;
	struct net_bridge_fdb_entry *pSrcFdbEntry, *pDstFdbEntry;


	/* init */
	pRxPkt = RTPKT_TO_OSPKT(pPacket);
	pNetDev = pRxPkt->dev;

	/* if pNetDev is promisc mode ??? */
	DBGPRINT(RT_DEBUG_INFO, ("ft bg> BG_FTPH_PacketFromApHandle\n"));

	if (pNetDev != NULL)
	{
		if (pNetDev->br_port != NULL)
		{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
			pDstFdbEntry = br_fdb_get_hook(pNetDev->br_port->br, pRxPkt->data);
			pSrcFdbEntry = br_fdb_get_hook(pNetDev->br_port->br, pRxPkt->data + 6);
#else
			/* br_fdb_get is not exported symbol, need exported in net/bridge/br.c */
			pDstFdbEntry = br_fdb_get(pNetDev->br_port->br, pRxPkt->data);
			pSrcFdbEntry = br_fdb_get(pNetDev->br_port->br, pRxPkt->data + 6);
#endif

			/* check destination address in bridge forwarding table */
			if ((pSrcFdbEntry == NULL) ||
				(pDstFdbEntry == NULL) ||
				(pDstFdbEntry->is_local) ||
				(pDstFdbEntry->dst == NULL) ||
				(pDstFdbEntry->dst->dev == NULL) ||
				(pDstFdbEntry->dst->dev == pNetDev) ||
				(pNetDev->br_port->state != BR_STATE_FORWARDING) ||
				((pSrcFdbEntry->dst != NULL) &&
					(pSrcFdbEntry->dst->dev != NULL) &&
					(pSrcFdbEntry->dst->dev != pNetDev)))
			{

				goto LabelPassToUpperLayer;
			} /* End of if */

			if ((!pDstFdbEntry->is_local) &&
				(pDstFdbEntry->dst != NULL) &&
				(pDstFdbEntry->dst->dev != NULL))
			{
				pRxPkt->dev = pDstFdbEntry->dst->dev;
				pDstFdbEntry->dst->dev->hard_start_xmit(pRxPkt, pDstFdbEntry->dst->dev);
				return 0;
			} /* End of if */
		} /* End of if */
	} /* End of if */

LabelPassToUpperLayer:
	DBGPRINT(RT_DEBUG_TRACE, ("ft bg> Pass packet to bridge module.\n"));
	return 1;
} /* End of BG_FTPH_PacketFromApHandle */
Exemplo n.º 2
0
static int __br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net_bridge *br;
	unsigned char *dest;
	struct net_bridge_fdb_entry *dst;

	br = dev->priv;
	br->statistics.tx_packets++;
	br->statistics.tx_bytes += skb->len;

	dest = skb->mac.raw = skb->data;
	skb_pull(skb, ETH_HLEN);

	if (dest[0] & 1) {
		br_flood_deliver(br, skb, 0);
		return 0;
	}

	if ((dst = br_fdb_get(br, dest)) != NULL) {
		br_deliver(dst->dst, skb);
		br_fdb_put(dst);
		return 0;
	}

	br_flood_deliver(br, skb, 0);
	return 0;
}
static int br_handle_frame_finish(struct sk_buff *skb)
{
	struct net_bridge *br;
	unsigned char *dest;
	struct net_bridge_fdb_entry *dst;
	struct net_bridge_port *p;
	int passedup;

	dest = skb->mac.ethernet->h_dest;

	p = skb->dev->br_port;
	if (p == NULL)
		goto err_nolock;

	br = p->br;
	read_lock(&br->lock);
	if (skb->dev->br_port == NULL)
		goto err;

	passedup = 0;
	if (br->dev.flags & IFF_PROMISC) {
		struct sk_buff *skb2;

		skb2 = skb_clone(skb, GFP_ATOMIC);
		if (skb2 != NULL) {
			passedup = 1;
			br_pass_frame_up(br, skb2);
		}
	}

	if (dest[0] & 1) {
		br_flood_forward(br, skb, !passedup);
		if (!passedup)
			br_pass_frame_up(br, skb);
		goto out;
	}

	dst = br_fdb_get(br, dest);
	if (dst != NULL && dst->is_local) {
		if (!passedup)
			br_pass_frame_up(br, skb);
		else
			kfree_skb(skb);
		br_fdb_put(dst);
		goto out;
	}

	if (dst != NULL) {
		br_forward(dst->dst, skb);
		br_fdb_put(dst);
		goto out;
	}

	br_flood_forward(br, skb, 0);

out:
	read_unlock(&br->lock);
	return 0;

err:
	read_unlock(&br->lock);
err_nolock:
	kfree_skb(skb);
	return 0;
}
Exemplo n.º 4
0
static int __br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net_bridge *br;
	unsigned char *dest;
	struct net_bridge_fdb_entry *dst;
#ifdef IGMP_SNOOPING
	struct iphdr *iph;
	unsigned int ipaddr=0;
	unsigned char proto=0;
	//unsigned char reserved=0;
	extern int igmpsnoopenabled;

	iph = skb->nh.iph;
	ipaddr = iph->daddr;
	proto = iph->protocol;
	//Brad disable 20080619	
	//	if ((ipaddr&0xF0FFFF00) == 0xE0000000)
	//		reserved=1;
		
#endif

	br = dev->priv;
	br->statistics.tx_packets++;
	br->statistics.tx_bytes += skb->len;

	dest = skb->mac.raw = skb->data;
	skb_pull(skb, ETH_HLEN);

	if (dest[0] & 1) {
#ifdef IGMP_SNOOPING
		if(igmpsnoopenabled && 
			(MULTICAST_MAC(dest) || IPV6_MULTICAST_MAC(dest))&& 
			(proto != IPPROTO_IGMP) && (ipaddr != 0xEFFFFFFA) 
			//&& (reserved == 0)
			) {
			if ((dst = br_fdb_get(br, dest)) != NULL) {
				br_multicast_deliver(br, dst, skb, 0);
				br_fdb_put(dst);
			}
			else {
				br_flood_deliver(br, skb, 0);
			}
		}
		else { // broadcast
			br_flood_deliver(br, skb, 0);
		}
		return 0;
#else
		br_flood_deliver(br, skb, 0);
		return 0;
#endif
	}

	if ((dst = br_fdb_get(br, dest)) != NULL) {
#ifdef NAT_SPEEDUP
		if (skb->dst && skb->dst->hh && skb->dst->hh->fdb_cache==NULL) {
			skb->dst->hh->fdb_cache = (void*)dst;
			dst->hh_ptr = skb->dst->hh;
		}
#endif
		br_deliver(dst->dst, skb);
		br_fdb_put(dst);
		return 0;
	}

	br_flood_deliver(br, skb, 0);
	return 0;
}