示例#1
0
/*
 * Description: This function is called by Netfilter when packet hits
 *              the bridge pre routing hook. All IP packets are given
 *              to EMFL for its processing.
 *
 * Input:       skb - Pointer to the packet buffer. Other parameters
 *                     are not used.
 *
 * Return:      Returns the value indicating packet can be forwarded
 *              or packet is stolen.
 */
static uint32
emf_br_pre_hook(uint32 hook, struct sk_buff *skb,
                const struct net_device *in,
                const struct net_device *out,
                int32 (*okfn)(struct sk_buff *))
{
	emf_info_t *emfi;

	EMF_INFO("Frame at BR_PRE_HOOK received from if %p %s\n",
	         skb->dev, skb->dev->name);

	/* Find the bridge that the receive interface corresponds to */
	emfi = emf_instance_find_by_ifptr(emf, skb->dev);
	if (emfi == NULL)
	{
		EMF_INFO("No EMF processing needed for unknown ports\n");
		return (NF_ACCEPT);
	}

	/* Non IP packet received from LAN port is returned back to
	 * bridge.
	 */
	if (skb->protocol != __constant_htons(ETH_P_IP))
	{
		EMF_INFO("Ignoring non IP packets from LAN ports\n");
		return (NF_ACCEPT);
	}

	EMF_DUMP_PKT(skb->data);

	return (emfc_input(emfi->emfci, skb, skb->dev,
	                   PKTDATA(NULL, skb), FALSE));
}
示例#2
0
文件: emf_linux.c 项目: gygy/asuswrt
/*
 * Description: This function is called by EMFL common code when it wants
 *              to forward the packet on to a specific port. It adds the
 *              MAC header and queues the frame to the interface.
 *
 * Input:       emfi    - EMF instance information
 *              skb     - Pointer to the packet buffer.
 *              mgrp_ip - Multicast destination address.
 *              txif    - Interface to send the frame on.
 *
 * Return:      SUCCESS or FAILURE.
 */
int32
emf_forward(emf_info_t *emfi, struct sk_buff *skb, uint32 mgrp_ip,
            struct net_device *txif, bool rt_port)
{
	struct ether_header *eh;

	EMF_DEBUG("Forwarding the frame %p on to %s\n", skb, txif->name);

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
	ASSERT(txif->br_port);
	/* Send only when the port is in forwarding state */
	if (EMF_BRPORT_STATE(txif) != BR_STATE_FORWARDING)
	{
		EMF_INFO("Dropping the frame as the port %s is not in"
		         " FORWARDING state\n", txif->name);
		kfree_skb(skb);
		return (FAILURE);
	}
	/* there is no access to the "bridge" struct from netif in 2.6.36 */
#endif
	eh = (struct ether_header *)skb_push(skb, ETH_HLEN);

	/* No need to fill the ether header fields for packets received
	 * from LAN ports.
	 */
	if (rt_port)
	{
		eh->ether_type = __constant_htons(ETH_P_IP);

		ETHER_FILL_MCAST_ADDR_FROM_IP(eh->ether_dhost, mgrp_ip);

		memcpy(eh->ether_shost, skb->dev->dev_addr, skb->dev->addr_len);
	}

	EMF_INFO("Group Addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
	         eh->ether_dhost[0], eh->ether_dhost[1], eh->ether_dhost[2],
	         eh->ether_dhost[3], eh->ether_dhost[4], eh->ether_dhost[5]);

	/* Send buffer as if it is delivered by bridge */

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
	skb_reset_mac_header(skb);
#else
	skb->mac.raw = skb->data;
#endif

	skb->dev = txif;
	dev_queue_xmit(skb);

	return (SUCCESS);
}
示例#3
0
/*
 * Description: This function is called by Netfilter when packet hits
 *              the ip post routing hook. The packet is sent to EMFL
 *              only when it is going on to bridge port.
 *
 * Input:       skb - Pointer to the packet buffer. Other parameters
 *                     are not used.
 *
 * Return:      Returns the value indicating packet can be forwarded
 *              or packet is stolen.
 */
static uint32
emf_ip_post_hook(uint32 hook, struct sk_buff *skb,
                 const struct net_device *in,
                 const struct net_device *out,
                 int32 (*okfn)(struct sk_buff *))
{
	emf_info_t *emfi;

	ASSERT(skb->protocol == __constant_htons(ETH_P_IP));

	EMF_DEBUG("Frame at IP_POST_HOOK going to if %p %s\n",
	          skb->dev, skb->dev->name);

	/* Find the LAN that the bridge interface corresponds to */
	emfi = emf_instance_find_by_brptr(emf, skb->dev);
	if (emfi == NULL)
	{
		EMF_INFO("No EMF processing needed for unknown ports\n");
		return (NF_ACCEPT);
	}

	EMF_DUMP_PKT(skb->data);

	return (emfc_input(emfi->emfci, skb, skb->dev,
	                   PKTDATA(NULL, skb), TRUE));
}
示例#4
0
文件: emf_linux.c 项目: gygy/asuswrt
/*
 * Description: This function is called by Netfilter when packet hits
 *              the ip post routing hook. The packet is sent to EMFL
 *              only when it is going on to bridge port.
 *
 * Input:       pskb - Pointer to the packet buffer. Other parameters
 *                     are not used.
 *
 * Return:      Returns the value indicating packet can be forwarded
 *              or packet is stolen.
 */
static uint32
emf_ip_post_hook(
	uint32 hook,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
	struct sk_buff *skb,
#else
	struct sk_buff **pskb,
#endif
	const struct net_device *in,
	const struct net_device *out,
	int32 (*okfn)(struct sk_buff *))
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
	struct sk_buff **pskb = &skb;
#endif
	emf_info_t *emfi;

	ASSERT((*pskb)->protocol == __constant_htons(ETH_P_IP));

	EMF_DEBUG("Frame at IP_POST_HOOK going to if %p %s\n",
	          (*pskb)->dev, (*pskb)->dev->name);

	/* Find the LAN that the bridge interface corresponds to */
	emfi = emf_instance_find_by_brptr(emf, (*pskb)->dev);
	if (emfi == NULL)
	{
		EMF_INFO("No EMF processing needed for unknown ports\n");
		return (NF_ACCEPT);
	}

	EMF_DUMP_PKT((*pskb)->data);

	return (emfc_input(emfi->emfci, *pskb, (*pskb)->dev,
	                   PKTDATA(NULL, *pskb), TRUE));
}
示例#5
0
/*
 * Description: This function is called when the user application enables
 *              EMF on a bridge interface. It primarily allocates memory
 *              for instance data and calls the common code init function.
 *
 * Input:       emf     - EMF module global data pointer
 *              inst_id - EMF instance name
 *              br_ptr  - Bridge device pointer
 */
static emf_info_t *
emf_instance_add(emf_struct_t *emf, int8 *inst_id, struct net_device *br_ptr)
{
	emf_info_t *emfi;
	osl_t *osh;
#ifdef CONFIG_PROC_FS
	uint8 proc_name[64];
#endif /* CONFIG_PROC_FS */
	emfc_wrapper_t emfl;

	if (emf->inst_count > EMF_MAX_INST)
	{
		EMF_ERROR("Max instance limit %d exceeded\n", EMF_MAX_INST);
		return (NULL);
	}

	emf->inst_count++;

	EMF_INFO("Creating EMF instance for %s\n", inst_id);

	osh = osl_attach(NULL, PCI_BUS, FALSE);

	ASSERT(osh);

	/* Allocate os specfic EMF info object */
	emfi = MALLOC(osh, sizeof(emf_info_t));
	if (emfi == NULL)
	{
		EMF_ERROR("Out of memory allocating emf_info\n");
		osl_detach(osh);
		return (NULL);
	}

	emfi->osh = osh;

	/* Save the EMF instance identifier */
	strncpy(emfi->inst_id, inst_id, IFNAMSIZ);
	emfi->inst_id[IFNAMSIZ - 1] = 0;

	/* Save the device pointer */
	emfi->br_dev = br_ptr;

	/* Fill the linux wrapper specific functions */
	emfl.forward_fn = (forward_fn_ptr)emf_forward;
	emfl.sendup_fn = (sendup_fn_ptr)emf_sendup;
	emfl.hooks_register_fn = (hooks_register_fn_ptr)emf_hooks_register;
	emfl.hooks_unregister_fn = (hooks_unregister_fn_ptr)emf_hooks_unregister;

	/* Initialize EMFC instance */
	if ((emfi->emfci = emfc_init(inst_id, (void *)emfi, osh, &emfl)) == NULL)
	{
		EMF_ERROR("EMFC init failed\n");
		MFREE(osh, emfi, sizeof(emf_info_t));
		osl_detach(osh);
		return (NULL);
	}

	EMF_INFO("Created EMFC instance for %s\n", inst_id);

	/* Initialize the iflist head */
	emfi->iflist_head = NULL;

#ifdef CONFIG_PROC_FS
	sprintf(proc_name, "net/emf_stats_%s", inst_id);
	create_proc_read_entry(proc_name, 0, 0, emf_stats_get, emfi);
	sprintf(proc_name, "net/emfdb_%s", inst_id);
	create_proc_read_entry(proc_name, 0, 0, emf_mfdb_list, emfi);
#endif /* CONFIG_PROC_FS */

	/* Add to the global EMF instance list */
	emfi->next = emf->list_head;
	emf->list_head = emfi;

	return (emfi);
}