···4848#define PACKET_RESERVE 124949#define PACKET_TX_RING 135050#define PACKET_LOSS 145151-#define PACKET_GAPDATA 1552515352struct tpacket_stats5453{5554 unsigned int tp_packets;5655 unsigned int tp_drops;5757- unsigned int tp_gap;5856};59576058struct tpacket_auxdata
-33
net/packet/af_packet.c
···525525}526526527527/*528528- * If we've lost frames since the last time we queued one to the529529- * sk_receive_queue, we need to record it here.530530- * This must be called under the protection of the socket lock531531- * to prevent racing with other softirqs and user space532532- */533533-static inline void record_packet_gap(struct sk_buff *skb,534534- struct packet_sock *po)535535-{536536- /*537537- * We overload the mark field here, since we're about538538- * to enqueue to a receive queue and no body else will539539- * use this field at this point540540- */541541- skb->mark = po->stats.tp_gap;542542- po->stats.tp_gap = 0;543543- return;544544-545545-}546546-547547-static inline __u32 check_packet_gap(struct sk_buff *skb)548548-{549549- return skb->mark;550550-}551551-552552-/*553528 This function makes lazy skb cloning in hope that most of packets554529 are discarded by BPF.555530···627652628653 spin_lock(&sk->sk_receive_queue.lock);629654 po->stats.tp_packets++;630630- record_packet_gap(skb, po);631655 __skb_queue_tail(&sk->sk_receive_queue, skb);632656 spin_unlock(&sk->sk_receive_queue.lock);633657 sk->sk_data_ready(sk, skb->len);···635661drop_n_acct:636662 spin_lock(&sk->sk_receive_queue.lock);637663 po->stats.tp_drops++;638638- po->stats.tp_gap++;639664 spin_unlock(&sk->sk_receive_queue.lock);640665641666drop_n_restore:···812839813840ring_is_full:814841 po->stats.tp_drops++;815815- po->stats.tp_gap++;816842 spin_unlock(&sk->sk_receive_queue.lock);817843818844 sk->sk_data_ready(sk, 0);···14211449 struct sk_buff *skb;14221450 int copied, err;14231451 struct sockaddr_ll *sll;14241424- __u32 gap;1425145214261453 err = -EINVAL;14271454 if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))···1498152714991528 put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);15001529 }15011501-15021502- gap = check_packet_gap(skb);15031503- if (gap)15041504- put_cmsg(msg, SOL_PACKET, PACKET_GAPDATA, sizeof(__u32), &gap);1505153015061531 /*15071532 * Free or return the buffer as appropriate. Again this