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>
This commit is contained in:
parent
029f542bb4
commit
3772c719e0
1 changed files with 29 additions and 30 deletions
|
@ -489,8 +489,9 @@ static bool ethernet_fill_in_dst_on_ipv4_mcast(struct net_pkt *pkt,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct net_pkt *ethernet_ll_prepare_on_ipv4(struct net_if *iface,
|
static int ethernet_ll_prepare_on_ipv4(struct net_if *iface,
|
||||||
struct net_pkt *pkt)
|
struct net_pkt *pkt,
|
||||||
|
struct net_pkt **out)
|
||||||
{
|
{
|
||||||
struct ethernet_context *ctx = net_if_l2_data(iface);
|
struct ethernet_context *ctx = net_if_l2_data(iface);
|
||||||
|
|
||||||
|
@ -503,36 +504,19 @@ static struct net_pkt *ethernet_ll_prepare_on_ipv4(struct net_if *iface,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ethernet_ipv4_dst_is_broadcast_or_mcast(pkt)) {
|
if (ethernet_ipv4_dst_is_broadcast_or_mcast(pkt)) {
|
||||||
return pkt;
|
return NET_ARP_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_NET_ARP)) {
|
if (IS_ENABLED(CONFIG_NET_ARP)) {
|
||||||
struct net_pkt *arp_pkt;
|
return net_arp_prepare(pkt, (struct in_addr *)NET_IPV4_HDR(pkt)->dst, NULL, out);
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = net_arp_prepare(pkt, (struct in_addr *)NET_IPV4_HDR(pkt)->dst, NULL, &arp_pkt);
|
|
||||||
if (ret == NET_ARP_COMPLETE) {
|
|
||||||
NET_DBG("Found ARP entry, sending pkt %p to iface %d (%p)",
|
|
||||||
pkt, net_if_get_by_iface(iface), iface);
|
|
||||||
} else if (ret == NET_ARP_PKT_REPLACED) {
|
|
||||||
NET_DBG("Sending arp pkt %p (orig %p) to iface %d (%p)",
|
|
||||||
arp_pkt, pkt, net_if_get_by_iface(iface), iface);
|
|
||||||
return arp_pkt;
|
|
||||||
} else if (ret == NET_ARP_PKT_QUEUED) {
|
|
||||||
NET_DBG("Pending ARP request, pkt %p queued", pkt);
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
NET_WARN("ARP failure (%d)", ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pkt;
|
return NET_ARP_COMPLETE;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define ethernet_ipv4_dst_is_broadcast_or_mcast(...) false
|
#define ethernet_ipv4_dst_is_broadcast_or_mcast(...) false
|
||||||
#define ethernet_fill_in_dst_on_ipv4_mcast(...) false
|
#define ethernet_fill_in_dst_on_ipv4_mcast(...) false
|
||||||
#define ethernet_ll_prepare_on_ipv4(...) NULL
|
#define ethernet_ll_prepare_on_ipv4(...) NET_ARP_COMPLETE
|
||||||
#endif /* CONFIG_NET_IPV4 */
|
#endif /* CONFIG_NET_IPV4 */
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPV6
|
#ifdef CONFIG_NET_IPV6
|
||||||
|
@ -727,18 +711,33 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
|
||||||
if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET &&
|
if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET &&
|
||||||
net_pkt_ll_proto_type(pkt) == NET_ETH_PTYPE_IP) {
|
net_pkt_ll_proto_type(pkt) == NET_ETH_PTYPE_IP) {
|
||||||
if (!net_pkt_ipv4_acd(pkt)) {
|
if (!net_pkt_ipv4_acd(pkt)) {
|
||||||
struct net_pkt *tmp;
|
struct net_pkt *arp;
|
||||||
|
|
||||||
tmp = ethernet_ll_prepare_on_ipv4(iface, pkt);
|
ret = ethernet_ll_prepare_on_ipv4(iface, pkt, &arp);
|
||||||
if (tmp == NULL) {
|
if (ret == NET_ARP_COMPLETE) {
|
||||||
ret = -ENOMEM;
|
/* ARP resolution complete, packet ready to send */
|
||||||
goto error;
|
NET_DBG("Found ARP entry, sending pkt %p to iface %d (%p)",
|
||||||
} else if (IS_ENABLED(CONFIG_NET_ARP) && tmp != pkt) {
|
pkt, net_if_get_by_iface(iface), iface);
|
||||||
|
} else if (ret == NET_ARP_PKT_REPLACED) {
|
||||||
/* Original pkt got queued and is replaced
|
/* Original pkt got queued and is replaced
|
||||||
* by an ARP request packet.
|
* by an ARP request packet.
|
||||||
*/
|
*/
|
||||||
pkt = tmp;
|
NET_DBG("Sending arp pkt %p (orig %p) to iface %d (%p)",
|
||||||
|
arp, pkt, net_if_get_by_iface(iface), iface);
|
||||||
|
net_pkt_unref(pkt);
|
||||||
|
pkt = arp;
|
||||||
ptype = htons(net_pkt_ll_proto_type(pkt));
|
ptype = htons(net_pkt_ll_proto_type(pkt));
|
||||||
|
} else if (ret == NET_ARP_PKT_QUEUED) {
|
||||||
|
/* Original pkt got queued, pending resolution
|
||||||
|
* of an ongoing ARP request.
|
||||||
|
*/
|
||||||
|
NET_DBG("Pending ARP request, pkt %p queued", pkt);
|
||||||
|
net_pkt_unref(pkt);
|
||||||
|
ret = 0;
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
__ASSERT_NO_MSG(ret < 0);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
|
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue