net: contiki: Fix net_buf lifecycle
siscslowpan_fragmentation would only free net_buf on failure. nullmac does not touch the net_buf, this results in all net_buf being exhausted eventually. csma always frees the net_buf, so in case of failure there is a double free with the one from siscslowpan_fragmentation. Fix: ref net_buf before every send, unref on every callback and once at the end, regardless of result. Don't free or ref the net_buf in csma. Also, replaced some code in fragment() with a call to send_packet() Change-Id: I4f329810ace07c09cde8f7522a83a1d6681f0906 Signed-off-by: Vlad Lungu <vlad.lungu@windriver.com>
This commit is contained in:
parent
0667c0fe0e
commit
244d5f8d07
2 changed files with 5 additions and 4 deletions
|
@ -189,7 +189,6 @@ free_packet(struct net_buf *buf, struct neighbor_queue *n, struct rdc_buf_list *
|
||||||
/* This was the last packet in the queue, we free the neighbor */
|
/* This was the last packet in the queue, we free the neighbor */
|
||||||
list_remove(uip_neighbor_list(buf), n);
|
list_remove(uip_neighbor_list(buf), n);
|
||||||
memb_free(&neighbor_memb, n);
|
memb_free(&neighbor_memb, n);
|
||||||
l2_buf_unref(buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,6 +390,7 @@ packet_sent(struct net_buf *buf, void *ptr, int status, int transmissions)
|
||||||
const linkaddr_t *dest = packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER);
|
const linkaddr_t *dest = packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER);
|
||||||
uip_ds6_link_neighbor_callback(dest, status, transmissions);
|
uip_ds6_link_neighbor_callback(dest, status, transmissions);
|
||||||
uip_last_tx_status(buf) = status;
|
uip_last_tx_status(buf) = status;
|
||||||
|
l2_buf_unref(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
|
@ -467,10 +468,8 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
if((int)uip_len(buf) <= max_payload) {
|
if((int)uip_len(buf) <= max_payload) {
|
||||||
/* The packet does not need to be fragmented, send buf */
|
/* The packet does not need to be fragmented, send buf */
|
||||||
packetbuf_copyfrom(mbuf, uip_buf(buf), uip_len(buf));
|
packetbuf_copyfrom(mbuf, uip_buf(buf), uip_len(buf));
|
||||||
packetbuf_set_addr(mbuf, PACKETBUF_ADDR_RECEIVER,
|
send_packet(mbuf, &ip_buf_ll_dest(buf), true, ptr);
|
||||||
&ip_buf_ll_dest(buf));
|
|
||||||
ip_buf_unref(buf);
|
ip_buf_unref(buf);
|
||||||
NETSTACK_LLSEC.send(mbuf, &packet_sent, true, ptr);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,6 +520,7 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
PRINTFO("could not allocate queuebuf for first fragment, dropping packet\n");
|
PRINTFO("could not allocate queuebuf for first fragment, dropping packet\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
net_buf_ref(mbuf);
|
||||||
send_packet(mbuf, &ip_buf_ll_dest(buf), last_fragment, ptr);
|
send_packet(mbuf, &ip_buf_ll_dest(buf), last_fragment, ptr);
|
||||||
queuebuf_to_packetbuf(mbuf, q);
|
queuebuf_to_packetbuf(mbuf, q);
|
||||||
queuebuf_free(q);
|
queuebuf_free(q);
|
||||||
|
@ -567,6 +567,7 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
PRINTFO("could not allocate queuebuf, dropping fragment\n");
|
PRINTFO("could not allocate queuebuf, dropping fragment\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
net_buf_ref(mbuf);
|
||||||
send_packet(mbuf, &ip_buf_ll_dest(buf), last_fragment, ptr);
|
send_packet(mbuf, &ip_buf_ll_dest(buf), last_fragment, ptr);
|
||||||
queuebuf_to_packetbuf(mbuf, q);
|
queuebuf_to_packetbuf(mbuf, q);
|
||||||
queuebuf_free(q);
|
queuebuf_free(q);
|
||||||
|
@ -583,6 +584,7 @@ static int fragment(struct net_buf *buf, void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_buf_unref(buf);
|
ip_buf_unref(buf);
|
||||||
|
l2_buf_unref(mbuf);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue