Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | /** @file
* @brief IPv6 neighbor management.
*/
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __NET_NBR_H
#define __NET_NBR_H
#include <stddef.h>
#include <zephyr/types.h>
#include <stdbool.h>
#include <net/net_if.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NET_NBR_LLADDR_UNKNOWN 0xff
/* The neighbors are tracked by link layer address. This is not part
* of struct net_nbr because this data can be shared between different
* neighboring tables.
*/
struct net_nbr_lladdr {
/** Link layer address */
struct net_linkaddr_storage lladdr;
/** Reference count. */
u8_t ref;
};
#define NET_NBR_LLADDR_INIT(_name, _count) \
struct net_nbr_lladdr _name[_count] = { }
/* Alignment needed for various parts of the neighbor definition */
#define __net_nbr_align __aligned(sizeof(int))
/* The neighbor node generic data. There can be sub-system specific
* data at the end of the node.
*/
struct net_nbr {
/** Reference count. */
u8_t ref;
/** Link to ll address. This is the index into lladdr array.
* The value NET_NBR_LLADDR_UNKNOWN tells that this neighbor
* does not yet have lladdr linked to it.
*/
u8_t idx;
/** Amount of data that this neighbor buffer can store. */
const u16_t size;
/** Extra data size associated with this neighbor */
const u16_t extra_data_size;
/** Interface this neighbor is found */
struct net_if *iface;
/** Pointer to the start of data in the neighbor table. */
u8_t *data;
/** Function to be called when the neighbor is removed. */
void (*const remove)(struct net_nbr *nbr);
/** Start of the data storage. Not to be accessed directly
* (the data pointer should be used instead).
*/
u8_t __nbr[0] __net_nbr_align;
};
/* This is an array of struct net_nbr + some additional data */
#define NET_NBR_POOL_INIT(_name, _count, _size, _remove, _extra_size) \
struct { \
struct net_nbr nbr; \
u8_t data[ROUND_UP(_size, 4)] __net_nbr_align; \
u8_t extra[ROUND_UP(_extra_size, 4)] __net_nbr_align;\
} _name[_count] = { \
[0 ... (_count - 1)] = { .nbr = { \
.idx = NET_NBR_LLADDR_UNKNOWN, \
.remove = _remove, \
.size = ROUND_UP(_size, 4), \
.extra_data_size = ROUND_UP(_extra_size, 4) } },\
}
struct net_nbr_table {
/** Link to a neighbor pool */
struct net_nbr *nbr;
/** Function to be called when the table is cleared. */
void (*const clear)(struct net_nbr_table *table);
/** Max number of neighbors in the pool */
const u16_t nbr_count;
};
#define NET_NBR_LOCAL static
#define NET_NBR_GLOBAL
/* Type of the table can be NET_NBR_LOCAL or NET_NBR_GLOBAL
*/
#define NET_NBR_TABLE_INIT(_type, _name, _pool, _clear) \
_type struct net_nbr_table_##_name { \
struct net_nbr_table table; \
} net_##_name __used = { \
.table = { \
.clear = _clear, \
.nbr = (struct net_nbr *)_pool, \
.nbr_count = ARRAY_SIZE(_pool), \
} \
}
/**
* @brief Get a pointer to the extra data of a neighbor entry.
*
* @param nbr A valid pointer to neighbor
*
* @return Pointer to the extra data of the nbr.
*/
static inline void *net_nbr_extra_data(struct net_nbr *nbr)
{
return (void *)ROUND_UP((nbr->__nbr + nbr->size), sizeof(int));
}
/**
* @brief Decrement the reference count. If count goes to 0, the neighbor
* is released and returned to free list.
* @param nbr Pointer to neighbor
*/
#if defined(CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL_DBG)
void net_nbr_unref_debug(struct net_nbr *nbr, const char *caller, int line);
#define net_nbr_unref(nbr) net_nbr_unref_debug(nbr, __func__, __LINE__)
#else
void net_nbr_unref(struct net_nbr *nbr);
#endif
/**
* @brief Increment the reference count.
* @param nbr Pointer to neighbor
* @return Pointer to neighbor
*/
#if defined(CONFIG_NET_IPV6_NBR_CACHE_LOG_LEVEL_DBG)
struct net_nbr *net_nbr_ref_debug(struct net_nbr *nbr, const char *caller,
int line);
#define net_nbr_ref(nbr) net_nbr_ref_debug(nbr, __func__, __LINE__)
#else
struct net_nbr *net_nbr_ref(struct net_nbr *nbr);
#endif
/**
* @brief Get a free neighbor from specific table.
* @param table Neighbor table
* @return Pointer to neighbor, NULL if no free neighbors
*/
struct net_nbr *net_nbr_get(struct net_nbr_table *table);
/**
* @brief Find a neighbor from specific table.
* @param table Neighbor table
* @param iface Network interface to use
* @param lladdr Neighbor link layer address
* @return Pointer to neighbor, NULL if not found
*/
struct net_nbr *net_nbr_lookup(struct net_nbr_table *table,
struct net_if *iface,
struct net_linkaddr *lladdr);
/**
* @brief Link a neighbor to specific link layer address.
* @param table Neighbor table
* @param iface Network interface to use
* @param lladdr Neighbor link layer address
* @return 0 if ok, <0 if linking failed
*/
int net_nbr_link(struct net_nbr *nbr, struct net_if *iface,
struct net_linkaddr *lladdr);
/**
* @brief Unlink a neighbor from specific link layer address.
* @param table Neighbor table
* @param lladdr Neighbor link layer address
* @return 0 if ok, <0 if unlinking failed
*/
int net_nbr_unlink(struct net_nbr *nbr, struct net_linkaddr *lladdr);
/**
* @brief Return link address for a specific lladdr table index
* @param idx Link layer address index in ll table.
* @return Pointer to link layer address storage, NULL if not found
*/
struct net_linkaddr_storage *net_nbr_get_lladdr(u8_t idx);
/**
* @brief Clear table from all neighbors. After this the linking between
* lladdr and neighbor is removed.
* @param table Neighbor table
*/
void net_nbr_clear_table(struct net_nbr_table *table);
/**
* @brief Debug helper to print out the neighbor information.
* @param table Neighbor table
*/
void net_nbr_print(struct net_nbr_table *table);
#ifdef __cplusplus
}
#endif
#endif /* __NET_NBR_H */
|