Exemplo n.º 1
0
/*
 *	This function assumes it is being called from dev_queue_xmit()
 *	and that skb is filled properly by that function.
 */
static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct ip_tunnel *tunnel = netdev_priv(dev);
	const struct iphdr *tiph;
	struct iphdr fiph;

	if (unlikely(skb->protocol != htons(ETH_P_IP)))
		goto tx_error;

	skb = iptunnel_handle_offloads(skb, false, SKB_GSO_IPIP);
	if (IS_ERR(skb))
		goto out;

	if (ipip_tunnel_is_fan(tunnel)) {
		if (ipip_build_fan_iphdr(tunnel, skb, &fiph))
			goto tx_error;
		tiph = &fiph;
	} else {
		tiph = &tunnel->parms.iph;
	}

	skb_set_inner_ipproto(skb, IPPROTO_IPIP);

	ip_tunnel_xmit(skb, dev, tiph, tiph->protocol);
	return NETDEV_TX_OK;

tx_error:
	kfree_skb(skb);
out:
	dev->stats.tx_errors++;
	return NETDEV_TX_OK;
}
Exemplo n.º 2
0
/*
 *	This function assumes it is being called from dev_queue_xmit()
 *	and that skb is filled properly by that function.
 */
static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb,
				    struct net_device *dev)
{
	struct ip_tunnel *tunnel = netdev_priv(dev);
	const struct iphdr  *tiph = &tunnel->parms.iph;
	u8 ipproto;

	switch (skb->protocol) {
	case htons(ETH_P_IP):
		ipproto = IPPROTO_IPIP;
		break;
#if IS_ENABLED(CONFIG_MPLS)
	case htons(ETH_P_MPLS_UC):
		ipproto = IPPROTO_MPLS;
		break;
#endif
	default:
		goto tx_error;
	}

	if (tiph->protocol != ipproto && tiph->protocol != 0)
		goto tx_error;

	if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4))
		goto tx_error;

	skb_set_inner_ipproto(skb, ipproto);

	if (tunnel->collect_md)
		ip_md_tunnel_xmit(skb, dev, ipproto);
	else
		ip_tunnel_xmit(skb, dev, tiph, ipproto);
	return NETDEV_TX_OK;

tx_error:
	kfree_skb(skb);

	dev->stats.tx_errors++;
	return NETDEV_TX_OK;
}
Exemplo n.º 3
0
Arquivo: ipip.c Projeto: upa/madcap
/*
 *	This function assumes it is being called from dev_queue_xmit()
 *	and that skb is filled properly by that function.
 */
static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct ip_tunnel *tunnel = netdev_priv(dev);
	const struct iphdr  *tiph = &tunnel->parms.iph;
	struct net_device *mcdev;	/* madcap device */

#ifdef OVBENCH
	if (SKB_OVBENCH (skb)) {
		skb->ipip_tunnel_xmit_in = rdtsc ();
	}
#endif

	if (unlikely(skb->protocol != htons(ETH_P_IP)))
		goto tx_error;

	skb = iptunnel_handle_offloads(skb, false, SKB_GSO_IPIP);
	if (IS_ERR(skb))
		goto out;

	if (madcap_enable) {
		mcdev = __dev_get_by_index (dev_net (dev), tunnel->parms.link);
		if (mcdev && get_madcap_ops (mcdev)) {
			madcap_queue_xmit (skb, mcdev);
			return NETDEV_TX_OK;
		}
	}

	skb_set_inner_ipproto(skb, IPPROTO_IPIP);

	ip_tunnel_xmit(skb, dev, tiph, tiph->protocol);
	return NETDEV_TX_OK;

tx_error:
	kfree_skb(skb);
out:
	dev->stats.tx_errors++;
	return NETDEV_TX_OK;
}