lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20080411135745.GB8137@tp64>
Date:	Fri, 11 Apr 2008 22:57:45 +0900
From:	Joonwoo Park <joonwpark81@...il.com>
To:	kaber@...sh.net
Cc:	davem@...emloft.net, netdev@...r.kernel.org
Subject: [PATCH 2/5] [VLAN]: Add vlan tag into PACKET_AUXDATA

The hardware vlan acceleration feature of netdev strips vlan tag.
This patch put the tag into auxdata if it was stripped.
Since the skb->cb has no additional room for the tag, this patch
eliminates sll_family from the skb->cb which is AF_PACKET always.

Signed-off-by: Joonwoo Park <joonwpark81@...il.com>
---
 include/linux/if_packet.h |    1 +
 net/packet/af_packet.c    |   78 +++++++++++++++++++++++++++++++++++----------
 2 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/include/linux/if_packet.h b/include/linux/if_packet.h
index ad09609..08ba915 100644
--- a/include/linux/if_packet.h
+++ b/include/linux/if_packet.h
@@ -57,6 +57,7 @@ struct tpacket_auxdata
 	__u32		tp_snaplen;
 	__u16		tp_mac;
 	__u16		tp_net;
+	__u16		tp_vlan_TCI;
 };
 
 struct tpacket_hdr
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index b8b827c..2897aaf 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -79,6 +79,7 @@
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/if_vlan.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>
@@ -191,11 +192,26 @@ struct packet_sock {
 #endif
 };
 
+struct sockaddr_ll_af {
+	/* unsigned short	sll_family; */
+	__be16			sll_protocol;
+	int			sll_ifindex;
+	unsigned short		sll_hatype;
+	unsigned char		sll_pkttype;
+	unsigned char		sll_halen;
+	unsigned char		sll_addr[8];
+} __attribute__ ((packed));
+
+#define BUILD_OFFSET_BUG_ON(ll, offset)					\
+	BUILD_BUG_ON(offsetof(struct sockaddr_ll_af, ll) + offset	\
+		     != offsetof(struct sockaddr_ll, ll));
+
 struct packet_skb_cb {
-	unsigned int origlen;
+	unsigned int		origlen;
+	unsigned short		vlan_TCI;
 	union {
 		struct sockaddr_pkt pkt;
-		struct sockaddr_ll ll;
+		struct sockaddr_ll_af ll_af;
 	} sa;
 };
 
@@ -241,6 +257,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct
 {
 	struct sock *sk;
 	struct sockaddr_pkt *spkt;
+	unsigned short tag;
 
 	/*
 	 *	When we registered the protocol we saved the socket in the data
@@ -288,6 +305,13 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct
 	strlcpy(spkt->spkt_device, dev->name, sizeof(spkt->spkt_device));
 	spkt->spkt_protocol = skb->protocol;
 
+	if (dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX))
+		__vlan_hwaccel_get_tag(skb, &tag);
+	else
+		tag = 0;
+
+	PACKET_SKB_CB(skb)->vlan_TCI = tag;
+
 	/*
 	 *	Charge the memory to the socket. This is done specifically
 	 *	to prevent sockets using all the memory up.
@@ -439,11 +463,12 @@ static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
 static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
 {
 	struct sock *sk;
-	struct sockaddr_ll *sll;
+	struct sockaddr_ll_af *sll_af;
 	struct packet_sock *po;
 	u8 * skb_head = skb->data;
 	int skb_len = skb->len;
 	unsigned int snaplen, res;
+	unsigned short tag;
 
 	if (skb->pkt_type == PACKET_LOOPBACK)
 		goto drop;
@@ -500,17 +525,23 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
 	BUILD_BUG_ON(sizeof(*PACKET_SKB_CB(skb)) + MAX_ADDR_LEN - 8 >
 		     sizeof(skb->cb));
 
-	sll = &PACKET_SKB_CB(skb)->sa.ll;
-	sll->sll_family = AF_PACKET;
-	sll->sll_hatype = dev->type;
-	sll->sll_protocol = skb->protocol;
-	sll->sll_pkttype = skb->pkt_type;
+	if (dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX))
+		__vlan_hwaccel_get_tag(skb, &tag);
+	else
+		tag = 0;
+
+	sll_af = &PACKET_SKB_CB(skb)->sa.ll_af;
+	sll_af->sll_hatype = dev->type;
+	sll_af->sll_protocol = skb->protocol;
+	sll_af->sll_pkttype = skb->pkt_type;
 	if (unlikely(po->origdev))
-		sll->sll_ifindex = orig_dev->ifindex;
+		sll_af->sll_ifindex = orig_dev->ifindex;
 	else
-		sll->sll_ifindex = dev->ifindex;
+		sll_af->sll_ifindex = dev->ifindex;
 
-	sll->sll_halen = dev_parse_header(skb, sll->sll_addr);
+	sll_af->sll_halen = dev_parse_header(skb, sll_af->sll_addr);
+
+	PACKET_SKB_CB(skb)->vlan_TCI = tag;
 
 	PACKET_SKB_CB(skb)->origlen = skb->len;
 
@@ -1034,7 +1065,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 	struct sock *sk = sock->sk;
 	struct sk_buff *skb;
 	int copied, err;
-	struct sockaddr_ll *sll;
+	struct sockaddr_ll_af *sll_af;
 
 	err = -EINVAL;
 	if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
@@ -1071,11 +1102,12 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 	 *	it in now.
 	 */
 
-	sll = &PACKET_SKB_CB(skb)->sa.ll;
+	sll_af = &PACKET_SKB_CB(skb)->sa.ll_af;
 	if (sock->type == SOCK_PACKET)
 		msg->msg_namelen = sizeof(struct sockaddr_pkt);
 	else
-		msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
+		msg->msg_namelen = sll_af->sll_halen
+				   + offsetof(struct sockaddr_ll_af, sll_addr);
 
 	/*
 	 *	You lose any data beyond the buffer you gave. If it worries a
@@ -1095,9 +1127,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 
 	sock_recv_timestamp(msg, sk, skb);
 
-	if (msg->msg_name)
-		memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
-		       msg->msg_namelen);
+	if (msg->msg_name) {
+		struct sockaddr_ll *ll = (struct sockaddr_ll*)msg->msg_name;
+
+		BUILD_OFFSET_BUG_ON(sll_protocol,  sizeof(ll->sll_family));
+		BUILD_OFFSET_BUG_ON(sll_ifindex,  sizeof(ll->sll_family));
+		BUILD_OFFSET_BUG_ON(sll_hatype,  sizeof(ll->sll_family));
+		BUILD_OFFSET_BUG_ON(sll_pkttype,  sizeof(ll->sll_family));
+		BUILD_OFFSET_BUG_ON(sll_halen,  sizeof(ll->sll_family));
+		BUILD_OFFSET_BUG_ON(sll_addr,  sizeof(ll->sll_family));
+
+		ll->sll_family = AF_PACKET;
+		memcpy((unsigned char*)ll + sizeof(ll->sll_family),
+		       &PACKET_SKB_CB(skb)->sa, msg->msg_namelen);
+	}
 
 	if (pkt_sk(sk)->auxdata) {
 		struct tpacket_auxdata aux;
@@ -1109,6 +1152,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 		aux.tp_snaplen = skb->len;
 		aux.tp_mac = 0;
 		aux.tp_net = skb_network_offset(skb);
+		aux.tp_vlan_TCI = PACKET_SKB_CB(skb)->vlan_TCI;
 
 		put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
 	}
-- 
1.5.4.3


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ