From 3d821ee195c416b19312fadae55b2362efb1374a Mon Sep 17 00:00:00 2001
From: Martine Lenders <m.lenders@fu-berlin.de>
Date: Thu, 3 May 2018 19:12:24 +0200
Subject: [PATCH] gnrc_rpl: remove route before updating it

The "new" forwarding table does not update an old route but just adds
another as long as it is not *exactly* the same. However, the RPL
adaptation missed to remove the old route so RPL got easily confused
about where it actually needed to send packets.
---
 sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c | 3 +++
 sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c            | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c
index 47fad77e5b..0bee108ac3 100644
--- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c
+++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c
@@ -467,6 +467,7 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt
                       ipv6_addr_to_str(addr_str, &(target->target), (unsigned)sizeof(addr_str)),
                       target->prefix_length);
 
+                gnrc_ipv6_nib_ft_del(&(target->target), target->prefix_length);
                 gnrc_ipv6_nib_ft_add(&(target->target), target->prefix_length, src,
                                      dodag->iface,
                                      dodag->default_lifetime * dodag->lifetime_unit);
@@ -487,6 +488,8 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt
                           ipv6_addr_to_str(addr_str, &(first_target->target), sizeof(addr_str)),
                           first_target->prefix_length);
 
+                    gnrc_ipv6_nib_ft_del(&(first_target->target),
+                                         first_target->prefix_length);
                     gnrc_ipv6_nib_ft_add(&(first_target->target),
                                          first_target->prefix_length, src,
                                          dodag->iface,
diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c
index 87d055a4fe..6a5ead9f2d 100644
--- a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c
+++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c
@@ -258,6 +258,7 @@ void gnrc_rpl_parent_update(gnrc_rpl_dodag_t *dodag, gnrc_rpl_parent_t *parent)
         if (dodag->instance->mop != GNRC_RPL_P2P_MOP) {
 #endif
         if (parent == dodag->parents) {
+            gnrc_ipv6_nib_ft_del(NULL, 0);
             gnrc_ipv6_nib_ft_add(NULL, 0, &parent->addr, dodag->iface,
                                  dodag->default_lifetime * dodag->lifetime_unit);
         }
@@ -308,6 +309,7 @@ static gnrc_rpl_parent_t *_gnrc_rpl_find_preferred_parent(gnrc_rpl_dodag_t *doda
 #ifdef MODULE_GNRC_RPL_P2P
     if (dodag->instance->mop != GNRC_RPL_P2P_MOP) {
 #endif
+        gnrc_ipv6_nib_ft_del(NULL, 0);
         gnrc_ipv6_nib_ft_add(NULL, 0, &dodag->parents->addr, dodag->iface,
                              dodag->default_lifetime * dodag->lifetime_unit);
 #ifdef MODULE_GNRC_RPL_P2P
-- 
GitLab