From f383754400735b53e5afa3f2f12c23da919150b0 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 18 Jul 2008 18:05:19 -0700 Subject: [PATCH] --- yaml --- r: 103637 b: refs/heads/master c: 8913336a7e8d56e984109a3137d6c0e3362596a4 h: refs/heads/master i: 103635: e6e398d77a089a9f28037f74debd74d8074e3add v: v3 --- [refs] | 2 +- trunk/include/linux/if_packet.h | 1 + trunk/net/packet/af_packet.c | 29 ++++++++++++++++++++++++++--- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 42b51a92a50d..92e4b5773d3c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3ca4095f246c21c285d9e4be2ea4d3ee7fbacebd +refs/heads/master: 8913336a7e8d56e984109a3137d6c0e3362596a4 diff --git a/trunk/include/linux/if_packet.h b/trunk/include/linux/if_packet.h index a630295b255f..18db0668065a 100644 --- a/trunk/include/linux/if_packet.h +++ b/trunk/include/linux/if_packet.h @@ -45,6 +45,7 @@ struct sockaddr_ll #define PACKET_ORIGDEV 9 #define PACKET_VERSION 10 #define PACKET_HDRLEN 11 +#define PACKET_RESERVE 12 struct tpacket_stats { diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index db792e02a37f..de73bcb5235a 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -188,6 +188,7 @@ struct packet_sock { unsigned int pg_vec_len; enum tpacket_versions tp_version; unsigned int tp_hdrlen; + unsigned int tp_reserve; #endif }; @@ -635,11 +636,13 @@ 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(po->tp_hdrlen) + 16; + macoff = netoff = TPACKET_ALIGN(po->tp_hdrlen) + 16 + + po->tp_reserve; } else { unsigned maclen = skb_network_offset(skb); netoff = TPACKET_ALIGN(po->tp_hdrlen + - (maclen < 16 ? 16 : maclen)); + (maclen < 16 ? 16 : maclen)) + + po->tp_reserve; macoff = netoff - maclen; } @@ -1448,6 +1451,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv return -EINVAL; } } + case PACKET_RESERVE: + { + unsigned int val; + + if (optlen != sizeof(val)) + return -EINVAL; + if (po->pg_vec) + return -EBUSY; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; + po->tp_reserve = val; + return 0; + } #endif case PACKET_AUXDATA: { @@ -1547,6 +1563,12 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, } data = &val; break; + case PACKET_RESERVE: + if (len > sizeof(unsigned int)) + len = sizeof(unsigned int); + val = po->tp_reserve; + data = &val; + break; #endif default: return -ENOPROTOOPT; @@ -1790,7 +1812,8 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing return -EINVAL; if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) return -EINVAL; - if (unlikely(req->tp_frame_size < po->tp_hdrlen)) + if (unlikely(req->tp_frame_size < po->tp_hdrlen + + po->tp_reserve)) return -EINVAL; if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1))) return -EINVAL;