From bd6de2401f48346383ac8e0816ec7ac070e4082a Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Sun, 10 Dec 2017 20:34:50 +0100 Subject: [PATCH 1/4] added some documentation --- os/net/ipv6/uipbuf.c | 2 +- os/net/ipv6/uipbuf.h | 105 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 90 insertions(+), 17 deletions(-) diff --git a/os/net/ipv6/uipbuf.c b/os/net/ipv6/uipbuf.c index c0f9da4e2..6ccbb99aa 100644 --- a/os/net/ipv6/uipbuf.c +++ b/os/net/ipv6/uipbuf.c @@ -128,6 +128,6 @@ uipbuf_clr_attr_flag(uint16_t flag) uint16_t uipbuf_is_attr_flag(uint16_t flag) { - return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) > 0; + return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) == flag; } /*---------------------------------------------------------------------------*/ diff --git a/os/net/ipv6/uipbuf.h b/os/net/ipv6/uipbuf.h index 16b201843..337ffe17f 100644 --- a/os/net/ipv6/uipbuf.h +++ b/os/net/ipv6/uipbuf.h @@ -35,33 +35,106 @@ #include "contiki.h" -/* Get the next header given the buffer - start indicates that this is - start of the IPv6 header - needs to be set to 0 when in an ext hdr */ - +/** + * \brief Get the next IPv6 header. + * \param buffer A pointer to the buffer holding the IPv6 packet + * \param size The size of the data in the buffer + * \param protocol A pointer to a variable where the protocol of the header will be stored + * \param start A flag that indicates if this is expected to be the IPv6 packet header or a later header (Extension header) + * \retval returns address of the starting position of the next header + * + * This function moves to the next header in a IPv6 packet. + */ uint8_t* uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, uint8_t start); -/* Get the final header given the buffer - that is assumed to be at start - of an IPv6 header */ + + +/** + * \brief Get the last IPv6 header. + * \param buffer A pointer to the buffer holding the IPv6 packet + * \param size The size of the data in the buffer + * \param protocol A pointer to a variable where the protocol of the header will be stored + * \retval returns address of the starting position of the next header + * + * This function moves to the last header of the IPv6 packet. + */ uint8_t* uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol); -/* Attributes relating to the current packet in uipbuf */ + +/** + * \brief Get the value of the attribute + * \param type The attribute to get the value of + * \retval the value of the attribute + * + * This function gets the value of a specific uipbuf attribute. + */ uint16_t uipbuf_get_attr(uint8_t type); -void uipbuf_set_attr_flag(uint16_t flag); -void uipbuf_clr_attr_flag(uint16_t flag); -uint16_t uipbuf_is_attr_flag(uint16_t flag); + + +/** + * \brief Set the value of the attribute + * \param type The attribute to set the value of + * \param value The value to set + * \retval 0 - indicates failure of setting the value + * \retval 1 - indicates success of setting the value + * + * This function sets the value of a specific uipbuf attribute. + */ int uipbuf_set_attr(uint8_t type, uint16_t value); + +/** + * \brief Set bits in the uipbuf attribute flags. + * \param flag_bits The bits to set in the flag. + * + * This function sets the uipbuf attributes flag of specified bits. + */ +void uipbuf_set_attr_flag(uint16_t flag_bits); + +/** + * \brief Clear bits in the uipbuf attribute flags. + * \param flag_bits The bits to clear in the flag. + * + * This function clears the uipbuf attributes flag of specified bits. + */ +void uipbuf_clr_attr_flag(uint16_t flag_bits); + +/** + * \brief Check if bits in the uipbuf attribute flag are set. + * \param flag_bits The bits to check in the flag. + * + * This function checks if the specified bits are set in the + * uipbuf attributes flag. + */ +uint16_t uipbuf_is_attr_flag(uint16_t flag_bits); + + +/** + * \brief Clear all attributes. + * + * This function clear all attributes in the uipbuf attributes + * including all flags. + */ void uipbuf_clear_attr(void); -/* These flags will be used for being */ +/** + * \brief The bits defined for uipbuf attributes flag. + * + */ +/* Avoid using NHC compression on the packet (6LoWPAN) */ #define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_NHC_COMPRESSION 0x01 +/* Avoid using prefix compression on the packet (6LoWPAN) */ #define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_PREFIX_COMPRESSION 0x02 +/** + * \brief The attributes defined for uipbuf attributes function. + * + */ enum { - UIPBUF_ATTR_LLSEC_LEVEL, - UIPBUF_ATTR_LLSEC_KEY_ID, - UIPBUF_ATTR_INTERFACE_ID, - UIPBUF_ATTR_PHYSICAL_NETWORK_ID, - UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, - UIPBUF_ATTR_FLAGS, + UIPBUF_ATTR_LLSEC_LEVEL, /**< Control link layer security level. */ + UIPBUF_ATTR_LLSEC_KEY_ID, /**< Control link layer security key ID. */ + UIPBUF_ATTR_INTERFACE_ID, /**< The interface to output packet on */ + UIPBUF_ATTR_PHYSICAL_NETWORK_ID, /**< Physical network ID (mapped to PAN ID)*/ + UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, /**< MAX transmissions of the packet MAC */ + UIPBUF_ATTR_FLAGS, /**< Flags that can control lower layers. see above. */ UIPBUF_ATTR_MAX }; From ed239372c1f7e4dfd1d427de5a80c146f62a60e4 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:04:53 +0100 Subject: [PATCH 2/4] Use UIP_LLH_LEN in multicast engines and add more traces --- os/net/ipv6/multicast/esmrf.c | 13 ++++++++----- os/net/ipv6/multicast/roll-tm.c | 2 +- os/net/ipv6/multicast/smrf.c | 9 +++++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/os/net/ipv6/multicast/esmrf.c b/os/net/ipv6/multicast/esmrf.c index 2da8da400..adbea25e0 100644 --- a/os/net/ipv6/multicast/esmrf.c +++ b/os/net/ipv6/multicast/esmrf.c @@ -229,7 +229,7 @@ icmp_input() uip_process(UIP_UDP_SEND_CONN); - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; /* pass the packet to our uip_process to check if it is allowed to * accept this packet or not */ @@ -239,7 +239,7 @@ icmp_input() uip_process(UIP_DATA); - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; /* Return the IP of the original Multicast sender */ uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &src_ip); @@ -257,7 +257,7 @@ icmp_input() static void mcast_fwd(void *p) { - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); @@ -291,7 +291,7 @@ in() parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr); if(parent_lladdr == NULL) { - PRINTF("ESMRF: NO Parent exist \n"); + PRINTF("ESMRF: No Parent found\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -309,6 +309,7 @@ in() if(UIP_IP_BUF->ttl <= 1) { UIP_MCAST6_STATS_ADD(mcast_dropped); + PRINTF("ESMRF: TTL too low\n"); return UIP_MCAST6_DROP; } @@ -350,12 +351,14 @@ in() fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread)); } - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL); } PRINTF("ESMRF: %u bytes: fwd in %u [%u]\n", uip_len, fwd_delay, fwd_spread); + } else { + PRINTF("ESMRF: Group unknown, dropping\n"); } /* Done with this packet unless we are a member of the mcast group */ diff --git a/os/net/ipv6/multicast/roll-tm.c b/os/net/ipv6/multicast/roll-tm.c index edf86b22b..1d19512d6 100644 --- a/os/net/ipv6/multicast/roll-tm.c +++ b/os/net/ipv6/multicast/roll-tm.c @@ -1321,7 +1321,7 @@ static void out() { - if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE) { + if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE - UIP_LLH_LEN) { PRINTF("ROLL TM: Multicast Out can not add HBHO. Packet too long\n"); goto drop; } diff --git a/os/net/ipv6/multicast/smrf.c b/os/net/ipv6/multicast/smrf.c index 06167f75a..00043d60b 100644 --- a/os/net/ipv6/multicast/smrf.c +++ b/os/net/ipv6/multicast/smrf.c @@ -82,7 +82,7 @@ static uint8_t fwd_spread; static void mcast_fwd(void *p) { - memcpy(uip_buf, &mcast_buf, mcast_len); + memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len); uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); @@ -106,6 +106,7 @@ in() */ d = rpl_get_any_dag(); if(!d) { + PRINTF("SMRF: No DODAG\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -115,6 +116,7 @@ in() parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr); if(parent_lladdr == NULL) { + PRINTF("SMRF: No Parent found\n"); UIP_MCAST6_STATS_ADD(mcast_dropped); return UIP_MCAST6_DROP; } @@ -132,6 +134,7 @@ in() if(UIP_IP_BUF->ttl <= 1) { UIP_MCAST6_STATS_ADD(mcast_dropped); + PRINTF("SMRF: TTL too low\n"); return UIP_MCAST6_DROP; } @@ -173,12 +176,14 @@ in() fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread)); } - memcpy(&mcast_buf, uip_buf, uip_len); + memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len); mcast_len = uip_len; ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL); } PRINTF("SMRF: %u bytes: fwd in %u [%u]\n", uip_len, fwd_delay, fwd_spread); + } else { + PRINTF("SMRF: Group unknown, dropping\n"); } /* Done with this packet unless we are a member of the mcast group */ From a97148abd48d3aaff6472430cbfc7de359351409 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:56:12 +0100 Subject: [PATCH 3/4] Make multicast route lifetime identical to unicast routes --- os/net/rpl-classic/rpl-private.h | 7 ------- os/net/rpl-classic/rpl-timers.c | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/os/net/rpl-classic/rpl-private.h b/os/net/rpl-classic/rpl-private.h index f00734821..723154cdd 100644 --- a/os/net/rpl-classic/rpl-private.h +++ b/os/net/rpl-classic/rpl-private.h @@ -199,13 +199,6 @@ #define RPL_ROUTE_FROM_MULTICAST_DAO 2 #define RPL_ROUTE_FROM_DIO 3 -/* Multicast Route Lifetime as a multiple of the lifetime unit */ -#ifdef RPL_CONF_MCAST_LIFETIME -#define RPL_MCAST_LIFETIME RPL_CONF_MCAST_LIFETIME -#else -#define RPL_MCAST_LIFETIME 3 -#endif - /* DIS related */ #define RPL_DIS_SEND 1 diff --git a/os/net/rpl-classic/rpl-timers.c b/os/net/rpl-classic/rpl-timers.c index b89a1258d..56eda7abc 100644 --- a/os/net/rpl-classic/rpl-timers.c +++ b/os/net/rpl-classic/rpl-timers.c @@ -283,7 +283,7 @@ handle_dao_timer(void *ptr) if(uip_ds6_if.maddr_list[i].isused && uip_is_addr_mcast_global(&uip_ds6_if.maddr_list[i].ipaddr)) { dao_output_target(instance->current_dag->preferred_parent, - &uip_ds6_if.maddr_list[i].ipaddr, RPL_MCAST_LIFETIME); + &uip_ds6_if.maddr_list[i].ipaddr, instance->default_lifetime); } } @@ -293,7 +293,7 @@ handle_dao_timer(void *ptr) /* Don't send if it's also our own address, done that already */ if(uip_ds6_maddr_lookup(&mcast_route->group) == NULL) { dao_output_target(instance->current_dag->preferred_parent, - &mcast_route->group, RPL_MCAST_LIFETIME); + &mcast_route->group, instance->default_lifetime); } mcast_route = list_item_next(mcast_route); } From a79fa138052d31bbc7bc8c8fcf0a616c3e163c04 Mon Sep 17 00:00:00 2001 From: Laurent Deru Date: Thu, 7 Dec 2017 14:52:37 +0100 Subject: [PATCH 4/4] Additional cleanup when becoming DODAG Root (rpl-classic) --- os/net/rpl-classic/rpl-dag.c | 8 ++++++++ os/net/rpl-classic/rpl-icmp6.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/os/net/rpl-classic/rpl-dag.c b/os/net/rpl-classic/rpl-dag.c index e4f4191b1..96f086b8d 100644 --- a/os/net/rpl-classic/rpl-dag.c +++ b/os/net/rpl-classic/rpl-dag.c @@ -370,6 +370,7 @@ rpl_set_root(uint8_t instance_id, uip_ipaddr_t *dag_id) } if(dag == dag->instance->current_dag) { PRINTF("RPL: Dropping a joined DAG when setting this node as root"); + rpl_set_default_route(instance, NULL); dag->instance->current_dag = NULL; } else { PRINTF("RPL: Dropping a DAG when setting this node as root"); @@ -665,6 +666,10 @@ rpl_free_dag(rpl_dag_t *dag) if(RPL_IS_STORING(dag->instance)) { rpl_remove_routes(dag); } + /* Stop the DAO retransmit timer */ +#if RPL_WITH_DAO_ACK + ctimer_stop(&dag->instance->dao_retransmit_timer); +#endif /* RPL_WITH_DAO_ACK */ /* Remove autoconfigured address */ if((dag->prefix_info.flags & UIP_ND6_RA_FLAG_AUTONOMOUS)) { @@ -1323,6 +1328,9 @@ rpl_local_repair(rpl_instance_t *instance) /* no downward route anymore */ instance->has_downward_route = 0; +#if RPL_WITH_DAO_ACK + ctimer_stop(&instance->dao_retransmit_timer); +#endif /* RPL_WITH_DAO_ACK */ rpl_reset_dio_timer(instance); if(RPL_IS_STORING(instance)) { diff --git a/os/net/rpl-classic/rpl-icmp6.c b/os/net/rpl-classic/rpl-icmp6.c index 6da3c2656..c5114fd14 100644 --- a/os/net/rpl-classic/rpl-icmp6.c +++ b/os/net/rpl-classic/rpl-icmp6.c @@ -1282,6 +1282,12 @@ dao_ack_input(void) parent = NULL; } + if(instance->current_dag->rank == ROOT_RANK(instance)) { + PRINTF("RPL: DODAG root received a DAO ACK, ignoring it\n"); + uip_clear_buf(); + return; + } + PRINTF("RPL: Received a DAO %s with sequence number %d (%d) and status %d from ", status < 128 ? "ACK" : "NACK", sequence, instance->my_dao_seqno, status);