Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 75c65772 authored by Maxim Mikityanskiy's avatar Maxim Mikityanskiy Committed by David S. Miller
Browse files

net/packet: Ask driver for protocol if not provided by user



If a socket was created with socket(AF_PACKET, SOCK_RAW, 0), the
protocol number is unavailable. Try to ask the driver to extract it from
the L2 header in order for skb_try_probe_transport_header to succeed.

Signed-off-by: default avatarMaxim Mikityanskiy <maximmi@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ace53b2e
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -1850,6 +1850,15 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,
	return 0;
}

static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
{
	if (!skb->protocol && sock->type == SOCK_RAW) {
		skb_reset_mac_header(skb);
		skb->protocol = dev_parse_header_protocol(skb);
	}

	skb_probe_transport_header(skb);
}

/*
 *	Output a raw packet to a device layer. This bypasses all the other
@@ -1970,7 +1979,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg,
	if (unlikely(extra_len == 4))
		skb->no_fcs = 1;

	skb_probe_transport_header(skb);
	packet_parse_headers(skb, sock);

	dev_queue_xmit(skb);
	rcu_read_unlock();
@@ -2519,7 +2528,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
		len = ((to_write > len_max) ? len_max : to_write);
	}

	skb_probe_transport_header(skb);
	packet_parse_headers(skb, sock);

	return tp_len;
}
@@ -2925,7 +2934,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
		virtio_net_hdr_set_proto(skb, &vnet_hdr);
	}

	skb_probe_transport_header(skb);
	packet_parse_headers(skb, sock);

	if (unlikely(extra_len == 4))
		skb->no_fcs = 1;