net/ethernet/arp: Let ethernet L2 managing pkt's reference while sending

prepare_arp() was unreferencing original pkt (called pending there) in
case of error.

net_prepare_arp() was always unreferencing pkt, though it could have
been already unreferenced by prepare_arp() as seen previously which is
an extra bogus unref in this case.

And in case it returned NULL, ethernet_send() would return NET_DROP
which in turn would make net_if's tx code to unref again the pkt.

This patch ensures pkt is unrefed only once and at the right place.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka
2017-09-05 16:07:11 +02:00
committed by Jukka Rissanen
parent 7e3d30880b
commit cd35742a2b
2 changed files with 8 additions and 9 deletions

View File

@@ -110,12 +110,13 @@ static inline struct net_pkt *prepare_arp(struct net_if *iface,
pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr), K_FOREVER);
if (!pkt) {
goto fail;
return NULL;
}
frag = net_pkt_get_frag(pkt, K_FOREVER);
if (!frag) {
goto fail;
net_pkt_unref(pkt);
return NULL;
}
net_pkt_frag_add(pkt, frag);
@@ -176,11 +177,6 @@ static inline struct net_pkt *prepare_arp(struct net_if *iface,
net_buf_add(frag, sizeof(struct net_arp_hdr));
return pkt;
fail:
net_pkt_unref(pkt);
net_pkt_unref(pending);
return NULL;
}
struct net_pkt *net_arp_prepare(struct net_pkt *pkt)
@@ -260,8 +256,6 @@ struct net_pkt *net_arp_prepare(struct net_pkt *pkt)
addr, NULL, pkt);
NET_DBG("Resending ARP %p", req);
net_pkt_unref(pkt);
return req;
}

View File

@@ -203,6 +203,11 @@ static enum net_verdict ethernet_send(struct net_if *iface,
NET_DBG("Sending arp pkt %p (orig %p) to iface %p",
arp_pkt, pkt, iface);
if (pkt != arp_pkt) {
/* pkt went to ARP pending queue */
net_pkt_unref(pkt);
}
pkt = arp_pkt;
net_pkt_ll_src(pkt)->addr = (u8_t *)&NET_ETH_HDR(pkt)->src;