3636#include "xsk_queue.h"
3737#include "xdp_umem.h"
3838
39+ #define TX_BATCH_SIZE 16
40+
3941static struct xdp_sock * xdp_sk (struct sock * sk )
4042{
4143 return (struct xdp_sock * )sk ;
@@ -101,6 +103,108 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
101103 return err ;
102104}
103105
106+ static void xsk_destruct_skb (struct sk_buff * skb )
107+ {
108+ u32 id = (u32 )(long )skb_shinfo (skb )-> destructor_arg ;
109+ struct xdp_sock * xs = xdp_sk (skb -> sk );
110+
111+ WARN_ON_ONCE (xskq_produce_id (xs -> umem -> cq , id ));
112+
113+ sock_wfree (skb );
114+ }
115+
116+ static int xsk_generic_xmit (struct sock * sk , struct msghdr * m ,
117+ size_t total_len )
118+ {
119+ bool need_wait = !(m -> msg_flags & MSG_DONTWAIT );
120+ u32 max_batch = TX_BATCH_SIZE ;
121+ struct xdp_sock * xs = xdp_sk (sk );
122+ bool sent_frame = false;
123+ struct xdp_desc desc ;
124+ struct sk_buff * skb ;
125+ int err = 0 ;
126+
127+ if (unlikely (!xs -> tx ))
128+ return - ENOBUFS ;
129+ if (need_wait )
130+ return - EOPNOTSUPP ;
131+
132+ mutex_lock (& xs -> mutex );
133+
134+ while (xskq_peek_desc (xs -> tx , & desc )) {
135+ char * buffer ;
136+ u32 id , len ;
137+
138+ if (max_batch -- == 0 ) {
139+ err = - EAGAIN ;
140+ goto out ;
141+ }
142+
143+ if (xskq_reserve_id (xs -> umem -> cq )) {
144+ err = - EAGAIN ;
145+ goto out ;
146+ }
147+
148+ len = desc .len ;
149+ if (unlikely (len > xs -> dev -> mtu )) {
150+ err = - EMSGSIZE ;
151+ goto out ;
152+ }
153+
154+ skb = sock_alloc_send_skb (sk , len , !need_wait , & err );
155+ if (unlikely (!skb )) {
156+ err = - EAGAIN ;
157+ goto out ;
158+ }
159+
160+ skb_put (skb , len );
161+ id = desc .idx ;
162+ buffer = xdp_umem_get_data (xs -> umem , id ) + desc .offset ;
163+ err = skb_store_bits (skb , 0 , buffer , len );
164+ if (unlikely (err )) {
165+ kfree_skb (skb );
166+ goto out ;
167+ }
168+
169+ skb -> dev = xs -> dev ;
170+ skb -> priority = sk -> sk_priority ;
171+ skb -> mark = sk -> sk_mark ;
172+ skb_shinfo (skb )-> destructor_arg = (void * )(long )id ;
173+ skb -> destructor = xsk_destruct_skb ;
174+
175+ err = dev_direct_xmit (skb , xs -> queue_id );
176+ /* Ignore NET_XMIT_CN as packet might have been sent */
177+ if (err == NET_XMIT_DROP || err == NETDEV_TX_BUSY ) {
178+ err = - EAGAIN ;
179+ /* SKB consumed by dev_direct_xmit() */
180+ goto out ;
181+ }
182+
183+ sent_frame = true;
184+ xskq_discard_desc (xs -> tx );
185+ }
186+
187+ out :
188+ if (sent_frame )
189+ sk -> sk_write_space (sk );
190+
191+ mutex_unlock (& xs -> mutex );
192+ return err ;
193+ }
194+
195+ static int xsk_sendmsg (struct socket * sock , struct msghdr * m , size_t total_len )
196+ {
197+ struct sock * sk = sock -> sk ;
198+ struct xdp_sock * xs = xdp_sk (sk );
199+
200+ if (unlikely (!xs -> dev ))
201+ return - ENXIO ;
202+ if (unlikely (!(xs -> dev -> flags & IFF_UP )))
203+ return - ENETDOWN ;
204+
205+ return xsk_generic_xmit (sk , m , total_len );
206+ }
207+
104208static unsigned int xsk_poll (struct file * file , struct socket * sock ,
105209 struct poll_table_struct * wait )
106210{
@@ -110,6 +214,8 @@ static unsigned int xsk_poll(struct file *file, struct socket *sock,
110214
111215 if (xs -> rx && !xskq_empty_desc (xs -> rx ))
112216 mask |= POLLIN | POLLRDNORM ;
217+ if (xs -> tx && !xskq_full_desc (xs -> tx ))
218+ mask |= POLLOUT | POLLWRNORM ;
113219
114220 return mask ;
115221}
@@ -270,6 +376,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
270376 xs -> queue_id = sxdp -> sxdp_queue_id ;
271377
272378 xskq_set_umem (xs -> rx , & xs -> umem -> props );
379+ xskq_set_umem (xs -> tx , & xs -> umem -> props );
273380
274381out_unlock :
275382 if (err )
@@ -383,8 +490,6 @@ static int xsk_mmap(struct file *file, struct socket *sock,
383490 q = xs -> umem -> fq ;
384491 else if (offset == XDP_UMEM_PGOFF_COMPLETION_RING )
385492 q = xs -> umem -> cq ;
386- else
387- return - EINVAL ;
388493 }
389494
390495 if (!q )
@@ -420,7 +525,7 @@ static const struct proto_ops xsk_proto_ops = {
420525 .shutdown = sock_no_shutdown ,
421526 .setsockopt = xsk_setsockopt ,
422527 .getsockopt = sock_no_getsockopt ,
423- .sendmsg = sock_no_sendmsg ,
528+ .sendmsg = xsk_sendmsg ,
424529 .recvmsg = sock_no_recvmsg ,
425530 .mmap = xsk_mmap ,
426531 .sendpage = sock_no_sendpage ,
0 commit comments