Skip to content

Commit

Permalink
Omit NA sending in ARO success cases. Use ACK instead. (ARMmbed#1587)
Browse files Browse the repository at this point in the history
When "omit_aro_success" - flag is set, success response is not send to request.
MAC ack is used to indicate success address registration.
  • Loading branch information
Tero Heinonen authored Feb 28, 2018
1 parent 4686668 commit 057b6ec
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 0 deletions.
7 changes: 7 additions & 0 deletions source/6LoWPAN/ws/ws_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,16 @@ static void ws_bootstrap_address_registration_ns_send(struct protocol_interface_
aro_t aro;
buffer_t *buf;

tr_debug("Send ARO");

aro.status = ARO_SUCCESS;
aro.present = true;
aro.lifetime = addr->preferred_lifetime;
memcpy(aro.eui64, interface->mac, 8);

/* Fill address to be registered */
memcpy(&interface->if_6lowpan_dad_process.address, addr->address, 16);

ns_list_foreach(struct rpl_instance, instance, &interface->rpl_domain->instances) {
const uint8_t *preferred_parent = rpl_control_preferred_parent_addr(instance, false);
if (preferred_parent) {
Expand Down Expand Up @@ -153,6 +158,8 @@ static int8_t ws_bootsrap_event_trig(ws_bootsrap_event_type_e event_type, int8_t
}
/* Disable SLLAO send/mandatory receive with the ARO */
cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro = true;
/* Omit sending of NA if ARO SUCCESS */
cur->ipv6_neighbour_cache.omit_aro_success = true;

ws_bootstrap_event_discovery_start(cur);

Expand Down
30 changes: 30 additions & 0 deletions source/Common_Protocols/icmpv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,25 @@ uint8_t *icmpv6_write_mtu_option(uint32_t mtu, uint8_t *dptr)
return dptr;
}

static void icmpv6_ns_ack_cb(struct buffer *buf, uint8_t status)
{
(void) buf;

if (status == SOCKET_TX_DONE) {
tr_debug("NS ARO ack received %s", trace_ipv6(buf->interface->if_6lowpan_dad_process.address));

if_address_entry_t *addr_entry = addr_get_entry(buf->interface, buf->interface->if_6lowpan_dad_process.address);
if (!addr_entry) {
return;
}
/* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */
addr_entry->state_timer = (addr_entry->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10);
} else {
// todo: What to do when address registration fails?
tr_debug("NS ARO send failed");
}
}

buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t target_addr[16], const uint8_t *prompting_src_addr, bool unicast, bool unspecified_source, const aro_t *aro)
{
if (!cur || addr_is_ipv6_multicast(target_addr)) {
Expand Down Expand Up @@ -1286,6 +1305,11 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta
if (!cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro) {
ptr = icmpv6_write_icmp_lla(cur, ptr, ICMPV6_OPT_SRC_LL_ADDR, aro, buf->src_sa.address);
}
/* If ARO Success sending is omitted, MAC ACK is used instead */
/* Setting callback for receiving ACK from adaptation layer */
if (aro && cur->ipv6_neighbour_cache.omit_aro_success) {
buf->ack_receive_cb = icmpv6_ns_ack_cb;
}
}
buf->src_sa.addr_type = ADDR_IPV6;

Expand Down Expand Up @@ -1419,6 +1443,12 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited,

tr_debug("Build NA");

/* Check if ARO status == success, then sending can be omitted with flag */
if (aro && cur->ipv6_neighbour_cache.omit_aro_success && aro->status == ARO_SUCCESS) {
tr_debug("Omit success reply");
return NULL;
}

buffer_t *buf = buffer_get(8 + 16 + 16 + 16); /* fixed, target addr, target ll addr, aro */
if (!buf) {
return NULL;
Expand Down
1 change: 1 addition & 0 deletions source/Core/include/ns_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ typedef struct buffer {
uint8_t trickle_data_field[4];
buffer_options_t options; /*!< Additional signal info etc */
buffer_routing_info_t *route; /* A pointer last to try to get neat alignment for data */
void (*ack_receive_cb)(struct buffer *buffer_ptr, uint8_t status); /*!< ACK receive callback. If set, will be called when TX is done */
uint8_t buf[]; /*!< Trailing buffer data */
} buffer_t;

Expand Down
4 changes: 4 additions & 0 deletions source/Core/ns_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -1396,6 +1396,10 @@ buffer_t *socket_tx_buffer_event(buffer_t *buf, uint8_t status)
* and we mapped straight to MAC address).
*/

if (buf->ack_receive_cb) {
buf->ack_receive_cb(buf, status);
}

/* Suppress events once socket orphaned */
if (!buf->socket || (buf->socket->flags & (SOCKET_FLAG_PENDING|SOCKET_FLAG_CLOSED))) {
return buf;
Expand Down
1 change: 1 addition & 0 deletions source/ipv6_stack/ipv6_routing_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ typedef struct ipv6_neighbour_cache {
bool recv_ns_aro : 1;
bool recv_na_aro : 1;
bool use_eui64_as_slla_in_aro : 1;
bool omit_aro_success : 1;
int8_t interface_id;
uint8_t max_ll_len;
uint8_t gc_timer;
Expand Down

0 comments on commit 057b6ec

Please sign in to comment.