iPXE
neighbour.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <ipxe/iobuf.h>
32 #include <ipxe/retry.h>
33 #include <ipxe/timer.h>
34 #include <ipxe/malloc.h>
35 #include <ipxe/pending.h>
36 #include <ipxe/neighbour.h>
37 #include <config/fault.h>
38 
39 /** @file
40  *
41  * Neighbour discovery
42  *
43  * This file implements the abstract functions of neighbour discovery,
44  * independent of the underlying network protocol (e.g. ARP or NDP).
45  *
46  */
47 
48 /** Neighbour discovery minimum timeout */
49 #define NEIGHBOUR_MIN_TIMEOUT ( TICKS_PER_SEC / 8 )
50 
51 /** Neighbour discovery maximum timeout */
52 #define NEIGHBOUR_MAX_TIMEOUT ( TICKS_PER_SEC * 3 )
53 
54 /** Neighbour discovery maximum burst count for delayed transmissions
55  *
56  * When using delay injection, timer quantisation can cause a large
57  * number of delayed packets to be scheduled at the same time. This
58  * can quickly exhaust available transmit descriptors, leading to
59  * packets that are dropped completely (not just delayed).
60  *
61  * Limit the number of delayed packets that we will attempt to
62  * transmit at once, to allow time for transmit completions to occur.
63  */
64 #define NEIGHBOUR_DELAY_MAX_BURST 2
65 
66 /** The neighbour cache */
68 
69 /** Pending operation for delayed transmissions */
71 
72 static void neighbour_expired ( struct retry_timer *timer, int over );
73 
74 /**
75  * Free neighbour cache entry
76  *
77  * @v refcnt Reference count
78  */
79 static void neighbour_free ( struct refcnt *refcnt ) {
80  struct neighbour *neighbour =
81  container_of ( refcnt, struct neighbour, refcnt );
82 
83  /* Sanity check */
85 
86  /* Drop reference to network device */
88 
89  /* Free neighbour */
90  free ( neighbour );
91 }
92 
93 /**
94  * Create neighbour cache entry
95  *
96  * @v netdev Network device
97  * @v net_protocol Network-layer protocol
98  * @v net_dest Destination network-layer address
99  * @ret neighbour Neighbour cache entry, or NULL if allocation failed
100  */
101 static struct neighbour * neighbour_create ( struct net_device *netdev,
102  struct net_protocol *net_protocol,
103  const void *net_dest ) {
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 }
127 
128 /**
129  * Find neighbour cache entry
130  *
131  * @v netdev Network device
132  * @v net_protocol Network-layer protocol
133  * @v net_dest Destination network-layer address
134  * @ret neighbour Neighbour cache entry, or NULL if not found
135  */
136 static struct neighbour * neighbour_find ( struct net_device *netdev,
137  struct net_protocol *net_protocol,
138  const void *net_dest ) {
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 }
156 
157 /**
158  * Start neighbour discovery
159  *
160  * @v neighbour Neighbour cache entry
161  * @v discovery Neighbour discovery protocol
162  * @v net_source Source network-layer address
163  */
164 static void neighbour_discover ( struct neighbour *neighbour,
166  const void *net_source ) {
167  struct net_device *netdev = neighbour->netdev;
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",
182 }
183 
184 /**
185  * Transmit deferred packets
186  *
187  * @v neighbour Neighbour cache entry
188  */
189 static void neighbour_tx_queue ( struct neighbour *neighbour ) {
190  struct net_device *netdev = neighbour->netdev;
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 */
201  stop_timer ( &neighbour->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  */
207  ref_get ( &neighbour->refcnt );
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",
250  strerror ( rc ) );
251  /* Ignore error and continue */
252  }
253  }
254  ref_put ( &neighbour->refcnt );
255 }
256 
257 /**
258  * Complete neighbour discovery
259  *
260  * @v neighbour Neighbour cache entry
261  * @v ll_dest Destination link-layer address
262  */
264  const void *ll_dest ) {
265  struct net_device *netdev = neighbour->netdev;
268 
269  /* Fill in link-layer address */
271  DBGC ( neighbour, "NEIGHBOUR %s %s %s is %s %s\n", netdev->name,
274 
275  /* Mark discovery as complete */
277 
278  /* Transmit any deferred packets */
280 }
281 
282 /**
283  * Destroy neighbour cache entry
284  *
285  * @v neighbour Neighbour cache entry
286  * @v rc Reason for destruction
287  */
288 static void neighbour_destroy ( struct neighbour *neighbour, int rc ) {
289  struct net_device *netdev = neighbour->netdev;
291  struct io_buffer *iobuf;
292 
293  /* Take ownership from cache */
294  list_del ( &neighbour->list );
295 
296  /* Stop timer */
297  stop_timer ( &neighbour->timer );
298 
299  /* Discard any outstanding I/O buffers */
300  while ( ( iobuf = list_first_entry ( &neighbour->tx_queue,
301  struct io_buffer, list )) != NULL){
302  DBGC2 ( neighbour, "NEIGHBOUR %s %s %s discarding deferred "
303  "packet: %s\n", netdev->name, net_protocol->name,
305  strerror ( rc ) );
306  list_del ( &iobuf->list );
307  if ( NEIGHBOUR_DELAY_MS )
309  netdev_tx_err ( neighbour->netdev, iobuf, rc );
310  }
311 
312  DBGC ( neighbour, "NEIGHBOUR %s %s %s destroyed: %s\n", netdev->name,
314  strerror ( rc ) );
315 
316  /* Drop remaining reference */
317  ref_put ( &neighbour->refcnt );
318 }
319 
320 /**
321  * Handle neighbour timer expiry
322  *
323  * @v timer Retry timer
324  * @v fail Failure indicator
325  */
326 static void neighbour_expired ( struct retry_timer *timer, int fail ) {
327  struct neighbour *neighbour =
328  container_of ( timer, struct neighbour, timer );
329  struct net_device *netdev = neighbour->netdev;
331  struct neighbour_discovery *discovery =
333  const void *net_dest = neighbour->net_dest;
334  const void *net_source = neighbour->net_source;
335  int rc;
336 
337  /* If the timer is being (ab)used for delay injection, then
338  * transmit the deferred packet queue.
339  */
340  if ( NEIGHBOUR_DELAY_MS && ( ! neighbour->discovery ) ) {
342  return;
343  }
344 
345  /* If we have failed, destroy the cache entry */
346  if ( fail ) {
348  return;
349  }
350 
351  /* Restart the timer */
353 
354  /* Transmit neighbour request */
355  if ( ( rc = discovery->tx_request ( netdev, net_protocol, net_dest,
356  net_source ) ) != 0 ) {
357  DBGC ( neighbour, "NEIGHBOUR %s %s %s could not transmit %s "
358  "request: %s\n", netdev->name, net_protocol->name,
361  /* Retransmit when timer expires */
362  return;
363  }
364 }
365 
366 /**
367  * Transmit packet, determining link-layer address via neighbour discovery
368  *
369  * @v iobuf I/O buffer
370  * @v netdev Network device
371  * @v discovery Neighbour discovery protocol
372  * @v net_protocol Network-layer protocol
373  * @v net_dest Destination network-layer address
374  * @v net_source Source network-layer address
375  * @ret rc Return status code
376  */
377 int neighbour_tx ( struct io_buffer *iobuf, struct net_device *netdev,
378  struct net_protocol *net_protocol, const void *net_dest,
379  struct neighbour_discovery *discovery,
380  const void *net_source ) {
381  struct neighbour *neighbour;
382  struct neighbour_delay *delay;
383  int rc;
384 
385  /* Find or create neighbour cache entry */
386  neighbour = neighbour_find ( netdev, net_protocol, net_dest );
387  if ( ! neighbour ) {
389  if ( ! neighbour )
390  return -ENOMEM;
391  neighbour_discover ( neighbour, discovery, net_source );
392  }
393 
394  /* If discovery is still in progress or if delay injection is
395  * in use, then queue for later transmission.
396  */
398 
399  /* Add to deferred packet queue */
400  DBGC2 ( neighbour, "NEIGHBOUR %s %s %s deferring packet\n",
402  net_protocol->ntoa ( net_dest ) );
403  list_add_tail ( &iobuf->list, &neighbour->tx_queue );
404 
405  /* Handle delay injection, if applicable */
406  if ( NEIGHBOUR_DELAY_MS ) {
407 
408  /* Record original transmission time */
409  delay = iob_push ( iobuf, sizeof ( *delay ) );
410  delay->start = currticks();
411 
412  /* Add pending operation */
414 
415  /* Process deferred packet queue, if possible */
416  if ( ! neighbour->discovery )
418  }
419 
420  return 0;
421  }
422 
423  /* Otherwise, transmit immediately */
424  if ( ( rc = net_tx ( iobuf, netdev, net_protocol, neighbour->ll_dest,
425  netdev->ll_addr ) ) != 0 ) {
426  return rc;
427  }
428 
429  return 0;
430 }
431 
432 /**
433  * Update existing neighbour cache entry
434  *
435  * @v netdev Network device
436  * @v net_protocol Network-layer protocol
437  * @v net_dest Destination network-layer address
438  * @v ll_dest Destination link-layer address
439  * @ret rc Return status code
440  */
442  struct net_protocol *net_protocol,
443  const void *net_dest, const void *ll_dest ) {
444  struct neighbour *neighbour;
445 
446  /* Find neighbour cache entry */
448  if ( ! neighbour )
449  return -ENOENT;
450 
451  /* Set destination address */
453 
454  return 0;
455 }
456 
457 /**
458  * Define neighbour cache entry
459  *
460  * @v netdev Network device
461  * @v net_protocol Network-layer protocol
462  * @v net_dest Destination network-layer address
463  * @v ll_dest Destination link-layer address, if known
464  * @ret rc Return status code
465  */
467  struct net_protocol *net_protocol,
468  const void *net_dest, const void *ll_dest ) {
469  struct neighbour *neighbour;
470 
471  /* Find or create neighbour cache entry */
473  if ( ! neighbour ) {
475  if ( ! neighbour )
476  return -ENOMEM;
477  }
478 
479  /* Set destination address */
481 
482  return 0;
483 }
484 
485 /**
486  * Update neighbour cache on network device state change or removal
487  *
488  * @v netdev Network device
489  * @v priv Private data
490  */
491 static void neighbour_flush ( struct net_device *netdev, void *priv __unused ) {
492  struct neighbour *neighbour;
493  struct neighbour *tmp;
494 
495  /* Remove all neighbour cache entries when a network device is closed */
496  if ( ! netdev_is_open ( netdev ) ) {
499  }
500 }
501 
502 /** Neighbour driver (for net device notifications) */
503 struct net_driver neighbour_net_driver __net_driver = {
504  .name = "Neighbour",
505  .notify = neighbour_flush,
506  .remove = neighbour_flush,
507 };
508 
509 /**
510  * Discard some cached neighbour entries
511  *
512  * @ret discarded Number of cached items discarded
513  */
514 static unsigned int neighbour_discard ( void ) {
515  struct neighbour *neighbour;
516 
517  /* Drop oldest cache entry, if any */
519  if ( neighbour ) {
521  return 1;
522  } else {
523  return 0;
524  }
525 }
526 
527 /**
528  * Neighbour cache discarder
529  *
530  * Neighbour cache entries are deemed to have a high replacement cost,
531  * since flushing an active neighbour cache entry midway through a TCP
532  * transfer will cause substantial disruption.
533  */
534 struct cache_discarder neighbour_discarder __cache_discarder (CACHE_EXPENSIVE)={
536 };
#define iob_pull(iobuf, len)
Definition: iobuf.h:107
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Protocol name.
Definition: netdevice.h:67
const char * name
Name.
Definition: neighbour.h:22
#define NEIGHBOUR_MIN_TIMEOUT
Neighbour discovery minimum timeout.
Definition: neighbour.c:49
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 start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:100
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
struct cache_discarder neighbour_discarder __cache_discarder(CACHE_EXPENSIVE)
Neighbour cache discarder.
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
uint8_t net_dest[MAX_NET_ADDR_LEN]
Network-layer destination address.
Definition: neighbour.h:49
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:70
void netdev_tx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard transmitted packet.
Definition: netdevice.c:441
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
Error codes.
#define iob_push(iobuf, len)
Definition: iobuf.h:89
I/O buffers.
struct net_protocol * net_protocol
Network-layer protocol.
Definition: neighbour.h:47
Retry timers.
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition: pending.c:59
#define DBGC(...)
Definition: compiler.h:505
struct list_head neighbours
The neighbour cache.
Definition: neighbour.c:67
struct retry_timer timer
Retransmission timer.
Definition: neighbour.h:58
A retry timer.
Definition: retry.h:22
A neighbour discovery protocol.
Definition: neighbour.h:20
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define NEIGHBOUR_DELAY_MAX_BURST
Neighbour discovery maximum burst count for delayed transmissions.
Definition: neighbour.c:64
iPXE timers
Fault injection.
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.
Definition: neighbour.c:441
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:347
A network upper-layer driver.
Definition: netdevice.h:477
A link-layer protocol.
Definition: netdevice.h:115
A doubly-linked list entry (or list head)
Definition: list.h:19
Dynamic memory allocation.
A reference counter.
Definition: refcnt.h:27
A timer.
Definition: timer.h:29
struct refcnt refcnt
Reference count.
Definition: neighbour.h:40
struct list_head list
List of neighbour cache entries.
Definition: neighbour.h:42
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
unsigned long tmp
Definition: linux_pci.h:65
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:334
const char * name
Protocol name.
Definition: netdevice.h:117
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
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
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
const char * name
Name.
Definition: netdevice.h:479
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:662
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:576
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
#define CACHE_EXPENSIVE
Items with a high replacement cost.
Definition: malloc.h:115
unsigned int(* discard)(void)
Discard some cached data.
Definition: malloc.h:99
FILE_SECBOOT(PERMITTED)
struct neighbour_discovery * discovery
Neighbour discovery protocol (if discovery is ongoing)
Definition: neighbour.h:54
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:94
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition: netdevice.h:95
int neighbour_define(struct net_device *netdev, struct net_protocol *net_protocol, const void *net_dest, const void *ll_dest)
Define neighbour cache entry.
Definition: neighbour.c:466
static struct net_device * netdev
Definition: gdbudp.c:53
static unsigned int count
Number of entries.
Definition: dwmac.h:225
struct net_driver neighbour_net_driver __net_driver
Neighbour driver (for net device notifications)
Definition: neighbour.c:503
struct list_head tx_queue
Pending I/O buffers.
Definition: neighbour.h:61
static unsigned int neighbour_discard(void)
Discard some cached neighbour entries.
Definition: neighbour.c:514
uint8_t ll_dest[MAX_LL_ADDR_LEN]
Link-layer destination address.
Definition: neighbour.h:51
#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
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:93
#define NEIGHBOUR_DELAY_MS
Definition: fault.h:19
A network device.
Definition: netdevice.h:353
#define ENODEV
No such device.
Definition: errno.h:510
A cache discarder.
Definition: malloc.h:93
static void neighbour_discovered(struct neighbour *neighbour, const void *ll_dest)
Complete neighbour discovery.
Definition: neighbour.c:263
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:565
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
A neighbour cache entry.
Definition: neighbour.h:38
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:94
A network-layer protocol.
Definition: netdevice.h:65
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:65
Pending operations.
static void neighbour_flush(struct net_device *netdev, void *priv __unused)
Update neighbour cache on network device state change or removal.
Definition: neighbour.c:491
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:118
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:45
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:1074
#define NEIGHBOUR_MAX_TIMEOUT
Neighbour discovery maximum timeout.
Definition: neighbour.c:52
#define ENOBUFS
No buffer space available.
Definition: errno.h:499
#define DBGC2(...)
Definition: compiler.h:522
static struct tlan_private * priv
Definition: tlan.c:225
uint8_t net_addr_len
Network-layer address length.
Definition: netdevice.h:102
uint16_t delay
Forward delay.
Definition: stp.h:41
Neighbour discovery.
void * data
Start of data.
Definition: iobuf.h:53
static void neighbour_expired(struct retry_timer *timer, int over)
Handle neighbour timer expiry.
Definition: neighbour.c:326
struct net_device * netdev
Network device.
Definition: neighbour.h:45
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.
Definition: neighbour.c:377
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:164
A pending operation.
Definition: pending.h:14
static struct pending_operation neighbour_delayed
Pending operation for delayed transmissions.
Definition: neighbour.c:70
static void neighbour_destroy(struct neighbour *neighbour, int rc)
Destroy neighbour cache entry.
Definition: neighbour.c:288
static void neighbour_free(struct refcnt *refcnt)
Free neighbour cache entry.
Definition: neighbour.c:79
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:388
A neighbour transmission delay pseudo-header.
Definition: neighbour.h:65
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:43
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:31
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670
String functions.
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition: pending.c:46
#define TICKS_PER_MS
Number of ticks per millisecond.
Definition: timer.h:26
uint8_t net_source[MAX_NET_ADDR_LEN]
Network-layer source address (for discovery requests)
Definition: neighbour.h:56
static void neighbour_tx_queue(struct neighbour *neighbour)
Transmit deferred packets.
Definition: neighbour.c:189
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
static void neighbour_discover(struct neighbour *neighbour, struct neighbour_discovery *discovery, const void *net_source)
Start neighbour discovery.
Definition: neighbour.c:164
A persistent I/O buffer.
Definition: iobuf.h:38