@@ -1265,9 +1265,9 @@ struct wolfIP {
12651265#endif
12661266 uint8_t loopback_buf [WOLFIP_LOOPBACK_QUEUE_DEPTH ][IP_MTU_MAX ];
12671267 uint32_t loopback_pending_len [WOLFIP_LOOPBACK_QUEUE_DEPTH ];
1268- uint8_t loopback_head ;
1269- uint8_t loopback_tail ;
1270- uint8_t loopback_count ;
1268+ uint32_t loopback_head ;
1269+ uint32_t loopback_tail ;
1270+ uint32_t loopback_count ;
12711271#endif
12721272};
12731273
@@ -1372,10 +1372,46 @@ static inline uint32_t tcp_tx_payload_cap(const struct tsocket *t)
13721372
13731373#if WOLFIP_ENABLE_LOOPBACK
13741374
1375+ static void wolfIP_notify_loopback_space_available (struct wolfIP * s )
1376+ {
1377+ int i ;
1378+
1379+ if (!s )
1380+ return ;
1381+
1382+ for (i = 0 ; i < MAX_TCPSOCKETS ; i ++ ) {
1383+ struct tsocket * t = & s -> tcpsockets [i ];
1384+ if (t -> proto != WI_IPPROTO_TCP )
1385+ continue ;
1386+ if (wolfIP_socket_if_idx (t ) != WOLFIP_LOOPBACK_IF_IDX )
1387+ continue ;
1388+ if (tx_has_writable_space (t ))
1389+ t -> events |= CB_EVENT_WRITABLE ;
1390+ }
1391+ for (i = 0 ; i < MAX_UDPSOCKETS ; i ++ ) {
1392+ struct tsocket * t = & s -> udpsockets [i ];
1393+ if (t -> proto != WI_IPPROTO_UDP )
1394+ continue ;
1395+ if (wolfIP_socket_if_idx (t ) != WOLFIP_LOOPBACK_IF_IDX )
1396+ continue ;
1397+ if (tx_has_writable_space (t ))
1398+ t -> events |= CB_EVENT_WRITABLE ;
1399+ }
1400+ for (i = 0 ; i < MAX_ICMPSOCKETS ; i ++ ) {
1401+ struct tsocket * t = & s -> icmpsockets [i ];
1402+ if (t -> proto != WI_IPPROTO_ICMP )
1403+ continue ;
1404+ if (wolfIP_socket_if_idx (t ) != WOLFIP_LOOPBACK_IF_IDX )
1405+ continue ;
1406+ if (tx_has_writable_space (t ))
1407+ t -> events |= CB_EVENT_WRITABLE ;
1408+ }
1409+ }
1410+
13751411static int wolfIP_loopback_send (struct wolfIP_ll_dev * ll , void * buf , uint32_t len )
13761412{
13771413 struct wolfIP * s ;
1378- uint8_t slot ;
1414+ uint32_t slot ;
13791415 if (!ll || !buf )
13801416 return -1 ;
13811417 s = WOLFIP_CONTAINER_OF (ll , struct wolfIP , ll_dev );
@@ -1391,16 +1427,17 @@ static int wolfIP_loopback_send(struct wolfIP_ll_dev *ll, void *buf, uint32_t le
13911427 slot = s -> loopback_tail ;
13921428 memcpy (s -> loopback_buf [slot ], buf , len );
13931429 s -> loopback_pending_len [slot ] = len ;
1394- s -> loopback_tail = (uint8_t )(( slot + 1U ) % WOLFIP_LOOPBACK_QUEUE_DEPTH ) ;
1430+ s -> loopback_tail = (slot + 1U ) % WOLFIP_LOOPBACK_QUEUE_DEPTH ;
13951431 s -> loopback_count ++ ;
13961432 return (int )len ;
13971433}
13981434
13991435static int wolfIP_loopback_poll (struct wolfIP_ll_dev * ll , void * buf , uint32_t len )
14001436{
14011437 struct wolfIP * s ;
1402- uint8_t slot ;
1438+ uint32_t slot ;
14031439 uint32_t pending ;
1440+ int queue_was_full ;
14041441 if (!ll || !buf )
14051442 return 0 ;
14061443 s = WOLFIP_CONTAINER_OF (ll , struct wolfIP , ll_dev );
@@ -1412,10 +1449,13 @@ static int wolfIP_loopback_poll(struct wolfIP_ll_dev *ll, void *buf, uint32_t le
14121449 pending = s -> loopback_pending_len [slot ];
14131450 if (pending > len )
14141451 return 0 ;
1452+ queue_was_full = (s -> loopback_count >= WOLFIP_LOOPBACK_QUEUE_DEPTH ) ? 1 : 0 ;
14151453 memcpy (buf , s -> loopback_buf [slot ], pending );
14161454 s -> loopback_pending_len [slot ] = 0 ;
1417- s -> loopback_head = (uint8_t )(( slot + 1U ) % WOLFIP_LOOPBACK_QUEUE_DEPTH ) ;
1455+ s -> loopback_head = (slot + 1U ) % WOLFIP_LOOPBACK_QUEUE_DEPTH ;
14181456 s -> loopback_count -- ;
1457+ if (queue_was_full )
1458+ wolfIP_notify_loopback_space_available (s );
14191459 return (int )pending ;
14201460}
14211461#endif
@@ -1436,24 +1476,23 @@ static inline int wolfIP_ll_is_non_ethernet(struct wolfIP *s, unsigned int if_id
14361476 return (ll && ll -> non_ethernet ) ? 1 : 0 ;
14371477}
14381478
1439- static inline void wolfIP_ll_send_frame (struct wolfIP * s , unsigned int if_idx ,
1440- void * buf , uint32_t len )
1479+ static inline int wolfIP_ll_send_frame (struct wolfIP * s , unsigned int if_idx ,
1480+ void * buf , uint32_t len )
14411481{
14421482 struct wolfIP_ll_dev * ll = wolfIP_ll_at (s , if_idx );
14431483 uint32_t frame_mtu ;
14441484
14451485 if (!ll || !ll -> send )
1446- return ;
1486+ return -1 ;
14471487 frame_mtu = wolfIP_ll_frame_mtu (ll );
14481488 if (len > frame_mtu )
1449- return ;
1489+ return -1 ;
14501490 if (ll -> non_ethernet ) {
14511491 if (len <= ETH_HEADER_LEN )
1452- return ;
1453- ll -> send (ll , (uint8_t * )buf + ETH_HEADER_LEN , len - ETH_HEADER_LEN );
1454- return ;
1492+ return -1 ;
1493+ return ll -> send (ll , (uint8_t * )buf + ETH_HEADER_LEN , len - ETH_HEADER_LEN );
14551494 }
1456- ll -> send (ll , buf , len );
1495+ return ll -> send (ll , buf , len );
14571496}
14581497
14591498static inline struct ipconf * wolfIP_ipconf_at (struct wolfIP * s , unsigned int if_idx )
@@ -2605,8 +2644,10 @@ static int tcp_send_empty_immediate(struct tsocket *t, struct wolfIP_tcp_seg *tc
26052644 }
26062645#endif
26072646
2608- wolfIP_ll_send_frame (t -> S , tx_if , tcp , frame_len );
2609- return 0 ;
2647+ {
2648+ int send_ret = wolfIP_ll_send_frame (t -> S , tx_if , tcp , frame_len );
2649+ return (send_ret < 0 ) ? send_ret : 0 ;
2650+ }
26102651}
26112652
26122653static int tcp_send_empty (struct tsocket * t , uint8_t flags )
@@ -7567,6 +7608,7 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)
75677608 while (desc && send_guard ++ < send_budget ) {
75687609 unsigned int tx_if = wolfIP_socket_if_idx (ts );
75697610 struct pkt_desc * next_desc = NULL ;
7611+ int send_ret = 0 ;
75707612 tcp = (struct wolfIP_tcp_seg * )(ts -> txmem + desc -> pos + sizeof (* desc ));
75717613 if (desc -> flags & PKT_FLAG_SENT ) {
75727614 next_desc = fifo_next (& ts -> sock .tcp .txbuf , desc );
@@ -7633,15 +7675,22 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)
76337675 if (esp_err == 1 ) {
76347676 /* ipsec not configured on this interface.
76357677 * send plaintext. */
7636- wolfIP_ll_send_frame (s , tx_if , tcp , desc -> len );
7678+ send_ret = wolfIP_ll_send_frame (s , tx_if , tcp , desc -> len );
76377679 }
76387680 } else {
7639- wolfIP_ll_send_frame (s , tx_if , tcp , desc -> len );
7681+ send_ret = wolfIP_ll_send_frame (s , tx_if , tcp , desc -> len );
76407682 }
76417683 #else
7642- wolfIP_ll_send_frame (s , tx_if , tcp , desc -> len );
7684+ send_ret = wolfIP_ll_send_frame (s , tx_if , tcp , desc -> len );
76437685 #endif /* WOLFIP_ESP */
76447686 }
7687+ if (send_ret == - WOLFIP_EAGAIN ) {
7688+ if (tx_has_writable_space (ts ))
7689+ ts -> events |= CB_EVENT_WRITABLE ;
7690+ break ;
7691+ }
7692+ if (send_ret < 0 )
7693+ break ;
76457694 desc -> flags |= PKT_FLAG_SENT ;
76467695 desc -> flags &= ~PKT_FLAG_RETRANS ;
76477696 if (is_retrans )
@@ -7697,6 +7746,7 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)
76977746 while (desc ) {
76987747 struct wolfIP_udp_datagram * udp = (struct wolfIP_udp_datagram * )(t -> txmem + desc -> pos + sizeof (* desc ));
76997748 unsigned int tx_if = wolfIP_socket_if_idx (t );
7749+ int send_ret = 0 ;
77007750#ifdef ETHERNET
77017751 struct ipconf * conf = wolfIP_ipconf_at (s , tx_if );
77027752 ip4 nexthop = wolfIP_select_nexthop (conf , t -> remote_ip );
@@ -7737,15 +7787,19 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)
77377787 if (esp_send (ll , (struct wolfIP_ip_packet * )udp , len ) == 1 ) {
77387788 /* ipsec not configured on this interface.
77397789 * send plaintext. */
7740- wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
7790+ send_ret = wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
77417791 }
77427792 } else {
7743- wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
7793+ send_ret = wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
77447794 }
77457795 #else
7746- wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
7796+ send_ret = wolfIP_ll_send_frame (s , tx_if , udp , desc -> len );
77477797 #endif /* WOLFIP_ESP */
77487798 }
7799+ if (send_ret == - WOLFIP_EAGAIN )
7800+ break ;
7801+ if (send_ret < 0 )
7802+ break ;
77497803 fifo_pop (& t -> sock .udp .txbuf );
77507804 desc = fifo_peek (& t -> sock .udp .txbuf );
77517805 }
@@ -7756,6 +7810,7 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)
77567810 while (desc ) {
77577811 struct wolfIP_icmp_packet * icmp = (struct wolfIP_icmp_packet * )(t -> txmem + desc -> pos + sizeof (* desc ));
77587812 unsigned int tx_if = wolfIP_socket_if_idx (t );
7813+ int send_ret = 0 ;
77597814#ifdef ETHERNET
77607815 struct ipconf * conf = wolfIP_ipconf_at (s , tx_if );
77617816 ip4 nexthop = wolfIP_select_nexthop (conf , t -> remote_ip );
@@ -7792,15 +7847,19 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)
77927847 if (esp_send (ll , (struct wolfIP_ip_packet * )icmp , len ) == 1 ) {
77937848 /* ipsec not configured on this interface.
77947849 * send plaintext. */
7795- wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
7850+ send_ret = wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
77967851 }
77977852 } else {
7798- wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
7853+ send_ret = wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
77997854 }
78007855 #else
7801- wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
7856+ send_ret = wolfIP_ll_send_frame (s , tx_if , icmp , desc -> len );
78027857 #endif /* WOLFIP_ESP */
78037858 }
7859+ if (send_ret == - WOLFIP_EAGAIN )
7860+ break ;
7861+ if (send_ret < 0 )
7862+ break ;
78047863 fifo_pop (& t -> sock .udp .txbuf );
78057864 desc = fifo_peek (& t -> sock .udp .txbuf );
78067865 }
0 commit comments