net: ipv6: routing: decide whether to set interface's LL address
While routing between interfaces source Link-Local L2 address is set for a packet. However, it should not be done for some of the interfaces. This commit adds helper function to check this condition in runtime. Signed-off-by: Konrad Derda <konrad.derda@nordicsemi.no>
This commit is contained in:
parent
0ac5ab4a4e
commit
4e7bf281a1
1 changed files with 52 additions and 40 deletions
|
|
@ -1008,6 +1008,27 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool is_ll_addr_supported(struct net_if *iface)
|
||||
{
|
||||
#if defined(CONFIG_NET_L2_DUMMY)
|
||||
if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_NET_L2_PPP)
|
||||
if (net_if_l2(iface) == &NET_L2_GET_NAME(PPP)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_NET_L2_OPENTHREAD)
|
||||
if (net_if_l2(iface) == &NET_L2_GET_NAME(OPENTHREAD)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int net_route_packet(struct net_pkt *pkt, struct in6_addr *nexthop)
|
||||
{
|
||||
struct net_linkaddr_storage *lladdr;
|
||||
|
|
@ -1032,48 +1053,36 @@ int net_route_packet(struct net_pkt *pkt, struct in6_addr *nexthop)
|
|||
goto error;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_L2_DUMMY)
|
||||
/* No need to do this check for dummy L2 as it does not have any
|
||||
* link layer. This is done at runtime because we can have multiple
|
||||
* network technologies enabled.
|
||||
*/
|
||||
if (net_if_l2(net_pkt_iface(pkt)) != &NET_L2_GET_NAME(DUMMY)) {
|
||||
#endif
|
||||
#if defined(CONFIG_NET_L2_PPP)
|
||||
/* PPP does not populate the lladdr fields */
|
||||
if (net_if_l2(net_pkt_iface(pkt)) != &NET_L2_GET_NAME(PPP)) {
|
||||
#endif
|
||||
if (!net_pkt_lladdr_src(pkt)->addr) {
|
||||
NET_DBG("Link layer source address not set");
|
||||
err = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Sanitycheck: If src and dst ll addresses are going
|
||||
* to be same, then something went wrong in route
|
||||
* lookup.
|
||||
*/
|
||||
if (!memcmp(net_pkt_lladdr_src(pkt)->addr, lladdr->addr,
|
||||
lladdr->len)) {
|
||||
NET_ERR("Src ll and Dst ll are same");
|
||||
err = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
#if defined(CONFIG_NET_L2_PPP)
|
||||
if (is_ll_addr_supported(net_pkt_iface(pkt)) &&
|
||||
is_ll_addr_supported(net_pkt_orig_iface(pkt))) {
|
||||
if (!net_pkt_lladdr_src(pkt)->addr) {
|
||||
NET_DBG("Link layer source address not set");
|
||||
err = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Sanitycheck: If src and dst ll addresses are going
|
||||
* to be same, then something went wrong in route
|
||||
* lookup.
|
||||
*/
|
||||
if (!memcmp(net_pkt_lladdr_src(pkt)->addr, lladdr->addr,
|
||||
lladdr->len)) {
|
||||
NET_ERR("Src ll and Dst ll are same");
|
||||
err = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_NET_L2_DUMMY)
|
||||
}
|
||||
#endif
|
||||
|
||||
net_pkt_set_forwarding(pkt, true);
|
||||
|
||||
/* Set the destination and source ll address in the packet.
|
||||
* We set the destination address to be the nexthop recipient.
|
||||
/* Set the source ll address of the iface (if relevant) and the
|
||||
* destination address to be the nexthop recipient.
|
||||
*/
|
||||
net_pkt_lladdr_src(pkt)->addr = net_pkt_lladdr_if(pkt)->addr;
|
||||
net_pkt_lladdr_src(pkt)->type = net_pkt_lladdr_if(pkt)->type;
|
||||
net_pkt_lladdr_src(pkt)->len = net_pkt_lladdr_if(pkt)->len;
|
||||
if (is_ll_addr_supported(net_pkt_iface(pkt))) {
|
||||
net_pkt_lladdr_src(pkt)->addr = net_pkt_lladdr_if(pkt)->addr;
|
||||
net_pkt_lladdr_src(pkt)->type = net_pkt_lladdr_if(pkt)->type;
|
||||
net_pkt_lladdr_src(pkt)->len = net_pkt_lladdr_if(pkt)->len;
|
||||
}
|
||||
|
||||
net_pkt_lladdr_dst(pkt)->addr = lladdr->addr;
|
||||
net_pkt_lladdr_dst(pkt)->type = lladdr->type;
|
||||
|
|
@ -1082,6 +1091,7 @@ int net_route_packet(struct net_pkt *pkt, struct in6_addr *nexthop)
|
|||
net_pkt_set_iface(pkt, nbr->iface);
|
||||
|
||||
net_ipv6_nbr_unlock();
|
||||
|
||||
return net_send_data(pkt);
|
||||
|
||||
error:
|
||||
|
|
@ -1094,15 +1104,17 @@ int net_route_packet_if(struct net_pkt *pkt, struct net_if *iface)
|
|||
/* The destination is reachable via iface. But since no valid nexthop
|
||||
* is known, net_pkt_lladdr_dst(pkt) cannot be set here.
|
||||
*/
|
||||
|
||||
net_pkt_set_orig_iface(pkt, net_pkt_iface(pkt));
|
||||
net_pkt_set_iface(pkt, iface);
|
||||
|
||||
net_pkt_set_forwarding(pkt, true);
|
||||
|
||||
net_pkt_lladdr_src(pkt)->addr = net_pkt_lladdr_if(pkt)->addr;
|
||||
net_pkt_lladdr_src(pkt)->type = net_pkt_lladdr_if(pkt)->type;
|
||||
net_pkt_lladdr_src(pkt)->len = net_pkt_lladdr_if(pkt)->len;
|
||||
/* Set source LL address if only if relevant */
|
||||
if (is_ll_addr_supported(iface)) {
|
||||
net_pkt_lladdr_src(pkt)->addr = net_pkt_lladdr_if(pkt)->addr;
|
||||
net_pkt_lladdr_src(pkt)->type = net_pkt_lladdr_if(pkt)->type;
|
||||
net_pkt_lladdr_src(pkt)->len = net_pkt_lladdr_if(pkt)->len;
|
||||
}
|
||||
|
||||
return net_send_data(pkt);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue