Commit 47029b22 authored by Jelle De Vleeschouwer's avatar Jelle De Vleeschouwer Committed by Jelle De Vleeschouwer

Merge remote tracking branch 'origin/development' into 'development'

parent d2296138
......@@ -370,6 +370,8 @@ units: mod core lib $(UNITS_OBJ) $(MOD_OBJ)
@$(CC) -o $(PREFIX)/test/modunit_fragments.elf $(CFLAGS) -I. test/unit/modunit_pico_fragments.c -lcheck -lm -pthread -lrt $(UNITS_OBJ) $(PREFIX)/lib/libpicotcp.a
@$(CC) -o $(PREFIX)/test/modunit_queue.elf $(CFLAGS) -I. test/unit/modunit_queue.c -lcheck -lm -pthread -lrt $(UNITS_OBJ)
@$(CC) -o $(PREFIX)/test/modunit_dev_ppp.elf $(CFLAGS) -I. test/unit/modunit_pico_dev_ppp.c -lcheck -lm -pthread -lrt $(UNITS_OBJ) $(PREFIX)/lib/libpicotcp.a
@$(CC) -o $(PREFIX)/test/modunit_mld.elf $(CFLAGS) -I. test/unit/modunit_pico_mld.c -lcheck -lm -pthread -lrt $(UNITS_OBJ) $(PREFIX)/lib/libpicotcp.a
@$(CC) -o $(PREFIX)/test/modunit_igmp.elf $(CFLAGS) -I. test/unit/modunit_pico_igmp.c -lcheck -lm -pthread -lrt $(UNITS_OBJ) $(PREFIX)/lib/libpicotcp.a
@$(CC) -o $(PREFIX)/test/modunit_dev_sixlowpan.elf $(CFLAGS) -I. test/unit/modunit_dev_sixlowpan.c -lcheck -lm -pthread -lrt $(UNITS_OBJ) $(PREFIX)/lib/libpicotcp.a
devunits: mod core lib
......
......@@ -16,9 +16,8 @@
#include "pico_tree.h"
#include "pico_socket.h"
#include "pico_dev_sixlowpan.h"
#define icmp6_dbg(...) do {} while(0)
/* #define icmp6_dbg dbg */
#include "pico_mld.h"
#define icmp6_dbg(...) do { }while(0);
static struct pico_queue icmp6_in;
static struct pico_queue icmp6_out;
......@@ -386,8 +385,8 @@ int pico_icmp6_neighbor_solicitation(struct pico_device *dev, struct pico_ip6 *d
icmp->msg.info.neigh_sol.unused = 0;
icmp->msg.info.neigh_sol.target = *dst;
llao = (struct pico_icmp6_opt_lladdr *)icmp->msg.info.neigh_sol.options;
aro = (struct pico_icmp6_opt_aro *)(icmp->msg.info.neigh_sol.options + llao_len);
llao = (struct pico_icmp6_opt_lladdr *)(((uint8_t *)&icmp->msg.info.neigh_sol) + sizeof(struct neigh_sol_s));
aro = (struct pico_icmp6_opt_aro *)(((uint8_t *)&icmp->msg.info.neigh_sol) + sizeof(struct neigh_sol_s) + llao_len);
if (LL_MODE_ETHERNET == dev->mode && type != PICO_ICMP6_ND_DAD) {
pico_icmp6_provide_llao(llao, PICO_ND_OPT_LLADDR_SRC, dev, NULL);
}
......@@ -528,7 +527,7 @@ int pico_icmp6_router_solicitation(struct pico_device *dev, struct pico_ip6 *src
icmp6_hdr->code = 0;
if (!pico_ipv6_is_unspecified(src->addr)) {
lladdr = (struct pico_icmp6_opt_lladdr *)icmp6_hdr->msg.info.router_sol.options;
lladdr = (struct pico_icmp6_opt_lladdr *)((uint8_t *)&icmp6_hdr->msg.info.router_sol + sizeof(struct router_sol_s));
if (pico_icmp6_provide_llao(lladdr, PICO_ND_OPT_LLADDR_SRC, dev, NULL)) {
pico_frame_discard(sol);
return -1;
......
......@@ -10,7 +10,6 @@
#include "pico_addressing.h"
#include "pico_protocol.h"
#include "pico_tree.h"
#include "pico_device.h"
#define PICO_IPV4_INADDR_ANY 0x00000000U
......
......@@ -17,6 +17,7 @@
#include "pico_device.h"
#include "pico_tree.h"
#include "pico_fragments.h"
#include "pico_mld.h"
#include "pico_dev_sixlowpan.h"
#ifdef PICO_SUPPORT_IPV6
......@@ -818,12 +819,17 @@ static int pico_ipv6_process_in(struct pico_protocol *self, struct pico_frame *f
{
int proto = 0;
struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->net_hdr;
struct pico_ipv6_exthdr *hbh;
IGNORE_PARAMETER(self);
/* TODO: Check hop-by-hop hdr before forwarding */
/* forward if not local, except if router alert is set */
if (pico_ipv6_is_unicast(&hdr->dst) && !pico_ipv6_link_get(&hdr->dst)) {
return pico_ipv6_forward(f);
if(hdr->nxthdr == 0) {
hbh = (struct pico_ipv6_exthdr *) f->transport_hdr;
if(hbh->ext.routing.routtype == 0)
return pico_ipv6_forward(f);
} else
/* not local, try to forward. */
return pico_ipv6_forward(f);
}
proto = pico_ipv6_extension_headers(f);
......@@ -1252,13 +1258,12 @@ static inline void ipv6_push_hdr_adjust(struct pico_frame *f, struct pico_ipv6_l
/* RFC6775 $5.5.1:
* ... An unspecified source address MUST NOT be used in NS messages.
*/
if (f->dev->mode == LL_MODE_ETHERNET && (is_dad || link->istentative) && icmp6_hdr->type == PICO_ICMP6_NEIGH_SOL)
memcpy(hdr->src.addr, PICO_IP6_ANY, PICO_SIZE_IP6);
if (f->dev->mode == LL_MODE_ETHERNET && (is_dad || link->istentative) && icmp6_hdr->type == PICO_ICMP6_NEIGH_SOL) {
memcpy(hdr->src.addr, PICO_IP6_ANY, PICO_SIZE_IP6);
}
icmp6_hdr->crc = 0;
icmp6_hdr->crc = short_be(pico_icmp6_checksum(f));
icmp6_hdr->crc = short_be(pico_icmp6_checksum(f));
break;
}
#ifdef PICO_SUPPORT_UDP
......@@ -1660,8 +1665,10 @@ static struct pico_ipv6_link *pico_ipv6_do_link_add(struct pico_device *dev, str
* addresses assigned to the interface. (RFC 4861 $7.2.1)
*/
#ifdef PICO_DEBUG_IPV6
pico_ipv6_to_string(ipstr, new->address.addr);
dbg("Assigned ipv6 %s to device %s\n", ipstr, new->dev->name);
#endif
return new;
}
......@@ -1777,11 +1784,9 @@ struct pico_ipv6_link *pico_ipv6_link_get(struct pico_ip6 *address)
if (!found) {
return NULL;
}
if (found->istentative) {
return NULL;
}
return found;
}
......@@ -1916,7 +1921,6 @@ void pico_ipv6_check_lifetime_expired(pico_time now, void *arg)
link = index->keyValue;
if ((link->expire_time > 0) && (link->expire_time < now)) {
dbg("Warning: IPv6 address has expired.\n");
pico_ipv6_link_del(link->dev, link->address);
/* RFC6775, 5.3:
*
......@@ -1927,6 +1931,7 @@ void pico_ipv6_check_lifetime_expired(pico_time now, void *arg)
link = pico_ipv6_linklocal_get(link->dev);
pico_6lp_nd_start_solicitating(link);
}
pico_ipv6_link_del(link->dev, link->address);
}
}
pico_timer_add(1000, pico_ipv6_check_lifetime_expired, NULL);
......
......@@ -10,6 +10,7 @@
#include "pico_addressing.h"
#include "pico_protocol.h"
#include "pico_ipv4.h"
#define PICO_SIZE_IP6HDR ((uint32_t)(sizeof(struct pico_ipv6_hdr)))
#define PICO_IPV6_DEFAULT_HOP 64
#define PICO_IPV6_MIN_MTU 1280
......@@ -23,9 +24,11 @@
#define PICO_IPV6_EXTHDR_NONE 59
#define PICO_IPV6_EXTHDR_DESTOPT 60
#define IPV6_OPTLEN(x) ((uint16_t)(((x + 1) << 3)))
#define PICO_IPV6_EXTHDR_OPT_ROUTER_ALERT 5
#define PICO_IPV6_EXTHDR_OPT_ROUTER_ALERT_DATALEN 2
#define HBH_LEN(hbh) ((((hbh->ext.hopbyhop.len + 1) << 3) - 2)) /* len in bytes, minus nxthdr and len byte */
#define IPV6_OPTLEN(x) ((uint16_t)(((x + 1) << 3)))
extern const uint8_t PICO_IP6_ANY[PICO_SIZE_IP6];
extern struct pico_protocol pico_proto_ipv6;
......@@ -64,8 +67,8 @@ struct pico_ipv6_link
uint8_t mcast_compatibility;
uint8_t mcast_last_query_interval;
#endif
};
union pico_link {
struct pico_ipv4_link ipv4;
struct pico_ipv6_link ipv6;
......@@ -97,7 +100,6 @@ struct pico_ipv6_route
uint32_t metric;
};
PACKED_STRUCT_DEF pico_ipv6_exthdr {
uint8_t nxthdr;
......
......@@ -27,8 +27,7 @@
#define ND_ARO_STATUS_DUPLICATE (1u)
#define ND_ARO_STATUS_CACHE_FULL (2u)
static struct pico_frame *frames_queued_v6[PICO_ND_MAX_FRAMES_QUEUED] = { };
static uint8_t lbr = 0;
static struct pico_frame *frames_queued_v6[PICO_ND_MAX_FRAMES_QUEUED] = { 0 };
enum pico_ipv6_neighbor_state {
PICO_ND_STATE_INCOMPLETE = 0,
......@@ -253,15 +252,15 @@ static int nd_options(uint8_t *options, struct pico_icmp6_opt_lladdr *opt, uint8
optlen -= len << 3; /* len in units of 8 octets */
if (len <= 0)
return -1; /* malformed option. */
if (type == expected_opt) {
if (found > 0)
return -1; /* malformed option: option is there twice. */
memcpy(opt, (struct pico_icmp6_opt_lladdr *)options, (size_t)(len << 3));
found++;
}
if (optlen > 0) {
options += len << 3;
} else { /* parsing options: terminated. */
......@@ -269,7 +268,6 @@ static int nd_options(uint8_t *options, struct pico_icmp6_opt_lladdr *opt, uint8
}
}
return found;
}
static int neigh_options(struct pico_frame *f, struct pico_icmp6_opt_lladdr *opt, uint8_t expected_opt)
......@@ -288,7 +286,7 @@ static int neigh_options(struct pico_frame *f, struct pico_icmp6_opt_lladdr *opt
icmp6_hdr = (struct pico_icmp6_hdr *)f->transport_hdr;
optlen = f->transport_len - PICO_ICMP6HDR_NEIGH_ADV_SIZE;
if (optlen)
option = icmp6_hdr->msg.info.neigh_adv.options;
option = ((uint8_t *)&icmp6_hdr->msg.info.neigh_adv) + sizeof(struct neigh_adv_s);
return nd_options(option, opt, expected_opt, optlen, len);
}
......@@ -311,7 +309,7 @@ static int router_options(struct pico_frame *f, struct pico_icmp6_opt_lladdr *op
icmp6_hdr = (struct pico_icmp6_hdr *)f->transport_hdr;
optlen = f->transport_len - PICO_ICMP6HDR_ROUTER_SOL_SIZE;
if (optlen)
options = icmp6_hdr->msg.info.router_sol.options;
options = ((uint8_t *)&icmp6_hdr->msg.info.router_sol) + sizeof(struct router_sol_s);
return nd_options(options, opt, expected_opt, optlen, len);
}
......@@ -514,7 +512,6 @@ static struct pico_ipv6_neighbor *pico_nd_add_6lp(struct pico_ip6 naddr, struct
if ((new = pico_nd_add(&naddr, dev))) {
new->expire = PICO_TIME_MS() + (pico_time)(ONE_MINUTE * aro->lifetime);
}
return new;
......@@ -523,7 +520,7 @@ static struct pico_ipv6_neighbor *pico_nd_add_6lp(struct pico_ip6 naddr, struct
static inline int validate_aro(struct pico_icmp6_opt_aro *aro)
{
if (aro->len != 2 || aro->status != 0)
return 1;
return -1;
return 0;
}
......@@ -542,7 +539,7 @@ static int neigh_sol_dad_reply(struct pico_frame *sol, struct pico_icmp6_opt_lla
aro->status = status;
/* Remove the SLLAO from the frame */
memmove(icmp->msg.info.neigh_sol.options, icmp->msg.info.neigh_sol.options + sllao_len, (size_t)(aro->len * 8));
memmove(((uint8_t *)&icmp->msg.info.neigh_sol) + sizeof(struct neigh_sol_s), ((uint8_t *)&icmp->msg.info.neigh_sol) + sizeof(struct neigh_sol_s) + sllao_len, (size_t)(aro->len * 8));
adv->transport_len = (uint16_t)(adv->transport_len - sllao_len);
adv->len = (uint16_t)(adv->len - sllao_len);
......@@ -568,8 +565,8 @@ static int neigh_sol_detect_dad_6lp(struct pico_frame *f)
ip = (struct pico_ipv6_hdr *)f->net_hdr;
icmp = (struct pico_icmp6_hdr *)f->transport_hdr;
sllao = (struct pico_icmp6_opt_lladdr *)icmp->msg.info.neigh_adv.options;
aro = (struct pico_icmp6_opt_aro *)(icmp->msg.info.neigh_adv.options + (sllao->len * 8));
sllao = (struct pico_icmp6_opt_lladdr *)((uint8_t *)&icmp->msg.info.neigh_adv + sizeof(struct neigh_adv_s));
aro = (struct pico_icmp6_opt_aro *)(((uint8_t *)&icmp->msg.info.neigh_adv) + sizeof(struct neigh_adv_s) + (sllao->len * 8));
/* Validate Address Registration Option */
if (validate_aro(aro))
......@@ -596,7 +593,7 @@ static int neigh_sol_detect_dad(struct pico_frame *f)
struct pico_ipv6_link *link = NULL;
ipv6_hdr = (struct pico_ipv6_hdr *)f->net_hdr;
icmp6_hdr = (struct pico_icmp6_hdr *)f->transport_hdr;
if (LL_MODE_ETHERNET == f->dev->mode) {
link = pico_ipv6_link_istentative(&icmp6_hdr->msg.info.neigh_adv.target);
if (link) {
......@@ -902,7 +899,7 @@ static int sixlowpan_router_sol_process(struct pico_frame *f)
if (router_sol_checks(f) < 0)
return -1;
/* Maybe create a tentative NCE? Nah.. will add an NCE later */
/* Maybe create a tentative NCE? No, will do it later */
/* Send a router advertisement via unicast to requesting host */
hdr = (struct pico_ipv6_hdr *)f->net_hdr;
......@@ -1159,9 +1156,7 @@ static void pico_6lp_nd_do_solicit(pico_time now, void *arg)
/* Schedule next check */
/* TODO: Apply exponential retransmission timer, see RFC6775 5.3 */
pico_timer_add(PICO_SIXLOWPAN_RTR_SOLICITATION_INTERVAL, pico_6lp_nd_do_solicit, l);
nd_dbg("[6LP-ND]$ No default routers configured, solicitating\n");
return;
}
}
......@@ -1182,7 +1177,6 @@ int pico_6lp_nd_start_solicitating(struct pico_ipv6_link *l)
}
#endif /* PICO_SUPPORT_SIXLOWPAN */
#define PICO_IPV6_ND_MIN_RADV_INTERVAL (5000)
#define PICO_IPV6_ND_MAX_RADV_INTERVAL (15000)
......@@ -1194,7 +1188,7 @@ static void pico_ipv6_nd_ra_timer_callback(pico_time now, void *arg)
struct pico_ipv6_route *rt;
struct pico_ip6 nm64 = { {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0 } };
pico_time next_timer_expire = 0u;
(void)arg;
(void)now;
pico_tree_foreach(rindex, &IPV6Routes)
......@@ -1214,11 +1208,7 @@ static void pico_ipv6_nd_ra_timer_callback(pico_time now, void *arg)
}
}
next_timer_expire = PICO_IPV6_ND_MIN_RADV_INTERVAL + (pico_rand() % (PICO_IPV6_ND_MAX_RADV_INTERVAL - PICO_IPV6_ND_MIN_RADV_INTERVAL));
if (lbr) {
/* Only when I'm an edge router I may have other interface wich are not 6LoWPAN-interfaces,
* so only then check if periodic router advertisements are required */
pico_timer_add(next_timer_expire, pico_ipv6_nd_ra_timer_callback, NULL);
}
pico_timer_add(next_timer_expire, pico_ipv6_nd_ra_timer_callback, NULL);
}
/* Public API */
......
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