Skip to content

Commit 023628f

Browse files
committed
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 <[email protected]>
1 parent e84d1a4 commit 023628f

File tree

2 files changed

+72
-33
lines changed

2 files changed

+72
-33
lines changed

subsys/net/ip/ipv6.c

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
#include "rpl.h"
3737
#include "net_stats.h"
3838

39+
/* Timeout value to be used when allocating net buffer during various
40+
* neighbor discovery procedures.
41+
*/
42+
#define ND_NET_BUF_TIMEOUT MSEC(100)
43+
3944
/* IPv6 wildcard and loopback address defined by RFC2553 */
4045
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
4146
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
@@ -461,6 +466,7 @@ struct net_nbr *net_ipv6_nbr_add(struct net_if *iface,
461466
enum net_ipv6_nbr_state state)
462467
{
463468
struct net_nbr *nbr;
469+
int ret;
464470
#if defined(CONFIG_NET_MGMT_EVENT_INFO)
465471
struct net_event_ipv6_nbr info;
466472
#endif
@@ -500,7 +506,10 @@ struct net_nbr *net_ipv6_nbr_add(struct net_if *iface,
500506
/* Send NS so that we can verify that the neighbor is
501507
* reachable.
502508
*/
503-
net_ipv6_send_ns(iface, NULL, NULL, NULL, addr, false);
509+
ret = net_ipv6_send_ns(iface, NULL, NULL, NULL, addr, false);
510+
if (ret < 0) {
511+
NET_DBG("Cannot send NS (%d)", ret);
512+
}
504513
}
505514

506515
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)
961970
struct in6_addr *nexthop = NULL;
962971
struct net_if *iface = NULL;
963972
struct net_nbr *nbr;
973+
int ret;
964974

965975
NET_ASSERT(pkt && pkt->frags);
966976

@@ -972,8 +982,6 @@ struct net_pkt *net_ipv6_prepare_for_send(struct net_pkt *pkt)
972982
size_t pkt_len = net_pkt_get_len(pkt);
973983

974984
if (pkt_len > NET_IPV6_MTU) {
975-
int ret;
976-
977985
ret = net_ipv6_send_fragmented_pkt(net_pkt_iface(pkt),
978986
pkt, pkt_len);
979987
if (ret < 0) {
@@ -1125,20 +1133,21 @@ struct net_pkt *net_ipv6_prepare_for_send(struct net_pkt *pkt)
11251133

11261134
#if defined(CONFIG_NET_IPV6_ND)
11271135
/* We need to send NS and wait for NA before sending the packet. */
1128-
if (net_ipv6_send_ns(net_pkt_iface(pkt),
1129-
pkt,
1130-
&NET_IPV6_HDR(pkt)->src,
1131-
NULL,
1132-
nexthop,
1133-
false) < 0) {
1136+
ret = net_ipv6_send_ns(net_pkt_iface(pkt), pkt,
1137+
&NET_IPV6_HDR(pkt)->src, NULL,
1138+
nexthop, false);
1139+
if (ret < 0) {
11341140
/* In case of an error, the NS send function will unref
11351141
* the pkt.
11361142
*/
1143+
NET_DBG("Cannot send NS (%d)", ret);
11371144
return NULL;
11381145
}
11391146

11401147
NET_DBG("pkt %p (frag %p) will be sent later", pkt, pkt->frags);
11411148
#else
1149+
ARG_UNUSED(ret);
1150+
11421151
NET_DBG("pkt %p (frag %p) cannot be sent, dropping it.", pkt,
11431152
pkt->frags);
11441153

@@ -1270,13 +1279,16 @@ int net_ipv6_send_na(struct net_if *iface, const struct in6_addr *src,
12701279
u8_t llao_len;
12711280

12721281
pkt = net_pkt_get_reserve_tx(net_if_get_ll_reserve(iface, dst),
1273-
K_FOREVER);
1274-
1275-
NET_ASSERT_INFO(pkt, "Out of TX packets");
1276-
1277-
frag = net_pkt_get_frag(pkt, K_FOREVER);
1282+
ND_NET_BUF_TIMEOUT);
1283+
if (!pkt) {
1284+
return -ENOMEM;
1285+
}
12781286

1279-
NET_ASSERT_INFO(frag, "Out of DATA buffers");
1287+
frag = net_pkt_get_frag(pkt, ND_NET_BUF_TIMEOUT);
1288+
if (!frag) {
1289+
net_pkt_unref(pkt);
1290+
return -ENOMEM;
1291+
}
12801292

12811293
net_pkt_frag_add(pkt, frag);
12821294

@@ -1590,6 +1602,7 @@ static enum net_verdict handle_ns_input(struct net_pkt *pkt)
15901602
tgt,
15911603
flags);
15921604
if (!ret) {
1605+
NET_DBG("Cannot send NA (%d)", ret);
15931606
net_pkt_unref(pkt);
15941607
return NET_OK;
15951608
}
@@ -1611,6 +1624,7 @@ static void nd_reachable_timeout(struct k_work *work)
16111624
reachable);
16121625

16131626
struct net_nbr *nbr = get_nbr_from_data(data);
1627+
int ret;
16141628

16151629
if (!data || !nbr) {
16161630
NET_DBG("ND reachable timeout but no nbr data "
@@ -1641,8 +1655,11 @@ static void nd_reachable_timeout(struct k_work *work)
16411655
NET_DBG("nbr %p incomplete count %u", nbr,
16421656
data->ns_count);
16431657

1644-
net_ipv6_send_ns(nbr->iface, NULL, NULL, NULL,
1645-
&data->addr, false);
1658+
ret = net_ipv6_send_ns(nbr->iface, NULL, NULL, NULL,
1659+
&data->addr, false);
1660+
if (ret < 0) {
1661+
NET_DBG("Cannot send NS (%d)", ret);
1662+
}
16461663
}
16471664
break;
16481665

@@ -1688,8 +1705,11 @@ static void nd_reachable_timeout(struct k_work *work)
16881705
NET_DBG("nbr %p probe count %u", nbr,
16891706
data->ns_count);
16901707

1691-
net_ipv6_send_ns(nbr->iface, NULL, NULL, NULL,
1692-
&data->addr, false);
1708+
ret = net_ipv6_send_ns(nbr->iface, NULL, NULL, NULL,
1709+
&data->addr, false);
1710+
if (ret < 0) {
1711+
NET_DBG("Cannot send NS (%d)", ret);
1712+
}
16931713

16941714
k_delayed_work_submit(
16951715
&net_ipv6_nbr_data(nbr)->reachable,
@@ -2011,13 +2031,16 @@ int net_ipv6_send_ns(struct net_if *iface,
20112031
u8_t llao_len;
20122032

20132033
pkt = net_pkt_get_reserve_tx(net_if_get_ll_reserve(iface, dst),
2014-
K_FOREVER);
2015-
2016-
NET_ASSERT_INFO(pkt, "Out of TX packets");
2017-
2018-
frag = net_pkt_get_frag(pkt, K_FOREVER);
2034+
ND_NET_BUF_TIMEOUT);
2035+
if (!pkt) {
2036+
return -ENOMEM;
2037+
}
20192038

2020-
NET_ASSERT_INFO(frag, "Out of DATA buffers");
2039+
frag = net_pkt_get_frag(pkt, ND_NET_BUF_TIMEOUT);
2040+
if (!frag) {
2041+
net_pkt_unref(pkt);
2042+
return -ENOMEM;
2043+
}
20212044

20222045
net_pkt_frag_add(pkt, frag);
20232046

@@ -2146,9 +2169,16 @@ int net_ipv6_send_rs(struct net_if *iface)
21462169
u8_t llao_len = 0;
21472170

21482171
pkt = net_pkt_get_reserve_tx(net_if_get_ll_reserve(iface, NULL),
2149-
K_FOREVER);
2172+
ND_NET_BUF_TIMEOUT);
2173+
if (!pkt) {
2174+
return -ENOMEM;
2175+
}
21502176

2151-
frag = net_pkt_get_frag(pkt, K_FOREVER);
2177+
frag = net_pkt_get_frag(pkt, ND_NET_BUF_TIMEOUT);
2178+
if (!frag) {
2179+
net_pkt_unref(pkt);
2180+
return -ENOMEM;
2181+
}
21522182

21532183
net_pkt_frag_add(pkt, frag);
21542184

subsys/net/ip/l2/arp.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <net/arp.h>
2222
#include "net_private.h"
2323

24+
#define NET_BUF_TIMEOUT MSEC(100)
25+
2426
static struct arp_entry arp_table[CONFIG_NET_ARP_TABLE_SIZE];
2527

2628
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,
100102
struct net_eth_hdr *eth;
101103
struct in_addr *my_addr;
102104

103-
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr), K_FOREVER);
105+
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr),
106+
NET_BUF_TIMEOUT);
104107
if (!pkt) {
105108
return NULL;
106109
}
107110

108-
frag = net_pkt_get_frag(pkt, K_FOREVER);
111+
frag = net_pkt_get_frag(pkt, NET_BUF_TIMEOUT);
109112
if (!frag) {
110113
net_pkt_unref(pkt);
111114
return NULL;
@@ -187,9 +190,12 @@ struct net_pkt *net_arp_prepare(struct net_pkt *pkt)
187190
/* Add the ethernet header if it is missing. */
188191
struct net_buf *header;
189192

190-
net_pkt_set_ll_reserve(pkt, sizeof(struct net_eth_hdr));
193+
header = net_pkt_get_frag(pkt, NET_BUF_TIMEOUT);
194+
if (!header) {
195+
return NULL;
196+
}
191197

192-
header = net_pkt_get_frag(pkt, K_FOREVER);
198+
net_pkt_set_ll_reserve(pkt, sizeof(struct net_eth_hdr));
193199

194200
hdr = (struct net_eth_hdr *)(header->data -
195201
net_pkt_ll_reserve(pkt));
@@ -358,12 +364,13 @@ static inline struct net_pkt *prepare_arp_reply(struct net_if *iface,
358364
struct net_arp_hdr *hdr, *query;
359365
struct net_eth_hdr *eth, *eth_query;
360366

361-
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr), K_FOREVER);
367+
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr),
368+
NET_BUF_TIMEOUT);
362369
if (!pkt) {
363370
goto fail;
364371
}
365372

366-
frag = net_pkt_get_frag(pkt, K_FOREVER);
373+
frag = net_pkt_get_frag(pkt, NET_BUF_TIMEOUT);
367374
if (!frag) {
368375
goto fail;
369376
}
@@ -455,6 +462,8 @@ enum net_verdict net_arp_input(struct net_pkt *pkt)
455462
reply = prepare_arp_reply(net_pkt_iface(pkt), pkt);
456463
if (reply) {
457464
net_if_queue_tx(net_pkt_iface(reply), reply);
465+
} else {
466+
NET_DBG("Cannot send ARP reply");
458467
}
459468
break;
460469

0 commit comments

Comments
 (0)