Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 57 additions & 27 deletions subsys/net/ip/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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);

Expand All @@ -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) {
Expand Down Expand Up @@ -1125,20 +1133,21 @@ struct net_pkt *net_ipv6_prepare_for_send(struct net_pkt *pkt)

#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);

Expand Down Expand Up @@ -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);

NET_ASSERT_INFO(pkt, "Out of TX packets");

frag = net_pkt_get_frag(pkt, K_FOREVER);
ND_NET_BUF_TIMEOUT);
if (!pkt) {
return -ENOMEM;
}

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);

Expand Down Expand Up @@ -1587,6 +1599,7 @@ static enum net_verdict handle_ns_input(struct net_pkt *pkt)
tgt,
flags);
if (!ret) {
NET_DBG("Cannot send NA (%d)", ret);
net_pkt_unref(pkt);
return NET_OK;
}
Expand All @@ -1608,6 +1621,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 "
Expand Down Expand Up @@ -1638,8 +1652,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;

Expand Down Expand Up @@ -1685,8 +1702,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,
Expand Down Expand Up @@ -2008,13 +2028,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);

NET_ASSERT_INFO(pkt, "Out of TX packets");

frag = net_pkt_get_frag(pkt, K_FOREVER);
ND_NET_BUF_TIMEOUT);
if (!pkt) {
return -ENOMEM;
}

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);

Expand Down Expand Up @@ -2143,9 +2166,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);

Expand Down
21 changes: 15 additions & 6 deletions subsys/net/ip/l2/arp.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <net/arp.h>
#include "net_private.h"

#define NET_BUF_TIMEOUT MSEC(100)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, this would be ARP_NET_BUF_TIMEOUT then ;-).


static struct arp_entry arp_table[CONFIG_NET_ARP_TABLE_SIZE];

static inline struct arp_entry *find_entry(struct net_if *iface,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down