Skip to content

Commit 061c6ca

Browse files
gasbytesdanielinux
authored andcommitted
Merge icmp and udp into one single function when reading datagrams
The is_udp flag was introduced to differ in 4 bits where udp does something different from icmp: - any multicast interaction (this includes the next jump (hop) and the loopback); - tx_drained logic (that checks if we sent at least one datagram), so that we can "wake" the sender whenever we actually have freed some space in the buffer; One minor bit is the notify logic was using t->S instead of directly using the stack pointer already passed into the function.
1 parent c20a6c9 commit 061c6ca

1 file changed

Lines changed: 50 additions & 112 deletions

File tree

src/wolfip.c

Lines changed: 50 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -10280,17 +10280,20 @@ static void flush_tcp_tx(struct wolfIP *s, uint64_t now)
1028010280
}
1028110281
}
1028210282

10283-
static void flush_udp_tx(struct wolfIP *s)
10283+
static void flush_datagram_tx(struct wolfIP *s, struct tsocket *socks,
10284+
int count, uint8_t proto)
1028410285
{
1028510286
int i;
10286-
int len;
10287+
int is_udp = (proto == WI_IPPROTO_UDP);
1028710288

10288-
for (i = 0; i < MAX_UDPSOCKETS; i++) {
10289-
struct tsocket *t = &s->udpsockets[i];
10289+
for (i = 0; i < count; i++) {
10290+
struct tsocket *t = &socks[i];
1029010291
struct pkt_desc *desc = fifo_peek(&t->sock.udp.txbuf);
1029110292
int tx_drained = 0;
10293+
int len;
1029210294
while (desc) {
10293-
struct wolfIP_udp_datagram *udp = (struct wolfIP_udp_datagram *)(t->txmem + desc->pos + sizeof(*desc));
10295+
struct wolfIP_ip_packet *ip =
10296+
(struct wolfIP_ip_packet *)(t->txmem + desc->pos + sizeof(*desc));
1029410297
unsigned int tx_if = wolfIP_socket_if_idx(t);
1029510298
int send_ret = 0;
1029610299
#ifdef ETHERNET
@@ -10301,144 +10304,79 @@ static void flush_udp_tx(struct wolfIP *s)
1030110304
memcpy(t->nexthop_mac, loop->mac, 6);
1030210305
} else if (!wolfIP_ll_is_non_ethernet(s, tx_if)) {
1030310306
#ifdef IP_MULTICAST
10304-
if (wolfIP_ip_is_multicast(t->remote_ip)) {
10307+
if (is_udp && wolfIP_ip_is_multicast(t->remote_ip)) {
1030510308
mcast_ip_to_eth(t->remote_ip, t->nexthop_mac);
1030610309
} else
1030710310
#endif
10308-
if ((!wolfIP_ip_is_broadcast(s, nexthop) &&
10309-
(arp_lookup(s, tx_if, nexthop, t->nexthop_mac) < 0))) {
10310-
/* Send ARP request */
10311-
arp_request(s, tx_if, nexthop);
10312-
break;
10313-
}
10311+
if (!wolfIP_ip_is_broadcast(s, nexthop) &&
10312+
arp_lookup(s, tx_if, nexthop, t->nexthop_mac) < 0) {
10313+
/* Send ARP request */
10314+
arp_request(s, tx_if, nexthop);
10315+
break;
10316+
}
1031410317
if (wolfIP_ip_is_broadcast(s, nexthop))
1031510318
memset(t->nexthop_mac, 0xFF, 6);
1031610319
}
1031710320
#endif
1031810321
len = desc->len - ETH_HEADER_LEN;
10319-
ip_output_add_header(t, (struct wolfIP_ip_packet *)udp, WI_IPPROTO_UDP, len);
10320-
if (wolfIP_filter_notify_udp(WOLFIP_FILT_SENDING, t->S, tx_if, udp, desc->len) != 0)
10321-
break;
10322-
if (wolfIP_filter_notify_ip(WOLFIP_FILT_SENDING, t->S, tx_if, &udp->ip, desc->len) != 0)
10322+
ip_output_add_header(t, ip, proto, len);
10323+
10324+
if (is_udp) {
10325+
if (wolfIP_filter_notify_udp(WOLFIP_FILT_SENDING, s, tx_if,
10326+
(struct wolfIP_udp_datagram *)ip, desc->len) != 0)
10327+
break;
10328+
} else {
10329+
if (wolfIP_filter_notify_icmp(WOLFIP_FILT_SENDING, s, tx_if,
10330+
(struct wolfIP_icmp_packet *)ip, desc->len) != 0)
10331+
break;
10332+
}
10333+
if (wolfIP_filter_notify_ip(WOLFIP_FILT_SENDING, s, tx_if, ip, desc->len) != 0)
1032310334
break;
1032410335
#ifdef ETHERNET
1032510336
if (!wolfIP_ll_is_non_ethernet(t->S, tx_if)) {
10326-
if (wolfIP_filter_notify_eth(WOLFIP_FILT_SENDING, t->S, tx_if, &udp->ip.eth, desc->len) != 0)
10337+
if (wolfIP_filter_notify_eth(WOLFIP_FILT_SENDING, s, tx_if,
10338+
&ip->eth, desc->len) != 0)
1032710339
break;
1032810340
}
1032910341
#endif
10330-
{
10331-
#ifdef DEBUG_UDP
10332-
wolfIP_print_udp(udp);
10333-
#endif /* DEBUG_UDP */
10334-
#ifdef WOLFIP_ESP
10335-
if (!wolfIP_ll_is_non_ethernet(s, tx_if)) {
10336-
struct wolfIP_ll_dev *ll = wolfIP_ll_at(s, tx_if);
10337-
if (esp_send(ll, (struct wolfIP_ip_packet *)udp, len) == 1) {
10338-
/* ipsec not configured on this interface.
10339-
* send plaintext. */
10340-
send_ret = wolfIP_ll_send_frame(s, tx_if, udp, desc->len);
10341-
}
10342-
} else {
10343-
send_ret = wolfIP_ll_send_frame(s, tx_if, udp, desc->len);
10344-
}
10345-
#else
10346-
send_ret = wolfIP_ll_send_frame(s, tx_if, udp, desc->len);
10347-
#endif /* WOLFIP_ESP */
10342+
#ifdef WOLFIP_ESP
10343+
if (!wolfIP_ll_is_non_ethernet(s, tx_if)) {
10344+
struct wolfIP_ll_dev *ll = wolfIP_ll_at(s, tx_if);
10345+
/* IPsec not configured on this interface.
10346+
* Send plaintext instead.
10347+
* */
10348+
if (esp_send(ll, ip, len) == 1)
10349+
send_ret = wolfIP_ll_send_frame(s, tx_if, ip, desc->len);
10350+
} else {
10351+
send_ret = wolfIP_ll_send_frame(s, tx_if, ip, desc->len);
1034810352
}
10349-
if (send_ret == -WOLFIP_EAGAIN)
10350-
break;
10351-
if (send_ret < 0)
10353+
#else
10354+
send_ret = wolfIP_ll_send_frame(s, tx_if, ip, desc->len);
10355+
#endif
10356+
if (send_ret == -WOLFIP_EAGAIN || send_ret < 0)
1035210357
break;
1035310358
#ifdef IP_MULTICAST
10354-
/* Loopback only after a successful wire send. Running udp_try_recv
10359+
/* UDP: Loopback only after a successful wire send. Running udp_try_recv
1035510360
* before the filter/send path caused repeated local deliveries
1035610361
* when a SENDING filter blocked the frame or the driver returned
1035710362
* -EAGAIN: the descriptor stays in the txbuf and every subsequent
1035810363
* wolfIP_poll() re-enters the loop and re-loops the datagram. */
10359-
if (wolfIP_ip_is_multicast(t->remote_ip) && t->sock.udp.mcast_loop) {
10360-
udp_try_recv(s, tx_if, udp, desc->len);
10361-
}
10364+
if (is_udp && wolfIP_ip_is_multicast(t->remote_ip) && t->sock.udp.mcast_loop)
10365+
udp_try_recv(s, tx_if, (struct wolfIP_udp_datagram *)ip, desc->len);
1036210366
#endif
1036310367
fifo_pop(&t->sock.udp.txbuf);
1036410368
tx_drained = 1;
1036510369
desc = fifo_peek(&t->sock.udp.txbuf);
1036610370
}
10367-
/* Draining the txbuf frees space; raise CB_EVENT_WRITABLE so a sender
10371+
/* UDP: Draining the txbuf frees space; raise CB_EVENT_WRITABLE so a sender
1036810372
* blocked on a full buffer (e.g. the FreeRTOS BSD shim's sendto()) is
1036910373
* woken. The loopback path is handled separately via
1037010374
* wolfIP_notify_loopback_space_available(). */
10371-
if (tx_drained && tx_has_writable_space(t))
10375+
if (is_udp && tx_drained && tx_has_writable_space(t))
1037210376
t->events |= CB_EVENT_WRITABLE;
1037310377
}
1037410378
}
1037510379

10376-
static void flush_icmp_tx(struct wolfIP *s)
10377-
{
10378-
int i;
10379-
int len;
10380-
10381-
for (i = 0; i < MAX_ICMPSOCKETS; i++) {
10382-
struct tsocket *t = &s->icmpsockets[i];
10383-
struct pkt_desc *desc = fifo_peek(&t->sock.udp.txbuf);
10384-
while (desc) {
10385-
struct wolfIP_icmp_packet *icmp = (struct wolfIP_icmp_packet *)(t->txmem + desc->pos + sizeof(*desc));
10386-
unsigned int tx_if = wolfIP_socket_if_idx(t);
10387-
int send_ret = 0;
10388-
#ifdef ETHERNET
10389-
ip4 nexthop = wolfIP_select_nexthop_ex(s, &tx_if, t->remote_ip);
10390-
if (wolfIP_is_loopback_if(tx_if)) {
10391-
struct wolfIP_ll_dev *loop = wolfIP_ll_at(s, tx_if);
10392-
if (loop)
10393-
memcpy(t->nexthop_mac, loop->mac, 6);
10394-
} else if (!wolfIP_ll_is_non_ethernet(s, tx_if)) {
10395-
if ((!wolfIP_ip_is_broadcast(s, nexthop) &&
10396-
(arp_lookup(s, tx_if, nexthop, t->nexthop_mac) < 0))) {
10397-
arp_request(s, tx_if, nexthop);
10398-
break;
10399-
}
10400-
if (wolfIP_ip_is_broadcast(s, nexthop))
10401-
memset(t->nexthop_mac, 0xFF, 6);
10402-
}
10403-
#endif
10404-
len = desc->len - ETH_HEADER_LEN;
10405-
ip_output_add_header(t, (struct wolfIP_ip_packet *)icmp, WI_IPPROTO_ICMP, len);
10406-
if (wolfIP_filter_notify_icmp(WOLFIP_FILT_SENDING, t->S, tx_if, icmp, desc->len) != 0)
10407-
break;
10408-
if (wolfIP_filter_notify_ip(WOLFIP_FILT_SENDING, t->S, tx_if, &icmp->ip, desc->len) != 0)
10409-
break;
10410-
#ifdef ETHERNET
10411-
if (!wolfIP_ll_is_non_ethernet(t->S, tx_if)) {
10412-
if (wolfIP_filter_notify_eth(WOLFIP_FILT_SENDING, t->S, tx_if, &icmp->ip.eth, desc->len) != 0)
10413-
break;
10414-
}
10415-
#endif
10416-
{
10417-
#ifdef WOLFIP_ESP
10418-
if (!wolfIP_ll_is_non_ethernet(s, tx_if)) {
10419-
struct wolfIP_ll_dev *ll = wolfIP_ll_at(s, tx_if);
10420-
if (esp_send(ll, (struct wolfIP_ip_packet *)icmp, len) == 1) {
10421-
/* ipsec not configured on this interface.
10422-
* send plaintext. */
10423-
send_ret = wolfIP_ll_send_frame(s, tx_if, icmp, desc->len);
10424-
}
10425-
} else {
10426-
send_ret = wolfIP_ll_send_frame(s, tx_if, icmp, desc->len);
10427-
}
10428-
#else
10429-
send_ret = wolfIP_ll_send_frame(s, tx_if, icmp, desc->len);
10430-
#endif /* WOLFIP_ESP */
10431-
}
10432-
if (send_ret == -WOLFIP_EAGAIN)
10433-
break;
10434-
if (send_ret < 0)
10435-
break;
10436-
fifo_pop(&t->sock.udp.txbuf);
10437-
desc = fifo_peek(&t->sock.udp.txbuf);
10438-
}
10439-
}
10440-
}
10441-
1044210380
static void flush_raw_tx(struct wolfIP *s)
1044310381
{
1044410382
#if WOLFIP_RAWSOCKETS
@@ -10568,8 +10506,8 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)
1056810506

1056910507
/* Attempt to write any pending data for all supported protocols */
1057010508
flush_tcp_tx(s, now);
10571-
flush_udp_tx(s);
10572-
flush_icmp_tx(s);
10509+
flush_datagram_tx(s, s->udpsockets, MAX_UDPSOCKETS, WI_IPPROTO_UDP);
10510+
flush_datagram_tx(s, s->icmpsockets, MAX_ICMPSOCKETS, WI_IPPROTO_ICMP);
1057310511
flush_raw_tx(s);
1057410512
flush_packet_tx(s);
1057510513

0 commit comments

Comments
 (0)