8383#include <net/netfilter/nf_conntrack_bpf.h>
8484#include <net/netkit.h>
8585#include <linux/un.h>
86+ #include <net/xdp_sock_drv.h>
8687
8788#include "dev.h"
8889
@@ -4094,6 +4095,42 @@ static int bpf_xdp_frags_increase_tail(struct xdp_buff *xdp, int offset)
40944095 return 0 ;
40954096}
40964097
4098+ static void __shrink_data (struct xdp_buff * xdp , struct xdp_mem_info * mem_info ,
4099+ skb_frag_t * frag , int shrink )
4100+ {
4101+ if (mem_info -> type == MEM_TYPE_XSK_BUFF_POOL ) {
4102+ struct xdp_buff * tail = xsk_buff_get_tail (xdp );
4103+
4104+ if (tail )
4105+ tail -> data_end -= shrink ;
4106+ }
4107+ skb_frag_size_sub (frag , shrink );
4108+ }
4109+
4110+ static bool shrink_data (struct xdp_buff * xdp , skb_frag_t * frag , int shrink )
4111+ {
4112+ struct xdp_mem_info * mem_info = & xdp -> rxq -> mem ;
4113+
4114+ if (skb_frag_size (frag ) == shrink ) {
4115+ struct page * page = skb_frag_page (frag );
4116+ struct xdp_buff * zc_frag = NULL ;
4117+
4118+ if (mem_info -> type == MEM_TYPE_XSK_BUFF_POOL ) {
4119+ zc_frag = xsk_buff_get_tail (xdp );
4120+
4121+ if (zc_frag ) {
4122+ xdp_buff_clear_frags_flag (zc_frag );
4123+ xsk_buff_tail_del (zc_frag );
4124+ }
4125+ }
4126+
4127+ __xdp_return (page_address (page ), mem_info , false, zc_frag );
4128+ return true;
4129+ }
4130+ __shrink_data (xdp , mem_info , frag , shrink );
4131+ return false;
4132+ }
4133+
40974134static int bpf_xdp_frags_shrink_tail (struct xdp_buff * xdp , int offset )
40984135{
40994136 struct skb_shared_info * sinfo = xdp_get_shared_info_from_buff (xdp );
@@ -4108,17 +4145,10 @@ static int bpf_xdp_frags_shrink_tail(struct xdp_buff *xdp, int offset)
41084145
41094146 len_free += shrink ;
41104147 offset -= shrink ;
4111-
4112- if (skb_frag_size (frag ) == shrink ) {
4113- struct page * page = skb_frag_page (frag );
4114-
4115- __xdp_return (page_address (page ), & xdp -> rxq -> mem ,
4116- false, NULL );
4148+ if (shrink_data (xdp , frag , shrink ))
41174149 n_frags_free ++ ;
4118- } else {
4119- skb_frag_size_sub (frag , shrink );
4150+ else
41204151 break ;
4121- }
41224152 }
41234153 sinfo -> nr_frags -= n_frags_free ;
41244154 sinfo -> xdp_frags_size -= len_free ;
0 commit comments