iPXE
neighbour.c File Reference

Neighbour discovery. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/iobuf.h>
#include <ipxe/retry.h>
#include <ipxe/timer.h>
#include <ipxe/malloc.h>
#include <ipxe/pending.h>
#include <ipxe/neighbour.h>
#include <config/fault.h>

Go to the source code of this file.

Macros

#define NEIGHBOUR_MIN_TIMEOUT   ( TICKS_PER_SEC / 8 )
 Neighbour discovery minimum timeout.
#define NEIGHBOUR_MAX_TIMEOUT   ( TICKS_PER_SEC * 3 )
 Neighbour discovery maximum timeout.
#define NEIGHBOUR_DELAY_MAX_BURST   2
 Neighbour discovery maximum burst count for delayed transmissions.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void neighbour_expired (struct retry_timer *timer, int fail)
 Handle neighbour timer expiry.
static void neighbour_free (struct refcnt *refcnt)
 Free neighbour cache entry.
static struct neighbourneighbour_create (struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest)
 Create neighbour cache entry.
static struct neighbourneighbour_find (struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest)
 Find neighbour cache entry.
static void neighbour_discover (struct neighbour *neighbour, struct neighbour_discovery *discovery, const void *net_source)
 Start neighbour discovery.
static void neighbour_tx_queue (struct neighbour *neighbour)
 Transmit deferred packets.
static unsigned int neighbour_drop (struct neighbour *neighbour, int rc)
 Drop a deferred packet.
static void neighbour_discovered (struct neighbour *neighbour, const void *ll_dest)
 Complete neighbour discovery.
static void neighbour_destroy (struct neighbour *neighbour, int rc)
 Destroy neighbour cache entry.
int neighbour_tx (struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, struct neighbour_discovery *discovery, const void *net_source)
 Transmit packet, determining link-layer address via neighbour discovery.
int neighbour_update (struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *ll_dest)
 Update existing neighbour cache entry.
int neighbour_define (struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *ll_dest)
 Define neighbour cache entry.
static void neighbour_flush (struct net_device *netdev, void *priv __unused)
 Update neighbour cache on network device state change or removal.
static unsigned int neighbour_queue_discard (void)
 Discard some deferred packets from neighbour cache entries.
struct cache_discarder neighbour_queue_discarder __cache_discarder (CACHE_NORMAL)
 Neighbour cache deferred packet discarder.
static unsigned int neighbour_discard (void)
 Discard some complete neighbour cache entries.
struct cache_discarder neighbour_discarder __cache_discarder (CACHE_EXPENSIVE)
 Neighbour cache discarder.

Variables

struct list_head neighbours = LIST_HEAD_INIT ( neighbours )
 The neighbour cache.
static struct pending_operation neighbour_delayed
 Pending operation for delayed transmissions.
struct net_driver neighbour_net_driver __net_driver
 Neighbour driver (for net device notifications).

Detailed Description

Neighbour discovery.

This file implements the abstract functions of neighbour discovery, independent of the underlying network protocol (e.g. ARP or NDP).

Definition in file neighbour.c.

Macro Definition Documentation

◆ NEIGHBOUR_MIN_TIMEOUT

#define NEIGHBOUR_MIN_TIMEOUT   ( TICKS_PER_SEC / 8 )

Neighbour discovery minimum timeout.

Definition at line 49 of file neighbour.c.

Referenced by neighbour_create().

◆ NEIGHBOUR_MAX_TIMEOUT

#define NEIGHBOUR_MAX_TIMEOUT   ( TICKS_PER_SEC * 3 )

Neighbour discovery maximum timeout.

Definition at line 52 of file neighbour.c.

Referenced by neighbour_create().

◆ NEIGHBOUR_DELAY_MAX_BURST

#define NEIGHBOUR_DELAY_MAX_BURST   2

Neighbour discovery maximum burst count for delayed transmissions.

When using delay injection, timer quantisation can cause a large number of delayed packets to be scheduled at the same time. This can quickly exhaust available transmit descriptors, leading to packets that are dropped completely (not just delayed).

Limit the number of delayed packets that we will attempt to transmit at once, to allow time for transmit completions to occur.

Definition at line 64 of file neighbour.c.

Referenced by neighbour_tx_queue().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ neighbour_expired()

void neighbour_expired ( struct retry_timer * timer,
int fail )
static

Handle neighbour timer expiry.

Parameters
timerRetry timer
failFailure indicator

Definition at line 345 of file neighbour.c.

345 {
346 struct neighbour *neighbour =
347 container_of ( timer, struct neighbour, timer );
350 struct neighbour_discovery *discovery =
352 const void *net_dest = neighbour->net_dest;
353 const void *net_source = neighbour->net_source;
354 int rc;
355
356 /* If the timer is being (ab)used for delay injection, then
357 * transmit the deferred packet queue.
358 */
359 if ( NEIGHBOUR_DELAY_MS && ( ! neighbour->discovery ) ) {
361 return;
362 }
363
364 /* If we have failed, destroy the cache entry */
365 if ( fail ) {
367 return;
368 }
369
370 /* Restart the timer */
372
373 /* Transmit neighbour request */
374 if ( ( rc = discovery->tx_request ( netdev, net_protocol, net_dest,
375 net_source ) ) != 0 ) {
376 DBGC ( neighbour, "NEIGHBOUR %s %s %s could not transmit %s "
377 "request: %s\n", netdev->name, net_protocol->name,
380 /* Retransmit when timer expires */
381 return;
382 }
383}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define NEIGHBOUR_DELAY_MS
Definition fault.h:19
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:530
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
static void neighbour_destroy(struct neighbour *neighbour, int rc)
Destroy neighbour cache entry.
Definition neighbour.c:318
static void neighbour_tx_queue(struct neighbour *neighbour)
Transmit deferred packets.
Definition neighbour.c:189
void start_timer(struct retry_timer *timer)
Start timer.
Definition retry.c:94
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A neighbour discovery protocol.
Definition neighbour.h:20
int(* tx_request)(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *net_source)
Transmit neighbour discovery request.
Definition neighbour.h:32
const char * name
Name.
Definition neighbour.h:22
A neighbour cache entry.
Definition neighbour.h:38
struct neighbour_discovery * discovery
Neighbour discovery protocol (if discovery is ongoing).
Definition neighbour.h:54
uint8_t net_source[MAX_NET_ADDR_LEN]
Network-layer source address (for discovery requests).
Definition neighbour.h:56
struct retry_timer timer
Retransmission timer.
Definition neighbour.h:58
struct net_protocol * net_protocol
Network-layer protocol.
Definition neighbour.h:47
struct net_device * netdev
Network device.
Definition neighbour.h:45
uint8_t net_dest[MAX_NET_ADDR_LEN]
Network-layer destination address.
Definition neighbour.h:49
A network device.
Definition netdevice.h:353
A network-layer protocol.
Definition netdevice.h:65
const char * name
Protocol name.
Definition netdevice.h:67
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition netdevice.h:95
A timer.
Definition timer.h:29

References container_of, DBGC, neighbour::discovery, ETIMEDOUT, neighbour_discovery::name, net_protocol::name, NEIGHBOUR_DELAY_MS, neighbour_destroy(), neighbour_tx_queue(), neighbour::net_dest, neighbour::net_protocol, neighbour::net_source, neighbour::netdev, netdev, net_protocol::ntoa, rc, start_timer(), strerror(), neighbour::timer, and neighbour_discovery::tx_request.

Referenced by neighbour_create().

◆ neighbour_free()

void neighbour_free ( struct refcnt * refcnt)
static

Free neighbour cache entry.

Parameters
refcntReference count

Definition at line 79 of file neighbour.c.

79 {
80 struct neighbour *neighbour =
82
83 /* Sanity check */
85
86 /* Drop reference to network device */
88
89 /* Free neighbour */
90 free ( neighbour );
91}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:579
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
struct list_head tx_queue
Pending I/O buffers.
Definition neighbour.h:61
A reference counter.
Definition refcnt.h:27

References assert, container_of, free, list_empty, neighbour::netdev, netdev_put(), and neighbour::tx_queue.

Referenced by neighbour_create().

◆ neighbour_create()

struct neighbour * neighbour_create ( struct net_device * netdev,
struct net_protocol * net_protocol,
const void * net_dest )
static

Create neighbour cache entry.

Parameters
netdevNetwork device
net_protocolNetwork-layer protocol
net_destDestination network-layer address
Return values
neighbourNeighbour cache entry, or NULL if allocation failed

Definition at line 101 of file neighbour.c.

103 {
104 struct neighbour *neighbour;
105
106 /* Allocate and initialise entry */
107 neighbour = zalloc ( sizeof ( *neighbour ) );
108 if ( ! neighbour )
109 return NULL;
115 timer_init ( &neighbour->timer, neighbour_expired, &neighbour->refcnt );
116 set_timer_limits ( &neighbour->timer, NEIGHBOUR_MIN_TIMEOUT,
119
120 /* Transfer ownership to cache */
122
123 DBGC ( neighbour, "NEIGHBOUR %s %s %s created\n", netdev->name,
125 return neighbour;
126}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static void neighbour_expired(struct retry_timer *timer, int over)
Handle neighbour timer expiry.
Definition neighbour.c:345
#define NEIGHBOUR_MAX_TIMEOUT
Neighbour discovery maximum timeout.
Definition neighbour.c:52
struct list_head neighbours
The neighbour cache.
Definition neighbour.c:67
#define NEIGHBOUR_MIN_TIMEOUT
Neighbour discovery minimum timeout.
Definition neighbour.c:49
static void neighbour_free(struct refcnt *refcnt)
Free neighbour cache entry.
Definition neighbour.c:79
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:568
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
struct refcnt refcnt
Reference count.
Definition neighbour.h:40
struct list_head list
List of neighbour cache entries.
Definition neighbour.h:42
uint8_t net_addr_len
Network-layer address length.
Definition netdevice.h:102

References DBGC, INIT_LIST_HEAD, neighbour::list, list_add, memcpy(), net_protocol::name, neighbour_expired(), neighbour_free(), NEIGHBOUR_MAX_TIMEOUT, NEIGHBOUR_MIN_TIMEOUT, neighbours, net_protocol::net_addr_len, neighbour::net_dest, neighbour::net_protocol, neighbour::netdev, netdev, netdev_get(), net_protocol::ntoa, NULL, ref_init, neighbour::refcnt, neighbour::timer, neighbour::tx_queue, and zalloc().

Referenced by neighbour_define(), and neighbour_tx().

◆ neighbour_find()

struct neighbour * neighbour_find ( struct net_device * netdev,
struct net_protocol * net_protocol,
const void * net_dest )
static

Find neighbour cache entry.

Parameters
netdevNetwork device
net_protocolNetwork-layer protocol
net_destDestination network-layer address
Return values
neighbourNeighbour cache entry, or NULL if not found

Definition at line 136 of file neighbour.c.

138 {
139 struct neighbour *neighbour;
140
142 if ( ( neighbour->netdev == netdev ) &&
145 net_protocol->net_addr_len ) == 0 ) ) {
146
147 /* Move to start of cache */
148 list_del ( &neighbour->list );
150
151 return neighbour;
152 }
153 }
154 return NULL;
155}
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115

References neighbour::list, list_add, list_del, list_for_each_entry, memcmp(), neighbours, net_protocol::net_addr_len, neighbour::net_dest, neighbour::net_protocol, neighbour::netdev, netdev, and NULL.

Referenced by neighbour_define(), neighbour_tx(), and neighbour_update().

◆ neighbour_discover()

void neighbour_discover ( struct neighbour * neighbour,
struct neighbour_discovery * discovery,
const void * net_source )
static

Start neighbour discovery.

Parameters
neighbourNeighbour cache entry
discoveryNeighbour discovery protocol
net_sourceSource network-layer address

Definition at line 164 of file neighbour.c.

166 {
169
170 /* Record discovery protocol and source network-layer address */
171 neighbour->discovery = discovery;
172 memcpy ( neighbour->net_source, net_source,
174
175 /* Start timer to trigger neighbour discovery */
177
178 DBGC ( neighbour, "NEIGHBOUR %s %s %s discovering via %s\n",
179 netdev->name, net_protocol->name,
182}
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition retry.h:100

References DBGC, neighbour::discovery, memcpy(), neighbour_discovery::name, net_protocol::name, net_protocol::net_addr_len, neighbour::net_dest, neighbour::net_protocol, neighbour::net_source, neighbour::netdev, netdev, net_protocol::ntoa, start_timer_nodelay(), and neighbour::timer.

Referenced by neighbour_tx().

◆ neighbour_tx_queue()

void neighbour_tx_queue ( struct neighbour * neighbour)
static

Transmit deferred packets.

Parameters
neighbourNeighbour cache entry

Definition at line 189 of file neighbour.c.

189 {
192 const void *ll_dest = neighbour->ll_dest;
193 struct neighbour_delay *delay;
194 struct io_buffer *iobuf;
195 unsigned long elapsed;
196 unsigned long threshold;
197 unsigned int count = 0;
198 int rc;
199
200 /* Stop retransmission timer */
202
203 /* Transmit any packets in queue. Take out a temporary
204 * reference on the entry to prevent it from going out of
205 * scope during the call to net_tx().
206 */
208 while ( ( iobuf = list_first_entry ( &neighbour->tx_queue,
209 struct io_buffer, list )) != NULL){
210
211 /* Handle delay injection */
212 if ( NEIGHBOUR_DELAY_MS ) {
213
214 /* Determine elapsed time since transmission attempt */
215 delay = iobuf->data;
216 elapsed = ( currticks() - delay->start );
217 threshold = ( NEIGHBOUR_DELAY_MS * TICKS_PER_MS );
218
219 /* Defer transmission if not yet scheduled */
220 if ( elapsed < threshold ) {
222 ( threshold - elapsed ) );
223 break;
224 }
225
226 /* Defer transmission if maximum burst count reached */
227 if ( ++count >= NEIGHBOUR_DELAY_MAX_BURST ) {
229 break;
230 }
231
232 /* Strip pseudo-header */
233 iob_pull ( iobuf, sizeof ( *delay ) );
234
235 /* Remove pending operation */
237 }
238
239 /* Transmit deferred packet */
240 DBGC2 ( neighbour, "NEIGHBOUR %s %s %s transmitting deferred "
241 "packet\n", netdev->name, net_protocol->name,
243 list_del ( &iobuf->list );
244 if ( ( rc = net_tx ( iobuf, netdev, net_protocol, ll_dest,
245 netdev->ll_addr ) ) != 0 ) {
246 DBGC ( neighbour, "NEIGHBOUR %s %s %s could not "
247 "transmit deferred packet: %s\n",
248 netdev->name, net_protocol->name,
250 strerror ( rc ) );
251 /* Ignore error and continue */
252 }
253 }
255}
#define delay(nanosec)
Definition epic100.c:49
#define DBGC2(...)
Definition compiler.h:547
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define TICKS_PER_MS
Number of ticks per millisecond.
Definition timer.h:26
#define iob_pull(iobuf, len)
Definition iobuf.h:107
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
static struct pending_operation neighbour_delayed
Pending operation for delayed transmissions.
Definition neighbour.c:70
#define NEIGHBOUR_DELAY_MAX_BURST
Neighbour discovery maximum burst count for delayed transmissions.
Definition neighbour.c:64
int net_tx(struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest, const void *ll_source)
Transmit network-layer packet.
Definition netdevice.c:1078
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition pending.c:59
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition retry.c:65
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition retry.c:118
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45
A neighbour transmission delay pseudo-header.
Definition neighbour.h:65
uint8_t ll_dest[MAX_LL_ADDR_LEN]
Link-layer destination address.
Definition neighbour.h:51
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43

References count, currticks(), io_buffer::data, DBGC, DBGC2, delay, iob_pull, io_buffer::list, list_del, list_first_entry, neighbour::ll_dest, net_protocol::name, NEIGHBOUR_DELAY_MAX_BURST, NEIGHBOUR_DELAY_MS, neighbour_delayed, neighbour::net_dest, neighbour::net_protocol, net_tx(), neighbour::netdev, netdev, net_protocol::ntoa, NULL, pending_put(), rc, ref_get, ref_put, neighbour::refcnt, start_timer_fixed(), start_timer_nodelay(), stop_timer(), strerror(), TICKS_PER_MS, neighbour::timer, and neighbour::tx_queue.

Referenced by neighbour_discovered(), neighbour_expired(), and neighbour_tx().

◆ neighbour_drop()

unsigned int neighbour_drop ( struct neighbour * neighbour,
int rc )
static

Drop a deferred packet.

Parameters
neighbourNeighbour cache entry
rcReason for drop
Return values
droppedNumber of deferred packets dropped

Definition at line 264 of file neighbour.c.

264 {
267 struct io_buffer *iobuf;
268
269 /* Get oldest deferred packet, if any */
270 iobuf = list_first_entry ( &neighbour->tx_queue, struct io_buffer,
271 list );
272 if ( ! iobuf )
273 return 0;
274
275 /* Drop deferred packet */
276 DBGC2 ( neighbour, "NEIGHBOUR %s %s %s dropping deferred packet: %s\n",
277 netdev->name, net_protocol->name,
279 list_del ( &iobuf->list );
280 if ( NEIGHBOUR_DELAY_MS )
282 netdev_tx_err ( neighbour->netdev, iobuf, rc );
283
284 return 1;
285}
void netdev_tx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard transmitted packet.
Definition netdevice.c:441

References DBGC2, io_buffer::list, list_del, list_first_entry, net_protocol::name, NEIGHBOUR_DELAY_MS, neighbour_delayed, neighbour::net_dest, neighbour::net_protocol, neighbour::netdev, netdev, netdev_tx_err(), net_protocol::ntoa, pending_put(), rc, strerror(), and neighbour::tx_queue.

Referenced by neighbour_destroy(), and neighbour_queue_discard().

◆ neighbour_discovered()

void neighbour_discovered ( struct neighbour * neighbour,
const void * ll_dest )
static

Complete neighbour discovery.

Parameters
neighbourNeighbour cache entry
ll_destDestination link-layer address

Definition at line 293 of file neighbour.c.

294 {
296 struct ll_protocol *ll_protocol = netdev->ll_protocol;
298
299 /* Fill in link-layer address */
301 DBGC ( neighbour, "NEIGHBOUR %s %s %s is %s %s\n", netdev->name,
304
305 /* Mark discovery as complete */
307
308 /* Transmit any deferred packets */
310}
A link-layer protocol.
Definition netdevice.h:115
const char * name
Protocol name.
Definition netdevice.h:117
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition netdevice.h:164
uint8_t ll_addr_len
Link-layer address length.
Definition netdevice.h:199

References DBGC, neighbour::discovery, ll_protocol::ll_addr_len, neighbour::ll_dest, memcpy(), ll_protocol::name, net_protocol::name, neighbour_tx_queue(), neighbour::net_dest, neighbour::net_protocol, neighbour::netdev, netdev, ll_protocol::ntoa, net_protocol::ntoa, and NULL.

Referenced by neighbour_define(), and neighbour_update().

◆ neighbour_destroy()

void neighbour_destroy ( struct neighbour * neighbour,
int rc )
static

Destroy neighbour cache entry.

Parameters
neighbourNeighbour cache entry
rcReason for destruction

Definition at line 318 of file neighbour.c.

318 {
321
322 /* Take ownership from cache */
323 list_del ( &neighbour->list );
324
325 /* Stop timer */
327
328 /* Drop any deferred packets */
329 while ( neighbour_drop ( neighbour, rc ) ) {}
331
332 /* Drop remaining reference */
333 DBGC ( neighbour, "NEIGHBOUR %s %s %s destroyed: %s\n", netdev->name,
335 strerror ( rc ) );
337}
static unsigned int neighbour_drop(struct neighbour *neighbour, int rc)
Drop a deferred packet.
Definition neighbour.c:264

References assert, DBGC, neighbour::list, list_del, list_empty, net_protocol::name, neighbour_drop(), neighbour::net_dest, neighbour::net_protocol, neighbour::netdev, netdev, net_protocol::ntoa, rc, ref_put, neighbour::refcnt, stop_timer(), strerror(), neighbour::timer, and neighbour::tx_queue.

Referenced by neighbour_discard(), neighbour_expired(), and neighbour_flush().

◆ neighbour_tx()

int neighbour_tx ( struct io_buffer * iobuf,
struct net_device * netdev,
struct net_protocol * net_protocol,
const void * net_dest,
struct neighbour_discovery * discovery,
const void * net_source )

Transmit packet, determining link-layer address via neighbour discovery.

Parameters
iobufI/O buffer
netdevNetwork device
discoveryNeighbour discovery protocol
net_protocolNetwork-layer protocol
net_destDestination network-layer address
net_sourceSource network-layer address
Return values
rcReturn status code

Definition at line 396 of file neighbour.c.

399 {
400 struct neighbour *neighbour;
401 struct neighbour_delay *delay;
402 int rc;
403
404 /* Find or create neighbour cache entry */
406 if ( ! neighbour ) {
408 if ( ! neighbour )
409 return -ENOMEM;
410 neighbour_discover ( neighbour, discovery, net_source );
411 }
412
413 /* If discovery is still in progress or if delay injection is
414 * in use, then queue for later transmission.
415 */
417
418 /* Add to deferred packet queue */
419 DBGC2 ( neighbour, "NEIGHBOUR %s %s %s deferring packet\n",
420 netdev->name, net_protocol->name,
421 net_protocol->ntoa ( net_dest ) );
422 list_add_tail ( &iobuf->list, &neighbour->tx_queue );
423
424 /* Handle delay injection, if applicable */
425 if ( NEIGHBOUR_DELAY_MS ) {
426
427 /* Record original transmission time */
428 delay = iob_push ( iobuf, sizeof ( *delay ) );
429 delay->start = currticks();
430
431 /* Add pending operation */
433
434 /* Process deferred packet queue, if possible */
435 if ( ! neighbour->discovery )
437 }
438
439 return 0;
440 }
441
442 /* Otherwise, transmit immediately */
443 if ( ( rc = net_tx ( iobuf, netdev, net_protocol, neighbour->ll_dest,
444 netdev->ll_addr ) ) != 0 ) {
445 return rc;
446 }
447
448 return 0;
449}
#define ENOMEM
Not enough space.
Definition errno.h:535
#define iob_push(iobuf, len)
Definition iobuf.h:89
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
static struct neighbour * neighbour_create(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest)
Create neighbour cache entry.
Definition neighbour.c:101
static struct neighbour * neighbour_find(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest)
Find neighbour cache entry.
Definition neighbour.c:136
static void neighbour_discover(struct neighbour *neighbour, struct neighbour_discovery *discovery, const void *net_source)
Start neighbour discovery.
Definition neighbour.c:164
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition pending.c:46

References currticks(), DBGC2, delay, neighbour::discovery, ENOMEM, iob_push, io_buffer::list, list_add_tail, neighbour::ll_dest, net_protocol::name, neighbour_create(), NEIGHBOUR_DELAY_MS, neighbour_delayed, neighbour_discover(), neighbour_find(), neighbour_tx_queue(), net_tx(), netdev, net_protocol::ntoa, pending_get(), rc, and neighbour::tx_queue.

Referenced by arp_tx(), and ndp_tx().

◆ neighbour_update()

int neighbour_update ( struct net_device * netdev,
struct net_protocol * net_protocol,
const void * net_dest,
const void * ll_dest )

Update existing neighbour cache entry.

Parameters
netdevNetwork device
net_protocolNetwork-layer protocol
net_destDestination network-layer address
ll_destDestination link-layer address
Return values
rcReturn status code

Definition at line 460 of file neighbour.c.

462 {
463 struct neighbour *neighbour;
464
465 /* Find neighbour cache entry */
467 if ( ! neighbour )
468 return -ENOENT;
469
470 /* Set destination address */
472
473 return 0;
474}
#define ENOENT
No such file or directory.
Definition errno.h:515
static void neighbour_discovered(struct neighbour *neighbour, const void *ll_dest)
Complete neighbour discovery.
Definition neighbour.c:293

References ENOENT, neighbour::ll_dest, neighbour_discovered(), neighbour_find(), neighbour::net_dest, and netdev.

Referenced by arp_rx(), and ndp_rx_neighbour_advertisement_ll_target().

◆ neighbour_define()

int neighbour_define ( struct net_device * netdev,
struct net_protocol * net_protocol,
const void * net_dest,
const void * ll_dest )

Define neighbour cache entry.

Parameters
netdevNetwork device
net_protocolNetwork-layer protocol
net_destDestination network-layer address
ll_destDestination link-layer address, if known
Return values
rcReturn status code

Definition at line 485 of file neighbour.c.

487 {
488 struct neighbour *neighbour;
489
490 /* Find or create neighbour cache entry */
492 if ( ! neighbour ) {
494 if ( ! neighbour )
495 return -ENOMEM;
496 }
497
498 /* Set destination address */
500
501 return 0;
502}

References ENOMEM, neighbour::ll_dest, neighbour_create(), neighbour_discovered(), neighbour_find(), neighbour::net_dest, and netdev.

Referenced by ndp_rx_neighbour_solicitation_ll_source(), and ndp_rx_router_advertisement_ll_source().

◆ neighbour_flush()

void neighbour_flush ( struct net_device * netdev,
void *priv __unused )
static

Update neighbour cache on network device state change or removal.

Parameters
netdevNetwork device
privPrivate data

Definition at line 510 of file neighbour.c.

510 {
511 struct neighbour *neighbour;
512 struct neighbour *tmp;
513
514 /* Remove all neighbour cache entries when a network device is closed */
515 if ( ! netdev_is_open ( netdev ) ) {
518 }
519}
#define ENODEV
No such device.
Definition errno.h:510
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:665

References __unused, ENODEV, neighbour::list, list_for_each_entry_safe, neighbour_destroy(), neighbours, netdev, netdev_is_open(), priv, and tmp.

◆ neighbour_queue_discard()

unsigned int neighbour_queue_discard ( void )
static

Discard some deferred packets from neighbour cache entries.

Return values
discardedNumber of cached items discarded

Definition at line 533 of file neighbour.c.

533 {
534 struct neighbour *neighbour;
535 unsigned int discarded = 0;
536
537 /* Try to discard one deferred packet from each cache entry */
539 discarded += neighbour_drop ( neighbour, -ENOBUFS );
540
541 return discarded;
542}
#define ENOBUFS
No buffer space available.
Definition errno.h:499

References ENOBUFS, neighbour::list, list_for_each_entry, neighbour_drop(), and neighbours.

Referenced by __cache_discarder().

◆ __cache_discarder() [1/2]

struct cache_discarder neighbour_queue_discarder __cache_discarder ( CACHE_NORMAL )

Neighbour cache deferred packet discarder.

References __cache_discarder, CACHE_NORMAL, and neighbour_queue_discard().

◆ neighbour_discard()

unsigned int neighbour_discard ( void )
static

Discard some complete neighbour cache entries.

Return values
discardedNumber of cached items discarded

Definition at line 555 of file neighbour.c.

555 {
556 struct neighbour *neighbour;
557
558 /* Identify oldest cache entry, if any */
560 if ( ! neighbour )
561 return 0;
562
563 /* Sanity check: all deferred packets must already have been dropped */
565
566 /* Destroy the cache entry */
568
569 return 1;
570}
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition list.h:347

References assert, ENOBUFS, neighbour::list, list_empty, list_last_entry, neighbour_destroy(), neighbours, and neighbour::tx_queue.

Referenced by __cache_discarder().

◆ __cache_discarder() [2/2]

struct cache_discarder neighbour_discarder __cache_discarder ( CACHE_EXPENSIVE )

Neighbour cache discarder.

Neighbour cache entries are deemed to have a high replacement cost, since flushing an active neighbour cache entry midway through a TCP transfer will cause substantial disruption.

References __cache_discarder, CACHE_EXPENSIVE, and neighbour_discard().

Variable Documentation

◆ neighbours

struct list_head neighbours = LIST_HEAD_INIT ( neighbours )

The neighbour cache.

Definition at line 67 of file neighbour.c.

Referenced by neighbour_create(), neighbour_discard(), neighbour_find(), neighbour_flush(), neighbour_queue_discard(), and nstat().

◆ neighbour_delayed

struct pending_operation neighbour_delayed
static

Pending operation for delayed transmissions.

Definition at line 70 of file neighbour.c.

Referenced by neighbour_drop(), neighbour_tx(), and neighbour_tx_queue().

◆ __net_driver

struct net_driver neighbour_net_driver __net_driver
Initial value:
= {
.name = "Neighbour",
.notify = neighbour_flush,
.remove = neighbour_flush,
}
static void neighbour_flush(struct net_device *netdev, void *priv __unused)
Update neighbour cache on network device state change or removal.
Definition neighbour.c:510

Neighbour driver (for net device notifications).

Definition at line 522 of file neighbour.c.

522 {
523 .name = "Neighbour",
524 .notify = neighbour_flush,
525 .remove = neighbour_flush,
526};