Example #1
0
static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
{
	struct net *net = dev_net(skb->dev);
	struct metadata_dst *tun_dst = NULL;
	struct ip_tunnel_net *itn;
	const struct iphdr *iph;
	struct ip_tunnel *tunnel;

	if (tpi->proto == htons(ETH_P_TEB))
		itn = net_generic(net, gre_tap_net_id);
	else
		itn = net_generic(net, ipgre_net_id);

	iph = ip_hdr(skb);
	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
				  iph->saddr, iph->daddr, tpi->key);

	if (tunnel) {
		skb_pop_mac_header(skb);
		if (tunnel->collect_md) {
			__be16 flags;
			__be64 tun_id;

			flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
			tun_id = key_to_tunnel_id(tpi->key);
			tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
			if (!tun_dst)
				return PACKET_REJECT;
		}

		ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
		return PACKET_RCVD;
	}
	return PACKET_REJECT;
}
Example #2
0
static int ipgre_rcv(struct sk_buff *skb)
{
	struct net *net = dev_net(skb->dev);
	struct ip_tunnel_net *itn;
	const struct iphdr *iph;
	struct ip_tunnel *tunnel;
	struct tnl_ptk_info tpi;
	int hdr_len;
	bool csum_err = false;

	if (parse_gre_header(skb, &tpi, &csum_err, &hdr_len) < 0)
		goto drop;

	if (tpi.proto == htons(ETH_P_TEB))
		itn = net_generic(net, gre_tap_net_id);
	else
		itn = net_generic(net, ipgre_net_id);

	iph = ip_hdr(skb);
	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi.flags,
				  iph->saddr, iph->daddr, tpi.key);

	if (tunnel) {
		skb_pop_mac_header(skb);
		ip_tunnel_rcv(tunnel, skb, &tpi, hdr_len, log_ecn_error);
		return 0;
	}
	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
drop:
	kfree_skb(skb);
	return 0;
}
Example #3
0
static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
{
	struct net *net = dev_net(skb->dev);
	struct metadata_dst *tun_dst = NULL;
	struct ip_tunnel_net *itn;
	const struct iphdr *iph;
	struct ip_tunnel *tunnel;

	if (tpi->proto == htons(ETH_P_TEB))
		itn = net_generic(net, gre_tap_net_id);
	else
		itn = net_generic(net, ipgre_net_id);

	iph = ip_hdr(skb);
	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
				  iph->saddr, iph->daddr, tpi->key);

	if (tunnel) {
		skb_pop_mac_header(skb);
		if (tunnel->collect_md) {
			struct ip_tunnel_info *info;

			tun_dst = metadata_dst_alloc(0, GFP_ATOMIC);
			if (!tun_dst)
				return PACKET_REJECT;

			info = &tun_dst->u.tun_info;
			info->key.ipv4_src = iph->saddr;
			info->key.ipv4_dst = iph->daddr;
			info->key.ipv4_tos = iph->tos;
			info->key.ipv4_ttl = iph->ttl;

			info->mode = IP_TUNNEL_INFO_RX;
			info->key.tun_flags = tpi->flags &
					      (TUNNEL_CSUM | TUNNEL_KEY);
			info->key.tun_id = key_to_tunnel_id(tpi->key);

			info->key.tp_src = 0;
			info->key.tp_dst = 0;
		}

		ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
		return PACKET_RCVD;
	}
	return PACKET_REJECT;
}
Example #4
0
static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
{
	struct net *net = dev_net(skb->dev);
	struct metadata_dst tun_dst;
	struct ip_tunnel_net *itn;
	const struct iphdr *iph;
	struct ip_tunnel *tunnel;

	if (tpi->proto != htons(ETH_P_TEB))
		return PACKET_REJECT;

	itn = net_generic(net, gre_tap_net_id);

	iph = ip_hdr(skb);
	tunnel = rcu_dereference(itn->collect_md_tun);
	if (tunnel) {
		__be16 flags;
		__be64 tun_id;
		int err;


		skb_pop_mac_header(skb);
		flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
		tun_id = key_to_tunnel_id(tpi->key);
		ovs_ip_tun_rx_dst(&tun_dst, skb, flags, tun_id, 0);

		skb_reset_network_header(skb);
		err = IP_ECN_decapsulate(iph, skb);
		if (unlikely(err)) {
			if (err > 1) {
				++tunnel->dev->stats.rx_frame_errors;
				++tunnel->dev->stats.rx_errors;
				return PACKET_REJECT;
			}
		}

		ovs_ip_tunnel_rcv(tunnel->dev, skb, &tun_dst);
		return PACKET_RCVD;
	}
	return PACKET_REJECT;
}
Example #5
0
static int __ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi,
		       struct ip_tunnel_net *itn, int hdr_len, bool raw_proto)
{
	struct metadata_dst *tun_dst = NULL;
	const struct iphdr *iph;
	struct ip_tunnel *tunnel;

	iph = ip_hdr(skb);
	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
				  iph->saddr, iph->daddr, tpi->key);

	if (tunnel) {
		if (__iptunnel_pull_header(skb, hdr_len, tpi->proto,
					   raw_proto, false) < 0)
			goto drop;

		if (tunnel->dev->type != ARPHRD_NONE)
			skb_pop_mac_header(skb);
		else
			skb_reset_mac_header(skb);
		if (tunnel->collect_md) {
			__be16 flags;
			__be64 tun_id;

			flags = tpi->flags & (TUNNEL_CSUM | TUNNEL_KEY);
			tun_id = key32_to_tunnel_id(tpi->key);
			tun_dst = ip_tun_rx_dst(skb, flags, tun_id, 0);
			if (!tun_dst)
				return PACKET_REJECT;
		}

		ip_tunnel_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
		return PACKET_RCVD;
	}
	return PACKET_NEXT;

drop:
	kfree_skb(skb);
	return PACKET_RCVD;
}
Example #6
0
File: ip_gre.c Project: 3null/linux
static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
{
	struct net *net = dev_net(skb->dev);
	struct ip_tunnel_net *itn;
	const struct iphdr *iph;
	struct ip_tunnel *tunnel;

	if (tpi->proto == htons(ETH_P_TEB))
		itn = net_generic(net, gre_tap_net_id);
	else
		itn = net_generic(net, ipgre_net_id);

	iph = ip_hdr(skb);
	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi->flags,
				  iph->saddr, iph->daddr, tpi->key);

	if (tunnel) {
		skb_pop_mac_header(skb);
		ip_tunnel_rcv(tunnel, skb, tpi, log_ecn_error);
		return PACKET_RCVD;
	}
	return PACKET_REJECT;
}