mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-24 22:13:52 +01:00
Merge pull request #17547 from benpicco/gnrc_ipv6_auto_subnets-multi
gnrc/ipv6_auto_subnets: allow to join multiple subnets
This commit is contained in:
commit
a61c4b738c
@ -94,6 +94,7 @@
|
||||
#ifndef CONFIG_GNRC_IPV6_AUTO_SUBNETS_TX_PER_PERIOD
|
||||
#define CONFIG_GNRC_IPV6_AUTO_SUBNETS_TX_PER_PERIOD (3)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief How long to wait for other routers annoucements before resending
|
||||
* or creating subnets when the retry counter is exhausted
|
||||
@ -102,6 +103,31 @@
|
||||
#define CONFIG_GNRC_IPV6_AUTO_SUBNETS_TIMEOUT_MS (50)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief How many bits of a new prefix have to match the old prefix
|
||||
* for it to be considered for replacement.
|
||||
*
|
||||
* Set this if you want to join multiple subnets at the same time.
|
||||
*
|
||||
* If you use `gnrc_ipv6_auto_subnets` instead of `gnrc_ipv6_auto_subnets_simple`
|
||||
* make sure to also set CONFIG_GNRC_IPV6_AUTO_SUBNETS_NUMOF accordingly.
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_IPV6_AUTO_SUBNETS_PREFIX_FIX_LEN
|
||||
#define CONFIG_GNRC_IPV6_AUTO_SUBNETS_PREFIX_FIX_LEN (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of subnets that can be configured.
|
||||
*
|
||||
* This is not needed when using the `gnrc_ipv6_auto_subnets_simple` module.
|
||||
*
|
||||
* If this is set to any number higher than 1, make sure to also configure
|
||||
* CONFIG_GNRC_IPV6_AUTO_SUBNETS_PREFIX_FIX_LEN to suit your setup.
|
||||
*/
|
||||
#ifndef CONFIG_GNRC_IPV6_AUTO_SUBNETS_NUMOF
|
||||
#define CONFIG_GNRC_IPV6_AUTO_SUBNETS_NUMOF (1)
|
||||
#endif
|
||||
|
||||
#define SERVER_THREAD_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
|
||||
#define SERVER_MSG_QUEUE_SIZE (CONFIG_GNRC_IPV6_AUTO_SUBNETS_PEERS_MAX)
|
||||
#define SERVER_MSG_TYPE_TIMEOUT (0x8fae)
|
||||
@ -123,7 +149,8 @@ typedef struct __attribute__((packed)) {
|
||||
|
||||
/* keep a copy of PIO information in memory */
|
||||
static gnrc_netif_t *_upstream;
|
||||
static ndp_opt_pi_t _pio_cache;
|
||||
static ndp_opt_pi_t _pio_cache[CONFIG_GNRC_IPV6_AUTO_SUBNETS_NUMOF];
|
||||
static mutex_t _pio_cache_lock;
|
||||
|
||||
static char auto_subnets_stack[SERVER_THREAD_STACKSIZE];
|
||||
static msg_t server_queue[SERVER_MSG_QUEUE_SIZE];
|
||||
@ -135,6 +162,23 @@ static uint8_t l2addrs[CONFIG_GNRC_IPV6_AUTO_SUBNETS_PEERS_MAX]
|
||||
/* PID of the event thread */
|
||||
static kernel_pid_t _server_pid;
|
||||
|
||||
static bool _store_pio(const ndp_opt_pi_t *pio)
|
||||
{
|
||||
mutex_lock(&_pio_cache_lock);
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(_pio_cache); ++i) {
|
||||
if (_pio_cache[i].len == 0) {
|
||||
_pio_cache[i] = *pio;
|
||||
|
||||
mutex_unlock(&_pio_cache_lock);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&_pio_cache_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
static int _send_udp(gnrc_netif_t *netif, const ipv6_addr_t *addr,
|
||||
uint16_t port, const void *data, size_t len)
|
||||
{
|
||||
@ -219,7 +263,7 @@ static bool _remove_old_prefix(gnrc_netif_t *netif,
|
||||
gnrc_pktsnip_t *tmp;
|
||||
void *state = NULL;
|
||||
ipv6_addr_t old_pfx;
|
||||
uint8_t old_pfx_len = 0;
|
||||
uint8_t old_pfx_len = CONFIG_GNRC_IPV6_AUTO_SUBNETS_PREFIX_FIX_LEN;
|
||||
|
||||
/* iterate prefix list to see if the prefix already exists */
|
||||
while (gnrc_ipv6_nib_pl_iter(netif->pid, &state, &entry)) {
|
||||
@ -238,7 +282,7 @@ static bool _remove_old_prefix(gnrc_netif_t *netif,
|
||||
}
|
||||
|
||||
/* no prefix found */
|
||||
if (old_pfx_len == 0) {
|
||||
if (old_pfx_len == CONFIG_GNRC_IPV6_AUTO_SUBNETS_PREFIX_FIX_LEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -362,7 +406,10 @@ void gnrc_ipv6_nib_rtr_adv_pio_cb(gnrc_netif_t *upstream, const ndp_opt_pi_t *pi
|
||||
#else
|
||||
|
||||
/* store PIO information for later use */
|
||||
_pio_cache = *pio;
|
||||
if (!_store_pio(pio)) {
|
||||
DEBUG("auto_subnets: no space left in PIO cache, increase CONFIG_GNRC_IPV6_AUTO_SUBNETS_NUMOF\n");
|
||||
return;
|
||||
}
|
||||
_upstream = upstream;
|
||||
|
||||
/* start advertising by sending timeout message to the server thread */
|
||||
@ -518,6 +565,25 @@ static void _send_announce(uint8_t local_subnets, xtimer_t *timer, msg_t *msg)
|
||||
DEBUG("auto_subnets: announce sent, next timeout in %" PRIu32 " µs\n", timeout_us);
|
||||
}
|
||||
|
||||
static void _process_pio_cache(uint8_t subnets, uint8_t idx_start, gnrc_netif_t *upstream)
|
||||
{
|
||||
mutex_lock(&_pio_cache_lock);
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(_pio_cache); ++i) {
|
||||
if (!_pio_cache[i].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* use PIO for prefix configuration */
|
||||
_configure_subnets(subnets, idx_start, upstream, &_pio_cache[i]);
|
||||
|
||||
/* invalidate entry */
|
||||
_pio_cache[i].len = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&_pio_cache_lock);
|
||||
}
|
||||
|
||||
static void *_eventloop(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
@ -556,7 +622,7 @@ static void *_eventloop(void *arg)
|
||||
_send_announce(local_subnets, &timeout_timer, &timeout_msg);
|
||||
} else {
|
||||
/* config round done, configure subnets */
|
||||
_configure_subnets(subnets, idx_start, _upstream, &_pio_cache);
|
||||
_process_pio_cache(subnets, idx_start, _upstream);
|
||||
|
||||
/* start a new round of counting */
|
||||
tx_period = CONFIG_GNRC_IPV6_AUTO_SUBNETS_TX_PER_PERIOD;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user