net: Add ll addresses on net_if_send_data
This makes sure ll addresses are properly set before sending reducing the duplicated code on L2 drivers. Change-Id: I5330c1d00a344e77555c6f31033ae42af20214bf Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
6aae825a2d
commit
a94f179252
5 changed files with 48 additions and 74 deletions
|
@ -491,6 +491,11 @@ struct net_buf *net_ipv6_prepare_for_send(struct net_buf *buf)
|
|||
struct net_if *iface = NULL;
|
||||
struct net_nbr *nbr;
|
||||
|
||||
if (net_nbuf_ll_dst(buf)->addr ||
|
||||
net_is_ipv6_addr_mcast(&NET_IPV6_BUF(buf)->dst)) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (net_if_ipv6_addr_onlink(&iface,
|
||||
&NET_IPV6_BUF(buf)->dst)) {
|
||||
nexthop = &NET_IPV6_BUF(buf)->dst;
|
||||
|
|
|
@ -87,27 +87,6 @@ static enum net_verdict net_bt_send(struct net_if *iface, struct net_buf *buf)
|
|||
return NET_DROP;
|
||||
}
|
||||
|
||||
/* TODO: Move ll address check to the stack */
|
||||
|
||||
/* If the ll address is not set at all, then we must set
|
||||
* it here.
|
||||
*/
|
||||
if (!net_nbuf_ll_src(buf)->addr) {
|
||||
net_nbuf_ll_src(buf)->addr = net_nbuf_ll_if(buf)->addr;
|
||||
net_nbuf_ll_src(buf)->len = net_nbuf_ll_if(buf)->len;
|
||||
}
|
||||
|
||||
/* If the ll dst address is not set check if it is present in the nbr
|
||||
* cache.
|
||||
*/
|
||||
if (!net_nbuf_ll_dst(buf)->addr &&
|
||||
!net_is_ipv6_addr_mcast(&NET_IPV6_BUF(buf)->dst)) {
|
||||
buf = net_ipv6_prepare_for_send(buf);
|
||||
if (!buf) {
|
||||
return NET_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!net_6lo_compress(buf, true, NULL)) {
|
||||
NET_DBG("Packet compression failed");
|
||||
return NET_DROP;
|
||||
|
|
|
@ -218,25 +218,17 @@ static enum net_verdict ethernet_send(struct net_if *iface,
|
|||
NET_DBG("Sending buf %p to iface %p", buf, iface);
|
||||
#endif
|
||||
|
||||
/* If the ll address is not set at all, then we must set
|
||||
* it here.
|
||||
/* If the src ll address is multicast or broadcast, then
|
||||
* what probably happened is that the RX buffer is used
|
||||
* for sending data back to recipient. We must
|
||||
* substitute the src address using the real ll address.
|
||||
*/
|
||||
if (!net_nbuf_ll_src(buf)->addr) {
|
||||
if (net_eth_is_addr_broadcast((struct net_eth_addr *)
|
||||
net_nbuf_ll_src(buf)->addr) ||
|
||||
net_eth_is_addr_multicast((struct net_eth_addr *)
|
||||
net_nbuf_ll_src(buf)->addr)) {
|
||||
net_nbuf_ll_src(buf)->addr = net_nbuf_ll_if(buf)->addr;
|
||||
net_nbuf_ll_src(buf)->len = net_nbuf_ll_if(buf)->len;
|
||||
} else {
|
||||
/* If the src ll address is multicast or broadcast, then
|
||||
* what probably happened is that the RX buffer is used
|
||||
* for sending data back to recipient. We must
|
||||
* substitute the src address using the real ll address.
|
||||
*/
|
||||
if (net_eth_is_addr_broadcast((struct net_eth_addr *)
|
||||
net_nbuf_ll_src(buf)->addr) ||
|
||||
net_eth_is_addr_multicast((struct net_eth_addr *)
|
||||
net_nbuf_ll_src(buf)->addr)) {
|
||||
net_nbuf_ll_src(buf)->addr = net_nbuf_ll_if(buf)->addr;
|
||||
net_nbuf_ll_src(buf)->len = net_nbuf_ll_if(buf)->len;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the destination address is not set, then use broadcast
|
||||
|
@ -244,34 +236,17 @@ static enum net_verdict ethernet_send(struct net_if *iface,
|
|||
*/
|
||||
if (!net_nbuf_ll_dst(buf)->addr) {
|
||||
#if defined(CONFIG_NET_IPV6)
|
||||
if (net_nbuf_family(buf) == AF_INET6) {
|
||||
if (net_is_ipv6_addr_mcast(&NET_IPV6_BUF(buf)->dst)) {
|
||||
struct net_eth_addr *dst =
|
||||
&NET_ETH_BUF(buf)->dst;
|
||||
if (net_nbuf_family(buf) == AF_INET6 &&
|
||||
net_is_ipv6_addr_mcast(&NET_IPV6_BUF(buf)->dst)) {
|
||||
struct net_eth_addr *dst = &NET_ETH_BUF(buf)->dst;
|
||||
|
||||
memcpy(dst, (uint8_t *)multicast_eth_addr.addr,
|
||||
sizeof(struct net_eth_addr) - 4);
|
||||
memcpy((uint8_t *)dst + 2,
|
||||
(uint8_t *)(&NET_IPV6_BUF(buf)->dst) +
|
||||
12,
|
||||
sizeof(struct net_eth_addr) - 2);
|
||||
memcpy(dst, (uint8_t *)multicast_eth_addr.addr,
|
||||
sizeof(struct net_eth_addr) - 4);
|
||||
memcpy((uint8_t *)dst + 2,
|
||||
(uint8_t *)(&NET_IPV6_BUF(buf)->dst) + 12,
|
||||
sizeof(struct net_eth_addr) - 2);
|
||||
|
||||
net_nbuf_ll_dst(buf)->addr =
|
||||
(uint8_t *)dst->addr;
|
||||
} else {
|
||||
/* Check neighbor cache if it has the
|
||||
* destination address.
|
||||
*/
|
||||
net_nbuf_set_ll_reserve(buf,
|
||||
sizeof(struct net_eth_hdr));
|
||||
|
||||
buf = net_ipv6_prepare_for_send(buf);
|
||||
if (!buf) {
|
||||
/* The actual packet will be send later
|
||||
*/
|
||||
return NET_CONTINUE;
|
||||
}
|
||||
}
|
||||
net_nbuf_ll_dst(buf)->addr = (uint8_t *)dst->addr;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
|
|
@ -270,14 +270,6 @@ static enum net_verdict ieee802154_send(struct net_if *iface,
|
|||
return NET_DROP;
|
||||
}
|
||||
|
||||
if (!net_nbuf_ll_dst(buf)->addr &&
|
||||
!net_is_ipv6_addr_mcast(&NET_IPV6_BUF(buf)->dst)) {
|
||||
buf = net_ipv6_prepare_for_send(buf);
|
||||
if (!buf) {
|
||||
return NET_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* 6lo is going to compress the ipv6 header, and thus accessing
|
||||
* packet's ipv6 address won't be possible anymore when creating
|
||||
* the frame */
|
||||
|
|
|
@ -144,15 +144,38 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_buf *buf)
|
|||
enum net_verdict verdict;
|
||||
int status = -EIO;
|
||||
|
||||
if (atomic_test_bit(iface->flags, NET_IF_UP)) {
|
||||
verdict = iface->l2->send(iface, buf);
|
||||
} else {
|
||||
if (!atomic_test_bit(iface->flags, NET_IF_UP)) {
|
||||
/* Drop packet if interface is not up */
|
||||
NET_WARN("iface %p is down", iface);
|
||||
verdict = NET_DROP;
|
||||
status = -ENETDOWN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If the ll address is not set at all, then we must set
|
||||
* it here.
|
||||
*/
|
||||
if (!net_nbuf_ll_src(buf)->addr) {
|
||||
net_nbuf_ll_src(buf)->addr = net_nbuf_ll_if(buf)->addr;
|
||||
net_nbuf_ll_src(buf)->len = net_nbuf_ll_if(buf)->len;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_IPV6)
|
||||
/* If the ll dst address is not set check if it is present in the nbr
|
||||
* cache.
|
||||
*/
|
||||
if (net_nbuf_family(buf) == AF_INET6) {
|
||||
buf = net_ipv6_prepare_for_send(buf);
|
||||
if (!buf) {
|
||||
verdict = NET_CONTINUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
verdict = iface->l2->send(iface, buf);
|
||||
|
||||
done:
|
||||
/* The L2 send() function can return
|
||||
* NET_OK in which case packet was sent successfully.
|
||||
* In that case we need to check if any user callbacks need
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue