Re: [Zephyr-devel] RPL Tests


Pedro
 

As you requested,


Thank you.

2017-11-29 10:02 GMT-02:00 Pedro Paulo Canto Martucci <pedrom@...>:

Hi Ravi,

I will send a WIP PR, with my setup and README which allows you to reproduce.

Thanks!

2017-11-29 9:40 GMT-02:00 Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>:
Hi Pedro,

On 11/28/2017 10:12 PM, Pedro Paulo Canto Martucci wrote:
Hi,

I'm trying to validate some RPL features using QEMU. I know it's not the best approach but here we go.
   Yep, we can not completely validate RPL using QEMU. But at-least you started to check some features,
  thanks for that.


For this tests, I'm using 83cf82b7a tag from zephyr git project.

I created a root node to build the RPL network using the code bellow:

'''
#define CURRENT_VERSION 0

void main(void) {
u8_t init_version = CURRENT_VERSION;

char prefix_str[NET_IPV6_ADDR_LEN + 1];
struct in6_addr prefix;
u8_t prefix_len;

printk("RPL root node starting\n");

struct net_if *iface = net_if_get_default();
if (!iface) {
printk("Interface is NULL\n");
printk("Failed to setup RPL root node\n");
return;
}

// Read prefix from KConfig and parse it
memset(prefix_str, 0, sizeof(prefix_str));
memcpy(prefix_str, CONFIG_NET_RPL_PREFIX, min(strlen(CONFIG_NET_RPL_PREFIX), NET_IPV6_ADDR_LEN));

char *slash = strstr(prefix_str, "/");
if (!slash) {
prefix_len = 64;
} else {
*slash = '\0';
prefix_len = atoi(slash + 1);
}

if (prefix_len == 0) {
printk("Invalid prefix length %s", slash + 1);
return;
}

if (net_addr_pton(AF_INET6, prefix_str, &prefix) < 0) {
printk("Invalid IPv6 prefix %s", prefix_str);
return;
}

// Check the current version
if (CURRENT_VERSION == 0) {
// case 0 - call init
init_version = net_rpl_lollipop_init();
} else if (CURRENT_VERSION > 0) {
// case > 0 - increment
net_rpl_lollipop_increment(&init_version);
} else {
printk("CURRENT_VERSION should be greater or eqaul to 0");
return;
}

// Setup the root node
struct net_rpl_dag *dag = net_rpl_set_root_with_version(iface, CONFIG_NET_RPL_DEFAULT_INSTANCE, &prefix, init_version);

if (!dag) {
printk("Cannot set root node");
return;
}

bool ret = net_rpl_set_prefix(iface, dag, &prefix, prefix_len);
if (!ret) {
printk("Cannot set prefix %s/%d", prefix_str, prefix_len);
return;
}
}
'''

Most part of the code are based in pull request #980 and #5035, except version update handling, which I do manually.
   Those PR's are work in progress. It's taking some time test with different topologies and scenarios. Net subsystem
    needs to support some kind flash memory, so I haven't verified 'global repair' scenario.

The leaf node will run an empty main, I'll do the validation just pinging between the nodes using net shell.

On KConfig definitions for root node I setup RPL, 6LoWPAN and uart_pipe driver for 802.15.4:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_GROUNDED=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1
CONFIG_NET_RPL_PREFIX="2001:db8::1/64"

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n

# Application Settings
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
'''

In leaf node:
'''
CONFIG_NET_RPL=y
CONFIG_NET_DEBUG_RPL=y
CONFIG_NET_RPL_MAX_DAG_PER_INSTANCE=1

# IPv6 (L3)
CONFIG_NET_IPV6=y

# 6LoWPAN (L2 - Adaptation Layer)
CONFIG_NET_6LO=y

# 802.15.4 (L2)
CONFIG_NET_L2_IEEE802154=y
CONFIG_NET_L2_IEEE802154_FRAGMENT=y

# 802.15.4 (L1)
CONFIG_IEEE802154_UPIPE=y

# Enabled Shell Extensions
CONFIG_NET_SHELL=y
CONFIG_NET_L2_IEEE802154_SHELL=y

# Disable default Ethernet interface
CONFIG_NET_SLIP_TAP=n
'''

This way, I was able to run the example fine. The root published the prefix in DIO messages, the leaf node joined the DAG with DAO and I managed to ping between hosts using net shell.

My problems started when I tried to simulate a global repair scenario, rebooting the root node. To achieve this, it was necessary to modify some environments configurations.

To setup the QEMU environment I created the pipes manually and disabled removing/creation commands from zephyr/cmake/qemu/CMakeLists.txt in QEMU_NET_STACK session. This way when the 'server' node is rebooted the connection is not lost in the 'client' caused by the pipes recreation.
 
     It would be good to send a WIP PR with your setup and some readme file also. So that I can reproduce the issue and investigate purpose.
 
Also needed to modify get_mac() function from ieee802154_uart_pipe driver to assure that the MAC address assigned to the root node will be always the same:
'''
static inline u8_t *get_mac(struct device *dev)
{
struct upipe_context *upipe = dev->driver_data;


upipe->mac_addr[0] = 0x00;
upipe->mac_addr[1] = 0x10;
upipe->mac_addr[2] = 0x20;
upipe->mac_addr[3] = 0x30;

#if defined(CONFIG_NET_RPL_GROUNDED)
upipe->mac_addr[4] = 0xAA;
upipe->mac_addr[5] = 0xAA;
upipe->mac_addr[6] = 0xAA;
upipe->mac_addr[7] = 0xAA;
#else
UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
      (u32_t *) ((void *)upipe->mac_addr+4));
#endif

return upipe->mac_addr;
}
'''

Can you try with these Kconfig options.
 CONFIG_IEEE802154_CC2520_RANDOM_MAC=n
CONFIG_IEEE802154_CC2520_MAC4=0x00
CONFIG_IEEE802154_CC2520_MAC5=0x10
CONFIG_IEEE802154_CC2520_MAC6=0x20
CONFIG_IEEE802154_CC2520_MAC7=0x30


Now I run both applications and wait the network to be configured. After that, I kill the root node, update the constant CURRENT_VERSION in main.c to 240, recompile and rerun it.

The leaf node receives the DIO messages from the root with the new version and and trigger the global repair. During this process it removes the old neighbors/parents and try to setup the new one.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9b:9856 from fe80::210:2030:9b:9856 to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): nbr linking failure (-69)
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Cannot add RPL neighbor
[net/rpl] [DBG] global_repair: (0x20000558): Failed to add a parent during the global repair
[net/rpl] [DBG] global_repair: (0x20000558): Participating in a global repair version 241 rank 65535
'''

I think it should send a DAO message to the root to rejoin the network if everything is ok, but as we can see in the log it doesn't went right.

I tried to discover the reason why it was unable to add the parent, starting from nbr_add(). I reached to net_nbr_link() function from nbr.c and clearly it failed because of idx check (-EALREADY = -69):
'''
if (nbr->idx != NET_NBR_LLADDR_UNKNOWN) {
return -EALREADY;
}
'''

I don't understand properly the neighbor structures and organization from zephyr to reach any conclusion here, but seems the neighbor passed as argument to net_nbr_link() is not properly cleared as the function expects.

After expending some time on gdb, I verified that the neighbor passed as an argument is the same which was removed right before global repair process. This brings me to net_rpl_neighbor_data_remove() function from rpl.c, which just prints a message and doesn't clear nbr.

Based on this I did a stupid test adding a line to net_rpl_neighbor_data_remove(), just to check what would happen: 
'''
nbr->idx = 0xff;
'''

After rerunning the case I got the RPL network restablished.

'''
[net/rpl] [DBG] handle_dio: (0x20000558): Received DODAG Information Object from fe80::210:2030:aaaa:aaaa to ff02::1a
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO len 72 id 30 ver 241 rank 256
[net/rpl] [DBG] handle_dio: (0x20000558): Incoming DIO dag_id 2001:db8::1 pref 0
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 4 length 14
[net/rpl] [DBG] handle_dio: (0x20000558): DAG conf dbl 8 min 12 red 10 maxinc 1792 mininc 256 ocp 1 d_l 255 l_u 65535
[net/rpl] [DBG] handle_dio: (0x20000558): DIO option 8 length 30
[net/rpl] [DBG] handle_dio: (0x20000558): Prefix 2001:db8::/64
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Global repair
[net/rpl] [DBG] net_rpl_process_dio: (0x20000558): Prefix announced in DIO
[net/rpl] [DBG] net_rpl_set_prefix: (0x20000558): Prefix is non-NULL, will announce this in DIOs
[net/rpl] [DBG] check_prefix: (0x20000558): Same prefix 2001:db8::/64 flags 0x40
[net/rpl] [DBG] remove_parents: (0x20000558): Removing parents minimum rank 0
[net/rpl] [DBG] net_rpl_remove_parent: (0x20000558): Removing parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Removing default route fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_dao_send: (0x20000558): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent not set
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_nullify_parent: (0x20000558): Nullifying parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] nbr_free: (0x20000558): nbr 0x200062b0
[net/rpl] [DBG] net_rpl_neighbor_data_remove: (0x20000558): Neighbor 0x200062b0 removed
[net/rpl] [DBG] net_rpl_mrhof_reset: (0x20000558): Reset MRHOF
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): Add parent fe80::210:2030:aaaa:aaaa [00:10:20:30:AA:AA:AA:AA]
[net/rpl] [DBG] nbr_add: (0x20000558): [0] nbr 0x200062b0 IPv6 fe80::210:2030:aaaa:aaaa ll 00:10:20:30:AA:AA:AA:AA iface 0x200067a0
[net/rpl] [DBG] net_rpl_add_parent: (0x20000558): [0] nbr 0x200062b0 parent 0x200062c4
[net/rpl] [DBG] global_repair: (0x20000558): Starting global repair
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): Preferred parent fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_set_preferred_parent: (0x20000558): It used to be not set
[net/rpl] [DBG] net_rpl_set_default_route: (0x20000558): Adding default route through fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_select_dag: (0x20000558): Changed preferred parent, rank changed from 768 to 768
[net/rpl] [DBG] schedule_dao: (0x20000558): Scheduling DAO timer 4800 ms in the future
[net/rpl] [DBG] dao_timer: (0x20000cb0): Sending DAO iface 0x200067a0
[net/rpl] [DBG] net_rpl_dao_send: (0x20000cb0): Send DAO with prefix 2001:db8::210:2030:9c:475a from fe80::210:2030:9c:475a to fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] net_rpl_link_neighbor_callback: (0x2000060c): Neighbor link callback triggering update
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received Destination Advertisement Object Ack from fe80::210:2030:aaaa:aaaa to fe80::210:2030:9c:475a
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Received a DAO ACK with seq number 244(244) status 0 from fe80::210:2030:aaaa:aaaa
[net/rpl] [DBG] handle_dao_ack: (0x20000558): Status ACK
'''

Clearly my approach wasn't correct, I don't even understand properly the neighbor dynamics. Did I miss something in my setup which might have caused this behavior? Or there are something wrong on neighbor management?

At-least now I will investigate with above logs, it would be good if you can send your patches and steps to reproduce.

Thanks,
Ravi.
Thank you!

--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995


_______________________________________________
Zephyr-devel mailing list
Zephyr-devel@...ct.org
https://lists.zephyrproject.org/mailman/listinfo/zephyr-devel




--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995



--
Att,
Pedro Martucci
---
Gerência de Tecnologias de Controle e Inteligência de Sistemas
CPqD - Diretoria de Tecnologias de Comunicação
Tel.: +55 19 3705-5995

Join users@lists.zephyrproject.org to automatically receive all group messages.