Skip to content

Commit 82f23bc

Browse files
rveerama1jukkar
authored andcommitted
net: rpl: Fix handling of DAO message
When a node receives DIO message from peer then node adds peer as a neighbor (nbr with linklayer address). But when a node receives DAO message from different peer (chances are peer selected different route to reach this node), remove peer with previous link layer address and add as a neighbor with new link layer address with new route information. Now node can properly route packets to peer from neighbor table or based on nexthop information from routing table. Signed-off-by: Ravi kumar Veeramally <[email protected]>
1 parent 6245dd6 commit 82f23bc

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

subsys/net/ip/rpl.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3494,6 +3494,43 @@ static enum net_verdict handle_dao(struct net_pkt *pkt)
34943494
NET_DBG("Adding DAO route to %s", net_sprint_ipv6_addr(dao_sender));
34953495

34963496
ipv6_nbr = net_ipv6_nbr_lookup(net_pkt_iface(pkt), dao_sender);
3497+
if (ipv6_nbr) {
3498+
struct net_linkaddr_storage *nbr_lladdr;
3499+
struct net_linkaddr *src_lladdr;
3500+
3501+
NET_DBG("Neighbor %s [%s] already in neighbor cache",
3502+
net_sprint_ipv6_addr(dao_sender),
3503+
net_sprint_ll_addr(net_pkt_ll_src(pkt)->addr,
3504+
net_pkt_ll_src(pkt)->len));
3505+
3506+
nbr_lladdr = net_nbr_get_lladdr(ipv6_nbr->idx);
3507+
if (!nbr_lladdr) {
3508+
NET_ERR("Invalid lladdr from ipv6 nbr");
3509+
return NET_DROP;
3510+
}
3511+
3512+
src_lladdr = net_pkt_ll_src(pkt);
3513+
if (!src_lladdr || !src_lladdr->addr) {
3514+
NET_ERR("Invalid src lladdr in net pkt");
3515+
return NET_DROP;
3516+
}
3517+
3518+
/* DAO received from different LLAddr, so remove IPv6 nbr from
3519+
* previous LLAddr and add as a new nbr from current LLAddr.
3520+
*/
3521+
if (memcmp(nbr_lladdr->addr, src_lladdr->addr,
3522+
nbr_lladdr->len)) {
3523+
3524+
if (!net_ipv6_nbr_rm(net_pkt_iface(pkt), dao_sender)) {
3525+
NET_ERR("Failed to remove %s, doesn't exist",
3526+
net_sprint_ipv6_addr(dao_sender));
3527+
return NET_DROP;
3528+
}
3529+
3530+
ipv6_nbr = NULL;
3531+
}
3532+
}
3533+
34973534
if (!ipv6_nbr) {
34983535
ipv6_nbr = net_ipv6_nbr_add(net_pkt_iface(pkt), dao_sender,
34993536
net_pkt_ll_src(pkt), false,

0 commit comments

Comments
 (0)