aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-06-26 18:15:43 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2020-06-26 18:18:41 -0600
commit73b20c384a8bc498c6b8950672003410ed6016da (patch)
tree77e988112fb56a173013a37c21755c18d7a6be99
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net (diff)
downloadwireguard-linux-jd/header-ops.tar.xz
wireguard-linux-jd/header-ops.zip
wireguard: device: implement header_ops->parse_protocol for AF_PACKETjd/header-ops
We don't want to handle skbs without their protocol set, which means for AF_PACKET injection, we need to support its call chain of: packet_sendmsg -> packet_snd -> packet_parse_headers -> dev_parse_header_protocol -> parse_protocol Without a valid parse_protocol, this returns zero, and wireguard rightfully rejects the skb. Fortunately, we already have a parse_protocol function that matches the signature of what header_ops wants, so we set dev->header_ops at creation time, and AF_PACKET now works fine. Reported-by: Hans Wippel <ndev@hwipl.net> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--drivers/net/wireguard/device.c3
-rw-r--r--drivers/net/wireguard/queueing.h2
2 files changed, 4 insertions, 1 deletions
diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c
index a8f151b1b5fa..8d030c6e37ff 100644
--- a/drivers/net/wireguard/device.c
+++ b/drivers/net/wireguard/device.c
@@ -218,6 +218,8 @@ static const struct net_device_ops netdev_ops = {
.ndo_get_stats64 = ip_tunnel_get_stats64
};
+static const struct header_ops header_ops = { .parse_protocol = wg_examine_packet_protocol };
+
static void wg_destruct(struct net_device *dev)
{
struct wg_device *wg = netdev_priv(dev);
@@ -262,6 +264,7 @@ static void wg_setup(struct net_device *dev)
max(sizeof(struct ipv6hdr), sizeof(struct iphdr));
dev->netdev_ops = &netdev_ops;
+ dev->header_ops = &header_ops;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->needed_headroom = DATA_PACKET_HEAD_ROOM;
diff --git a/drivers/net/wireguard/queueing.h b/drivers/net/wireguard/queueing.h
index c58df439dbbe..1985eeb25262 100644
--- a/drivers/net/wireguard/queueing.h
+++ b/drivers/net/wireguard/queueing.h
@@ -66,7 +66,7 @@ struct packet_cb {
#define PACKET_PEER(skb) (PACKET_CB(skb)->keypair->entry.peer)
/* Returns either the correct skb->protocol value, or 0 if invalid. */
-static inline __be16 wg_examine_packet_protocol(struct sk_buff *skb)
+static inline __be16 wg_examine_packet_protocol(const struct sk_buff *skb)
{
if (skb_network_header(skb) >= skb->head &&
(skb_network_header(skb) + sizeof(struct iphdr)) <=