* [PATCH 00/08]: VLAN update
@ 2008-07-09 12:09 Patrick McHardy
2008-07-09 12:09 ` [PATCH 01/08]: vlan: Don't store VLAN tag in cb Patrick McHardy
` (9 more replies)
0 siblings, 10 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
These patches include an updated set of the VLAN packet socket fixes,
now also supporting VLAN TCI delivery to userspace using mmaped packet
sockets, as well as a patch to add ->get_flags ethtool support and
a few minor cleanup patches.
To recap the VLAN packet socket problems fixed by these patches:
- With hardware tagging, outgoing packets are visible without
the VLAN header, while with software tagging the full VLAN
header is visible
- With hardware stripping, incoming packets for locally configured
VLANs appear on the VLAN device without being visible on the
underlying device. Packets for unknown VLANs are not visible
at all. Without hardware stripping, all VLAN packets are visible
on the underlying device.
The patches move the VLAN TCI from skb->cb to a new skb member
to avoid clashes with qdiscs and packet sockets use of skb->cb.
On the TX path this is enough to make sure that packet sockets
can be made aware of the VLAN TCI. On the hardware accelerated
RX path, we also store the VLAN TCI in the skb and manually invoke
the ptype_all handlers. The packet socket code stores the TCI in
either the auxdata (for regular packet sockets) or the new
tpacket2_hdr (for mmaped packet sockets) and delivers it to
userspace, where it can be used to reconstruct the VLAN header.
The only remaining problem is that socket filters contructed for
VLAN headers don't work properly since no header is present.
Since with the approach taken by these patches, userspace has
to be aware of VLAN acceleration anyway, it seems reasonable
to add a new filter instruction for getting the VLAN TCI from
the skb and expect it to construct its filters accordingly.
This is not done so far however, other suggestions are still
welcome :)
include/linux/if_packet.h | 23 ++++++
include/linux/if_vlan.h | 31 ++------
include/linux/netdevice.h | 1 +
include/linux/skbuff.h | 3 +
net/8021q/vlan.c | 8 +--
net/8021q/vlan_core.c | 4 +
net/8021q/vlan_dev.c | 116 +++++++----------------------
net/8021q/vlanproc.c | 11 +--
net/core/dev.c | 27 +++++++
net/core/skbuff.c | 3 +
net/packet/af_packet.c | 181 ++++++++++++++++++++++++++++++++++++--------
11 files changed, 248 insertions(+), 160 deletions(-)
Patrick McHardy (8):
vlan: Don't store VLAN tag in cb
vlan: deliver packets received with VLAN acceleration to network taps
packet: support extensible, 64 bit clean mmaped ring structure
packet: deliver VLAN TCI to userspace
vlan: ethtool ->get_flags support
vlan: clean up vlan_dev_hard_header()
vlan: clean up hard_start_xmit functions
vlan: remove unnecessary include statements
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 01/08]: vlan: Don't store VLAN tag in cb
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
@ 2008-07-09 12:09 ` Patrick McHardy
2008-07-09 12:09 ` [PATCH 02/08]: vlan: deliver packets received with VLAN acceleration to network taps Patrick McHardy
` (8 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
vlan: Don't store VLAN tag in cb
Use a real skb member to store the skb to avoid clashes with qdiscs,
which are allowed to use the cb area themselves. As currently only real
devices that consume the skb set the NETIF_F_HW_VLAN_TX flag, no explicit
invalidation is neccessary.
The new member fills a hole on 64 bit, the skb layout changes from:
__u32 mark; /* 172 4 */
sk_buff_data_t transport_header; /* 176 4 */
sk_buff_data_t network_header; /* 180 4 */
sk_buff_data_t mac_header; /* 184 4 */
sk_buff_data_t tail; /* 188 4 */
/* --- cacheline 3 boundary (192 bytes) --- */
sk_buff_data_t end; /* 192 4 */
/* XXX 4 bytes hole, try to pack */
to
__u32 mark; /* 172 4 */
__u16 vlan_tci; /* 176 2 */
/* XXX 2 bytes hole, try to pack */
sk_buff_data_t transport_header; /* 180 4 */
sk_buff_data_t network_header; /* 184 4 */
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 5188944208232be946dbfa41e4e81cd13a5cc63f
tree c64a83b5852c11c1e970ca8d4955892a210138eb
parent 66f29353205907c92f202b6db8c143c7969cbedf
author Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 12:38:27 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 12:38:27 +0200
include/linux/if_vlan.h | 31 +++++++------------------------
include/linux/skbuff.h | 3 +++
net/core/skbuff.c | 3 +++
3 files changed, 13 insertions(+), 24 deletions(-)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 93f5d9b..9e7b49b 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -105,17 +105,8 @@ static inline void vlan_group_set_device(struct vlan_group *vg,
array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev;
}
-/* VLAN tx hw acceleration helpers. */
-struct vlan_skb_tx_cookie {
- u32 magic;
- u32 vlan_tag;
-};
-
-#define VLAN_TX_COOKIE_MAGIC 0x564c414e /* "VLAN" in ascii. */
-#define VLAN_TX_SKB_CB(__skb) ((struct vlan_skb_tx_cookie *)&((__skb)->cb[0]))
-#define vlan_tx_tag_present(__skb) \
- (VLAN_TX_SKB_CB(__skb)->magic == VLAN_TX_COOKIE_MAGIC)
-#define vlan_tx_tag_get(__skb) (VLAN_TX_SKB_CB(__skb)->vlan_tag)
+#define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci)
+#define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci)
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
@@ -210,17 +201,12 @@ static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci)
* @skb: skbuff to tag
* @vlan_tci: VLAN TCI to insert
*
- * Puts the VLAN TCI in @skb->cb[] and lets the device do the rest
+ * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest
*/
static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb,
u16 vlan_tci)
{
- struct vlan_skb_tx_cookie *cookie;
-
- cookie = VLAN_TX_SKB_CB(skb);
- cookie->magic = VLAN_TX_COOKIE_MAGIC;
- cookie->vlan_tag = vlan_tci;
-
+ skb->vlan_tci = vlan_tci;
return skb;
}
@@ -267,16 +253,13 @@ static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
* @skb: skbuff to query
* @vlan_tci: buffer to store vlaue
*
- * Returns error if @skb->cb[] is not set correctly
+ * Returns error if @skb->vlan_tci is not set correctly
*/
static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
u16 *vlan_tci)
{
- struct vlan_skb_tx_cookie *cookie;
-
- cookie = VLAN_TX_SKB_CB(skb);
- if (cookie->magic == VLAN_TX_COOKIE_MAGIC) {
- *vlan_tci = cookie->vlan_tag;
+ if (vlan_tx_tag_present(skb)) {
+ *vlan_tci = skb->vlan_tci;
return 0;
} else {
*vlan_tci = 0;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 8f10e3d..7ea44f6 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -246,6 +246,7 @@ typedef unsigned char *sk_buff_data_t;
* @dma_cookie: a cookie to one of several possible DMA operations
* done by skb DMA functions
* @secmark: security marking
+ * @vlan_tci: vlan tag control information
*/
struct sk_buff {
@@ -326,6 +327,8 @@ struct sk_buff {
__u32 mark;
+ __u16 vlan_tci;
+
sk_buff_data_t transport_header;
sk_buff_data_t network_header;
sk_buff_data_t mac_header;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 7c57156..50a853f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -459,6 +459,8 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->tc_verd = old->tc_verd;
#endif
#endif
+ new->vlan_tci = old->vlan_tci;
+
skb_copy_secmark(new, old);
}
@@ -2286,6 +2288,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
skb_copy_queue_mapping(nskb, skb);
nskb->priority = skb->priority;
nskb->protocol = skb->protocol;
+ nskb->vlan_tci = skb->vlan_tci;
nskb->dst = dst_clone(skb->dst);
memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
nskb->pkt_type = skb->pkt_type;
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 02/08]: vlan: deliver packets received with VLAN acceleration to network taps
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
2008-07-09 12:09 ` [PATCH 01/08]: vlan: Don't store VLAN tag in cb Patrick McHardy
@ 2008-07-09 12:09 ` Patrick McHardy
2008-07-09 12:35 ` Ben Hutchings
2008-07-09 12:09 ` [PATCH 03/08]: packet: support extensible, 64 bit clean mmaped ring structure Patrick McHardy
` (7 subsequent siblings)
9 siblings, 1 reply; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
vlan: deliver packets received with VLAN acceleration to network taps
When VLAN header stripping is used, packets currently bypass packet
sockets (and other network taps) completely. For locally existing
VLANs, they appear directly on the VLAN device, for unknown VLANs
they are silently dropped.
Add a new function netif_nit_deliver() to deliver incoming packets
to all network interface taps and use it in __vlan_hwaccel_rx() to
make VLAN packets visible on the underlying device.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 2150bca3247c0b497a83937005367092bca86530
tree 1a1c894d2d360dd2b90a759485ae0e2e0a441b41
parent 5188944208232be946dbfa41e4e81cd13a5cc63f
author Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 12:38:27 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 12:38:27 +0200
include/linux/netdevice.h | 1 +
net/8021q/vlan_core.c | 4 ++++
net/core/dev.c | 27 +++++++++++++++++++++++++++
3 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 203c550..85c5db8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1152,6 +1152,7 @@ extern int netif_rx(struct sk_buff *skb);
extern int netif_rx_ni(struct sk_buff *skb);
#define HAVE_NETIF_RECEIVE_SKB 1
extern int netif_receive_skb(struct sk_buff *skb);
+extern void netif_nit_deliver(struct sk_buff *skb);
extern int dev_valid_name(const char *name);
extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
extern int dev_ethtool(struct net *net, struct ifreq *);
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 68df12d..916061f 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -14,6 +14,9 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
return NET_RX_DROP;
}
+ skb->vlan_tci = vlan_tci;
+ netif_nit_deliver(skb);
+
skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
if (skb->dev == NULL) {
dev_kfree_skb_any(skb);
@@ -22,6 +25,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
return NET_RX_SUCCESS;
}
skb->dev->last_rx = jiffies;
+ skb->vlan_tci = 0;
stats = &skb->dev->stats;
stats->rx_packets++;
diff --git a/net/core/dev.c b/net/core/dev.c
index a29a359..c3bec22 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2068,6 +2068,33 @@ out:
}
#endif
+/*
+ * netif_tap_deliver - deliver received packets to network taps
+ * @skb: buffer
+ *
+ * This function is used to deliver incoming packets to network
+ * taps. It should be used when the normal netif_receive_skb path
+ * is bypassed, for example because of VLAN acceleration.
+ */
+void netif_nit_deliver(struct sk_buff *skb)
+{
+ struct packet_type *ptype;
+
+ if (list_empty(&ptype_all))
+ return;
+
+ skb_reset_network_header(skb);
+ skb_reset_transport_header(skb);
+ skb->mac_len = skb->network_header - skb->mac_header;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(ptype, &ptype_all, list) {
+ if (!ptype->dev || ptype->dev == skb->dev)
+ deliver_skb(skb, ptype, skb->dev);
+ }
+ rcu_read_unlock();
+}
+
/**
* netif_receive_skb - process receive buffer from network
* @skb: buffer to process
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 03/08]: packet: support extensible, 64 bit clean mmaped ring structure
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
2008-07-09 12:09 ` [PATCH 01/08]: vlan: Don't store VLAN tag in cb Patrick McHardy
2008-07-09 12:09 ` [PATCH 02/08]: vlan: deliver packets received with VLAN acceleration to network taps Patrick McHardy
@ 2008-07-09 12:09 ` Patrick McHardy
2008-07-09 12:09 ` [PATCH 04/08]: packet: deliver VLAN TCI to userspace Patrick McHardy
` (6 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
packet: support extensible, 64 bit clean mmaped ring structure
The tpacket_hdr is not 64 bit clean due to use of an unsigned long
and can't be extended because the following struct sockaddr_ll needs
to be at a fixed offset.
Add support for a version 2 tpacket protocol that removes these
limitations.
Userspace can query the header size through a new getsockopt option
and change the protocol version through a setsockopt option. The
changes needed to switch to the new protocol version are:
1. replace struct tpacket_hdr by struct tpacket2_hdr
2. query header len and save
3. set protocol version to 2
- set up ring as usual
4. for getting the sockaddr_ll, use (void *)hdr + TPACKET_ALIGN(hdrlen)
instead of (void *)hdr + TPACKET_ALIGN(sizeof(struct tpacket_hdr))
Steps 2 and 4 can be omitted if the struct sockaddr_ll isn't needed.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 67facd0da49b1c2061e17a6623904f675d0b1bc9
tree 3c3f7e5bcd481da693fbdda775c618abf9f89584
parent 2150bca3247c0b497a83937005367092bca86530
author Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:04:26 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:04:26 +0200
include/linux/if_packet.h | 21 +++++
net/packet/af_packet.c | 179 +++++++++++++++++++++++++++++++++++++--------
2 files changed, 167 insertions(+), 33 deletions(-)
diff --git a/include/linux/if_packet.h b/include/linux/if_packet.h
index ad09609..d4d3c82 100644
--- a/include/linux/if_packet.h
+++ b/include/linux/if_packet.h
@@ -43,6 +43,8 @@ struct sockaddr_ll
#define PACKET_COPY_THRESH 7
#define PACKET_AUXDATA 8
#define PACKET_ORIGDEV 9
+#define PACKET_VERSION 10
+#define PACKET_HDRLEN 11
struct tpacket_stats
{
@@ -79,6 +81,25 @@ struct tpacket_hdr
#define TPACKET_ALIGN(x) (((x)+TPACKET_ALIGNMENT-1)&~(TPACKET_ALIGNMENT-1))
#define TPACKET_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket_hdr)) + sizeof(struct sockaddr_ll))
+struct tpacket2_hdr
+{
+ __u32 tp_status;
+ __u32 tp_len;
+ __u32 tp_snaplen;
+ __u16 tp_mac;
+ __u16 tp_net;
+ __u32 tp_sec;
+ __u32 tp_nsec;
+};
+
+#define TPACKET2_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
+
+enum tpacket_versions
+{
+ TPACKET_V1,
+ TPACKET_V2,
+};
+
/*
Frame structure:
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index beca640..85ab3e3 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -186,6 +186,8 @@ struct packet_sock {
unsigned int pg_vec_order;
unsigned int pg_vec_pages;
unsigned int pg_vec_len;
+ enum tpacket_versions tp_version;
+ unsigned int tp_hdrlen;
#endif
};
@@ -201,14 +203,52 @@ struct packet_skb_cb {
#ifdef CONFIG_PACKET_MMAP
-static inline struct tpacket_hdr *packet_lookup_frame(struct packet_sock *po, unsigned int position)
+static void *packet_lookup_frame(struct packet_sock *po, unsigned int position,
+ int status)
{
unsigned int pg_vec_pos, frame_offset;
+ union {
+ struct tpacket_hdr *h1;
+ struct tpacket2_hdr *h2;
+ void *raw;
+ } h;
pg_vec_pos = position / po->frames_per_block;
frame_offset = position % po->frames_per_block;
- return (struct tpacket_hdr *)(po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size));
+ h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
+ switch (po->tp_version) {
+ case TPACKET_V1:
+ if (status != h.h1->tp_status ? TP_STATUS_USER :
+ TP_STATUS_KERNEL)
+ return NULL;
+ break;
+ case TPACKET_V2:
+ if (status != h.h2->tp_status ? TP_STATUS_USER :
+ TP_STATUS_KERNEL)
+ return NULL;
+ break;
+ }
+ return h.raw;
+}
+
+static void __packet_set_status(struct packet_sock *po, void *frame, int status)
+{
+ union {
+ struct tpacket_hdr *h1;
+ struct tpacket2_hdr *h2;
+ void *raw;
+ } h;
+
+ h.raw = frame;
+ switch (po->tp_version) {
+ case TPACKET_V1:
+ h.h1->tp_status = status;
+ break;
+ case TPACKET_V2:
+ h.h2->tp_status = status;
+ break;
+ }
}
#endif
@@ -551,14 +591,19 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
struct sock *sk;
struct packet_sock *po;
struct sockaddr_ll *sll;
- struct tpacket_hdr *h;
+ union {
+ struct tpacket_hdr *h1;
+ struct tpacket2_hdr *h2;
+ void *raw;
+ } h;
u8 * skb_head = skb->data;
int skb_len = skb->len;
unsigned int snaplen, res;
unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
- unsigned short macoff, netoff;
+ unsigned short macoff, netoff, hdrlen;
struct sk_buff *copy_skb = NULL;
struct timeval tv;
+ struct timespec ts;
if (skb->pkt_type == PACKET_LOOPBACK)
goto drop;
@@ -590,10 +635,11 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
snaplen = res;
if (sk->sk_type == SOCK_DGRAM) {
- macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16;
+ macoff = netoff = TPACKET_ALIGN(po->tp_hdrlen) + 16;
} else {
unsigned maclen = skb_network_offset(skb);
- netoff = TPACKET_ALIGN(TPACKET_HDRLEN + (maclen < 16 ? 16 : maclen));
+ netoff = TPACKET_ALIGN(po->tp_hdrlen +
+ (maclen < 16 ? 16 : maclen));
macoff = netoff - maclen;
}
@@ -616,9 +662,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
}
spin_lock(&sk->sk_receive_queue.lock);
- h = packet_lookup_frame(po, po->head);
-
- if (h->tp_status)
+ h.raw = packet_lookup_frame(po, po->head, TP_STATUS_KERNEL);
+ if (!h.raw)
goto ring_is_full;
po->head = po->head != po->frame_max ? po->head+1 : 0;
po->stats.tp_packets++;
@@ -630,20 +675,40 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
status &= ~TP_STATUS_LOSING;
spin_unlock(&sk->sk_receive_queue.lock);
- skb_copy_bits(skb, 0, (u8*)h + macoff, snaplen);
+ skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
- h->tp_len = skb->len;
- h->tp_snaplen = snaplen;
- h->tp_mac = macoff;
- h->tp_net = netoff;
- if (skb->tstamp.tv64)
- tv = ktime_to_timeval(skb->tstamp);
- else
- do_gettimeofday(&tv);
- h->tp_sec = tv.tv_sec;
- h->tp_usec = tv.tv_usec;
+ switch (po->tp_version) {
+ case TPACKET_V1:
+ h.h1->tp_len = skb->len;
+ h.h1->tp_snaplen = snaplen;
+ h.h1->tp_mac = macoff;
+ h.h1->tp_net = netoff;
+ if (skb->tstamp.tv64)
+ tv = ktime_to_timeval(skb->tstamp);
+ else
+ do_gettimeofday(&tv);
+ h.h1->tp_sec = tv.tv_sec;
+ h.h1->tp_usec = tv.tv_usec;
+ hdrlen = sizeof(*h.h1);
+ break;
+ case TPACKET_V2:
+ h.h2->tp_len = skb->len;
+ h.h2->tp_snaplen = snaplen;
+ h.h2->tp_mac = macoff;
+ h.h2->tp_net = netoff;
+ if (skb->tstamp.tv64)
+ ts = ktime_to_timespec(skb->tstamp);
+ else
+ getnstimeofday(&ts);
+ h.h2->tp_sec = ts.tv_sec;
+ h.h2->tp_nsec = ts.tv_nsec;
+ hdrlen = sizeof(*h.h2);
+ break;
+ default:
+ BUG();
+ }
- sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h)));
+ sll = h.raw + TPACKET_ALIGN(hdrlen);
sll->sll_halen = dev_parse_header(skb, sll->sll_addr);
sll->sll_family = AF_PACKET;
sll->sll_hatype = dev->type;
@@ -654,14 +719,14 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
else
sll->sll_ifindex = dev->ifindex;
- h->tp_status = status;
+ __packet_set_status(po, h.raw, status);
smp_mb();
{
struct page *p_start, *p_end;
- u8 *h_end = (u8 *)h + macoff + snaplen - 1;
+ u8 *h_end = h.raw + macoff + snaplen - 1;
- p_start = virt_to_page(h);
+ p_start = virt_to_page(h.raw);
p_end = virt_to_page(h_end);
while (p_start <= p_end) {
flush_dcache_page(p_start);
@@ -1356,6 +1421,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
pkt_sk(sk)->copy_thresh = val;
return 0;
}
+ case PACKET_VERSION:
+ {
+ int val;
+
+ if (optlen != sizeof(val))
+ return -EINVAL;
+ if (po->pg_vec)
+ return -EBUSY;
+ if (copy_from_user(&val, optval, sizeof(val)))
+ return -EFAULT;
+ switch (val) {
+ case TPACKET_V1:
+ case TPACKET_V2:
+ po->tp_version = val;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+ }
#endif
case PACKET_AUXDATA:
{
@@ -1431,6 +1515,31 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
data = &val;
break;
+#ifdef CONFIG_PACKET_MMAP
+ case PACKET_VERSION:
+ if (len > sizeof(int))
+ len = sizeof(int);
+ val = po->tp_version;
+ data = &val;
+ break;
+ case PACKET_HDRLEN:
+ if (len > sizeof(int))
+ len = sizeof(int);
+ if (copy_from_user(&val, optval, len))
+ return -EFAULT;
+ switch (val) {
+ case TPACKET_V1:
+ val = sizeof(struct tpacket_hdr);
+ break;
+ case TPACKET_V2:
+ val = sizeof(struct tpacket2_hdr);
+ break;
+ default:
+ return -EINVAL;
+ }
+ data = &val;
+ break;
+#endif
default:
return -ENOPROTOOPT;
}
@@ -1564,11 +1673,8 @@ static unsigned int packet_poll(struct file * file, struct socket *sock,
spin_lock_bh(&sk->sk_receive_queue.lock);
if (po->pg_vec) {
unsigned last = po->head ? po->head-1 : po->frame_max;
- struct tpacket_hdr *h;
-
- h = packet_lookup_frame(po, last);
- if (h->tp_status)
+ if (packet_lookup_frame(po, last, TP_STATUS_USER))
mask |= POLLIN | POLLRDNORM;
}
spin_unlock_bh(&sk->sk_receive_queue.lock);
@@ -1663,11 +1769,20 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
if (unlikely(po->pg_vec))
return -EBUSY;
+ switch (po->tp_version) {
+ case TPACKET_V1:
+ po->tp_hdrlen = TPACKET_HDRLEN;
+ break;
+ case TPACKET_V2:
+ po->tp_hdrlen = TPACKET2_HDRLEN;
+ break;
+ }
+
if (unlikely((int)req->tp_block_size <= 0))
return -EINVAL;
if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
return -EINVAL;
- if (unlikely(req->tp_frame_size < TPACKET_HDRLEN))
+ if (unlikely(req->tp_frame_size < po->tp_hdrlen))
return -EINVAL;
if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
return -EINVAL;
@@ -1686,13 +1801,11 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
goto out;
for (i = 0; i < req->tp_block_nr; i++) {
- char *ptr = pg_vec[i];
- struct tpacket_hdr *header;
+ void *ptr = pg_vec[i];
int k;
for (k = 0; k < po->frames_per_block; k++) {
- header = (struct tpacket_hdr *) ptr;
- header->tp_status = TP_STATUS_KERNEL;
+ __packet_set_status(po, ptr, TP_STATUS_KERNEL);
ptr += req->tp_frame_size;
}
}
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 04/08]: packet: deliver VLAN TCI to userspace
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
` (2 preceding siblings ...)
2008-07-09 12:09 ` [PATCH 03/08]: packet: support extensible, 64 bit clean mmaped ring structure Patrick McHardy
@ 2008-07-09 12:09 ` Patrick McHardy
2008-07-09 12:09 ` [PATCH 05/08]: vlan: ethtool ->get_flags support Patrick McHardy
` (5 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
packet: deliver VLAN TCI to userspace
Store the VLAN tag in the auxillary data/tpacket2_hdr so userspace can properly
deal with hardware VLAN tagging/stripping.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 1e655d00db6762d05f8d99912a70f58fe4c4f977
tree 605cd8de3e2752890703706e7dd9acaaadcf5324
parent 67facd0da49b1c2061e17a6623904f675d0b1bc9
author Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:56:52 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:56:52 +0200
include/linux/if_packet.h | 2 ++
net/packet/af_packet.c | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/include/linux/if_packet.h b/include/linux/if_packet.h
index d4d3c82..a630295 100644
--- a/include/linux/if_packet.h
+++ b/include/linux/if_packet.h
@@ -59,6 +59,7 @@ struct tpacket_auxdata
__u32 tp_snaplen;
__u16 tp_mac;
__u16 tp_net;
+ __u16 tp_vlan_tci;
};
struct tpacket_hdr
@@ -90,6 +91,7 @@ struct tpacket2_hdr
__u16 tp_net;
__u32 tp_sec;
__u32 tp_nsec;
+ __u16 tp_vlan_tci;
};
#define TPACKET2_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 85ab3e3..250e9b8 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -702,6 +702,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
getnstimeofday(&ts);
h.h2->tp_sec = ts.tv_sec;
h.h2->tp_nsec = ts.tv_nsec;
+ h.h2->tp_vlan_tci = skb->vlan_tci;
hdrlen = sizeof(*h.h2);
break;
default:
@@ -1172,6 +1173,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 = skb->vlan_tci;
put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
}
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 05/08]: vlan: ethtool ->get_flags support
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
` (3 preceding siblings ...)
2008-07-09 12:09 ` [PATCH 04/08]: packet: deliver VLAN TCI to userspace Patrick McHardy
@ 2008-07-09 12:09 ` Patrick McHardy
2008-07-09 12:09 ` [PATCH 06/08]: vlan: clean up vlan_dev_hard_header() Patrick McHardy
` (4 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
vlan: ethtool ->get_flags support
Allow to query LRO settings of underlying device when VLAN RX
acceleration is used.
Suggested by Ben Hutchings <bhutchings@solarflare.com>.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit b7ed86e1c799275adf2d36b8801abe91ffe66aec
tree 7374b192f8b6b88df2e2a9f6d92764423a14df9f
parent 1e655d00db6762d05f8d99912a70f58fe4c4f977
author Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:57:00 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:57:00 +0200
net/8021q/vlan_dev.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 8efa399..48617c1 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -709,9 +709,22 @@ static u32 vlan_ethtool_get_rx_csum(struct net_device *dev)
return real_dev->ethtool_ops->get_rx_csum(real_dev);
}
+static u32 vlan_ethtool_get_flags(struct net_device *dev)
+{
+ const struct vlan_dev_info *vlan = vlan_dev_info(dev);
+ struct net_device *real_dev = vlan->real_dev;
+
+ if (!(real_dev->features & NETIF_F_HW_VLAN_RX) ||
+ real_dev->ethtool_ops == NULL ||
+ real_dev->ethtool_ops->get_flags == NULL)
+ return 0;
+ return real_dev->ethtool_ops->get_flags(real_dev);
+}
+
static const struct ethtool_ops vlan_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_rx_csum = vlan_ethtool_get_rx_csum,
+ .get_flags = vlan_ethtool_get_flags,
};
void vlan_setup(struct net_device *dev)
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 06/08]: vlan: clean up vlan_dev_hard_header()
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
` (4 preceding siblings ...)
2008-07-09 12:09 ` [PATCH 05/08]: vlan: ethtool ->get_flags support Patrick McHardy
@ 2008-07-09 12:09 ` Patrick McHardy
2008-07-09 12:09 ` [PATCH 07/08]: vlan: clean up hard_start_xmit functions Patrick McHardy
` (3 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
vlan: clean up vlan_dev_hard_header()
Remove some debugging and excessive comments, merge the two dev_hard_header
calls into one.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 731075279c2229b454f9441da2b6bc82a39cde67
tree 4c7354bbc74d1d75da1a8fbc79fd6d19e7ec5021
parent b7ed86e1c799275adf2d36b8801abe91ffe66aec
author Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:57:00 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:57:00 +0200
net/8021q/vlan_dev.c | 55 ++++++++------------------------------------------
1 files changed, 9 insertions(+), 46 deletions(-)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 48617c1..8cd57c4 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -256,43 +256,18 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned int len)
{
struct vlan_hdr *vhdr;
+ unsigned int vhdrlen = 0;
u16 vlan_tci = 0;
- int rc = 0;
- int build_vlan_header = 0;
-
- pr_debug("%s: skb: %p type: %hx len: %u vlan_id: %hx, daddr: %p\n",
- __func__, skb, type, len, vlan_dev_info(dev)->vlan_id,
- daddr);
+ int rc;
if (WARN_ON(skb_headroom(skb) < dev->hard_header_len))
return -ENOSPC;
- /* build vlan header only if re_order_header flag is NOT set. This
- * fixes some programs that get confused when they see a VLAN device
- * sending a frame that is VLAN encoded (the consensus is that the VLAN
- * device should look completely like an Ethernet device when the
- * REORDER_HEADER flag is set) The drawback to this is some extra
- * header shuffling in the hard_start_xmit. Users can turn off this
- * REORDER behaviour with the vconfig tool.
- */
- if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR))
- build_vlan_header = 1;
-
- if (build_vlan_header) {
+ if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) {
vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN);
- /* build the four bytes that make this a VLAN header. */
-
- /* Now, construct the second two bytes. This field looks
- * something like:
- * usr_priority: 3 bits (high bits)
- * CFI 1 bit
- * VLAN ID 12 bits (low bits)
- *
- */
vlan_tci = vlan_dev_info(dev)->vlan_id;
vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
-
vhdr->h_vlan_TCI = htons(vlan_tci);
/*
@@ -300,37 +275,25 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
* put the length in here instead. It is up to the 802.2
* layer to carry protocol information.
*/
-
if (type != ETH_P_802_3)
vhdr->h_vlan_encapsulated_proto = htons(type);
else
vhdr->h_vlan_encapsulated_proto = htons(len);
skb->protocol = htons(ETH_P_8021Q);
+ type = ETH_P_8021Q;
+ vhdrlen = VLAN_HLEN;
}
/* Before delegating work to the lower layer, enter our MAC-address */
if (saddr == NULL)
saddr = dev->dev_addr;
+ /* Now make the underlying real hard header */
dev = vlan_dev_info(dev)->real_dev;
-
- if (build_vlan_header) {
- /* Now make the underlying real hard header */
- rc = dev_hard_header(skb, dev, ETH_P_8021Q, daddr, saddr,
- len + VLAN_HLEN);
- if (rc > 0)
- rc += VLAN_HLEN;
- else if (rc < 0)
- rc -= VLAN_HLEN;
- } else
- /* If here, then we'll just make a normal looking ethernet
- * frame, but, the hard_start_xmit method will insert the tag
- * (it has to be able to do this for bridged and other skbs
- * that don't come down the protocol stack in an orderly manner.
- */
- rc = dev_hard_header(skb, dev, type, daddr, saddr, len);
-
+ rc = dev_hard_header(skb, dev, type, daddr, saddr, len + vhdrlen);
+ if (rc > 0)
+ rc += vhdrlen;
return rc;
}
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 07/08]: vlan: clean up hard_start_xmit functions
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
` (5 preceding siblings ...)
2008-07-09 12:09 ` [PATCH 06/08]: vlan: clean up vlan_dev_hard_header() Patrick McHardy
@ 2008-07-09 12:09 ` Patrick McHardy
2008-07-09 12:09 ` [PATCH 08/08]: vlan: remove unnecessary include statements Patrick McHardy
` (2 subsequent siblings)
9 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
vlan: clean up hard_start_xmit functions
Remove excessive comments and debugging, use NETDEV_TX codes,
remove some empty lines.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit a1f83d7cbe06c3c104cfa7cf298fb0ccb26cb5a8
tree e5d55d0d2cc56417cc00788215050ae4f371cfe8
parent 731075279c2229b454f9441da2b6bc82a39cde67
author Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:57:01 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:57:01 +0200
net/8021q/vlan_dev.c | 41 ++++++-----------------------------------
1 files changed, 6 insertions(+), 35 deletions(-)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 8cd57c4..c5290c6 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -307,53 +307,31 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
* NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
* OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
*/
-
if (veth->h_vlan_proto != htons(ETH_P_8021Q) ||
- vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) {
- int orig_headroom = skb_headroom(skb);
+ vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) {
+ unsigned int orig_headroom = skb_headroom(skb);
u16 vlan_tci;
- /* This is not a VLAN frame...but we can fix that! */
vlan_dev_info(dev)->cnt_encap_on_xmit++;
- pr_debug("%s: proto to encap: 0x%hx\n",
- __func__, ntohs(veth->h_vlan_proto));
- /* Construct the second two bytes. This field looks something
- * like:
- * usr_priority: 3 bits (high bits)
- * CFI 1 bit
- * VLAN ID 12 bits (low bits)
- */
vlan_tci = vlan_dev_info(dev)->vlan_id;
vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
-
skb = __vlan_put_tag(skb, vlan_tci);
if (!skb) {
stats->tx_dropped++;
- return 0;
+ return NETDEV_TX_OK;
}
if (orig_headroom < VLAN_HLEN)
vlan_dev_info(dev)->cnt_inc_headroom_on_tx++;
}
- pr_debug("%s: about to send skb: %p to dev: %s\n",
- __func__, skb, skb->dev->name);
- pr_debug(" " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n",
- veth->h_dest[0], veth->h_dest[1], veth->h_dest[2],
- veth->h_dest[3], veth->h_dest[4], veth->h_dest[5],
- veth->h_source[0], veth->h_source[1], veth->h_source[2],
- veth->h_source[3], veth->h_source[4], veth->h_source[5],
- veth->h_vlan_proto, veth->h_vlan_TCI,
- veth->h_vlan_encapsulated_proto);
-
- stats->tx_packets++; /* for statics only */
+ stats->tx_packets++;
stats->tx_bytes += skb->len;
skb->dev = vlan_dev_info(dev)->real_dev;
dev_queue_xmit(skb);
-
- return 0;
+ return NETDEV_TX_OK;
}
static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
@@ -362,12 +340,6 @@ static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
struct net_device_stats *stats = &dev->stats;
u16 vlan_tci;
- /* Construct the second two bytes. This field looks something
- * like:
- * usr_priority: 3 bits (high bits)
- * CFI 1 bit
- * VLAN ID 12 bits (low bits)
- */
vlan_tci = vlan_dev_info(dev)->vlan_id;
vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
skb = __vlan_hwaccel_put_tag(skb, vlan_tci);
@@ -377,8 +349,7 @@ static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
skb->dev = vlan_dev_info(dev)->real_dev;
dev_queue_xmit(skb);
-
- return 0;
+ return NETDEV_TX_OK;
}
static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 08/08]: vlan: remove unnecessary include statements
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
` (6 preceding siblings ...)
2008-07-09 12:09 ` [PATCH 07/08]: vlan: clean up hard_start_xmit functions Patrick McHardy
@ 2008-07-09 12:09 ` Patrick McHardy
2008-07-09 12:12 ` [PATCH 00/08]: VLAN update Patrick McHardy
2008-07-15 5:56 ` David Miller
9 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:09 UTC (permalink / raw)
To: davem; +Cc: netdev, Patrick McHardy
vlan: remove unnecessary include statements
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 0b1a2cdc7acdd1fed69d6eefb16744f205fcd418
tree 3267d6c92125ad3918072c1ba180ed47c36b23f0
parent a1f83d7cbe06c3c104cfa7cf298fb0ccb26cb5a8
author Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:57:01 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 09 Jul 2008 13:57:01 +0200
net/8021q/vlan.c | 8 ++------
net/8021q/vlan_dev.c | 7 -------
net/8021q/vlanproc.c | 11 ++---------
3 files changed, 4 insertions(+), 22 deletions(-)
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 68bdcf4..9f04cab 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -18,21 +18,17 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <asm/uaccess.h> /* for copy_from_user */
#include <linux/capability.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
-#include <net/datalink.h>
-#include <linux/mm.h>
-#include <linux/in.h>
#include <linux/init.h>
-#include <net/p8022.h>
-#include <net/arp.h>
#include <linux/rtnetlink.h>
#include <linux/notifier.h>
+#include <net/rtnetlink.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
+#include <asm/uaccess.h>
#include <linux/if_vlan.h>
#include "vlan.h"
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index c5290c6..044fa0b 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -21,22 +21,15 @@
*/
#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/in.h>
-#include <linux/init.h>
-#include <asm/uaccess.h> /* for copy_from_user */
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
-#include <net/datalink.h>
-#include <net/p8022.h>
#include <net/arp.h>
#include "vlan.h"
#include "vlanproc.h"
#include <linux/if_vlan.h>
-#include <net/ip.h>
/*
* Rebuild the Ethernet MAC header. This is called after an ARP
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index 6073a88..0feefa4 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -18,16 +18,9 @@
*****************************************************************************/
#include <linux/module.h>
-#include <linux/stddef.h> /* offsetof(), etc. */
-#include <linux/errno.h> /* return codes */
+#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/slab.h> /* kmalloc(), kfree() */
-#include <linux/mm.h>
-#include <linux/string.h> /* inline mem*, str* functions */
-#include <linux/init.h> /* __initfunc et al. */
-#include <asm/byteorder.h> /* htons(), etc. */
-#include <asm/uaccess.h> /* copy_to_user */
-#include <asm/io.h>
+#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/fs.h>
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 00/08]: VLAN update
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
` (7 preceding siblings ...)
2008-07-09 12:09 ` [PATCH 08/08]: vlan: remove unnecessary include statements Patrick McHardy
@ 2008-07-09 12:12 ` Patrick McHardy
2008-07-15 5:56 ` David Miller
9 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:12 UTC (permalink / raw)
To: davem; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 549 bytes --]
Patrick McHardy wrote:
> These patches include an updated set of the VLAN packet socket fixes,
> now also supporting VLAN TCI delivery to userspace using mmaped packet
> sockets, as well as a patch to add ->get_flags ethtool support and
> a few minor cleanup patches.
And for reference, attached is a patch for libpcap to reconstruct
the VLAN header from the auxdata, as well as a ugly small program
for testing the new mmaped packet socket protocol version (since I
couldn't find a version of libpcap that already supports this for
some reason).
[-- Attachment #2: libpcap.diff --]
[-- Type: text/x-diff, Size: 3176 bytes --]
diff --git a/pcap-linux.c b/pcap-linux.c
index e9db010..e877cd8 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -471,7 +471,13 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
socklen_t fromlen;
int packet_len, caplen;
struct pcap_pkthdr pcap_header;
-
+ struct iovec iov;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ union {
+ struct cmsghdr cmsg;
+ char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
+ } cmsg_buf;
#ifdef HAVE_PF_PACKET_SOCKETS
/*
* If this is a cooked device, leave extra room for a
@@ -492,6 +498,15 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
/* Receive a single packet from the kernel */
bp = handle->buffer + handle->offset;
+
+ msg.msg_name = &from;
+ msg.msg_namelen = sizeof(from);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = &cmsg_buf;
+ msg.msg_controllen = sizeof(cmsg_buf);
+ msg.msg_flags = 0;
+
do {
/*
* Has "pcap_breakloop()" been called?
@@ -505,11 +520,11 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
handle->break_loop = 0;
return -2;
}
- fromlen = sizeof(from);
- packet_len = recvfrom(
- handle->fd, bp + offset,
- handle->bufsize - offset, MSG_TRUNC,
- (struct sockaddr *) &from, &fromlen);
+
+ iov.iov_len = handle->bufsize - offset;
+ iov.iov_base = bp + offset;
+
+ packet_len = recvmsg(handle->fd, &msg, MSG_TRUNC);
} while (packet_len == -1 && errno == EINTR);
/* Check if an error occured */
@@ -524,6 +539,38 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
}
}
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ struct tpacket_auxdata *aux;
+ unsigned int len, copy;
+ unsigned short *ptr;
+
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
+ cmsg->cmsg_level != SOL_PACKET ||
+ cmsg->cmsg_type != PACKET_AUXDATA)
+ continue;
+
+ aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
+ if (aux->tp_vlan_tci == 0)
+ continue;
+
+ len = packet_len > iov.iov_len ? iov.iov_len : packet_len;
+ if (len > 2 * ETH_ALEN + 4) {
+ copy = len - 2 * ETH_ALEN - 4;
+ if (copy > iov.iov_len - 2 * ETH_ALEN - 4)
+ copy = iov.iov_len - 2 * ETH_ALEN - 4;
+
+ memmove(iov.iov_base + 2 * ETH_ALEN + 4,
+ iov.iov_base + 2 * ETH_ALEN, copy);
+ }
+
+ ptr = (unsigned short *)(iov.iov_base + 2 * ETH_ALEN);
+ if (len >= 2 * ETH_ALEN + 2)
+ *(ptr++) = htons(ETH_P_8021Q);
+ if (len >= 2 * ETH_ALEN + 4)
+ *(ptr++) = htons(aux->tp_vlan_tci);
+ packet_len += 4;
+ }
+
#ifdef HAVE_PF_PACKET_SOCKETS
if (!handle->md.sock_packet) {
/*
@@ -1631,6 +1678,7 @@ iface_bind(int fd, int ifindex, char *ebuf)
struct sockaddr_ll sll;
int err;
socklen_t errlen = sizeof(err);
+ int val;
memset(&sll, 0, sizeof(sll));
sll.sll_family = AF_PACKET;
@@ -1657,6 +1705,12 @@ iface_bind(int fd, int ifindex, char *ebuf)
return -2;
}
+ val = 1;
+ if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, &val, sizeof(val)) == -1) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "setsockopt: %s", pcap_strerror(errno));
+ return -3;
+ }
return 0;
}
[-- Attachment #3: mmap-test.diff --]
[-- Type: text/x-diff, Size: 7535 bytes --]
diff -urN /tmp/null/if_packet.h mmap-test/if_packet.h
--- /tmp/null/if_packet.h 1970-01-01 01:00:00.000000000 +0100
+++ mmap-test/if_packet.h 2008-07-09 12:56:08.000000000 +0200
@@ -0,0 +1,144 @@
+#ifndef __LINUX_IF_PACKET_H
+#define __LINUX_IF_PACKET_H
+
+#include <linux/types.h>
+
+struct sockaddr_pkt
+{
+ unsigned short spkt_family;
+ unsigned char spkt_device[14];
+ __be16 spkt_protocol;
+};
+
+struct sockaddr_ll
+{
+ 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];
+};
+
+/* Packet types */
+
+#define PACKET_HOST 0 /* To us */
+#define PACKET_BROADCAST 1 /* To all */
+#define PACKET_MULTICAST 2 /* To group */
+#define PACKET_OTHERHOST 3 /* To someone else */
+#define PACKET_OUTGOING 4 /* Outgoing of any type */
+/* These ones are invisible by user level */
+#define PACKET_LOOPBACK 5 /* MC/BRD frame looped back */
+#define PACKET_FASTROUTE 6 /* Fastrouted frame */
+
+/* Packet socket options */
+
+#define PACKET_ADD_MEMBERSHIP 1
+#define PACKET_DROP_MEMBERSHIP 2
+#define PACKET_RECV_OUTPUT 3
+/* Value 4 is still used by obsolete turbo-packet. */
+#define PACKET_RX_RING 5
+#define PACKET_STATISTICS 6
+#define PACKET_COPY_THRESH 7
+#define PACKET_AUXDATA 8
+#define PACKET_ORIGDEV 9
+#define PACKET_VERSION 10
+#define PACKET_HDRLEN 11
+
+struct tpacket_stats
+{
+ unsigned int tp_packets;
+ unsigned int tp_drops;
+};
+
+struct tpacket_auxdata
+{
+ __u32 tp_status;
+ __u32 tp_len;
+ __u32 tp_snaplen;
+ __u16 tp_mac;
+ __u16 tp_net;
+ __u16 tp_vlan_tci;
+};
+
+struct tpacket_hdr
+{
+ unsigned long tp_status;
+#define TP_STATUS_KERNEL 0
+#define TP_STATUS_USER 1
+#define TP_STATUS_COPY 2
+#define TP_STATUS_LOSING 4
+#define TP_STATUS_CSUMNOTREADY 8
+ unsigned int tp_len;
+ unsigned int tp_snaplen;
+ unsigned short tp_mac;
+ unsigned short tp_net;
+ unsigned int tp_sec;
+ unsigned int tp_usec;
+};
+
+#define TPACKET_ALIGNMENT 16
+#define TPACKET_ALIGN(x) (((x)+TPACKET_ALIGNMENT-1)&~(TPACKET_ALIGNMENT-1))
+#define TPACKET_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket_hdr)) + sizeof(struct sockaddr_ll))
+
+struct tpacket2_hdr
+{
+ __u32 tp_status;
+ __u32 tp_len;
+ __u32 tp_snaplen;
+ __u16 tp_mac;
+ __u16 tp_net;
+ __u32 tp_sec;
+ __u32 tp_nsec;
+#ifdef TEST_VLAN_TCI
+ __u16 tp_vlan_tci;
+#endif
+};
+
+#ifdef __KERNEL__
+#define TPACKET2_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
+#else
+#define TPACKET2_HDRLEN(x) (TPACKET_ALIGN(x) + sizeof(struct sockaddr_ll))
+#endif
+
+enum tpacket_versions
+{
+ TPACKET_V1,
+ TPACKET_V2,
+};
+
+/*
+ Frame structure:
+
+ - Start. Frame must be aligned to TPACKET_ALIGNMENT=16
+ - struct tpacket_hdr
+ - pad to TPACKET_ALIGNMENT=16
+ - struct sockaddr_ll
+ - Gap, chosen so that packet data (Start+tp_net) alignes to TPACKET_ALIGNMENT=16
+ - Start+tp_mac: [ Optional MAC header ]
+ - Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16.
+ - Pad to align to TPACKET_ALIGNMENT=16
+ */
+
+struct tpacket_req
+{
+ unsigned int tp_block_size; /* Minimal size of contiguous block */
+ unsigned int tp_block_nr; /* Number of blocks */
+ unsigned int tp_frame_size; /* Size of frame */
+ unsigned int tp_frame_nr; /* Total number of frames */
+};
+
+struct packet_mreq
+{
+ int mr_ifindex;
+ unsigned short mr_type;
+ unsigned short mr_alen;
+ unsigned char mr_address[8];
+};
+
+#define PACKET_MR_MULTICAST 0
+#define PACKET_MR_PROMISC 1
+#define PACKET_MR_ALLMULTI 2
+
+#endif
diff -urN /tmp/null/Makefile mmap-test/Makefile
--- /tmp/null/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ mmap-test/Makefile 2008-07-09 03:21:21.000000000 +0200
@@ -0,0 +1,3 @@
+CFLAGS += -O2 -I. -Wall -g
+
+all: test
diff -urN /tmp/null/test.c mmap-test/test.c
--- /tmp/null/test.c 1970-01-01 01:00:00.000000000 +0100
+++ mmap-test/test.c 2008-07-09 12:56:40.000000000 +0200
@@ -0,0 +1,150 @@
+#include <unistd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/mman.h>
+#include <poll.h>
+#include <arpa/inet.h>
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/if_ether.h>
+
+#define V2
+#ifdef V2
+#define TEST_VLAN_TCI 1
+#endif
+
+#include "if_packet.h"
+
+int main(int argc, char **argv)
+{
+ struct sockaddr_ll lladdr;
+ struct tpacket_req req;
+#ifdef V2
+ struct tpacket2_hdr *hdr;
+#else
+ struct tpacket_hdr *hdr;
+#endif
+ unsigned int hdrlen;
+ int val;
+ socklen_t len;
+ void *ring;
+ unsigned int head;
+ unsigned int total = 0;
+ int fd;
+
+ fd = socket(AF_PACKET, SOCK_RAW, 0);
+ if (fd < 0) {
+ perror("socket");
+ return 1;
+ }
+
+#ifdef V2
+ val = TPACKET_V2;
+ len = sizeof(val);
+ if (getsockopt(fd, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) {
+ perror("setsockopt(PACKET_HDRLEN)");
+ return 1;
+ }
+ hdrlen = val;
+
+ printf("hdrlen=%u sizeof(struct tpacket2_hdr)=%Zu\n",
+ hdrlen, sizeof(struct tpacket2_hdr));
+
+ val = TPACKET_V2;
+ if (setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val)) < 0) {
+ perror("setsockopt(PACKET_VERSION)");
+ return 1;
+ }
+#else
+ hdrlen = sizeof(struct tpacket_hdr);
+#endif
+
+ memset(&req, 0, sizeof(req));
+ req.tp_block_size = 16 * 4096;
+ req.tp_block_nr = 16;
+ req.tp_frame_size = 1024;
+ req.tp_frame_nr = 16 * 64;
+
+ if (setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req)) < 0) {
+ perror("setsockopt");
+ return 1;
+ }
+
+ ring = mmap(NULL, req.tp_block_nr * req.tp_block_size,
+ PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if ((long)ring == -1L) {
+ perror("mmap");
+ return 1;
+ }
+
+ memset(&lladdr, 0, sizeof(lladdr));
+ lladdr.sll_family = AF_PACKET;
+ lladdr.sll_protocol = htons(ETH_P_ALL);
+ lladdr.sll_ifindex = 2;
+
+ if (bind(fd, (struct sockaddr *)&lladdr, sizeof(lladdr)) < 0) {
+ perror("bind");
+ return 1;
+ }
+
+ hdr = ring;
+ head = 0;
+
+ while (1) {
+ unsigned int cnt = 0;
+ struct pollfd pfds[1];
+
+ pfds[0].fd = fd;
+ pfds[0].events = POLLIN | POLLERR;
+ pfds[0].revents = 0;
+
+ if (poll(pfds, 1, -1) < 0 && errno != EINTR) {
+ perror("poll");
+ return 1;
+ }
+
+ if (pfds[0].revents & POLLERR) {
+ char buf[16384];
+ recv(fd, buf, sizeof(buf), MSG_DONTWAIT | MSG_ERRQUEUE);
+ printf("error %d\n", errno);
+ continue;
+ }
+
+ if (!(pfds[0].revents & POLLIN))
+ continue;
+
+ while (hdr->tp_status != TP_STATUS_KERNEL) {
+ struct sockaddr_ll *sll;
+ unsigned char *data = (void *)hdr + hdr->tp_mac;
+ unsigned int i;
+
+ printf("%.4u ring[%u]: tp_status=%u tp_len=%u "
+ "tp_snaplen=%u\n",
+ total, head, hdr->tp_status, hdr->tp_len, hdr->tp_snaplen);
+#ifdef TEST_VLAN_TCI
+ printf("tp_vlan_tci=%u id=%u\n",
+ hdr->tp_vlan_tci, hdr->tp_vlan_tci & 0xfff);
+#endif
+ for (i = 0; i < (hdr->tp_snaplen > 32 ? 32 : hdr->tp_snaplen); i++)
+ printf("%.2x ", data[i]);
+ printf("\n");
+
+ sll = (void *)hdr + TPACKET_ALIGN(hdrlen);
+ printf("sll_family=%u sll_protocol=%u sll_ifindex=%d sll_hatype=%u "
+ "sll_pkttype=%u sll_halen=%u\n",
+ sll->sll_family, ntohs(sll->sll_protocol),
+ sll->sll_ifindex, sll->sll_hatype,
+ sll->sll_pkttype, sll->sll_halen);
+ hdr->tp_status = TP_STATUS_KERNEL;
+
+ head = head == req.tp_frame_nr - 1 ? 0 : head + 1;
+ hdr = ring + head * req.tp_frame_size;
+ cnt++, total++;
+ }
+ printf("received %u consecutive entries, %u total\n\n", cnt, total);
+ }
+ return 0;
+}
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 02/08]: vlan: deliver packets received with VLAN acceleration to network taps
2008-07-09 12:09 ` [PATCH 02/08]: vlan: deliver packets received with VLAN acceleration to network taps Patrick McHardy
@ 2008-07-09 12:35 ` Ben Hutchings
2008-07-09 12:37 ` Patrick McHardy
0 siblings, 1 reply; 13+ messages in thread
From: Ben Hutchings @ 2008-07-09 12:35 UTC (permalink / raw)
To: Patrick McHardy; +Cc: davem, netdev
Patrick McHardy wrote:
> vlan: deliver packets received with VLAN acceleration to network taps
>
> When VLAN header stripping is used, packets currently bypass packet
> sockets (and other network taps) completely. For locally existing
> VLANs, they appear directly on the VLAN device, for unknown VLANs
> they are silently dropped.
>
> Add a new function netif_nit_deliver() to deliver incoming packets
> to all network interface taps and use it in __vlan_hwaccel_rx() to
> make VLAN packets visible on the underlying device.
[...]
> +/*
> + * netif_tap_deliver - deliver received packets to network taps
> + * @skb: buffer
> + *
> + * This function is used to deliver incoming packets to network
> + * taps. It should be used when the normal netif_receive_skb path
> + * is bypassed, for example because of VLAN acceleration.
> + */
> +void netif_nit_deliver(struct sk_buff *skb)
[...]
Is it supposed to be called netif_nit_deliver() or netif_tap_deliver()?
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 02/08]: vlan: deliver packets received with VLAN acceleration to network taps
2008-07-09 12:35 ` Ben Hutchings
@ 2008-07-09 12:37 ` Patrick McHardy
0 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2008-07-09 12:37 UTC (permalink / raw)
To: Ben Hutchings; +Cc: davem, netdev
[-- Attachment #1: Type: text/plain, Size: 1083 bytes --]
Ben Hutchings wrote:
> Patrick McHardy wrote:
>> vlan: deliver packets received with VLAN acceleration to network taps
>>
>> When VLAN header stripping is used, packets currently bypass packet
>> sockets (and other network taps) completely. For locally existing
>> VLANs, they appear directly on the VLAN device, for unknown VLANs
>> they are silently dropped.
>>
>> Add a new function netif_nit_deliver() to deliver incoming packets
>> to all network interface taps and use it in __vlan_hwaccel_rx() to
>> make VLAN packets visible on the underlying device.
> [...]
>> +/*
>> + * netif_tap_deliver - deliver received packets to network taps
>> + * @skb: buffer
>> + *
>> + * This function is used to deliver incoming packets to network
>> + * taps. It should be used when the normal netif_receive_skb path
>> + * is bypassed, for example because of VLAN acceleration.
>> + */
>> +void netif_nit_deliver(struct sk_buff *skb)
> [...]
>
> Is it supposed to be called netif_nit_deliver() or netif_tap_deliver()?
Thanks, seems I only renamed it half way :)
Fixed patch attached.
[-- Attachment #2: 02.diff --]
[-- Type: text/x-diff, Size: 2939 bytes --]
commit d5c10a9dd25c8c9333e12d92cd81191a37376097
Author: Patrick McHardy <kaber@trash.net>
Date: Wed Jul 9 14:37:44 2008 +0200
vlan: deliver packets received with VLAN acceleration to network taps
When VLAN header stripping is used, packets currently bypass packet
sockets (and other network taps) completely. For locally existing
VLANs, they appear directly on the VLAN device, for unknown VLANs
they are silently dropped.
Add a new function netif_nit_deliver() to deliver incoming packets
to all network interface taps and use it in __vlan_hwaccel_rx() to
make VLAN packets visible on the underlying device.
Signed-off-by: Patrick McHardy <kaber@trash.net>
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 203c550..85c5db8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1152,6 +1152,7 @@ extern int netif_rx(struct sk_buff *skb);
extern int netif_rx_ni(struct sk_buff *skb);
#define HAVE_NETIF_RECEIVE_SKB 1
extern int netif_receive_skb(struct sk_buff *skb);
+extern void netif_nit_deliver(struct sk_buff *skb);
extern int dev_valid_name(const char *name);
extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
extern int dev_ethtool(struct net *net, struct ifreq *);
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 68df12d..916061f 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -14,6 +14,9 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
return NET_RX_DROP;
}
+ skb->vlan_tci = vlan_tci;
+ netif_nit_deliver(skb);
+
skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
if (skb->dev == NULL) {
dev_kfree_skb_any(skb);
@@ -22,6 +25,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
return NET_RX_SUCCESS;
}
skb->dev->last_rx = jiffies;
+ skb->vlan_tci = 0;
stats = &skb->dev->stats;
stats->rx_packets++;
diff --git a/net/core/dev.c b/net/core/dev.c
index a29a359..feaab48 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2068,6 +2068,33 @@ out:
}
#endif
+/*
+ * netif_nit_deliver - deliver received packets to network taps
+ * @skb: buffer
+ *
+ * This function is used to deliver incoming packets to network
+ * taps. It should be used when the normal netif_receive_skb path
+ * is bypassed, for example because of VLAN acceleration.
+ */
+void netif_nit_deliver(struct sk_buff *skb)
+{
+ struct packet_type *ptype;
+
+ if (list_empty(&ptype_all))
+ return;
+
+ skb_reset_network_header(skb);
+ skb_reset_transport_header(skb);
+ skb->mac_len = skb->network_header - skb->mac_header;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(ptype, &ptype_all, list) {
+ if (!ptype->dev || ptype->dev == skb->dev)
+ deliver_skb(skb, ptype, skb->dev);
+ }
+ rcu_read_unlock();
+}
+
/**
* netif_receive_skb - process receive buffer from network
* @skb: buffer to process
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 00/08]: VLAN update
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
` (8 preceding siblings ...)
2008-07-09 12:12 ` [PATCH 00/08]: VLAN update Patrick McHardy
@ 2008-07-15 5:56 ` David Miller
9 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2008-07-15 5:56 UTC (permalink / raw)
To: kaber; +Cc: netdev
From: Patrick McHardy <kaber@trash.net>
Date: Wed, 9 Jul 2008 14:09:45 +0200 (MEST)
> These patches include an updated set of the VLAN packet socket fixes,
> now also supporting VLAN TCI delivery to userspace using mmaped packet
> sockets, as well as a patch to add ->get_flags ethtool support and
> a few minor cleanup patches.
Applied and pushed out to net-next-2.6, thanks Patrick.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2008-07-15 5:56 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-09 12:09 [PATCH 00/08]: VLAN update Patrick McHardy
2008-07-09 12:09 ` [PATCH 01/08]: vlan: Don't store VLAN tag in cb Patrick McHardy
2008-07-09 12:09 ` [PATCH 02/08]: vlan: deliver packets received with VLAN acceleration to network taps Patrick McHardy
2008-07-09 12:35 ` Ben Hutchings
2008-07-09 12:37 ` Patrick McHardy
2008-07-09 12:09 ` [PATCH 03/08]: packet: support extensible, 64 bit clean mmaped ring structure Patrick McHardy
2008-07-09 12:09 ` [PATCH 04/08]: packet: deliver VLAN TCI to userspace Patrick McHardy
2008-07-09 12:09 ` [PATCH 05/08]: vlan: ethtool ->get_flags support Patrick McHardy
2008-07-09 12:09 ` [PATCH 06/08]: vlan: clean up vlan_dev_hard_header() Patrick McHardy
2008-07-09 12:09 ` [PATCH 07/08]: vlan: clean up hard_start_xmit functions Patrick McHardy
2008-07-09 12:09 ` [PATCH 08/08]: vlan: remove unnecessary include statements Patrick McHardy
2008-07-09 12:12 ` [PATCH 00/08]: VLAN update Patrick McHardy
2008-07-15 5:56 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).