Commit 6d2e269f authored by Jelle De Vleeschouwer's avatar Jelle De Vleeschouwer

[6LoWPAN-ND] - Reviewed neighbor discovery optimizations

parent 5963f106
......@@ -49,7 +49,7 @@ int32_t pico_device_broadcast(struct pico_frame *f);
int pico_device_link_state(struct pico_device *dev);
int pico_device_ipv6_random_ll(struct pico_device *dev);
#ifdef PICO_SUPPORT_IPV6
struct pico_ipv6_link *pico_ipv6_link_add_local(struct pico_device *dev, const struct pico_ip6 *prefix, struct pico_ip6 *dst);
struct pico_ipv6_link *pico_ipv6_link_add_local(struct pico_device *dev, const struct pico_ip6 *prefix);
#endif
#endif
......@@ -167,11 +167,11 @@ static void ctx_lifetime_check(pico_time now, void *arg)
pico_tree_delete(&CTXtree, key);
PICO_FREE(key);
} else if (key->lifetime == 5) {
gw = pico_ipv6_default_gateway_configured(key->dev);
if (gw)
pico_6lp_nd_start_solicitating(pico_ipv6_linklocal_get(key->dev), &gw->gateway);
else
pico_6lp_nd_start_solicitating(pico_ipv6_linklocal_get(key->dev), NULL);
/* RFC6775: The host SHOULD unicast one or more RSs to the router well before the
* shortest of the, Router Lifetime, PIO lifetimes and the lifetime of the 6COs. */
while ((gw = pico_ipv6_gateway_by_dev_next(gw->link->dev, gw))) {
pico_6lp_nd_start_solicitating(pico_ipv6_linklocal_get(key->dev), gw);
}
}
}
}
......@@ -217,7 +217,7 @@ ll_mesh_header_estimator(struct pico_frame *f, union pico_ll_addr *src, union pi
IGNORE_PARAMETER(f);
IGNORE_PARAMETER(src);
IGNORE_PARAMETER(dst);
return (uint8_t)0;
return 0;
}
/*******************************************************************************
......
......@@ -24,7 +24,10 @@ static struct pico_queue icmp6_out;
/******************************************************************************
* Function prototypes
******************************************************************************/
#ifdef PICO_SUPPORT_6LOWPAN
static int pico_6lp_nd_neighbor_solicitation(struct pico_device *dev, struct pico_ip6 *tgt, uint8_t type, struct pico_ip6 *dst);
#endif
uint16_t pico_icmp6_checksum(struct pico_frame *f)
{
......@@ -285,6 +288,7 @@ MOCKABLE int pico_icmp6_frag_expired(struct pico_frame *f)
return pico_icmp6_notify(f, PICO_ICMP6_TIME_EXCEEDED, PICO_ICMP6_TIMXCEED_REASS, 0);
}
/* Provide a Link-Layer Address Option, either Source (SLLAO) or Destination (DLLAO) */
static int pico_icmp6_provide_llao(struct pico_icmp6_opt_lladdr *llao, uint8_t type, struct pico_device *dev, struct pico_ip6 *src)
{
#ifdef PICO_SUPPORT_6LOWPAN
......@@ -293,12 +297,12 @@ static int pico_icmp6_provide_llao(struct pico_icmp6_opt_lladdr *llao, uint8_t t
IGNORE_PARAMETER(src);
llao->type = type;
if (LL_MODE_ETHERNET == dev->mode && dev->eth) {
if (!dev->mode && dev->eth) {
memcpy(llao->addr.mac.addr, dev->eth->mac.addr, PICO_SIZE_ETH);
llao->len = 1;
}
#ifdef PICO_SUPPORT_6LOWPAN
if (dev->hostvars.lowpan && dev->eth) {
else if (dev->hostvars.lowpan && dev->eth) {
if (src && IID_16(&src->addr[8])) {
memcpy(llao->addr.pan.data, (uint8_t *)&info->addr_short.addr, SIZE_6LOWPAN_SHORT);
memset(llao->addr.pan.data + SIZE_6LOWPAN_SHORT, 0, 4);
......@@ -317,6 +321,7 @@ static int pico_icmp6_provide_llao(struct pico_icmp6_opt_lladdr *llao, uint8_t t
return 0;
}
/* Prepares a ICMP6 neighbor solicitation message */
static struct pico_frame *pico_icmp6_neigh_sol_prep(struct pico_device *dev, struct pico_ip6 *dst, uint16_t len)
{
struct pico_icmp6_hdr *icmp = NULL;
......@@ -349,12 +354,19 @@ int pico_icmp6_neighbor_solicitation(struct pico_device *dev, struct pico_ip6 *t
struct pico_frame *sol = NULL;
uint8_t i = 0;
uint16_t len = 0;
#ifndef PICO_SUPPORT_6LOWPAN
IGNORE_PARAMETER(dst);
#endif
if (pico_ipv6_is_multicast(tgt->addr)) {
return -1;
} else if (dev->hostvars.lowpan) {
}
#ifdef PICO_SUPPORT_6LOWPAN
else if (dev->hostvars.lowpan) {
return pico_6lp_nd_neighbor_solicitation(dev, tgt, type, dst);
} else {
}
#endif
else {
/* Determine the size frame needs to be for the Neighbor Solicitation */
len = PICO_ICMP6HDR_NEIGH_SOL_SIZE;
if (PICO_ICMP6_ND_DAD != type)
......@@ -372,9 +384,7 @@ int pico_icmp6_neighbor_solicitation(struct pico_device *dev, struct pico_ip6 *t
return -1;
} else {
/* Determine destination address */
if (dst) {
daddr = *dst;
} else if (type == PICO_ICMP6_ND_SOLICITED || type == PICO_ICMP6_ND_DAD) {
if (type == PICO_ICMP6_ND_SOLICITED || type == PICO_ICMP6_ND_DAD) {
for (i = 1; i <= 3; ++i)
daddr.addr[PICO_SIZE_IP6 - i] = tgt->addr[PICO_SIZE_IP6 - i];
} else {
......@@ -392,17 +402,21 @@ int pico_icmp6_neighbor_solicitation(struct pico_device *dev, struct pico_ip6 *t
}
#ifdef PICO_SUPPORT_6LOWPAN
static void pico_6lp_nd_provide_aro(struct pico_icmp6_opt_aro *aro, struct pico_device *dev)
/* Provide an Address Registration Option */
static void pico_6lp_nd_provide_aro(struct pico_icmp6_opt_aro *aro, struct pico_device *dev, uint8_t type)
{
struct pico_6lowpan_info *info = (struct pico_6lowpan_info *)dev->eth;
aro->type = PICO_ND_OPT_ARO;
aro->len = 2;
aro->status = 0;
aro->lifetime = short_be(PICO_6LP_ND_DEFAULT_LIFETIME);
if (PICO_ICMP6_ND_DEREGISTER == type)
aro->lifetime = 0;
else
aro->lifetime = short_be(PICO_6LP_ND_DEFAULT_LIFETIME);
memcpy(aro->eui64.addr, info->addr_ext.addr, SIZE_6LOWPAN_EXT);
}
/* Send an ICMP6 neighbor solicitation according to RFC6775 */
static int pico_6lp_nd_neighbor_solicitation(struct pico_device *dev, struct pico_ip6 *tgt, uint8_t type, struct pico_ip6 *dst)
{
uint32_t llao_len = IID_16(&tgt->addr[8]) ? 8 : 16;
......@@ -424,15 +438,13 @@ static int pico_6lp_nd_neighbor_solicitation(struct pico_device *dev, struct pic
/* Provide SLLAO if it's a neighbor solicitation for address registration */
llao = (struct pico_icmp6_opt_lladdr *)(((uint8_t *)&icmp->msg.info.neigh_sol) + sizeof(struct neigh_sol_s));
if (PICO_ICMP6_ND_DAD == type && pico_icmp6_provide_llao(llao, PICO_ND_OPT_LLADDR_SRC, dev, NULL)) {
if (pico_icmp6_provide_llao(llao, PICO_ND_OPT_LLADDR_SRC, dev, NULL)) {
pico_frame_discard(sol);
return -1;
} else {
/* Provide ARO when it's a neighbor solicitation for address registration */
/* Provide ARO when it's a neighbor solicitation for address registration or re-registration */
aro = (struct pico_icmp6_opt_aro *)(((uint8_t *)&icmp->msg.info.neigh_sol) + sizeof(struct neigh_sol_s) + llao_len);
if (PICO_ICMP6_ND_DAD == type) {
pico_6lp_nd_provide_aro(aro, dev);
}
pico_6lp_nd_provide_aro(aro, dev, type);
/* RFC6775: The address that is to be registered MUST be the IPv6 source address of the
* NS message. */
......@@ -443,7 +455,6 @@ static int pico_6lp_nd_neighbor_solicitation(struct pico_device *dev, struct pic
}
return -1;
}
#endif
/* RFC 4861 $7.2.4: sending solicited neighbor advertisements */
......@@ -514,8 +525,8 @@ int pico_icmp6_router_solicitation(struct pico_device *dev, struct pico_ip6 *src
#ifdef PICO_SUPPORT_6LOWPAN
if (dev->hostvars.lowpan)
len = (uint16_t)(len + 8);
} else { /* RFC6775 (6LoWPAN): An unspecified source address MUST NOT be used in RS messages.*/
return -1;
} else if (dev->hostvars.lowpan && pico_ipv6_is_unspecified(src->addr)) {
return -1; /* RFC6775 (6LoWPAN): An unspecified source address MUST NOT be used in RS messages. */
#endif
}
......@@ -542,15 +553,20 @@ int pico_icmp6_router_solicitation(struct pico_device *dev, struct pico_ip6 *src
sol->dev = dev;
if (dev->hostvars.lowpan) {
if (!dev->mode) {
/* f->src is set in frame_push, checksum calculated there */
pico_ipv6_frame_push(sol, NULL, &daddr, PICO_PROTO_ICMP6, 0);
}
#ifdef PICO_SUPPORT_6LOWPAN
else {
if (dst)
daddr = *dst;
/* Force this frame to be send with the EUI-64-address */
pico_ipv6_frame_push(sol, src, &daddr, PICO_PROTO_ICMP6, 0);
} else {
/* f->src is set in frame_push, checksum calculated there */
pico_ipv6_frame_push(sol, NULL, &daddr, PICO_PROTO_ICMP6, 0);
}
#else
IGNORE_PARAMETER(dst);
#endif
return 0;
}
......
......@@ -97,6 +97,7 @@
#define PICO_ICMP6_ND_ANYCAST 1
#define PICO_ICMP6_ND_SOLICITED 2
#define PICO_ICMP6_ND_DAD 3
#define PICO_ICMP6_ND_DEREGISTER 4
#define PICO_ICMP6_MAX_RTR_SOL_DELAY 1000
......
......@@ -1454,7 +1454,7 @@ static inline struct pico_ipv6_route *ipv6_route_add_link(struct pico_ip6 gatewa
return r;
}
struct pico_ipv6_route *pico_ipv6_default_gateway_configured(struct pico_device *dev)
struct pico_ipv6_route *pico_ipv6_gateway_by_dev(struct pico_device *dev)
{
struct pico_ipv6_link *link = pico_ipv6_link_by_dev(dev);
struct pico_ipv6_route *route = NULL;
......@@ -1463,9 +1463,8 @@ struct pico_ipv6_route *pico_ipv6_default_gateway_configured(struct pico_device
/* Iterate over the IPv6-routes */
pico_tree_foreach(node, &IPV6Routes) {
route = (struct pico_ipv6_route *)node->keyValue;
/* If the route is a default router, specified by the gw being set */
if (!pico_ipv6_is_unspecified(route->gateway.addr)) {
if (!pico_ipv6_is_unspecified(route->gateway.addr) && pico_ipv6_is_unspecified(route->netmask.addr)) {
/* Iterate over device's links */
while (link) {
/* If link is equal to route's link, routing list is not empty */
......@@ -1479,6 +1478,38 @@ struct pico_ipv6_route *pico_ipv6_default_gateway_configured(struct pico_device
return NULL;
}
struct pico_ipv6_route *pico_ipv6_gateway_by_dev_next(struct pico_device *dev, struct pico_ipv6_route *last)
{
struct pico_ipv6_link *link = NULL;
struct pico_ipv6_route *gw = NULL;
struct pico_tree_node *i = NULL;
int valid = 0;
if (last == NULL)
valid = 1;
pico_tree_foreach(i, &IPV6Routes) {
gw = (struct pico_ipv6_route *)i->keyValue;
/* If the route is a default router, specified by the gw being set */
if (!pico_ipv6_is_unspecified(gw->gateway.addr) && pico_ipv6_is_unspecified(gw->netmask.addr)) {
/* Iterate over device's links */
link = pico_ipv6_link_by_dev(dev);
while (link) {
/* If link is equal to route's link, routing list is not empty */
if (0 == ipv6_link_compare(link, gw->link)) {
if (last == gw) {
valid = 1;
} else if (valid) {
return gw;
}
link = pico_ipv6_link_by_dev_next(dev, link);
}
}
}
}
return NULL;
}
int pico_ipv6_route_add(struct pico_ip6 address, struct pico_ip6 netmask, struct pico_ip6 gateway, int metric, struct pico_ipv6_link *link)
{
struct pico_ip6 zerogateway = {{0}};
......@@ -1621,6 +1652,7 @@ static void pico_ipv6_nd_dad(pico_time now, void *arg)
else {
if (l->dup_detect_retrans-- == 0) {
dbg("IPv6: DAD verified valid address.\n");
l->istentative = 0;
} else {
/* Duplicate Address Detection */
......@@ -1712,7 +1744,9 @@ static struct pico_ipv6_link *pico_ipv6_do_link_add(struct pico_device *dev, str
IGNORE_PARAMETER(all_hosts);
#endif
pico_ipv6_route_add(network, netmask, gateway, 1, new);
#ifdef PICO_SUPPORT_6LOWPAN
if (!dev->hostvars.lowpan)
#endif
pico_ipv6_route_add(mcast_addr, mcast_nm, mcast_gw, 1, new);
/* XXX MUST join the all-nodes multicast address on that interface, as well as
* the solicited-node multicast address corresponding to each of the IP
......@@ -1720,7 +1754,6 @@ static struct pico_ipv6_link *pico_ipv6_do_link_add(struct pico_device *dev, str
* XXX RFC6775 (6LoWPAN): There is no need to join the solicited-node multicast address, since
* nobody multicasts NSs in this type of network. A host MUST join the all-nodes multicast
* address. */
#ifdef PICO_DEBUG_IPV6
pico_ipv6_to_string(ipstr, new->address.addr);
dbg("Assigned ipv6 %s to device %s\n", ipstr, new->dev->name);
......@@ -1728,20 +1761,12 @@ static struct pico_ipv6_link *pico_ipv6_do_link_add(struct pico_device *dev, str
return new;
}
struct pico_ipv6_link *pico_ipv6_link_add_no_dad(struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask, struct pico_ip6 *dst)
struct pico_ipv6_link *pico_ipv6_link_add_no_dad(struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask)
{
struct pico_ipv6_link *new = pico_ipv6_do_link_add(dev, address, netmask);
if (new) {
new->istentative = 0;
}
if (dev->hostvars.lowpan && !pico_ipv6_is_linklocal(address.addr)) {
/* RFC6775: When a host has configured a non-link-local IPv6 address, it registers that
* address with one or more of its default routers using the Address Registration
* Option (ARO) in an NS message. */
pico_icmp6_neighbor_solicitation(new->dev, &new->address, PICO_ICMP6_ND_DAD, dst);
}
return new;
}
......@@ -1984,13 +2009,14 @@ struct pico_ipv6_link *pico_ipv6_global_get(struct pico_device *dev)
}
#define TWO_HOURS ((pico_time)(1000 * 60 * 60 * 2))
#define ONE_MINUTE ((pico_time)(1000 * 60))
void pico_ipv6_check_lifetime_expired(pico_time now, void *arg)
{
struct pico_tree_node *index = NULL, *temp;
struct pico_ipv6_link *link = NULL;
#ifdef PICO_SUPPORT_6LOWPAN
struct pico_ipv6_route *gw = NULL;
#endif
(void)arg;
pico_tree_foreach_safe(index, &IPV6Links, temp) {
link = index->keyValue;
......@@ -2001,15 +2027,15 @@ void pico_ipv6_check_lifetime_expired(pico_time now, void *arg)
#ifdef PICO_SUPPORT_6LOWPAN
else if (link->dev->hostvars.lowpan && !pico_ipv6_is_linklocal(link->address.addr) &&
(link->expire_time > 0) && (int)(link->expire_time - now) < (int)(TWO_HOURS >> 4)) {
gw = pico_ipv6_default_gateway_configured(link->dev);
if (gw)
pico_6lp_nd_start_solicitating(link, &gw->gateway);
else
pico_6lp_nd_start_solicitating(link, NULL);
/* RFC6775: The host SHOULD unicast one or more RSs to the router well before the
* shortest of the, Router Lifetime, PIO lifetimes and the lifetime of the 6COs. */
while ((gw = pico_ipv6_gateway_by_dev_next(link->dev, gw))) {
pico_6lp_nd_start_solicitating(link, gw);
}
}
#endif
}
if (!pico_timer_add(ONE_MINUTE, pico_ipv6_check_lifetime_expired, NULL)) {
if (!pico_timer_add(1000, pico_ipv6_check_lifetime_expired, NULL)) {
dbg("IPv6: Failed to start check_lifetime timer\n");
/* TODO No more link lifetime checking now */
}
......
......@@ -61,6 +61,7 @@ struct pico_ipv6_link
uint8_t isduplicate : 1;
uint32_t dad_timer;
uint16_t dup_detect_retrans;
uint8_t retrans;
pico_time expire_time;
#ifdef PICO_SUPPORT_MCAST
struct pico_tree *MCASTGroups;
......@@ -96,6 +97,8 @@ struct pico_ipv6_route
struct pico_ip6 dest;
struct pico_ip6 netmask;
struct pico_ip6 gateway;
pico_time backoff;
uint8_t retrans;
struct pico_ipv6_link *link;
uint32_t metric;
};
......@@ -147,7 +150,7 @@ int pico_ipv6_route_del(struct pico_ip6 address, struct pico_ip6 netmask, struct
void pico_ipv6_unreachable(struct pico_frame *f, uint8_t code);
struct pico_ipv6_link *pico_ipv6_link_add(struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask);
struct pico_ipv6_link *pico_ipv6_link_add_no_dad(struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask, struct pico_ip6 *dst);
struct pico_ipv6_link *pico_ipv6_link_add_no_dad(struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask);
int pico_ipv6_link_del(struct pico_device *dev, struct pico_ip6 address);
int pico_ipv6_cleanup_links(struct pico_device *dev);
struct pico_ipv6_link *pico_ipv6_link_istentative(struct pico_ip6 *address);
......@@ -162,7 +165,8 @@ struct pico_ipv6_link *pico_ipv6_global_get(struct pico_device *dev);
struct pico_ipv6_link *pico_ipv6_linklocal_get(struct pico_device *dev);
struct pico_ipv6_link *pico_ipv6_sitelocal_get(struct pico_device *dev);
struct pico_ipv6_link *pico_ipv6_prefix_configured(struct pico_ip6 *prefix);
struct pico_ipv6_route *pico_ipv6_default_gateway_configured(struct pico_device *dev);
struct pico_ipv6_route *pico_ipv6_gateway_by_dev(struct pico_device *dev);
struct pico_ipv6_route *pico_ipv6_gateway_by_dev_next(struct pico_device *dev, struct pico_ipv6_route *last);
int pico_ipv6_lifetime_set(struct pico_ipv6_link *l, pico_time expire);
void pico_ipv6_check_lifetime_expired(pico_time now, void *arg);
int pico_ipv6_dev_routing_enable(struct pico_device *dev);
......
This diff is collapsed.
......@@ -18,8 +18,6 @@ struct pico_nd_hostvars {
pico_time basetime;
pico_time reachabletime;
pico_time retranstime;
pico_time backoff;
uint8_t retrans;
uint8_t lowpan;
};
......@@ -27,6 +25,10 @@ void pico_ipv6_nd_init(void);
struct pico_eth *pico_ipv6_get_neighbor(struct pico_frame *f);
void pico_ipv6_nd_postpone(struct pico_frame *f);
int pico_ipv6_nd_recv(struct pico_frame *f);
int pico_6lp_nd_start_solicitating(struct pico_ipv6_link *l, struct pico_ip6 *dst);
#ifdef PICO_SUPPORT_6LOWPAN
int pico_6lp_nd_start_solicitating(struct pico_ipv6_link *l, struct pico_ipv6_route *gw);
void pico_6lp_nd_register(struct pico_ipv6_link *link);
#endif
#endif
......@@ -55,7 +55,7 @@ static void device_init_ipv6_final(struct pico_device *dev, struct pico_ip6 *lin
dev->hostvars.hoplimit = PICO_IPV6_DEFAULT_HOP;
}
struct pico_ipv6_link *pico_ipv6_link_add_local(struct pico_device *dev, const struct pico_ip6 *prefix, struct pico_ip6 *dst)
struct pico_ipv6_link *pico_ipv6_link_add_local(struct pico_device *dev, const struct pico_ip6 *prefix)
{
struct pico_ip6 netmask64 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
struct pico_ipv6_link *link = NULL; /* Make sure to return NULL */
......@@ -64,7 +64,21 @@ struct pico_ipv6_link *pico_ipv6_link_add_local(struct pico_device *dev, const s
struct pico_6lowpan_info *info = (struct pico_6lowpan_info *)dev->eth;
#endif
if (LL_MODE_IEEE802154 == dev->mode) {
if (!dev->mode) {
memcpy(newaddr.addr, prefix->addr, PICO_SIZE_IP6);
/* modified EUI-64 + invert universal/local bit */
newaddr.addr[8] = (dev->eth->mac.addr[0] ^ 0x02);
newaddr.addr[9] = dev->eth->mac.addr[1];
newaddr.addr[10] = dev->eth->mac.addr[2];
newaddr.addr[11] = 0xff;
newaddr.addr[12] = 0xfe;
newaddr.addr[13] = dev->eth->mac.addr[3];
newaddr.addr[14] = dev->eth->mac.addr[4];
newaddr.addr[15] = dev->eth->mac.addr[5];
if ((link = pico_ipv6_link_add(dev, newaddr, netmask64))) {
device_init_ipv6_final(dev, &newaddr);
}
} else {
#ifdef PICO_SUPPORT_6LOWPAN
memcpy(newaddr.addr, prefix->addr, PICO_SIZE_IP6);
memcpy(newaddr.addr + 8, info->addr_ext.addr, SIZE_6LOWPAN_EXT);
......@@ -73,27 +87,15 @@ struct pico_ipv6_link *pico_ipv6_link_add_local(struct pico_device *dev, const s
/* RFC6775: No Duplicate Address Detection (DAD) is performed if
* EUI-64-based IPv6 addresses are used (as these addresses are assumed
* to be globally unique). */
if ((link = pico_ipv6_link_add_no_dad(dev, newaddr, netmask64, dst))) {
if ((link = pico_ipv6_link_add_no_dad(dev, newaddr, netmask64))) {
if (pico_ipv6_is_linklocal(newaddr.addr))
pico_6lp_nd_start_solicitating(link, NULL);
else
pico_6lp_nd_register(link);
}
#else
return NULL;
#endif
} else {
memcpy(newaddr.addr, prefix->addr, PICO_SIZE_IP6);
/* modified EUI-64 + invert universal/local bit */
newaddr.addr[8] = (dev->eth->mac.addr[0] ^ 0x02);
newaddr.addr[9] = dev->eth->mac.addr[1];
newaddr.addr[10] = dev->eth->mac.addr[2];
newaddr.addr[11] = 0xff;
newaddr.addr[12] = 0xfe;
newaddr.addr[13] = dev->eth->mac.addr[3];
newaddr.addr[14] = dev->eth->mac.addr[4];
newaddr.addr[15] = dev->eth->mac.addr[5];
if ((link = pico_ipv6_link_add(dev, newaddr, netmask64))) {
device_init_ipv6_final(dev, &newaddr);
}
}
return link;
......@@ -126,7 +128,7 @@ static int device_init_mac(struct pico_device *dev, const uint8_t *mac)
#endif
#ifdef PICO_SUPPORT_IPV6
if (pico_ipv6_link_add_local(dev, &linklocal, NULL) == NULL) {
if (pico_ipv6_link_add_local(dev, &linklocal) == NULL) {
PICO_FREE(dev->q_in);
PICO_FREE(dev->q_out);
if (!dev->mode) // Mode is Ethernet
......@@ -217,11 +219,13 @@ int pico_device_init(struct pico_device *dev, const char *name, const uint8_t *m
if (mac) {
ret = device_init_mac(dev, mac);
} else {
#ifdef PICO_SUPPORT_6LOWPAN
if (LL_MODE_IEEE802154 != dev->mode) {
if (!dev->mode) {
ret = device_init_nomac(dev);
} else {
}
#ifdef PICO_SUPPORT_6LOWPAN
else {
/* RFC6775: Link Local to be formed based on EUI-64 as per RFC6775 */
dbg("Link local address to be formed based on EUI-64\n");
return -1;
}
#endif
......
......@@ -379,10 +379,14 @@ int pico_datalink_receive(struct pico_frame *f)
{
if (f->dev->eth) {
/* If device has stack with datalink-layer pass frame through it */
if (0) {}
#ifdef PICO_SUPPORT_6LOWPAN
if (LL_MODE_IEEE802154 == f->dev->mode) {
f->datalink_hdr = f->buffer;
return pico_enqueue(pico_proto_6lowpan_ll.q_in, f);
} else {
}
#endif
else {
f->datalink_hdr = f->buffer;
return pico_enqueue(pico_proto_ethernet.q_in, f);
}
......@@ -399,9 +403,13 @@ MOCKABLE int pico_datalink_send(struct pico_frame *f)
{
if (f->dev->eth) {
/* If device has stack with datalink-layer pass frame through it */
if (0) {}
#ifdef PICO_SUPPORT_6LOWPAN
if (LL_MODE_IEEE802154 == f->dev->mode) {
return pico_enqueue(pico_proto_6lowpan.q_out, f);
} else {
}
#endif
else {
return pico_enqueue(pico_proto_ethernet.q_out, f);
}
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment