Add new sockopt to reserve some headroom in the mmaped ring frames in
front of the packet payload. This can be used f.i. when the VLAN header
needs to be (re)constructed to avoid moving the entire payload.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
#define PACKET_ORIGDEV 9
#define PACKET_VERSION 10
#define PACKET_HDRLEN 11
#define PACKET_ORIGDEV 9
#define PACKET_VERSION 10
#define PACKET_HDRLEN 11
+#define PACKET_RESERVE 12
unsigned int pg_vec_len;
enum tpacket_versions tp_version;
unsigned int tp_hdrlen;
unsigned int pg_vec_len;
enum tpacket_versions tp_version;
unsigned int tp_hdrlen;
+ unsigned int tp_reserve;
snaplen = res;
if (sk->sk_type == SOCK_DGRAM) {
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 +
} 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;
}
macoff = netoff - maclen;
}
+ 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:
{
#endif
case PACKET_AUXDATA:
{
+ case PACKET_RESERVE:
+ if (len > sizeof(unsigned int))
+ len = sizeof(unsigned int);
+ val = po->tp_reserve;
+ data = &val;
+ break;
#endif
default:
return -ENOPROTOOPT;
#endif
default:
return -ENOPROTOOPT;
return -EINVAL;
if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
return -EINVAL;
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;
return -EINVAL;
if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
return -EINVAL;