Skip to content

Commit 3772c71

Browse files
JordanYateskartben
authored andcommitted
net: l2: ethernet: ethernet_ll_prepare_on_ipv4 handling
Shift the error handling for `ethernet_ll_prepare_on_ipv4` out into `ethernet_send`, since that is the function that needs to handle the various result types of the ARP process. Signed-off-by: Jordan Yates <jordan@embeint.com>
1 parent 029f542 commit 3772c71

File tree

1 file changed

+30
-31
lines changed

1 file changed

+30
-31
lines changed

subsys/net/l2/ethernet/ethernet.c

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,9 @@ static bool ethernet_fill_in_dst_on_ipv4_mcast(struct net_pkt *pkt,
489489
return false;
490490
}
491491

492-
static struct net_pkt *ethernet_ll_prepare_on_ipv4(struct net_if *iface,
493-
struct net_pkt *pkt)
492+
static int ethernet_ll_prepare_on_ipv4(struct net_if *iface,
493+
struct net_pkt *pkt,
494+
struct net_pkt **out)
494495
{
495496
struct ethernet_context *ctx = net_if_l2_data(iface);
496497

@@ -503,36 +504,19 @@ static struct net_pkt *ethernet_ll_prepare_on_ipv4(struct net_if *iface,
503504
}
504505

505506
if (ethernet_ipv4_dst_is_broadcast_or_mcast(pkt)) {
506-
return pkt;
507+
return NET_ARP_COMPLETE;
507508
}
508509

509510
if (IS_ENABLED(CONFIG_NET_ARP)) {
510-
struct net_pkt *arp_pkt;
511-
int ret;
512-
513-
ret = net_arp_prepare(pkt, (struct in_addr *)NET_IPV4_HDR(pkt)->dst, NULL, &arp_pkt);
514-
if (ret == NET_ARP_COMPLETE) {
515-
NET_DBG("Found ARP entry, sending pkt %p to iface %d (%p)",
516-
pkt, net_if_get_by_iface(iface), iface);
517-
} else if (ret == NET_ARP_PKT_REPLACED) {
518-
NET_DBG("Sending arp pkt %p (orig %p) to iface %d (%p)",
519-
arp_pkt, pkt, net_if_get_by_iface(iface), iface);
520-
return arp_pkt;
521-
} else if (ret == NET_ARP_PKT_QUEUED) {
522-
NET_DBG("Pending ARP request, pkt %p queued", pkt);
523-
return NULL;
524-
} else {
525-
NET_WARN("ARP failure (%d)", ret);
526-
return NULL;
527-
}
511+
return net_arp_prepare(pkt, (struct in_addr *)NET_IPV4_HDR(pkt)->dst, NULL, out);
528512
}
529513

530-
return pkt;
514+
return NET_ARP_COMPLETE;
531515
}
532516
#else
533517
#define ethernet_ipv4_dst_is_broadcast_or_mcast(...) false
534518
#define ethernet_fill_in_dst_on_ipv4_mcast(...) false
535-
#define ethernet_ll_prepare_on_ipv4(...) NULL
519+
#define ethernet_ll_prepare_on_ipv4(...) NET_ARP_COMPLETE
536520
#endif /* CONFIG_NET_IPV4 */
537521

538522
#ifdef CONFIG_NET_IPV6
@@ -727,18 +711,33 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
727711
if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET &&
728712
net_pkt_ll_proto_type(pkt) == NET_ETH_PTYPE_IP) {
729713
if (!net_pkt_ipv4_acd(pkt)) {
730-
struct net_pkt *tmp;
731-
732-
tmp = ethernet_ll_prepare_on_ipv4(iface, pkt);
733-
if (tmp == NULL) {
734-
ret = -ENOMEM;
735-
goto error;
736-
} else if (IS_ENABLED(CONFIG_NET_ARP) && tmp != pkt) {
714+
struct net_pkt *arp;
715+
716+
ret = ethernet_ll_prepare_on_ipv4(iface, pkt, &arp);
717+
if (ret == NET_ARP_COMPLETE) {
718+
/* ARP resolution complete, packet ready to send */
719+
NET_DBG("Found ARP entry, sending pkt %p to iface %d (%p)",
720+
pkt, net_if_get_by_iface(iface), iface);
721+
} else if (ret == NET_ARP_PKT_REPLACED) {
737722
/* Original pkt got queued and is replaced
738723
* by an ARP request packet.
739724
*/
740-
pkt = tmp;
725+
NET_DBG("Sending arp pkt %p (orig %p) to iface %d (%p)",
726+
arp, pkt, net_if_get_by_iface(iface), iface);
727+
net_pkt_unref(pkt);
728+
pkt = arp;
741729
ptype = htons(net_pkt_ll_proto_type(pkt));
730+
} else if (ret == NET_ARP_PKT_QUEUED) {
731+
/* Original pkt got queued, pending resolution
732+
* of an ongoing ARP request.
733+
*/
734+
NET_DBG("Pending ARP request, pkt %p queued", pkt);
735+
net_pkt_unref(pkt);
736+
ret = 0;
737+
goto error;
738+
} else {
739+
__ASSERT_NO_MSG(ret < 0);
740+
goto error;
742741
}
743742
}
744743
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&

0 commit comments

Comments
 (0)