Merge branch 'master' of git://github.com/contiki-os/contiki into ds6_period_configurable
This commit is contained in:
commit
446208dc1c
107 changed files with 8338 additions and 1318 deletions
114
core/net/ipv6/multicast/README.md
Normal file
114
core/net/ipv6/multicast/README.md
Normal file
|
@ -0,0 +1,114 @@
|
|||
README file for Contiki's IPv6 multicast core
|
||||
|
||||
Author: George Oikonomou
|
||||
|
||||
What does it do
|
||||
===============
|
||||
These files, alongside some core modifications, add support for IPv6 multicast
|
||||
to contiki's uIPv6 engine.
|
||||
|
||||
Currently, two modes are supported:
|
||||
|
||||
* 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||
RPL in MOP 3 handles group management as per the RPL docs,
|
||||
SMRF is a lightweight engine which handles datagram forwarding.
|
||||
SMRF is documented here:
|
||||
http://dx.doi.org/10.1007/s11277-013-1250-5
|
||||
and here:
|
||||
http://dx.doi.org/10.1109/PerComW.2012.6197494
|
||||
* 'Multicast Forwarding with Trickle' according to the algorithm described
|
||||
in the internet draft:
|
||||
http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
||||
The version of this draft that's currently implementated is documented
|
||||
in `roll-tm.h`
|
||||
|
||||
More engines can (and hopefully will) be added in the future. The first
|
||||
addition is most likely going to be an updated implementation of MPL
|
||||
|
||||
The Big Gotcha
|
||||
==============
|
||||
Currently we only support traffic originating and destined inside a single 6LoWPAN
|
||||
To be able to send multicast traffic from the internet to 6LoWPAN nodes or the other
|
||||
way round, we need border routers or other gateway devices to be able to achieve
|
||||
the following:
|
||||
|
||||
* Add/Remove Trickle Multicast, RPL or other HBHO headers as necessary for datagrams
|
||||
entering / exiting the 6LoWPAN
|
||||
* Advertise multicast group membership to the internet (e.g. with MLD)
|
||||
|
||||
These are currently not implemented and are in the ToDo list. Contributions welcome.
|
||||
|
||||
Where to Start
|
||||
==============
|
||||
The best place in `examples/ipv6/multicast`
|
||||
|
||||
There is a cooja example demonstrating basic functionality
|
||||
|
||||
How to Use
|
||||
==========
|
||||
Look in `core/net/ipv6/multicast/uip-mcast6-engines.h` for a list of supported
|
||||
multicast engines.
|
||||
|
||||
To turn on multicast support, add this line in your `project-` or `contiki-conf.h`
|
||||
|
||||
#define UIP_MCAST6_CONF_ENGINE xyz
|
||||
|
||||
where xyz is a value from `uip-mcast6-engines.h`
|
||||
|
||||
To disable:
|
||||
|
||||
#define UIP_MCAST6_CONF_ENGINE 0
|
||||
|
||||
You also need to make sure the multicast code gets built. Your example's
|
||||
(or platform's) Makefile should include this:
|
||||
|
||||
MODULES += core/net/ipv6/multicast
|
||||
|
||||
How to extend
|
||||
=============
|
||||
Let's assume you want to write an engine called foo.
|
||||
The multicast API defines a multicast engine driver in a fashion similar to
|
||||
the various NETSTACK layer drivers. This API defines functions for basic
|
||||
multicast operations (init, in, out).
|
||||
In order to extend multicast with a new engine, perform the following steps:
|
||||
|
||||
- Open `uip-mcast6-engines.h` and assign a unique integer code to your engine
|
||||
|
||||
#define UIP_MCAST6_ENGINE_FOO xyz
|
||||
|
||||
- Include your engine's `foo.h`
|
||||
|
||||
- In `foo.c`, implement:
|
||||
* `init()`
|
||||
* `in()`
|
||||
* `out()`
|
||||
* Define your driver like so:
|
||||
|
||||
`const struct uip_mcast6_driver foo_driver = { ... }`
|
||||
|
||||
- If you want to maintain stats:
|
||||
* Standard multicast stats are maintained in `uip_mcast6_stats`. Don't access
|
||||
this struct directly, use the macros provided in `uip-mcast6-stats.h` instead
|
||||
* You can add your own stats extensions. To do so, declare your own stats
|
||||
struct in your engine's module, e.g `struct foo_stats`
|
||||
* When you initialise the stats module with `UIP_MCAST6_STATS_INIT`, pass
|
||||
a pointer to your stats variable as the macro's argument.
|
||||
An example of how to extend multicast stats, look at the ROLL TM engine
|
||||
|
||||
- Open `uip-mcast6.h` and add a section in the `#if` spree. This aims to
|
||||
configure the uIPv6 core. More specifically, you need to:
|
||||
* Specify if you want to put RPL in MOP3 by defining
|
||||
`RPL_CONF_MULTICAST`: 1: MOP 3, 0: non-multicast MOP
|
||||
* Define your engine details
|
||||
|
||||
#define UIP_MCAST6 foo_driver
|
||||
#define UIP_MCAST6_STATS foo_stats
|
||||
typedef struct foo_stats uip_mcast6_stats_t;
|
||||
|
||||
* Optionally, add a configuration check block to stop builds when the
|
||||
configuration is not sane.
|
||||
|
||||
If you need your engine to perform operations not supported by the generic
|
||||
UIP_MCAST6 API, you will have to hook those in the uip core manually. As an
|
||||
example, see how the core is modified so that it can deliver ICMPv6 datagrams
|
||||
to the ROLL TM engine.
|
1452
core/net/ipv6/multicast/roll-tm.c
Normal file
1452
core/net/ipv6/multicast/roll-tm.c
Normal file
File diff suppressed because it is too large
Load diff
224
core/net/ipv6/multicast/roll-tm.h
Normal file
224
core/net/ipv6/multicast/roll-tm.h
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Loughborough University - Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Header file for IPv6 multicast according to the algorithm in the
|
||||
* "MCAST Forwarding Using Trickle" internet draft.
|
||||
*
|
||||
* The current version of the draft can always be found in
|
||||
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
||||
*
|
||||
* This implementation is based on the draft version stored in
|
||||
* ROLL_TM_VER.
|
||||
*
|
||||
* In draft v2, the document was renamed to
|
||||
* "Multicast Protocol for Low power and Lossy Networks (MPL)"
|
||||
* Due to very significant changes between draft versions 1 and 2,
|
||||
* MPL will be implemented as a separate engine and this file here
|
||||
* will provide legacy support for Draft v1.
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#ifndef ROLL_TM_H_
|
||||
#define ROLL_TM_H_
|
||||
|
||||
#include "contiki-conf.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6-stats.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Protocol Constants */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define ROLL_TM_VER 1 /* Supported Draft Version */
|
||||
#define ROLL_TM_ICMP_CODE 0 /* ICMPv6 code field */
|
||||
#define ROLL_TM_IP_HOP_LIMIT 0xFF /* Hop limit for ICMP messages */
|
||||
#define ROLL_TM_INFINITE_REDUNDANCY 0xFF
|
||||
#define ROLL_TM_DGRAM_OUT 0
|
||||
#define ROLL_TM_DGRAM_IN 1
|
||||
|
||||
/*
|
||||
* The draft does not currently specify a default number for the trickle
|
||||
* interval nor a way to derive it. Examples however hint at 100 msec.
|
||||
*
|
||||
* In draft terminology, we use an 'aggressive' policy (M=0) and a conservative
|
||||
* one (M=1).
|
||||
*
|
||||
* When experimenting with the two policies on the sky platform,
|
||||
* an interval of 125ms proves to be way too low: When we have traffic,
|
||||
* doublings happen after the interval end and periodics fire after point T
|
||||
* within the interval (and sometimes even after interval end). When traffic
|
||||
* settles down, the code compensates the offsets.
|
||||
*
|
||||
* We consider 125, 250ms etc because they are nice divisors of 1 sec
|
||||
* (quotient is power of two). For some machines (e.g sky/msp430,
|
||||
* sensinode/cc243x), this is also a nice number of clock ticks
|
||||
*
|
||||
* After experimentation, the values of Imin leading to best performance are:
|
||||
* ContikiMAC: Imin=64 (500ms)
|
||||
* Null RDC: imin=16 (125ms)
|
||||
*/
|
||||
|
||||
/* Configuration for Timer with M=0 (aggressive) */
|
||||
#ifdef ROLL_TM_CONF_IMIN_0
|
||||
#define ROLL_TM_IMIN_0 ROLL_TM_CONF_IMIN_0
|
||||
#else
|
||||
#define ROLL_TM_IMIN_0 32 /* 250 msec */
|
||||
#endif
|
||||
|
||||
#ifdef ROLL_TM_CONF_IMAX_0
|
||||
#define ROLL_TM_IMAX_0 ROLL_TM_CONF_IMAX_0
|
||||
#else
|
||||
#define ROLL_TM_IMAX_0 1 /* Imax = 500ms */
|
||||
#endif
|
||||
|
||||
#ifdef ROLL_TM_CONF_K_0
|
||||
#define ROLL_TM_K_0 ROLL_TM_CONF_K_0
|
||||
#else
|
||||
#define ROLL_TM_K_0 ROLL_TM_INFINITE_REDUNDANCY
|
||||
#endif
|
||||
|
||||
#ifdef ROLL_TM_CONF_T_ACTIVE_0
|
||||
#define ROLL_TM_T_ACTIVE_0 ROLL_TM_CONF_T_ACTIVE_0
|
||||
#else
|
||||
#define ROLL_TM_T_ACTIVE_0 3
|
||||
#endif
|
||||
|
||||
#ifdef ROLL_TM_CONF_T_DWELL_0
|
||||
#define ROLL_TM_T_DWELL_0 ROLL_TM_CONF_T_DWELL_0
|
||||
#else
|
||||
#define ROLL_TM_T_DWELL_0 11
|
||||
#endif
|
||||
|
||||
/* Configuration for Timer with M=1 (conservative) */
|
||||
#ifdef ROLL_TM_CONF_IMIN_1
|
||||
#define ROLL_TM_IMIN_1 ROLL_TM_CONF_IMIN_1
|
||||
#else
|
||||
#define ROLL_TM_IMIN_1 64 /* 500 msec */
|
||||
#endif
|
||||
|
||||
#ifdef ROLL_TM_CONF_IMAX_1
|
||||
#define ROLL_TM_IMAX_1 ROLL_TM_CONF_IMAX_1
|
||||
#else
|
||||
#define ROLL_TM_IMAX_1 9 /* Imax = 256 secs */
|
||||
#endif
|
||||
|
||||
#ifdef ROLL_TM_CONF_K_1
|
||||
#define ROLL_TM_K_1 ROLL_TM_CONF_K_1
|
||||
#else
|
||||
#define ROLL_TM_K_1 1
|
||||
#endif
|
||||
|
||||
#ifdef ROLL_TM_CONF_T_ACTIVE_1
|
||||
#define ROLL_TM_T_ACTIVE_1 ROLL_TM_CONF_T_ACTIVE_1
|
||||
#else
|
||||
#define ROLL_TM_T_ACTIVE_1 3
|
||||
#endif
|
||||
|
||||
#ifdef ROLL_TM_CONF_T_DWELL_1
|
||||
#define ROLL_TM_T_DWELL_1 ROLL_TM_CONF_T_DWELL_1
|
||||
#else
|
||||
#define ROLL_TM_T_DWELL_1 12
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Configuration */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Number of Sliding Windows
|
||||
* In essence: How many unique sources of simultaneous multicast traffic do we
|
||||
* want to support for our lowpan
|
||||
* If a node is seeding two multicast streams, parametrized on different M
|
||||
* values, then this seed will occupy two different sliding windows
|
||||
*/
|
||||
#ifdef ROLL_TM_CONF_WINS
|
||||
#define ROLL_TM_WINS ROLL_TM_CONF_WINS
|
||||
#else
|
||||
#define ROLL_TM_WINS 2
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Maximum Number of Buffered Multicast Messages
|
||||
* This buffer is shared across all Seed IDs, therefore a new very active Seed
|
||||
* may eventually occupy all slots. It would make little sense (if any) to
|
||||
* define support for fewer buffered messages than seeds*2
|
||||
*/
|
||||
#ifdef ROLL_TM_CONF_BUFF_NUM
|
||||
#define ROLL_TM_BUFF_NUM ROLL_TM_CONF_BUFF_NUM
|
||||
#else
|
||||
#define ROLL_TM_BUFF_NUM 6
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Use Short Seed IDs [short: 2, long: 16 (default)]
|
||||
* It can be argued that we should (and it would be easy to) support both at
|
||||
* the same time but the draft doesn't list this as a MUST so we opt for
|
||||
* code/ram savings
|
||||
*/
|
||||
#ifdef ROLL_TM_CONF_SHORT_SEEDS
|
||||
#define ROLL_TM_SHORT_SEEDS ROLL_TM_CONF_SHORT_SEEDS
|
||||
#else
|
||||
#define ROLL_TM_SHORT_SEEDS 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Destination address for our ICMPv6 advertisements. The draft gives us a
|
||||
* choice between LL all-nodes or LL all-routers
|
||||
*
|
||||
* We use allrouters unless a conf directive chooses otherwise
|
||||
*/
|
||||
#ifdef ROLL_TM_CONF_DEST_ALL_NODES
|
||||
#define ROLL_TM_DEST_ALL_NODES ROLL_TM_CONF_DEST_ALL_NODES
|
||||
#else
|
||||
#define ROLL_TM_DEST_ALL_NODES 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* M param for our outgoing messages
|
||||
* By default, we set the M bit (conservative). Define this as 0 to clear the
|
||||
* M bit in our outgoing messages (aggressive)
|
||||
*/
|
||||
#ifdef ROLL_TM_CONF_SET_M_BIT
|
||||
#define ROLL_TM_SET_M_BIT ROLL_TM_CONF_SET_M_BIT
|
||||
#else
|
||||
#define ROLL_TM_SET_M_BIT 1
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Stats datatype */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct roll_tm_stats {
|
||||
UIP_MCAST6_STATS_DATATYPE icmp_in;
|
||||
UIP_MCAST6_STATS_DATATYPE icmp_out;
|
||||
UIP_MCAST6_STATS_DATATYPE icmp_bad;
|
||||
};
|
||||
|
||||
#endif /* ROLL_TM_H_ */
|
211
core/net/ipv6/multicast/smrf.c
Normal file
211
core/net/ipv6/multicast/smrf.c
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Loughborough University - Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* This file implements 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||
*
|
||||
* It will only work in RPL networks in MOP 3 "Storing with Multicast"
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6-route.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6-stats.h"
|
||||
#include "net/ipv6/multicast/smrf.h"
|
||||
#include "net/rpl/rpl.h"
|
||||
#include "net/netstack.h"
|
||||
#include <string.h>
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/ip/uip-debug.h"
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Macros */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* CCI */
|
||||
#define SMRF_FWD_DELAY() NETSTACK_RDC.channel_check_interval()
|
||||
/* Number of slots in the next 500ms */
|
||||
#define SMRF_INTERVAL_COUNT ((CLOCK_SECOND >> 2) / fwd_delay)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Internal Data */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static struct ctimer mcast_periodic;
|
||||
static uint8_t mcast_len;
|
||||
static uip_buf_t mcast_buf;
|
||||
static uint8_t fwd_delay;
|
||||
static uint8_t fwd_spread;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* uIPv6 Pointers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcast_fwd(void *p)
|
||||
{
|
||||
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||
uip_len = mcast_len;
|
||||
UIP_IP_BUF->ttl--;
|
||||
tcpip_output(NULL);
|
||||
uip_len = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
in()
|
||||
{
|
||||
rpl_dag_t *d; /* Our DODAG */
|
||||
uip_ipaddr_t *parent_ipaddr; /* Our pref. parent's IPv6 address */
|
||||
const uip_lladdr_t *parent_lladdr; /* Our pref. parent's LL address */
|
||||
|
||||
/*
|
||||
* Fetch a pointer to the LL address of our preferred parent
|
||||
*
|
||||
* ToDo: This rpl_get_any_dag() call is a dirty replacement of the previous
|
||||
* rpl_get_dag(RPL_DEFAULT_INSTANCE);
|
||||
* so that things can compile with the new RPL code. This needs updated to
|
||||
* read instance ID from the RPL HBHO and use the correct parent accordingly
|
||||
*/
|
||||
d = rpl_get_any_dag();
|
||||
if(!d) {
|
||||
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||
return UIP_MCAST6_DROP;
|
||||
}
|
||||
|
||||
/* Retrieve our preferred parent's LL address */
|
||||
parent_ipaddr = rpl_get_parent_ipaddr(d->preferred_parent);
|
||||
parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr);
|
||||
|
||||
if(parent_lladdr == NULL) {
|
||||
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||
return UIP_MCAST6_DROP;
|
||||
}
|
||||
|
||||
/*
|
||||
* We accept a datagram if it arrived from our preferred parent, discard
|
||||
* otherwise.
|
||||
*/
|
||||
if(memcmp(parent_lladdr, packetbuf_addr(PACKETBUF_ADDR_SENDER),
|
||||
UIP_LLADDR_LEN)) {
|
||||
PRINTF("SMRF: Routable in but SMRF ignored it\n");
|
||||
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||
return UIP_MCAST6_DROP;
|
||||
}
|
||||
|
||||
if(UIP_IP_BUF->ttl <= 1) {
|
||||
UIP_MCAST6_STATS_ADD(mcast_dropped);
|
||||
return UIP_MCAST6_DROP;
|
||||
}
|
||||
|
||||
UIP_MCAST6_STATS_ADD(mcast_in_all);
|
||||
UIP_MCAST6_STATS_ADD(mcast_in_unique);
|
||||
|
||||
/* If we have an entry in the mcast routing table, something with
|
||||
* a higher RPL rank (somewhere down the tree) is a group member */
|
||||
if(uip_mcast6_route_lookup(&UIP_IP_BUF->destipaddr)) {
|
||||
/* If we enter here, we will definitely forward */
|
||||
UIP_MCAST6_STATS_ADD(mcast_fwd);
|
||||
|
||||
/*
|
||||
* Add a delay (D) of at least SMRF_FWD_DELAY() to compensate for how
|
||||
* contikimac handles broadcasts. We can't start our TX before the sender
|
||||
* has finished its own.
|
||||
*/
|
||||
fwd_delay = SMRF_FWD_DELAY();
|
||||
|
||||
/* Finalise D: D = min(SMRF_FWD_DELAY(), SMRF_MIN_FWD_DELAY) */
|
||||
#if SMRF_MIN_FWD_DELAY
|
||||
if(fwd_delay < SMRF_MIN_FWD_DELAY) {
|
||||
fwd_delay = SMRF_MIN_FWD_DELAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(fwd_delay == 0) {
|
||||
/* No delay required, send it, do it now, why wait? */
|
||||
UIP_IP_BUF->ttl--;
|
||||
tcpip_output(NULL);
|
||||
UIP_IP_BUF->ttl++; /* Restore before potential upstack delivery */
|
||||
} else {
|
||||
/* Randomise final delay in [D , D*Spread], step D */
|
||||
fwd_spread = SMRF_INTERVAL_COUNT;
|
||||
if(fwd_spread > SMRF_MAX_SPREAD) {
|
||||
fwd_spread = SMRF_MAX_SPREAD;
|
||||
}
|
||||
if(fwd_spread) {
|
||||
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
|
||||
}
|
||||
|
||||
memcpy(&mcast_buf, uip_buf, 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);
|
||||
}
|
||||
|
||||
/* Done with this packet unless we are a member of the mcast group */
|
||||
if(!uip_ds6_is_my_maddr(&UIP_IP_BUF->destipaddr)) {
|
||||
PRINTF("SMRF: Not a group member. No further processing\n");
|
||||
return UIP_MCAST6_DROP;
|
||||
} else {
|
||||
PRINTF("SMRF: Ours. Deliver to upper layers\n");
|
||||
UIP_MCAST6_STATS_ADD(mcast_in_ours);
|
||||
return UIP_MCAST6_ACCEPT;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init()
|
||||
{
|
||||
UIP_MCAST6_STATS_INIT(NULL);
|
||||
|
||||
uip_mcast6_route_init();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
out()
|
||||
{
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct uip_mcast6_driver smrf_driver = {
|
||||
"SMRF",
|
||||
init,
|
||||
out,
|
||||
in,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* UIP_CONF_IPV6 */
|
75
core/net/ipv6/multicast/smrf.h
Normal file
75
core/net/ipv6/multicast/smrf.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Loughborough University - Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Header file for 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#ifndef SMRF_H_
|
||||
#define SMRF_H_
|
||||
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Configuration */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Fmin */
|
||||
#ifdef SMRF_CONF_MIN_FWD_DELAY
|
||||
#define SMRF_MIN_FWD_DELAY SMRF_CONF_MIN_FWD_DELAY
|
||||
#else
|
||||
#define SMRF_MIN_FWD_DELAY 4
|
||||
#endif
|
||||
|
||||
/* Max Spread */
|
||||
#ifdef SMRF_CONF_MAX_SPREAD
|
||||
#define SMRF_MAX_SPREAD SMRF_CONF_MAX_SPREAD
|
||||
#else
|
||||
#define SMRF_MAX_SPREAD 4
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Stats datatype */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct smrf_stats {
|
||||
uint16_t mcast_in_unique;
|
||||
uint16_t mcast_in_all; /* At layer 3 */
|
||||
uint16_t mcast_in_ours; /* Unique and we are a group member */
|
||||
uint16_t mcast_fwd; /* Forwarded by us but we are not the seed */
|
||||
uint16_t mcast_out; /* We are the seed */
|
||||
uint16_t mcast_bad;
|
||||
uint16_t mcast_dropped;
|
||||
};
|
||||
|
||||
#endif /* SMRF_H_ */
|
50
core/net/ipv6/multicast/uip-mcast6-engines.h
Normal file
50
core/net/ipv6/multicast/uip-mcast6-engines.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Loughborough University - Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Header file with definition of multicast engine constants
|
||||
*
|
||||
* When writing a new engine, add it here with a unique number and
|
||||
* then modify uip-mcast6.h accordingly
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#ifndef UIP_MCAST6_ENGINES_H_
|
||||
#define UIP_MCAST6_ENGINES_H_
|
||||
|
||||
#define UIP_MCAST6_ENGINE_NONE 0 /* Selecting this disables mcast */
|
||||
#define UIP_MCAST6_ENGINE_SMRF 1
|
||||
#define UIP_MCAST6_ENGINE_ROLL_TM 2
|
||||
|
||||
#endif /* UIP_MCAST6_ENGINES_H_ */
|
133
core/net/ipv6/multicast/uip-mcast6-route.c
Normal file
133
core/net/ipv6/multicast/uip-mcast6-route.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Loughborough University - Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Multicast routing table manipulation
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "lib/list.h"
|
||||
#include "lib/memb.h"
|
||||
#include "net/ip/uip.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6-route.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Size of the multicast routing table */
|
||||
#ifdef UIP_MCAST6_ROUTE_CONF_ROUTES
|
||||
#define UIP_MCAST6_ROUTE_ROUTES UIP_MCAST6_ROUTE_CONF_ROUTES
|
||||
#else
|
||||
#define UIP_MCAST6_ROUTE_ROUTES 1
|
||||
#endif /* UIP_CONF_DS6_MCAST_ROUTES */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
LIST(mcast_route_list);
|
||||
MEMB(mcast_route_memb, uip_mcast6_route_t, UIP_MCAST6_ROUTE_ROUTES);
|
||||
|
||||
static uip_mcast6_route_t *locmcastrt;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_mcast6_route_t *
|
||||
uip_mcast6_route_lookup(uip_ipaddr_t *group)
|
||||
{
|
||||
locmcastrt = NULL;
|
||||
for(locmcastrt = list_head(mcast_route_list);
|
||||
locmcastrt != NULL;
|
||||
locmcastrt = list_item_next(locmcastrt)) {
|
||||
if(uip_ipaddr_cmp(&locmcastrt->group, group)) {
|
||||
return locmcastrt;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_mcast6_route_t *
|
||||
uip_mcast6_route_add(uip_ipaddr_t *group)
|
||||
{
|
||||
/* _lookup must return NULL, i.e. the prefix does not exist in our table */
|
||||
locmcastrt = uip_mcast6_route_lookup(group);
|
||||
if(locmcastrt == NULL) {
|
||||
/* Allocate an entry and add the group to the list */
|
||||
locmcastrt = memb_alloc(&mcast_route_memb);
|
||||
if(locmcastrt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
list_add(mcast_route_list, locmcastrt);
|
||||
}
|
||||
|
||||
/* Reaching here means we either found the prefix or allocated a new one */
|
||||
|
||||
uip_ipaddr_copy(&(locmcastrt->group), group);
|
||||
|
||||
return locmcastrt;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_mcast6_route_rm(uip_mcast6_route_t *route)
|
||||
{
|
||||
/* Make sure it's actually in the list */
|
||||
for(locmcastrt = list_head(mcast_route_list);
|
||||
locmcastrt != NULL;
|
||||
locmcastrt = list_item_next(locmcastrt)) {
|
||||
if(locmcastrt == route) {
|
||||
list_remove(mcast_route_list, route);
|
||||
memb_free(&mcast_route_memb, route);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_mcast6_route_t *
|
||||
uip_mcast6_route_list_head(void)
|
||||
{
|
||||
return list_head(mcast_route_list);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
uip_mcast6_route_count(void)
|
||||
{
|
||||
return list_length(mcast_route_list);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_mcast6_route_init()
|
||||
{
|
||||
memb_init(&mcast_route_memb);
|
||||
list_init(mcast_route_list);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* UIP_CONF_IPV6 */
|
75
core/net/ipv6/multicast/uip-mcast6-route.h
Normal file
75
core/net/ipv6/multicast/uip-mcast6-route.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Loughborough University - Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Multicast routing table manipulation
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#ifndef UIP_MCAST6_ROUTE_H_
|
||||
#define UIP_MCAST6_ROUTE_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "net/ip/uip.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \brief An entry in the multicast routing table */
|
||||
typedef struct uip_mcast6_route {
|
||||
struct uip_mcast6_route *next;
|
||||
uip_ipaddr_t group;
|
||||
uint32_t lifetime; /* seconds */
|
||||
void *dag; /* Pointer to an rpl_dag_t struct */
|
||||
} uip_mcast6_route_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** \name Multicast Routing Table Manipulation */
|
||||
/** @{ */
|
||||
uip_mcast6_route_t *uip_mcast6_route_lookup(uip_ipaddr_t *group);
|
||||
uip_mcast6_route_t *uip_mcast6_route_add(uip_ipaddr_t *group);
|
||||
void uip_mcast6_route_rm(uip_mcast6_route_t *defrt);
|
||||
int uip_mcast6_route_count(void);
|
||||
uip_mcast6_route_t *uip_mcast6_route_list_head(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Multicast routing table init routine
|
||||
*
|
||||
* Multicast routing tables are not necessarily required by all
|
||||
* multicast engines. For instance, trickle multicast does not rely on
|
||||
* the existence of a routing table. Therefore, this function here
|
||||
* should be invoked by each engine's init routine only if the relevant
|
||||
* functionality is required. This is also why this function should not
|
||||
* get hooked into the uip-ds6 core.
|
||||
*/
|
||||
void uip_mcast6_route_init(void);
|
||||
/** @} */
|
||||
|
||||
#endif /* UIP_MCAST6_ROUTE_H_ */
|
49
core/net/ipv6/multicast/uip-mcast6-stats.c
Normal file
49
core/net/ipv6/multicast/uip-mcast6-stats.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2014, University of Bristol - http://www.bris.ac.uk
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* IPv6 multicast forwarding stats maintenance
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#include "net/ipv6/multicast/uip-mcast6-stats.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_mcast6_stats_t uip_mcast6_stats;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_mcast6_stats_init(void *stats)
|
||||
{
|
||||
memset(&uip_mcast6_stats, 0, sizeof(uip_mcast6_stats));
|
||||
uip_mcast6_stats.engine_stats = stats;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
91
core/net/ipv6/multicast/uip-mcast6-stats.h
Normal file
91
core/net/ipv6/multicast/uip-mcast6-stats.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2014, University of Bristol - http://www.bris.ac.uk
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Header file for IPv6 multicast forwarding stats maintenance
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#ifndef UIP_MCAST6_STATS_H_
|
||||
#define UIP_MCAST6_STATS_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#include <stdint.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* The platform can override the stats datatype */
|
||||
#ifdef UIP_MCAST6_CONF_STATS_DATATYPE
|
||||
#define UIP_MCAST6_STATS_DATATYPE UIP_MCAST6_CONF_STATS_DATATYPE
|
||||
#else
|
||||
#define UIP_MCAST6_STATS_DATATYPE uint16_t
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef UIP_MCAST6_CONF_STATS
|
||||
#define UIP_MCAST6_STATS UIP_MCAST6_CONF_STATS
|
||||
#else
|
||||
#define UIP_MCAST6_STATS 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Stats datatype */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct uip_mcast6_stats {
|
||||
UIP_MCAST6_STATS_DATATYPE mcast_in_unique;
|
||||
UIP_MCAST6_STATS_DATATYPE mcast_in_all; /* At layer 3 */
|
||||
UIP_MCAST6_STATS_DATATYPE mcast_in_ours; /* Unique and we are a group member */
|
||||
UIP_MCAST6_STATS_DATATYPE mcast_fwd; /* Forwarded by us but we are not the seed */
|
||||
UIP_MCAST6_STATS_DATATYPE mcast_out; /* We are the seed */
|
||||
UIP_MCAST6_STATS_DATATYPE mcast_bad;
|
||||
UIP_MCAST6_STATS_DATATYPE mcast_dropped;
|
||||
void *engine_stats; /* Opaque pointer to an engine's additional stats */
|
||||
} uip_mcast6_stats_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Access macros */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if UIP_MCAST6_STATS
|
||||
/* Don't access this variable directly, use the macros below */
|
||||
extern uip_mcast6_stats_t uip_mcast6_stats;
|
||||
|
||||
#define UIP_MCAST6_STATS_ADD(x) uip_mcast6_stats.x++
|
||||
#define UIP_MCAST6_STATS_GET(x) uip_mcast6_stats.x
|
||||
#define UIP_MCAST6_STATS_INIT(s) uip_mcast6_stats_init(s)
|
||||
#else /* UIP_MCAST6_STATS */
|
||||
#define UIP_MCAST6_STATS_ADD(x)
|
||||
#define UIP_MCAST6_STATS_GET(x) 0
|
||||
#define UIP_MCAST6_STATS_INIT(s)
|
||||
#endif /* UIP_MCAST6_STATS */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Initialise multicast stats
|
||||
* \param stats A pointer to a struct holding an engine's additional statistics
|
||||
*/
|
||||
void uip_mcast6_stats_init(void *stats);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* UIP_MCAST6_STATS_H_ */
|
162
core/net/ipv6/multicast/uip-mcast6.h
Normal file
162
core/net/ipv6/multicast/uip-mcast6.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Loughborough University - Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* This header file contains configuration directives for uIPv6
|
||||
* multicast support.
|
||||
*
|
||||
* We currently support 2 engines:
|
||||
* - 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||
* RPL does group management as per the RPL docs, SMRF handles datagram
|
||||
* forwarding
|
||||
* - 'Multicast Forwarding with Trickle' according to the algorithm described
|
||||
* in the internet draft:
|
||||
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#ifndef UIP_MCAST6_H_
|
||||
#define UIP_MCAST6_H_
|
||||
|
||||
#include "contiki-conf.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6-engines.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6-route.h"
|
||||
#include "net/ipv6/multicast/smrf.h"
|
||||
#include "net/ipv6/multicast/roll-tm.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Constants */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_MCAST6_DROP 0
|
||||
#define UIP_MCAST6_ACCEPT 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Multicast Address Scopes (RFC 4291 & draft-ietf-6man-multicast-scopes) */
|
||||
#define UIP_MCAST6_SCOPE_INTERFACE 0x01
|
||||
#define UIP_MCAST6_SCOPE_LINK_LOCAL 0x02
|
||||
#define UIP_MCAST6_SCOPE_REALM_LOCAL 0x03 /* draft-ietf-6man-multicast-scopes */
|
||||
#define UIP_MCAST6_SCOPE_ADMIN_LOCAL 0x04
|
||||
#define UIP_MCAST6_SCOPE_SITE_LOCAL 0x05
|
||||
#define UIP_MCAST6_SCOPE_ORG_LOCAL 0x08
|
||||
#define UIP_MCAST6_SCOPE_GLOBAL 0x0E
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Choose an engine or turn off based on user configuration */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef UIP_MCAST6_CONF_ENGINE
|
||||
#define UIP_MCAST6_ENGINE UIP_MCAST6_CONF_ENGINE
|
||||
#else
|
||||
#define UIP_MCAST6_ENGINE UIP_MCAST6_ENGINE_NONE
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Multicast API. Similar to NETSTACK, each engine must define a driver and
|
||||
* populate the fields with suitable function pointers
|
||||
*/
|
||||
struct uip_mcast6_driver {
|
||||
char *name;
|
||||
|
||||
/** Initialize the multicast engine */
|
||||
void (* init)(void);
|
||||
|
||||
/**
|
||||
* \brief Process an outgoing datagram with a multicast IPv6 destination
|
||||
* address
|
||||
*
|
||||
* This may be needed if the multicast engine needs to, for example,
|
||||
* add IPv6 extension headers to the datagram, cache it, decide it
|
||||
* needs dropped etc.
|
||||
*
|
||||
* It is sometimes desirable to let the engine handle datagram
|
||||
* dispatch instead of letting the networking core do it. If the
|
||||
* engine decides to send the datagram itself, it must afterwards
|
||||
* set uip_len = 0 to prevent the networking core from sending too
|
||||
*/
|
||||
void (* out)(void);
|
||||
|
||||
/**
|
||||
* \brief Process an incoming multicast datagram and determine whether it
|
||||
* should be delivered up the stack or not.
|
||||
*
|
||||
* \return 0: Drop, 1: Deliver
|
||||
*
|
||||
* When a datagram with a multicast destination address is received,
|
||||
* the forwarding logic in core is bypassed. Instead, we let the
|
||||
* multicast engine handle forwarding internally if and as necessary.
|
||||
* This function is where forwarding logic must be hooked in.
|
||||
*
|
||||
* Once the engine is done with forwarding, it must signal via the
|
||||
* return value whether the datagram needs delivered up the network
|
||||
* stack.
|
||||
*/
|
||||
uint8_t (* in)(void);
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Get a multicast address' scope.
|
||||
* a is of type uip_ip6addr_t*
|
||||
*/
|
||||
#define uip_mcast6_get_address_scope(a) ((a)->u8[1] & 0x0F)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Configure multicast and core/net to play nicely with the selected engine */
|
||||
#if UIP_MCAST6_ENGINE
|
||||
|
||||
/* Enable Multicast hooks in the uip6 core */
|
||||
#define UIP_CONF_IPV6_MULTICAST 1
|
||||
|
||||
#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_ROLL_TM
|
||||
#define RPL_CONF_MULTICAST 0 /* Not used by trickle */
|
||||
#define UIP_CONF_IPV6_ROLL_TM 1 /* ROLL Trickle ICMP type support */
|
||||
|
||||
#define UIP_MCAST6 roll_tm_driver
|
||||
#elif UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_SMRF
|
||||
#define RPL_CONF_MULTICAST 1
|
||||
|
||||
#define UIP_MCAST6 smrf_driver
|
||||
#else
|
||||
#error "Multicast Enabled with an Unknown Engine."
|
||||
#error "Check the value of UIP_MCAST6_CONF_ENGINE in conf files."
|
||||
#endif
|
||||
#endif /* UIP_MCAST6_ENGINE */
|
||||
|
||||
extern const struct uip_mcast6_driver UIP_MCAST6;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Configuration Checks */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if RPL_CONF_MULTICAST && (!UIP_CONF_IPV6_RPL)
|
||||
#error "The selected Multicast mode requires UIP_CONF_IPV6_RPL != 0"
|
||||
#error "Check the value of UIP_CONF_IPV6_RPL in conf files."
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* UIP_MCAST6_H_ */
|
|
@ -512,6 +512,10 @@ uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
|||
}
|
||||
}
|
||||
}
|
||||
#if UIP_IPV6_MULTICAST
|
||||
} else if(uip_is_addr_mcast_routable(dst)) {
|
||||
matchaddr = uip_ds6_get_global(ADDR_PREFERRED);
|
||||
#endif
|
||||
} else {
|
||||
matchaddr = uip_ds6_get_link_local(ADDR_PREFERRED);
|
||||
}
|
||||
|
|
|
@ -74,10 +74,53 @@
|
|||
static uip_ipaddr_t tmp_ipaddr;
|
||||
|
||||
LIST(echo_reply_callback_list);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* List of input handlers */
|
||||
LIST(input_handler_list);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uip_icmp6_input_handler_t *
|
||||
input_handler_lookup(uint8_t type, uint8_t icode)
|
||||
{
|
||||
uip_icmp6_input_handler_t *handler = NULL;
|
||||
|
||||
for(handler = list_head(input_handler_list);
|
||||
handler != NULL;
|
||||
handler = list_item_next(handler)) {
|
||||
if(handler->type == type &&
|
||||
(handler->icode == icode ||
|
||||
handler->icode == UIP_ICMP6_HANDLER_CODE_ANY)) {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
uip_icmp6_input(uint8_t type, uint8_t icode)
|
||||
{
|
||||
uip_icmp6_input_handler_t *handler = input_handler_lookup(type, icode);
|
||||
|
||||
if(handler == NULL) {
|
||||
return UIP_ICMP6_INPUT_ERROR;
|
||||
}
|
||||
|
||||
if(handler->handler == NULL) {
|
||||
return UIP_ICMP6_INPUT_ERROR;
|
||||
}
|
||||
|
||||
handler->handler();
|
||||
return UIP_ICMP6_INPUT_SUCCESS;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_icmp6_echo_request_input(void)
|
||||
uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler)
|
||||
{
|
||||
list_add(input_handler_list, handler);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
echo_request_input(void)
|
||||
{
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
uint8_t temp_ext_len;
|
||||
|
@ -275,8 +318,8 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
|
|||
tcpip_ipv6_output();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_icmp6_echo_reply_input(void)
|
||||
static void
|
||||
echo_reply_input(void)
|
||||
{
|
||||
int ttl;
|
||||
uip_ipaddr_t sender;
|
||||
|
@ -343,6 +386,8 @@ uip_icmp6_echo_reply_input(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
uip_len = 0;
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -362,5 +407,18 @@ uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n)
|
|||
list_remove(echo_reply_callback_list, n);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
UIP_ICMP6_HANDLER(echo_request_handler, ICMP6_ECHO_REQUEST,
|
||||
UIP_ICMP6_HANDLER_CODE_ANY, echo_request_input);
|
||||
UIP_ICMP6_HANDLER(echo_reply_handler, ICMP6_ECHO_REPLY,
|
||||
UIP_ICMP6_HANDLER_CODE_ANY, echo_reply_input);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_icmp6_init()
|
||||
{
|
||||
/* Register Echo Request and Reply handlers */
|
||||
uip_icmp6_register_input_handler(&echo_request_handler);
|
||||
uip_icmp6_register_input_handler(&echo_reply_handler);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
|
|
|
@ -65,6 +65,11 @@
|
|||
#define ICMP6_REDIRECT 137 /**< Redirect */
|
||||
|
||||
#define ICMP6_RPL 155 /**< RPL */
|
||||
#define ICMP6_PRIV_EXP_100 100 /**< Private Experimentation */
|
||||
#define ICMP6_PRIV_EXP_101 101 /**< Private Experimentation */
|
||||
#define ICMP6_PRIV_EXP_200 200 /**< Private Experimentation */
|
||||
#define ICMP6_PRIV_EXP_201 201 /**< Private Experimentation */
|
||||
#define ICMP6_ROLL_TM ICMP6_PRIV_EXP_200 /**< ROLL Trickle Multicast */
|
||||
/** @} */
|
||||
|
||||
|
||||
|
@ -104,24 +109,6 @@ typedef struct uip_icmp6_error{
|
|||
|
||||
/** \name ICMPv6 RFC4443 Message processing and sending */
|
||||
/** @{ */
|
||||
/** \
|
||||
* brief Process an echo request
|
||||
*
|
||||
* Perform a few checks, then send an Echo reply. The reply is
|
||||
* built here.
|
||||
*/
|
||||
void
|
||||
uip_icmp6_echo_request_input(void);
|
||||
|
||||
/** \
|
||||
* brief Process an echo reply
|
||||
*
|
||||
* Perform a few checks, then call applications to inform that an echo
|
||||
* reply has been received.
|
||||
*/
|
||||
void
|
||||
uip_icmp6_echo_reply_input(void);
|
||||
|
||||
/**
|
||||
* \brief Send an icmpv6 error message
|
||||
* \param type type of the error message
|
||||
|
@ -187,8 +174,66 @@ uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n,
|
|||
void
|
||||
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n);
|
||||
|
||||
/* Generic ICMPv6 input handers */
|
||||
typedef struct uip_icmp6_input_handler {
|
||||
struct uip_icmp6_input_handler *next;
|
||||
uint8_t type;
|
||||
uint8_t icode;
|
||||
void (*handler)(void);
|
||||
} uip_icmp6_input_handler_t;
|
||||
|
||||
#define UIP_ICMP6_INPUT_SUCCESS 0
|
||||
#define UIP_ICMP6_INPUT_ERROR 1
|
||||
|
||||
#define UIP_ICMP6_HANDLER_CODE_ANY 0xFF /* Handle all codes for this type */
|
||||
|
||||
/*
|
||||
* Initialise a variable of type uip_icmp6_input_handler, to be used later as
|
||||
* the argument to uip_icmp6_register_input_handler
|
||||
*
|
||||
* The function pointer stored in this variable will get called and will be
|
||||
* expected to handle incoming ICMPv6 datagrams of the specified type/code
|
||||
*
|
||||
* If code has a value of UIP_ICMP6_HANDLER_CODE_ANY, the same function
|
||||
* will handle all codes for this type. In other words, the ICMPv6
|
||||
* message's code is "don't care"
|
||||
*/
|
||||
#define UIP_ICMP6_HANDLER(name, type, code, func) \
|
||||
static uip_icmp6_input_handler_t name = { NULL, type, code, func }
|
||||
|
||||
/**
|
||||
* \brief Handle an incoming ICMPv6 message
|
||||
* \param type The ICMPv6 message type
|
||||
* \param icode The ICMPv6 message code
|
||||
* \return Success: UIP_ICMP6_INPUT_SUCCESS, Error: UIP_ICMP6_INPUT_ERROR
|
||||
*
|
||||
* Generic handler for unknown ICMPv6 types. It will lookup for a registered
|
||||
* function capable of handing this message type. The function must have first
|
||||
* been registered with uip_icmp6_register_input_handler. The function is in
|
||||
* charge of setting uip_len to 0, otherwise the uIPv6 core will attempt to
|
||||
* send whatever remains in the UIP_IP_BUF.
|
||||
*
|
||||
* A return value of UIP_ICMP6_INPUT_ERROR means that a handler could not be
|
||||
* invoked. This is most likely because the ICMPv6 type does not have a valid
|
||||
* handler associated with it.
|
||||
|
||||
* UIP_ICMP6_INPUT_SUCCESS signifies that a handler was found for this ICMPv6
|
||||
* type and that it was invoked. It does NOT provide any indication whatsoever
|
||||
* regarding whether the handler itself succeeded.
|
||||
*/
|
||||
uint8_t uip_icmp6_input(uint8_t type, uint8_t icode);
|
||||
|
||||
/**
|
||||
* \brief Register a handler which can handle a specific ICMPv6 message type
|
||||
* \param handler A pointer to the handler
|
||||
*/
|
||||
void uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialise the uIP ICMPv6 core
|
||||
*/
|
||||
void uip_icmp6_init(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -126,8 +126,6 @@ static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */
|
|||
static uip_ds6_nbr_t *nbr; /** Pointer to a nbr cache entry*/
|
||||
static uip_ds6_defrt_t *defrt; /** Pointer to a router list entry */
|
||||
static uip_ds6_addr_t *addr; /** Pointer to an interface address */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* create a llao */
|
||||
static void
|
||||
|
@ -143,8 +141,8 @@ create_llao(uint8_t *llao, uint8_t type) {
|
|||
/*------------------------------------------------------------------*/
|
||||
|
||||
|
||||
void
|
||||
uip_nd6_ns_input(void)
|
||||
static void
|
||||
ns_input(void)
|
||||
{
|
||||
uint8_t flags;
|
||||
PRINTF("Received NS from ");
|
||||
|
@ -388,12 +386,26 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
|||
PRINTF("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
void
|
||||
uip_nd6_na_input(void)
|
||||
/**
|
||||
* Neighbor Advertisement Processing
|
||||
*
|
||||
* we might have to send a pkt that had been buffered while address
|
||||
* resolution was performed (if we support buffering, see UIP_CONF_QUEUE_PKT)
|
||||
*
|
||||
* As per RFC 4861, on link layer that have addresses, TLLAO options MUST be
|
||||
* included when responding to multicast solicitations, SHOULD be included in
|
||||
* response to unicast (here we assume it is for now)
|
||||
*
|
||||
* NA can be received after sending NS for DAD, Address resolution or NUD. Can
|
||||
* be unsolicited as well.
|
||||
* It can trigger update of the state of the neighbor in the neighbor cache,
|
||||
* router in the router list.
|
||||
* If the NS was for DAD, it means DAD failed
|
||||
*
|
||||
*/
|
||||
static void
|
||||
na_input(void)
|
||||
{
|
||||
uint8_t is_llchange;
|
||||
uint8_t is_router;
|
||||
|
@ -548,8 +560,8 @@ discard:
|
|||
#if UIP_CONF_ROUTER
|
||||
#if UIP_ND6_SEND_RA
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_nd6_rs_input(void)
|
||||
static void
|
||||
rs_input(void)
|
||||
{
|
||||
|
||||
PRINTF("Received RS from");
|
||||
|
@ -761,11 +773,18 @@ uip_nd6_rs_output(void)
|
|||
PRINTF("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Process a Router Advertisement
|
||||
*
|
||||
* - Possible actions when receiving a RA: add router to router list,
|
||||
* recalculate reachable time, update link hop limit, update retrans timer.
|
||||
* - If MTU option: update MTU.
|
||||
* - If SLLAO option: update entry in neighbor cache
|
||||
* - If prefix option: start autoconf, add prefix to prefix list
|
||||
*/
|
||||
void
|
||||
uip_nd6_ra_input(void)
|
||||
ra_input(void)
|
||||
{
|
||||
PRINTF("Received RA from");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
|
@ -969,6 +988,52 @@ discard:
|
|||
return;
|
||||
}
|
||||
#endif /* !UIP_CONF_ROUTER */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* ICMPv6 input handlers */
|
||||
#if UIP_ND6_SEND_NA
|
||||
UIP_ICMP6_HANDLER(ns_input_handler, ICMP6_NS, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||
ns_input);
|
||||
UIP_ICMP6_HANDLER(na_input_handler, ICMP6_NA, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||
na_input);
|
||||
#endif
|
||||
|
||||
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
||||
UIP_ICMP6_HANDLER(rs_input_handler, ICMP6_RS, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||
rs_input);
|
||||
#endif
|
||||
|
||||
#if !UIP_CONF_ROUTER
|
||||
UIP_ICMP6_HANDLER(ra_input_handler, ICMP6_RA, UIP_ICMP6_HANDLER_CODE_ANY,
|
||||
ra_input);
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_nd6_init()
|
||||
{
|
||||
|
||||
#if UIP_ND6_SEND_NA
|
||||
/* Only handle NSs if we are prepared to send out NAs */
|
||||
uip_icmp6_register_input_handler(&ns_input_handler);
|
||||
|
||||
/*
|
||||
* Only handle NAs if we are prepared to send out NAs.
|
||||
* This is perhaps logically incorrect, but this condition was present in
|
||||
* uip_process and we keep it until proven wrong
|
||||
*/
|
||||
uip_icmp6_register_input_handler(&na_input_handler);
|
||||
#endif
|
||||
|
||||
|
||||
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
||||
/* Only accept RS if we are a router and happy to send out RAs */
|
||||
uip_icmp6_register_input_handler(&rs_input_handler);
|
||||
#endif
|
||||
|
||||
#if !UIP_CONF_ROUTER
|
||||
/* Only process RAs if we are not a router */
|
||||
uip_icmp6_register_input_handler(&ra_input_handler);
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
|
|
|
@ -337,34 +337,8 @@ uip_nd6_ns_input(void);
|
|||
void
|
||||
uip_nd6_ns_output(uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt);
|
||||
|
||||
/**
|
||||
* \brief Process a Neighbor Advertisement
|
||||
*
|
||||
* we might have to send a pkt that had been buffered while address
|
||||
* resolution was performed (if we support buffering, see UIP_CONF_QUEUE_PKT)
|
||||
*
|
||||
* As per RFC 4861, on link layer that have addresses, TLLAO options MUST be
|
||||
* included when responding to multicast solicitations, SHOULD be included in
|
||||
* response to unicast (here we assume it is for now)
|
||||
*
|
||||
* NA can be received after sending NS for DAD, Address resolution or NUD. Can
|
||||
* be unsolicited as well.
|
||||
* It can trigger update of the state of the neighbor in the neighbor cache,
|
||||
* router in the router list.
|
||||
* If the NS was for DAD, it means DAD failed
|
||||
*
|
||||
*/
|
||||
void
|
||||
uip_nd6_na_input(void);
|
||||
|
||||
#if UIP_CONF_ROUTER
|
||||
#if UIP_ND6_SEND_RA
|
||||
/**
|
||||
* \brief Process a Router Solicitation
|
||||
*
|
||||
*/
|
||||
void uip_nd6_rs_input(void);
|
||||
|
||||
/**
|
||||
* \brief send a Router Advertisement
|
||||
*
|
||||
|
@ -388,17 +362,9 @@ void uip_nd6_ra_output(uip_ipaddr_t *dest);
|
|||
void uip_nd6_rs_output(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* \brief process a Router Advertisement
|
||||
*
|
||||
* - Possible actions when receiving a RA: add router to router list,
|
||||
* recalculate reachable time, update link hop limit, update retrans timer.
|
||||
* - If MTU option: update MTU.
|
||||
* - If SLLAO option: update entry in neighbor cache
|
||||
* - If prefix option: start autoconf, add prefix to prefix list
|
||||
* \brief Initialise the uIP ND core
|
||||
*/
|
||||
void
|
||||
uip_nd6_ra_input(void);
|
||||
void uip_nd6_init(void);
|
||||
/** @} */
|
||||
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/ipv6/uip-nd6.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -410,6 +411,8 @@ uip_init(void)
|
|||
{
|
||||
|
||||
uip_ds6_init();
|
||||
uip_icmp6_init();
|
||||
uip_nd6_init();
|
||||
|
||||
#if UIP_TCP
|
||||
for(c = 0; c < UIP_LISTENPORTS; ++c) {
|
||||
|
@ -429,6 +432,10 @@ uip_init(void)
|
|||
uip_udp_conns[c].lport = 0;
|
||||
}
|
||||
#endif /* UIP_UDP */
|
||||
|
||||
#if UIP_CONF_IPV6_MULTICAST
|
||||
UIP_MCAST6.init();
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if UIP_TCP && UIP_ACTIVE_OPEN
|
||||
|
@ -1151,6 +1158,28 @@ uip_process(uint8_t flag)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Packets with a routable multicast destination:
|
||||
* - We invoke the multicast engine and let it do its thing
|
||||
* (cache, forward etc).
|
||||
* - We never execute the datagram forwarding logic in this file here. When
|
||||
* the engine returns, forwarding has been handled if and as required.
|
||||
* - Depending on the return value, we either discard or deliver up the stack
|
||||
*
|
||||
* All multicast engines must hook in here. After this function returns, we
|
||||
* expect UIP_BUF to be unmodified
|
||||
*/
|
||||
#if UIP_CONF_IPV6_MULTICAST
|
||||
if(uip_is_addr_mcast_routable(&UIP_IP_BUF->destipaddr)) {
|
||||
if(UIP_MCAST6.in() == UIP_MCAST6_ACCEPT) {
|
||||
/* Deliver up the stack */
|
||||
goto process;
|
||||
} else {
|
||||
/* Don't deliver up the stack */
|
||||
goto drop;
|
||||
}
|
||||
}
|
||||
#endif /* UIP_IPV6_CONF_MULTICAST */
|
||||
|
||||
/* TBD Some Parameter problem messages */
|
||||
if(!uip_ds6_is_my_addr(&UIP_IP_BUF->destipaddr) &&
|
||||
|
@ -1220,6 +1249,10 @@ uip_process(uint8_t flag)
|
|||
uip_ext_bitmap = 0;
|
||||
#endif /* UIP_CONF_ROUTER */
|
||||
|
||||
#if UIP_CONF_IPV6_MULTICAST
|
||||
process:
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
switch(*uip_next_hdr){
|
||||
#if UIP_TCP
|
||||
|
@ -1389,61 +1422,17 @@ uip_process(uint8_t flag)
|
|||
UIP_ICMP6_APPCALL(UIP_ICMP_BUF->type);
|
||||
#endif /*UIP_CONF_ICMP6*/
|
||||
|
||||
switch(UIP_ICMP_BUF->type) {
|
||||
case ICMP6_NS:
|
||||
#if UIP_ND6_SEND_NA
|
||||
uip_nd6_ns_input();
|
||||
#else /* UIP_ND6_SEND_NA */
|
||||
UIP_STAT(++uip_stat.icmp.drop);
|
||||
uip_len = 0;
|
||||
#endif /* UIP_ND6_SEND_NA */
|
||||
break;
|
||||
case ICMP6_NA:
|
||||
#if UIP_ND6_SEND_NA
|
||||
uip_nd6_na_input();
|
||||
#else /* UIP_ND6_SEND_NA */
|
||||
UIP_STAT(++uip_stat.icmp.drop);
|
||||
uip_len = 0;
|
||||
#endif /* UIP_ND6_SEND_NA */
|
||||
break;
|
||||
case ICMP6_RS:
|
||||
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
|
||||
uip_nd6_rs_input();
|
||||
#else /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
|
||||
/*
|
||||
* Search generic input handlers.
|
||||
* The handler is in charge of setting uip_len to 0
|
||||
*/
|
||||
if(uip_icmp6_input(UIP_ICMP_BUF->type,
|
||||
UIP_ICMP_BUF->icode) == UIP_ICMP6_INPUT_ERROR) {
|
||||
PRINTF("Unknown ICMPv6 message type/code %d\n", UIP_ICMP_BUF->type);
|
||||
UIP_STAT(++uip_stat.icmp.drop);
|
||||
UIP_STAT(++uip_stat.icmp.typeerr);
|
||||
UIP_LOG("icmp6: unknown ICMPv6 message.");
|
||||
uip_len = 0;
|
||||
#endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
|
||||
break;
|
||||
case ICMP6_RA:
|
||||
#if UIP_CONF_ROUTER
|
||||
UIP_STAT(++uip_stat.icmp.drop);
|
||||
uip_len = 0;
|
||||
#else /* UIP_CONF_ROUTER */
|
||||
uip_nd6_ra_input();
|
||||
#endif /* UIP_CONF_ROUTER */
|
||||
break;
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
case ICMP6_RPL:
|
||||
uip_rpl_input();
|
||||
break;
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
case ICMP6_ECHO_REQUEST:
|
||||
uip_icmp6_echo_request_input();
|
||||
break;
|
||||
case ICMP6_ECHO_REPLY:
|
||||
/** Call echo reply input function. */
|
||||
uip_icmp6_echo_reply_input();
|
||||
PRINTF("Received an icmp6 echo reply\n");
|
||||
UIP_STAT(++uip_stat.icmp.recv);
|
||||
uip_len = 0;
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unknown icmp6 message type %d\n", UIP_ICMP_BUF->type);
|
||||
UIP_STAT(++uip_stat.icmp.drop);
|
||||
UIP_STAT(++uip_stat.icmp.typeerr);
|
||||
UIP_LOG("icmp6: unknown ICMP message.");
|
||||
uip_len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(uip_len > 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue