Merge pull request #1493 from simonduq/pr/add-missing-ext-hdr
Insert RPL ext header before sending ICMP, UDP and TCP messages
This commit is contained in:
commit
21387b954f
|
@ -548,6 +548,15 @@ tcpip_ipv6_output(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if UIP_CONF_IPV6_RPL
|
||||||
|
if(!rpl_update_header()) {
|
||||||
|
/* Packet can not be forwarded */
|
||||||
|
PRINTF("tcpip_ipv6_output: RPL header update error\n");
|
||||||
|
uip_clear_buf();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
if(!uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||||
/* Next hop determination */
|
/* Next hop determination */
|
||||||
|
|
||||||
|
@ -651,12 +660,6 @@ tcpip_ipv6_output(void)
|
||||||
|
|
||||||
/* End of next hop determination */
|
/* End of next hop determination */
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
|
||||||
if(!rpl_finalize_header(nexthop)) {
|
|
||||||
uip_clear_buf();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
|
||||||
nbr = uip_ds6_nbr_lookup(nexthop);
|
nbr = uip_ds6_nbr_lookup(nexthop);
|
||||||
if(nbr == NULL) {
|
if(nbr == NULL) {
|
||||||
#if UIP_ND6_SEND_NA
|
#if UIP_ND6_SEND_NA
|
||||||
|
|
|
@ -160,11 +160,6 @@ echo_request_input(void)
|
||||||
uip_ext_len = 0;
|
uip_ext_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert RPL extension headers */
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
|
||||||
rpl_insert_header();
|
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
|
||||||
|
|
||||||
/* Below is important for the correctness of UIP_ICMP_BUF and the
|
/* Below is important for the correctness of UIP_ICMP_BUF and the
|
||||||
* checksum
|
* checksum
|
||||||
*/
|
*/
|
||||||
|
@ -260,10 +255,6 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
||||||
UIP_ICMP_BUF->icmpchksum = 0;
|
UIP_ICMP_BUF->icmpchksum = 0;
|
||||||
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
|
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
|
||||||
rpl_insert_header();
|
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
|
||||||
|
|
||||||
UIP_STAT(++uip_stat.icmp.sent);
|
UIP_STAT(++uip_stat.icmp.sent);
|
||||||
|
|
||||||
PRINTF("Sending ICMPv6 ERROR message type %d code %d to ", type, code);
|
PRINTF("Sending ICMPv6 ERROR message type %d code %d to ", type, code);
|
||||||
|
@ -301,9 +292,6 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
|
||||||
UIP_STAT(++uip_stat.icmp.sent);
|
UIP_STAT(++uip_stat.icmp.sent);
|
||||||
UIP_STAT(++uip_stat.ip.sent);
|
UIP_STAT(++uip_stat.ip.sent);
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
|
||||||
rpl_insert_header();
|
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
|
||||||
tcpip_ipv6_output();
|
tcpip_ipv6_output();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -890,7 +890,7 @@ ext_hdr_options_process(void)
|
||||||
*/
|
*/
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
PRINTF("Processing RPL option\n");
|
PRINTF("Processing RPL option\n");
|
||||||
if(rpl_verify_hbh_header(uip_ext_opt_offset)) {
|
if(!rpl_verify_hbh_header(uip_ext_opt_offset)) {
|
||||||
PRINTF("RPL Option Error: Dropping Packet\n");
|
PRINTF("RPL Option Error: Dropping Packet\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1228,14 +1228,6 @@ uip_process(uint8_t flag)
|
||||||
goto send;
|
goto send;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
|
||||||
if(!rpl_update_header()) {
|
|
||||||
/* Packet can not be forwarded */
|
|
||||||
PRINTF("RPL header update error\n");
|
|
||||||
goto drop;
|
|
||||||
}
|
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
|
||||||
|
|
||||||
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
||||||
PRINTF("Forwarding packet to ");
|
PRINTF("Forwarding packet to ");
|
||||||
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||||
|
@ -1582,10 +1574,6 @@ uip_process(uint8_t flag)
|
||||||
}
|
}
|
||||||
#endif /* UIP_UDP_CHECKSUMS */
|
#endif /* UIP_UDP_CHECKSUMS */
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
|
||||||
rpl_insert_header();
|
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
|
||||||
|
|
||||||
UIP_STAT(++uip_stat.udp.sent);
|
UIP_STAT(++uip_stat.udp.sent);
|
||||||
goto ip_send_nolen;
|
goto ip_send_nolen;
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
|
|
|
@ -78,26 +78,22 @@ rpl_verify_hbh_header(int uip_ext_opt_offset)
|
||||||
uip_ds6_route_t *route;
|
uip_ds6_route_t *route;
|
||||||
rpl_parent_t *sender = NULL;
|
rpl_parent_t *sender = NULL;
|
||||||
|
|
||||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) {
|
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||||
PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
|
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL
|
||||||
return 1;
|
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||||
}
|
|
||||||
|
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
|
PRINTF("RPL: Hop-by-hop extension header has wrong size or type (%u %u %u)\n",
|
||||||
PRINTF("RPL: Non RPL Hop-by-hop option\n");
|
UIP_HBHO_BUF->len,
|
||||||
return 1;
|
UIP_EXT_HDR_OPT_RPL_BUF->opt_type,
|
||||||
}
|
UIP_EXT_HDR_OPT_RPL_BUF->opt_len);
|
||||||
|
return 0; /* Drop */
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
|
||||||
PRINTF("RPL: Bad header option! (wrong length)\n");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||||
if(instance == NULL) {
|
if(instance == NULL) {
|
||||||
PRINTF("RPL: Unknown instance: %u\n",
|
PRINTF("RPL: Unknown instance: %u\n",
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||||
|
@ -116,14 +112,13 @@ rpl_verify_hbh_header(int uip_ext_opt_offset)
|
||||||
/* Trigger DAO retransmission */
|
/* Trigger DAO retransmission */
|
||||||
rpl_reset_dio_timer(instance);
|
rpl_reset_dio_timer(instance);
|
||||||
/* drop the packet as it is not routable */
|
/* drop the packet as it is not routable */
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!instance->current_dag->joined) {
|
if(!instance->current_dag->joined) {
|
||||||
PRINTF("RPL: No DAG in the instance\n");
|
PRINTF("RPL: No DAG in the instance\n");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
down = 0;
|
down = 0;
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) {
|
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) {
|
||||||
down = 1;
|
down = 1;
|
||||||
|
@ -167,16 +162,16 @@ rpl_verify_hbh_header(int uip_ext_opt_offset)
|
||||||
PRINTF("RPL: Rank error signalled in RPL option!\n");
|
PRINTF("RPL: Rank error signalled in RPL option!\n");
|
||||||
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */
|
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */
|
||||||
rpl_reset_dio_timer(instance);
|
rpl_reset_dio_timer(instance);
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
PRINTF("RPL: Single error tolerated\n");
|
PRINTF("RPL: Single error tolerated\n");
|
||||||
RPL_STAT(rpl_stats.loop_warnings++);
|
RPL_STAT(rpl_stats.loop_warnings++);
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRINTF("RPL: Rank OK\n");
|
PRINTF("RPL: Rank OK\n");
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if RPL_WITH_NON_STORING
|
#if RPL_WITH_NON_STORING
|
||||||
|
@ -383,7 +378,7 @@ insert_srh_header(void)
|
||||||
|
|
||||||
if(node == root_node) {
|
if(node == root_node) {
|
||||||
PRINTF("RPL: SRH no need to insert SRH\n");
|
PRINTF("RPL: SRH no need to insert SRH\n");
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(node != NULL && node != root_node) {
|
while(node != NULL && node != root_node) {
|
||||||
|
@ -482,52 +477,39 @@ update_hbh_header(void)
|
||||||
uip_ext_len = 0;
|
uip_ext_len = 0;
|
||||||
uip_ext_opt_offset = 2;
|
uip_ext_opt_offset = 2;
|
||||||
|
|
||||||
PRINTF("RPL: Verifying the presence of the RPL header option\n");
|
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||||
|
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||||
|
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||||
|
|
||||||
switch(UIP_IP_BUF->proto) {
|
PRINTF("RPL: Hop-by-hop extension header has wrong size (%u %u)\n",
|
||||||
case UIP_PROTO_HBHO:
|
UIP_EXT_HDR_OPT_RPL_BUF->opt_len,
|
||||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) {
|
uip_ext_len);
|
||||||
PRINTF("RPL: Hop-by-hop extension header has wrong size\n");
|
return 0; /* Drop */
|
||||||
uip_ext_len = last_uip_ext_len;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL) {
|
|
||||||
PRINTF("RPL: Non RPL Hop-by-hop option support not implemented\n");
|
|
||||||
uip_ext_len = last_uip_ext_len;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
|
||||||
PRINTF("RPL: RPL Hop-by-hop option has wrong length\n");
|
|
||||||
uip_ext_len = last_uip_ext_len;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||||
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
|
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
|
||||||
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect instance\n");
|
PRINTF("RPL: Unable to add/update hop-by-hop extension header: incorrect instance\n");
|
||||||
return 1;
|
uip_ext_len = last_uip_ext_len;
|
||||||
|
return 0; /* Drop */
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PRINTF("RPL: No hop-by-hop option found\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(UIP_EXT_HDR_OPT_BUF->type) {
|
|
||||||
case UIP_EXT_HDR_OPT_RPL:
|
|
||||||
PRINTF("RPL: Updating RPL option\n");
|
PRINTF("RPL: Updating RPL option\n");
|
||||||
|
/* Update sender rank and instance, will update flags next */
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
|
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||||
|
UIP_EXT_HDR_OPT_RPL_BUF->instance = instance->instance_id;
|
||||||
|
|
||||||
if(RPL_IS_STORING(instance)) { /* In non-storing mode, downwards traffic does not have the HBH option */
|
if(RPL_IS_STORING(instance)) { /* In non-storing mode, downwards traffic does not have the HBH option */
|
||||||
/* Check the direction of the down flag, as per Section 11.2.2.3,
|
/* Check the direction of the down flag, as per Section 11.2.2.3,
|
||||||
which states that if a packet is going down it should in
|
which states that if a packet is going down it should in
|
||||||
general not go back up again. If this happens, a
|
general not go back up again. If this happens, a
|
||||||
RPL_HDR_OPT_FWD_ERR should be flagged. */
|
RPL_HDR_OPT_FWD_ERR should be flagged. */
|
||||||
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
|
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
|
||||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
|
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||||
PRINTF("RPL forwarding error\n");
|
PRINTF("RPL forwarding error\n");
|
||||||
/* We should send back the packet to the originating parent,
|
/* We should send back the packet to the originating parent,
|
||||||
but it is not feasible yet, so we send a No-Path DAO instead */
|
but it is not feasible yet, so we send a No-Path DAO instead */
|
||||||
PRINTF("RPL generate No-Path DAO\n");
|
PRINTF("RPL generate No-Path DAO\n");
|
||||||
parent = rpl_get_parent((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
parent = rpl_get_parent((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
if(parent != NULL) {
|
if(parent != NULL) {
|
||||||
|
@ -538,11 +520,11 @@ update_hbh_header(void)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Set the down extension flag correctly as described in Section
|
/* Set the down extension flag correctly as described in Section
|
||||||
11.2 of RFC6550. If the packet progresses along a DAO route,
|
11.2 of RFC6550. If the packet progresses along a DAO route,
|
||||||
the down flag should be set. */
|
the down flag should be set. */
|
||||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||||
/* No route was found, so this packet will go towards the RPL
|
/* No route was found, so this packet will go towards the RPL
|
||||||
root. If so, we should not set the down flag. */
|
root. If so, we should not set the down flag. */
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
|
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
|
||||||
PRINTF("RPL option going up\n");
|
PRINTF("RPL option going up\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -552,18 +534,14 @@ update_hbh_header(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uip_ext_len = last_uip_ext_len;
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
PRINTF("RPL: Multi Hop-by-hop options not implemented\n");
|
|
||||||
uip_ext_len = last_uip_ext_len;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uip_ext_len = last_uip_ext_len;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
insert_hbh_header(void)
|
insert_hbh_header(const rpl_instance_t *instance)
|
||||||
{
|
{
|
||||||
int uip_ext_opt_offset;
|
int uip_ext_opt_offset;
|
||||||
int last_uip_ext_len;
|
int last_uip_ext_len;
|
||||||
|
@ -594,8 +572,8 @@ insert_hbh_header(void)
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
|
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
|
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
|
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = 0;
|
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = 0;
|
UIP_EXT_HDR_OPT_RPL_BUF->instance = instance->instance_id;
|
||||||
uip_len += RPL_HOP_BY_HOP_LEN;
|
uip_len += RPL_HOP_BY_HOP_LEN;
|
||||||
temp_len = UIP_IP_BUF->len[1];
|
temp_len = UIP_IP_BUF->len[1];
|
||||||
UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN;
|
UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN;
|
||||||
|
@ -604,44 +582,9 @@ insert_hbh_header(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
rpl_finalize_header(uip_ipaddr_t *addr)
|
|
||||||
{
|
|
||||||
rpl_parent_t *parent;
|
|
||||||
int uip_ext_opt_offset;
|
|
||||||
int last_uip_ext_len;
|
|
||||||
|
|
||||||
last_uip_ext_len = uip_ext_len;
|
/* Update header before returning */
|
||||||
uip_ext_len = 0;
|
return update_hbh_header();
|
||||||
uip_ext_opt_offset = 2;
|
|
||||||
|
|
||||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO) {
|
|
||||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)) {
|
|
||||||
PRINTF("RPL: Non RPL Hop-by-hop options support not implemented\n");
|
|
||||||
uip_ext_len = last_uip_ext_len;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(UIP_EXT_HDR_OPT_BUF->type == UIP_EXT_HDR_OPT_RPL) {
|
|
||||||
if(UIP_EXT_HDR_OPT_RPL_BUF->senderrank == 0) {
|
|
||||||
PRINTF("RPL: Updating RPL option\n");
|
|
||||||
if(default_instance == NULL || !default_instance->used || !default_instance->current_dag->joined) {
|
|
||||||
PRINTF("RPL: Unable to add hop-by-hop extension header: incorrect default instance\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
parent = rpl_find_parent(default_instance->current_dag, addr);
|
|
||||||
if(parent == NULL || parent != parent->dag->preferred_parent) {
|
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->flags = RPL_HDR_OPT_DOWN;
|
|
||||||
}
|
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = default_instance->instance_id;
|
|
||||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(default_instance->current_dag->rank);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -654,8 +597,6 @@ rpl_remove_header(void)
|
||||||
uip_ext_len = 0;
|
uip_ext_len = 0;
|
||||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||||
|
|
||||||
PRINTF("RPL: Verifying the presence of RPL extension headers\n");
|
|
||||||
|
|
||||||
/* Look for hop-by-hop and routing headers */
|
/* Look for hop-by-hop and routing headers */
|
||||||
while(uip_next_hdr != NULL) {
|
while(uip_next_hdr != NULL) {
|
||||||
switch(*uip_next_hdr) {
|
switch(*uip_next_hdr) {
|
||||||
|
@ -691,51 +632,33 @@ rpl_remove_header(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
|
||||||
rpl_insert_header(void)
|
|
||||||
{
|
|
||||||
if(default_instance == NULL || default_instance->current_dag == NULL
|
|
||||||
|| uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) || uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(RPL_IS_STORING(default_instance)) {
|
|
||||||
insert_hbh_header();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(RPL_IS_NON_STORING(default_instance)) {
|
|
||||||
if(default_instance->current_dag != NULL) {
|
|
||||||
if(default_instance->current_dag->rank == ROOT_RANK(default_instance)) {
|
|
||||||
insert_srh_header();
|
|
||||||
} else {
|
|
||||||
insert_hbh_header();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
int
|
int
|
||||||
rpl_update_header(void)
|
rpl_update_header(void)
|
||||||
{
|
{
|
||||||
if(default_instance == NULL) {
|
if(default_instance == NULL || default_instance->current_dag == NULL
|
||||||
return 0;
|
|| uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) || uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(default_instance->current_dag != NULL) {
|
if(default_instance->current_dag->rank == ROOT_RANK(default_instance)) {
|
||||||
if(default_instance->current_dag->rank == ROOT_RANK(default_instance)) {
|
/* At the root, remove headers if any, and insert SRH or HBH
|
||||||
/* At the root, remove headers if any, and insert SRH or HBH
|
* (SRH is inserted only if the destination is in the DODAG) */
|
||||||
* (SRH is inserted only if the destination is in the DODAG) */
|
rpl_remove_header();
|
||||||
rpl_remove_header();
|
if(RPL_IS_NON_STORING(default_instance)) {
|
||||||
if(RPL_IS_NON_STORING(default_instance)) {
|
return insert_srh_header();
|
||||||
return insert_srh_header();
|
|
||||||
} else {
|
|
||||||
return insert_hbh_header();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return update_hbh_header();
|
return insert_hbh_header(default_instance);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
if(uip_ds6_is_my_addr(&UIP_IP_BUF->srcipaddr)
|
||||||
|
&& UIP_IP_BUF->ttl == uip_ds6_if.cur_hop_limit) {
|
||||||
|
/* Insert HBH option at source. Checking the address is not sufficient because
|
||||||
|
* in non-storing mode, a packet may go up and then down the same path again */
|
||||||
|
return insert_hbh_header(default_instance);
|
||||||
|
} else {
|
||||||
|
/* Update HBH option at forwarders */
|
||||||
|
return update_hbh_header();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "net/rpl/rpl.h"
|
#include "net/rpl/rpl.h"
|
||||||
#include "net/ipv6/uip-ds6-route.h"
|
#include "net/ipv6/uip-ds6-route.h"
|
||||||
#include "net/mac/tsch/tsch.h"
|
#include "net/mac/tsch/tsch.h"
|
||||||
|
#include "net/rpl/rpl-private.h"
|
||||||
#if WITH_ORCHESTRA
|
#if WITH_ORCHESTRA
|
||||||
#include "orchestra.h"
|
#include "orchestra.h"
|
||||||
#endif /* WITH_ORCHESTRA */
|
#endif /* WITH_ORCHESTRA */
|
||||||
|
@ -68,46 +69,73 @@ print_network_status(void)
|
||||||
int i;
|
int i;
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
uip_ds6_defrt_t *default_route;
|
uip_ds6_defrt_t *default_route;
|
||||||
|
#if RPL_WITH_STORING
|
||||||
uip_ds6_route_t *route;
|
uip_ds6_route_t *route;
|
||||||
|
#endif /* RPL_WITH_STORING */
|
||||||
|
#if RPL_WITH_NON_STORING
|
||||||
|
rpl_ns_node_t *link;
|
||||||
|
#endif /* RPL_WITH_NON_STORING */
|
||||||
|
|
||||||
PRINTA("--- Network status ---\n");
|
PRINTF("--- Network status ---\n");
|
||||||
|
|
||||||
/* Our IPv6 addresses */
|
/* Our IPv6 addresses */
|
||||||
PRINTA("- Server IPv6 addresses:\n");
|
PRINTF("- Server IPv6 addresses:\n");
|
||||||
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
|
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
|
||||||
state = uip_ds6_if.addr_list[i].state;
|
state = uip_ds6_if.addr_list[i].state;
|
||||||
if(uip_ds6_if.addr_list[i].isused &&
|
if(uip_ds6_if.addr_list[i].isused &&
|
||||||
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
|
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
|
||||||
PRINTA("-- ");
|
PRINTF("-- ");
|
||||||
uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr);
|
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
|
||||||
PRINTA("\n");
|
PRINTF("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Our default route */
|
/* Our default route */
|
||||||
PRINTA("- Default route:\n");
|
PRINTF("- Default route:\n");
|
||||||
default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
|
default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
|
||||||
if(default_route != NULL) {
|
if(default_route != NULL) {
|
||||||
PRINTA("-- ");
|
PRINTF("-- ");
|
||||||
uip_debug_ipaddr_print(&default_route->ipaddr);
|
PRINT6ADDR(&default_route->ipaddr);
|
||||||
PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
|
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
|
||||||
} else {
|
} else {
|
||||||
PRINTA("-- None\n");
|
PRINTF("-- None\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RPL_WITH_STORING
|
||||||
/* Our routing entries */
|
/* Our routing entries */
|
||||||
PRINTA("- Routing entries (%u in total):\n", uip_ds6_route_num_routes());
|
PRINTF("- Routing entries (%u in total):\n", uip_ds6_route_num_routes());
|
||||||
route = uip_ds6_route_head();
|
route = uip_ds6_route_head();
|
||||||
while(route != NULL) {
|
while(route != NULL) {
|
||||||
PRINTA("-- ");
|
PRINTF("-- ");
|
||||||
uip_debug_ipaddr_print(&route->ipaddr);
|
PRINT6ADDR(&route->ipaddr);
|
||||||
PRINTA(" via ");
|
PRINTF(" via ");
|
||||||
uip_debug_ipaddr_print(uip_ds6_route_nexthop(route));
|
PRINT6ADDR(uip_ds6_route_nexthop(route));
|
||||||
PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
|
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
|
||||||
route = uip_ds6_route_next(route);
|
route = uip_ds6_route_next(route);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
PRINTA("----------------------\n");
|
#if RPL_WITH_NON_STORING
|
||||||
|
/* Our routing links */
|
||||||
|
PRINTF("- Routing links (%u in total):\n", rpl_ns_num_nodes());
|
||||||
|
link = rpl_ns_node_head();
|
||||||
|
while(link != NULL) {
|
||||||
|
if(link->parent != NULL) {
|
||||||
|
uip_ipaddr_t child_ipaddr;
|
||||||
|
uip_ipaddr_t parent_ipaddr;
|
||||||
|
rpl_ns_get_node_global_addr(&child_ipaddr, link);
|
||||||
|
rpl_ns_get_node_global_addr(&parent_ipaddr, link->parent);
|
||||||
|
PRINTF("-- ");
|
||||||
|
PRINT6ADDR(&child_ipaddr);
|
||||||
|
PRINTF(" to ");
|
||||||
|
PRINT6ADDR(&parent_ipaddr);
|
||||||
|
PRINTF(" (lifetime: %lu seconds)\n", (unsigned long)link->lifetime);
|
||||||
|
}
|
||||||
|
link = rpl_ns_node_next(link);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PRINTF("----------------------\n");
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -45,6 +45,17 @@
|
||||||
#define WITH_SECURITY 0
|
#define WITH_SECURITY 0
|
||||||
#endif /* WITH_SECURITY */
|
#endif /* WITH_SECURITY */
|
||||||
|
|
||||||
|
/*******************************************************/
|
||||||
|
/********* Enable RPL non-storing mode *****************/
|
||||||
|
/*******************************************************/
|
||||||
|
|
||||||
|
#undef UIP_CONF_MAX_ROUTES
|
||||||
|
#define UIP_CONF_MAX_ROUTES 0 /* No need for routes */
|
||||||
|
#undef RPL_CONF_MOP
|
||||||
|
#define RPL_CONF_MOP RPL_MOP_NON_STORING /* Mode of operation*/
|
||||||
|
#undef ORCHESTRA_CONF_RULES
|
||||||
|
#define ORCHESTRA_CONF_RULES { &eb_per_time_source, &unicast_per_neighbor_rpl_ns, &default_common } /* Orchestra in non-storing */
|
||||||
|
|
||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
/********************* Enable TSCH *********************/
|
/********************* Enable TSCH *********************/
|
||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
|
@ -140,8 +151,8 @@
|
||||||
#define UIP_CONF_TCP 0
|
#define UIP_CONF_TCP 0
|
||||||
#undef QUEUEBUF_CONF_NUM
|
#undef QUEUEBUF_CONF_NUM
|
||||||
#define QUEUEBUF_CONF_NUM 3
|
#define QUEUEBUF_CONF_NUM 3
|
||||||
#undef UIP_CONF_MAX_ROUTES
|
#undef RPL_NS_CONF_LINK_NUM
|
||||||
#define UIP_CONF_MAX_ROUTES 8
|
#define RPL_NS_CONF_LINK_NUM 8
|
||||||
#undef NBR_TABLE_CONF_MAX_NEIGHBORS
|
#undef NBR_TABLE_CONF_MAX_NEIGHBORS
|
||||||
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8
|
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8
|
||||||
#undef UIP_CONF_ND6_SEND_NA
|
#undef UIP_CONF_ND6_SEND_NA
|
||||||
|
|
|
@ -272,7 +272,7 @@ make node.z1 TARGET=z1 MAKE_WITH_ORCHESTRA=0 MAKE_WITH_SECURITY=0</commands>
|
||||||
/* Wait until a node (can only be the DAGRoot) has
|
/* Wait until a node (can only be the DAGRoot) has
|
||||||
* 8 routing entries (i.e. can reach every node) */
|
* 8 routing entries (i.e. can reach every node) */
|
||||||
log.log("Waiting for routing tables to fill\n");
|
log.log("Waiting for routing tables to fill\n");
|
||||||
WAIT_UNTIL(msg.endsWith("Routing entries (8 in total):"));
|
WAIT_UNTIL(msg.endsWith("Routing links (8 in total):"));
|
||||||
log.log("Root routing table ready\n");
|
log.log("Root routing table ready\n");
|
||||||

|

|
||||||
log.testOK(); /* Report test success and quit */</script>
|
log.testOK(); /* Report test success and quit */</script>
|
||||||
|
|
|
@ -277,7 +277,7 @@ log.log("Orchestra started\n");
|
||||||
/* Wait until a node (can only be the DAGRoot) has
|
/* Wait until a node (can only be the DAGRoot) has
|
||||||
* 8 routing entries (i.e. can reach every node) */
|
* 8 routing entries (i.e. can reach every node) */
|
||||||
log.log("Waiting for routing tables to fill\n");
|
log.log("Waiting for routing tables to fill\n");
|
||||||
WAIT_UNTIL(msg.endsWith("Routing entries (8 in total):"));
|
WAIT_UNTIL(msg.endsWith("Routing links (8 in total):"));
|
||||||
log.log("Root routing table ready\n");
|
log.log("Root routing table ready\n");
|
||||||

|

|
||||||
log.testOK(); /* Report test success and quit */</script>
|
log.testOK(); /* Report test success and quit */</script>
|
||||||
|
|
|
@ -274,7 +274,7 @@ log.log("Waiting for association with security\n");
|
||||||
/* Wait until a node (can only be the DAGRoot) has
|
/* Wait until a node (can only be the DAGRoot) has
|
||||||
* 8 routing entries (i.e. can reach every node) */
|
* 8 routing entries (i.e. can reach every node) */
|
||||||
log.log("Waiting for routing tables to fill\n");
|
log.log("Waiting for routing tables to fill\n");
|
||||||
WAIT_UNTIL(msg.endsWith("Routing entries (8 in total):"));
|
WAIT_UNTIL(msg.endsWith("Routing links (8 in total):"));
|
||||||
log.log("Root routing table ready\n");
|
log.log("Root routing table ready\n");
|
||||||

|

|
||||||
log.testOK(); /* Report test success and quit */</script>
|
log.testOK(); /* Report test success and quit */</script>
|
||||||
|
|
Loading…
Reference in a new issue