net: Set net_buf alloc timeout for IPv4 ARP and IPv6 ND
Instead of having K_FOREVER when allocating a packet in IPv4 ARP and IPv6 ND, set a timeout so that we do not have a case where we would wait net_buf forever. Fixes #5484 Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
e84d1a4f31
commit
023628f3d7
2 changed files with 72 additions and 33 deletions
|
|
@ -36,6 +36,11 @@
|
|||
#include "rpl.h"
|
||||
#include "net_stats.h"
|
||||
|
||||
/* Timeout value to be used when allocating net buffer during various
|
||||
* neighbor discovery procedures.
|
||||
*/
|
||||
#define ND_NET_BUF_TIMEOUT MSEC(100)
|
||||
|
||||
/* IPv6 wildcard and loopback address defined by RFC2553 */
|
||||
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
||||
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
|
||||
|
|
@ -461,6 +466,7 @@ struct net_nbr *net_ipv6_nbr_add(struct net_if *iface,
|
|||
enum net_ipv6_nbr_state state)
|
||||
{
|
||||
struct net_nbr *nbr;
|
||||
int ret;
|
||||
#if defined(CONFIG_NET_MGMT_EVENT_INFO)
|
||||
struct net_event_ipv6_nbr info;
|
||||
#endif
|
||||
|
|
@ -500,7 +506,10 @@ struct net_nbr *net_ipv6_nbr_add(struct net_if *iface,
|
|||
/* Send NS so that we can verify that the neighbor is
|
||||
* reachable.
|
||||
*/
|
||||
net_ipv6_send_ns(iface, NULL, NULL, NULL, addr, false);
|
||||
ret = net_ipv6_send_ns(iface, NULL, NULL, NULL, addr, false);
|
||||
if (ret < 0) {
|
||||
NET_DBG("Cannot send NS (%d)", ret);
|
||||
}
|
||||
}
|
||||
|
||||
NET_DBG("[%d] nbr %p state %d router %d IPv6 %s ll %s iface %p",
|
||||
|
|
@ -961,6 +970,7 @@ struct net_pkt *net_ipv6_prepare_for_send(struct net_pkt *pkt)
|
|||
struct in6_addr *nexthop = NULL;
|
||||
struct net_if *iface = NULL;
|
||||
struct net_nbr *nbr;
|
||||
int ret;
|
||||
|
||||
NET_ASSERT(pkt && pkt->frags);
|
||||
|
||||
|
|
@ -972,8 +982,6 @@ struct net_pkt *net_ipv6_prepare_for_send(struct net_pkt *pkt)
|
|||
size_t pkt_len = net_pkt_get_len(pkt);
|
||||
|
||||
if (pkt_len > NET_IPV6_MTU) {
|
||||
int ret;
|
||||
|
||||
ret = net_ipv6_send_fragmented_pkt(net_pkt_iface(pkt),
|
||||
pkt, pkt_len);
|
||||
if (ret < 0) {
|
||||
|
|
@ -1125,20 +1133,21 @@ try_send:
|
|||
|
||||
#if defined(CONFIG_NET_IPV6_ND)
|
||||
/* We need to send NS and wait for NA before sending the packet. */
|
||||
if (net_ipv6_send_ns(net_pkt_iface(pkt),
|
||||
pkt,
|
||||
&NET_IPV6_HDR(pkt)->src,
|
||||
NULL,
|
||||
nexthop,
|
||||
false) < 0) {
|
||||
ret = net_ipv6_send_ns(net_pkt_iface(pkt), pkt,
|
||||
&NET_IPV6_HDR(pkt)->src, NULL,
|
||||
nexthop, false);
|
||||
if (ret < 0) {
|
||||
/* In case of an error, the NS send function will unref
|
||||
* the pkt.
|
||||
*/
|
||||
NET_DBG("Cannot send NS (%d)", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NET_DBG("pkt %p (frag %p) will be sent later", pkt, pkt->frags);
|
||||
#else
|
||||
ARG_UNUSED(ret);
|
||||
|
||||
NET_DBG("pkt %p (frag %p) cannot be sent, dropping it.", pkt,
|
||||
pkt->frags);
|
||||
|
||||
|
|
@ -1270,13 +1279,16 @@ int net_ipv6_send_na(struct net_if *iface, const struct in6_addr *src,
|
|||
u8_t llao_len;
|
||||
|
||||
pkt = net_pkt_get_reserve_tx(net_if_get_ll_reserve(iface, dst),
|
||||
K_FOREVER);
|
||||
ND_NET_BUF_TIMEOUT);
|
||||
if (!pkt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
NET_ASSERT_INFO(pkt, "Out of TX packets");
|
||||
|
||||
frag = net_pkt_get_frag(pkt, K_FOREVER);
|
||||
|
||||
NET_ASSERT_INFO(frag, "Out of DATA buffers");
|
||||
frag = net_pkt_get_frag(pkt, ND_NET_BUF_TIMEOUT);
|
||||
if (!frag) {
|
||||
net_pkt_unref(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
net_pkt_frag_add(pkt, frag);
|
||||
|
||||
|
|
@ -1590,6 +1602,7 @@ send_na:
|
|||
tgt,
|
||||
flags);
|
||||
if (!ret) {
|
||||
NET_DBG("Cannot send NA (%d)", ret);
|
||||
net_pkt_unref(pkt);
|
||||
return NET_OK;
|
||||
}
|
||||
|
|
@ -1611,6 +1624,7 @@ static void nd_reachable_timeout(struct k_work *work)
|
|||
reachable);
|
||||
|
||||
struct net_nbr *nbr = get_nbr_from_data(data);
|
||||
int ret;
|
||||
|
||||
if (!data || !nbr) {
|
||||
NET_DBG("ND reachable timeout but no nbr data "
|
||||
|
|
@ -1641,8 +1655,11 @@ static void nd_reachable_timeout(struct k_work *work)
|
|||
NET_DBG("nbr %p incomplete count %u", nbr,
|
||||
data->ns_count);
|
||||
|
||||
net_ipv6_send_ns(nbr->iface, NULL, NULL, NULL,
|
||||
&data->addr, false);
|
||||
ret = net_ipv6_send_ns(nbr->iface, NULL, NULL, NULL,
|
||||
&data->addr, false);
|
||||
if (ret < 0) {
|
||||
NET_DBG("Cannot send NS (%d)", ret);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1688,8 +1705,11 @@ static void nd_reachable_timeout(struct k_work *work)
|
|||
NET_DBG("nbr %p probe count %u", nbr,
|
||||
data->ns_count);
|
||||
|
||||
net_ipv6_send_ns(nbr->iface, NULL, NULL, NULL,
|
||||
&data->addr, false);
|
||||
ret = net_ipv6_send_ns(nbr->iface, NULL, NULL, NULL,
|
||||
&data->addr, false);
|
||||
if (ret < 0) {
|
||||
NET_DBG("Cannot send NS (%d)", ret);
|
||||
}
|
||||
|
||||
k_delayed_work_submit(
|
||||
&net_ipv6_nbr_data(nbr)->reachable,
|
||||
|
|
@ -2011,13 +2031,16 @@ int net_ipv6_send_ns(struct net_if *iface,
|
|||
u8_t llao_len;
|
||||
|
||||
pkt = net_pkt_get_reserve_tx(net_if_get_ll_reserve(iface, dst),
|
||||
K_FOREVER);
|
||||
ND_NET_BUF_TIMEOUT);
|
||||
if (!pkt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
NET_ASSERT_INFO(pkt, "Out of TX packets");
|
||||
|
||||
frag = net_pkt_get_frag(pkt, K_FOREVER);
|
||||
|
||||
NET_ASSERT_INFO(frag, "Out of DATA buffers");
|
||||
frag = net_pkt_get_frag(pkt, ND_NET_BUF_TIMEOUT);
|
||||
if (!frag) {
|
||||
net_pkt_unref(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
net_pkt_frag_add(pkt, frag);
|
||||
|
||||
|
|
@ -2146,9 +2169,16 @@ int net_ipv6_send_rs(struct net_if *iface)
|
|||
u8_t llao_len = 0;
|
||||
|
||||
pkt = net_pkt_get_reserve_tx(net_if_get_ll_reserve(iface, NULL),
|
||||
K_FOREVER);
|
||||
ND_NET_BUF_TIMEOUT);
|
||||
if (!pkt) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
frag = net_pkt_get_frag(pkt, K_FOREVER);
|
||||
frag = net_pkt_get_frag(pkt, ND_NET_BUF_TIMEOUT);
|
||||
if (!frag) {
|
||||
net_pkt_unref(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
net_pkt_frag_add(pkt, frag);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
#include <net/arp.h>
|
||||
#include "net_private.h"
|
||||
|
||||
#define NET_BUF_TIMEOUT MSEC(100)
|
||||
|
||||
static struct arp_entry arp_table[CONFIG_NET_ARP_TABLE_SIZE];
|
||||
|
||||
static inline struct arp_entry *find_entry(struct net_if *iface,
|
||||
|
|
@ -100,12 +102,13 @@ static inline struct net_pkt *prepare_arp(struct net_if *iface,
|
|||
struct net_eth_hdr *eth;
|
||||
struct in_addr *my_addr;
|
||||
|
||||
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr), K_FOREVER);
|
||||
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr),
|
||||
NET_BUF_TIMEOUT);
|
||||
if (!pkt) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
frag = net_pkt_get_frag(pkt, K_FOREVER);
|
||||
frag = net_pkt_get_frag(pkt, NET_BUF_TIMEOUT);
|
||||
if (!frag) {
|
||||
net_pkt_unref(pkt);
|
||||
return NULL;
|
||||
|
|
@ -187,9 +190,12 @@ struct net_pkt *net_arp_prepare(struct net_pkt *pkt)
|
|||
/* Add the ethernet header if it is missing. */
|
||||
struct net_buf *header;
|
||||
|
||||
net_pkt_set_ll_reserve(pkt, sizeof(struct net_eth_hdr));
|
||||
header = net_pkt_get_frag(pkt, NET_BUF_TIMEOUT);
|
||||
if (!header) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
header = net_pkt_get_frag(pkt, K_FOREVER);
|
||||
net_pkt_set_ll_reserve(pkt, sizeof(struct net_eth_hdr));
|
||||
|
||||
hdr = (struct net_eth_hdr *)(header->data -
|
||||
net_pkt_ll_reserve(pkt));
|
||||
|
|
@ -358,12 +364,13 @@ static inline struct net_pkt *prepare_arp_reply(struct net_if *iface,
|
|||
struct net_arp_hdr *hdr, *query;
|
||||
struct net_eth_hdr *eth, *eth_query;
|
||||
|
||||
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr), K_FOREVER);
|
||||
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr),
|
||||
NET_BUF_TIMEOUT);
|
||||
if (!pkt) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
frag = net_pkt_get_frag(pkt, K_FOREVER);
|
||||
frag = net_pkt_get_frag(pkt, NET_BUF_TIMEOUT);
|
||||
if (!frag) {
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -455,6 +462,8 @@ enum net_verdict net_arp_input(struct net_pkt *pkt)
|
|||
reply = prepare_arp_reply(net_pkt_iface(pkt), pkt);
|
||||
if (reply) {
|
||||
net_if_queue_tx(net_pkt_iface(reply), reply);
|
||||
} else {
|
||||
NET_DBG("Cannot send ARP reply");
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue