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 
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <ipxe/iobuf.h>
31 #include <ipxe/retry.h>
32 #include <ipxe/timer.h>
33 #include <ipxe/malloc.h>
34 #include <ipxe/neighbour.h>
35 #include <config/fault.h>
36 
37 /** @file
38  *
39  * Neighbour discovery
40  *
41  * This file implements the abstract functions of neighbour discovery,
42  * independent of the underlying network protocol (e.g. ARP or NDP).
43  *
44  */
45 
46 /** Neighbour discovery minimum timeout */
47 #define NEIGHBOUR_MIN_TIMEOUT ( TICKS_PER_SEC / 8 )
48 
49 /** Neighbour discovery maximum timeout */
50 #define NEIGHBOUR_MAX_TIMEOUT ( TICKS_PER_SEC * 3 )
51 
52 /** Neighbour discovery maximum burst count for delayed transmissions
53  *
54  * When using delay injection, timer quantisation can cause a large
55  * number of delayed packets to be scheduled at the same time. This
56  * can quickly exhaust available transmit descriptors, leading to
57  * packets that are dropped completely (not just delayed).
58  *
59  * Limit the number of delayed packets that we will attempt to
60  * transmit at once, to allow time for transmit completions to occur.
61  */
62 #define NEIGHBOUR_DELAY_MAX_BURST 2
63 
64 /** The neighbour cache */
66 
67 static void neighbour_expired ( struct retry_timer *timer, int over );
68 
69 /**
70  * Free neighbour cache entry
71  *
72  * @v refcnt Reference count
73  */
74 static void neighbour_free ( struct refcnt *refcnt ) {
75  struct neighbour *neighbour =
76  container_of ( refcnt, struct neighbour, refcnt );
77 
78  /* Sanity check */
80 
81  /* Drop reference to network device */
83 
84  /* Free neighbour */
85  free ( neighbour );
86 }
87 
88 /**
89  * Create neighbour cache entry
90  *
91  * @v netdev Network device
92  * @v net_protocol Network-layer protocol
93  * @v net_dest Destination network-layer address
94  * @ret neighbour Neighbour cache entry, or NULL if allocation failed
95  */
96 static struct neighbour * neighbour_create ( struct net_device *netdev,
97  struct net_protocol *net_protocol,
98  const void *net_dest ) {
99  struct neighbour *neighbour;
100 
101  /* Allocate and initialise entry */
102  neighbour = zalloc ( sizeof ( *neighbour ) );
103  if ( ! neighbour )
104  return NULL;
110  timer_init ( &neighbour->timer, neighbour_expired, &neighbour->refcnt );
111  set_timer_limits ( &neighbour->timer, NEIGHBOUR_MIN_TIMEOUT,
114 
115  /* Transfer ownership to cache */
117 
118  DBGC ( neighbour, "NEIGHBOUR %s %s %s created\n", netdev->name,
120  return neighbour;
121 }
122 
123 /**
124  * Find neighbour cache entry
125  *
126  * @v netdev Network device
127  * @v net_protocol Network-layer protocol
128  * @v net_dest Destination network-layer address
129  * @ret neighbour Neighbour cache entry, or NULL if not found
130  */
131 static struct neighbour * neighbour_find ( struct net_device *netdev,
132  struct net_protocol *net_protocol,
133  const void *net_dest ) {
134  struct neighbour *neighbour;
135 
137  if ( ( neighbour->netdev == netdev ) &&
140  net_protocol->net_addr_len ) == 0 ) ) {
141 
142  /* Move to start of cache */
143  list_del ( &neighbour->list );
145 
146  return neighbour;
147  }
148  }
149  return NULL;
150 }
151 
152 /**
153  * Start neighbour discovery
154  *
155  * @v neighbour Neighbour cache entry
156  * @v discovery Neighbour discovery protocol
157  * @v net_source Source network-layer address
158  */
159 static void neighbour_discover ( struct neighbour *neighbour,
161  const void *net_source ) {
162  struct net_device *netdev = neighbour->netdev;
164 
165  /* Record discovery protocol and source network-layer address */
166  neighbour->discovery = discovery;
167  memcpy ( neighbour->net_source, net_source,
169 
170  /* Start timer to trigger neighbour discovery */
172 
173  DBGC ( neighbour, "NEIGHBOUR %s %s %s discovering via %s\n",
177 }
178 
179 /**
180  * Transmit deferred packets
181  *
182  * @v neighbour Neighbour cache entry
183  */
184 static void neighbour_tx_queue ( struct neighbour *neighbour ) {
185  struct net_device *netdev = neighbour->netdev;
187  const void *ll_dest = neighbour->ll_dest;
188  struct neighbour_delay *delay;
189  struct io_buffer *iobuf;
190  unsigned long elapsed;
191  unsigned long threshold;
192  unsigned int count = 0;
193  int rc;
194 
195  /* Stop retransmission timer */
196  stop_timer ( &neighbour->timer );
197 
198  /* Transmit any packets in queue. Take out a temporary
199  * reference on the entry to prevent it from going out of
200  * scope during the call to net_tx().
201  */
202  ref_get ( &neighbour->refcnt );
203  while ( ( iobuf = list_first_entry ( &neighbour->tx_queue,
204  struct io_buffer, list )) != NULL){
205 
206  /* Handle delay injection */
207  if ( NEIGHBOUR_DELAY_MS ) {
208 
209  /* Determine elapsed time since transmission attempt */
210  delay = iobuf->data;
211  elapsed = ( currticks() - delay->start );
212  threshold = ( NEIGHBOUR_DELAY_MS * TICKS_PER_MS );
213 
214  /* Defer transmission if not yet scheduled */
215  if ( elapsed < threshold ) {
217  ( threshold - elapsed ) );
218  break;
219  }
220 
221  /* Defer transmission if maximum burst count reached */
222  if ( ++count >= NEIGHBOUR_DELAY_MAX_BURST ) {
224  break;
225  }
226 
227  /* Strip pseudo-header */
228  iob_pull ( iobuf, sizeof ( *delay ) );
229  }
230 
231  /* Transmit deferred packet */
232  DBGC2 ( neighbour, "NEIGHBOUR %s %s %s transmitting deferred "
233  "packet\n", netdev->name, net_protocol->name,
235  list_del ( &iobuf->list );
236  if ( ( rc = net_tx ( iobuf, netdev, net_protocol, ll_dest,
237  netdev->ll_addr ) ) != 0 ) {
238  DBGC ( neighbour, "NEIGHBOUR %s %s %s could not "
239  "transmit deferred packet: %s\n",
242  strerror ( rc ) );
243  /* Ignore error and continue */
244  }
245  }
246  ref_put ( &neighbour->refcnt );
247 }
248 
249 /**
250  * Complete neighbour discovery
251  *
252  * @v neighbour Neighbour cache entry
253  * @v ll_dest Destination link-layer address
254  */
256  const void *ll_dest ) {
257  struct net_device *netdev = neighbour->netdev;
260 
261  /* Fill in link-layer address */
263  DBGC ( neighbour, "NEIGHBOUR %s %s %s is %s %s\n", netdev->name,
266 
267  /* Mark discovery as complete */
269 
270  /* Transmit any deferred packets */
272 }
273 
274 /**
275  * Destroy neighbour cache entry
276  *
277  * @v neighbour Neighbour cache entry
278  * @v rc Reason for destruction
279  */
280 static void neighbour_destroy ( struct neighbour *neighbour, int rc ) {
281  struct net_device *netdev = neighbour->netdev;
283  struct io_buffer *iobuf;
284 
285  /* Take ownership from cache */
286  list_del ( &neighbour->list );
287 
288  /* Stop timer */
289  stop_timer ( &neighbour->timer );
290 
291  /* Discard any outstanding I/O buffers */
292  while ( ( iobuf = list_first_entry ( &neighbour->tx_queue,
293  struct io_buffer, list )) != NULL){
294  DBGC2 ( neighbour, "NEIGHBOUR %s %s %s discarding deferred "
295  "packet: %s\n", netdev->name, net_protocol->name,
297  strerror ( rc ) );
298  list_del ( &iobuf->list );
299  netdev_tx_err ( neighbour->netdev, iobuf, rc );
300  }
301 
302  DBGC ( neighbour, "NEIGHBOUR %s %s %s destroyed: %s\n", netdev->name,
304  strerror ( rc ) );
305 
306  /* Drop remaining reference */
307  ref_put ( &neighbour->refcnt );
308 }
309 
310 /**
311  * Handle neighbour timer expiry
312  *
313  * @v timer Retry timer
314  * @v fail Failure indicator
315  */
316 static void neighbour_expired ( struct retry_timer *timer, int fail ) {
317  struct neighbour *neighbour =
318  container_of ( timer, struct neighbour, timer );
319  struct net_device *netdev = neighbour->netdev;
321  struct neighbour_discovery *discovery =
323  const void *net_dest = neighbour->net_dest;
324  const void *net_source = neighbour->net_source;
325  int rc;
326 
327  /* If the timer is being (ab)used for delay injection, then
328  * transmit the deferred packet queue.
329  */
330  if ( NEIGHBOUR_DELAY_MS && ( ! neighbour->discovery ) ) {
332  return;
333  }
334 
335  /* If we have failed, destroy the cache entry */
336  if ( fail ) {
338  return;
339  }
340 
341  /* Restart the timer */
343 
344  /* Transmit neighbour request */
345  if ( ( rc = discovery->tx_request ( netdev, net_protocol, net_dest,
346  net_source ) ) != 0 ) {
347  DBGC ( neighbour, "NEIGHBOUR %s %s %s could not transmit %s "
348  "request: %s\n", netdev->name, net_protocol->name,
351  /* Retransmit when timer expires */
352  return;
353  }
354 }
355 
356 /**
357  * Transmit packet, determining link-layer address via neighbour discovery
358  *
359  * @v iobuf I/O buffer
360  * @v netdev Network device
361  * @v discovery Neighbour discovery protocol
362  * @v net_protocol Network-layer protocol
363  * @v net_dest Destination network-layer address
364  * @v net_source Source network-layer address
365  * @ret rc Return status code
366  */
367 int neighbour_tx ( struct io_buffer *iobuf, struct net_device *netdev,
368  struct net_protocol *net_protocol, const void *net_dest,
369  struct neighbour_discovery *discovery,
370  const void *net_source ) {
371  struct neighbour *neighbour;
372  struct neighbour_delay *delay;
373  int rc;
374 
375  /* Find or create neighbour cache entry */
376  neighbour = neighbour_find ( netdev, net_protocol, net_dest );
377  if ( ! neighbour ) {
379  if ( ! neighbour )
380  return -ENOMEM;
381  neighbour_discover ( neighbour, discovery, net_source );
382  }
383 
384  /* If discovery is still in progress or if delay injection is
385  * in use, then queue for later transmission.
386  */
388 
389  /* Add to deferred packet queue */
390  DBGC2 ( neighbour, "NEIGHBOUR %s %s %s deferring packet\n",
392  net_protocol->ntoa ( net_dest ) );
393  list_add_tail ( &iobuf->list, &neighbour->tx_queue );
394 
395  /* Handle delay injection, if applicable */
396  if ( NEIGHBOUR_DELAY_MS ) {
397 
398  /* Record original transmission time */
399  delay = iob_push ( iobuf, sizeof ( *delay ) );
400  delay->start = currticks();
401 
402  /* Process deferred packet queue, if possible */
403  if ( ! neighbour->discovery )
405  }
406 
407  return 0;
408  }
409 
410  /* Otherwise, transmit immediately */
411  if ( ( rc = net_tx ( iobuf, netdev, net_protocol, neighbour->ll_dest,
412  netdev->ll_addr ) ) != 0 ) {
413  return rc;
414  }
415 
416  return 0;
417 }
418 
419 /**
420  * Update existing neighbour cache entry
421  *
422  * @v netdev Network device
423  * @v net_protocol Network-layer protocol
424  * @v net_dest Destination network-layer address
425  * @v ll_dest Destination link-layer address
426  * @ret rc Return status code
427  */
429  struct net_protocol *net_protocol,
430  const void *net_dest, const void *ll_dest ) {
431  struct neighbour *neighbour;
432 
433  /* Find neighbour cache entry */
435  if ( ! neighbour )
436  return -ENOENT;
437 
438  /* Set destination address */
440 
441  return 0;
442 }
443 
444 /**
445  * Define neighbour cache entry
446  *
447  * @v netdev Network device
448  * @v net_protocol Network-layer protocol
449  * @v net_dest Destination network-layer address
450  * @v ll_dest Destination link-layer address, if known
451  * @ret rc Return status code
452  */
454  struct net_protocol *net_protocol,
455  const void *net_dest, const void *ll_dest ) {
456  struct neighbour *neighbour;
457 
458  /* Find or create neighbour cache entry */
460  if ( ! neighbour ) {
462  if ( ! neighbour )
463  return -ENOMEM;
464  }
465 
466  /* Set destination address */
468 
469  return 0;
470 }
471 
472 /**
473  * Update neighbour cache on network device state change or removal
474  *
475  * @v netdev Network device
476  * @v priv Private data
477  */
478 static void neighbour_flush ( struct net_device *netdev, void *priv __unused ) {
479  struct neighbour *neighbour;
480  struct neighbour *tmp;
481 
482  /* Remove all neighbour cache entries when a network device is closed */
483  if ( ! netdev_is_open ( netdev ) ) {
486  }
487 }
488 
489 /** Neighbour driver (for net device notifications) */
490 struct net_driver neighbour_net_driver __net_driver = {
491  .name = "Neighbour",
492  .notify = neighbour_flush,
493  .remove = neighbour_flush,
494 };
495 
496 /**
497  * Discard some cached neighbour entries
498  *
499  * @ret discarded Number of cached items discarded
500  */
501 static unsigned int neighbour_discard ( void ) {
502  struct neighbour *neighbour;
503 
504  /* Drop oldest cache entry, if any */
506  if ( neighbour ) {
508  return 1;
509  } else {
510  return 0;
511  }
512 }
513 
514 /**
515  * Neighbour cache discarder
516  *
517  * Neighbour cache entries are deemed to have a high replacement cost,
518  * since flushing an active neighbour cache entry midway through a TCP
519  * transfer will cause substantial disruption.
520  */
521 struct cache_discarder neighbour_discarder __cache_discarder (CACHE_EXPENSIVE)={
523 };
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Protocol name.
Definition: netdevice.h:66
const char * name
Name.
Definition: neighbour.h:21
#define NEIGHBOUR_MIN_TIMEOUT
Neighbour discovery minimum timeout.
Definition: neighbour.c:47
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:131
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition: retry.h:99
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
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:96
uint8_t net_dest[MAX_NET_ADDR_LEN]
Network-layer destination address.
Definition: neighbour.h:48
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
void netdev_tx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard transmitted packet.
Definition: netdevice.c:440
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
Error codes.
#define iob_push(iobuf, len)
Definition: iobuf.h:88
I/O buffers.
struct net_protocol * net_protocol
Network-layer protocol.
Definition: neighbour.h:46
Retry timers.
#define DBGC(...)
Definition: compiler.h:505
struct list_head neighbours
The neighbour cache.
Definition: neighbour.c:65
struct retry_timer timer
Retransmission timer.
Definition: neighbour.h:57
A retry timer.
Definition: retry.h:21
A neighbour discovery protocol.
Definition: neighbour.h:19
#define ENOENT
No such file or directory.
Definition: errno.h:514
#define NEIGHBOUR_DELAY_MAX_BURST
Neighbour discovery maximum burst count for delayed transmissions.
Definition: neighbour.c:62
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:428
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition: list.h:346
A network upper-layer driver.
Definition: netdevice.h:476
A link-layer protocol.
Definition: netdevice.h:114
A doubly-linked list entry (or list head)
Definition: list.h:18
Dynamic memory allocation.
A reference counter.
Definition: refcnt.h:26
A timer.
Definition: timer.h:28
struct refcnt refcnt
Reference count.
Definition: neighbour.h:39
struct list_head list
List of neighbour cache entries.
Definition: neighbour.h:41
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:64
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
const char * name
Protocol name.
Definition: netdevice.h:116
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
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:31
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
const char * name
Name.
Definition: netdevice.h:478
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:661
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:575
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define CACHE_EXPENSIVE
Items with a high replacement cost.
Definition: malloc.h:114
unsigned int(* discard)(void)
Discard some cached data.
Definition: malloc.h:98
struct neighbour_discovery * discovery
Neighbour discovery protocol (if discovery is ongoing)
Definition: neighbour.h:53
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
#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:93
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition: netdevice.h:94
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:453
static struct net_device * netdev
Definition: gdbudp.c:52
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:490
struct list_head tx_queue
Pending I/O buffers.
Definition: neighbour.h:60
static unsigned int neighbour_discard(void)
Discard some cached neighbour entries.
Definition: neighbour.c:501
uint8_t ll_dest[MAX_LL_ADDR_LEN]
Link-layer destination address.
Definition: neighbour.h:50
#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:458
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
#define NEIGHBOUR_DELAY_MS
Definition: fault.h:18
A network device.
Definition: netdevice.h:352
#define ENODEV
No such device.
Definition: errno.h:509
A cache discarder.
Definition: malloc.h:92
static void neighbour_discovered(struct neighbour *neighbour, const void *ll_dest)
Complete neighbour discovery.
Definition: neighbour.c:255
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:564
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
A neighbour cache entry.
Definition: neighbour.h:37
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:93
A network-layer protocol.
Definition: netdevice.h:64
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
static void neighbour_flush(struct net_device *netdev, void *priv __unused)
Update neighbour cache on network device state change or removal.
Definition: neighbour.c:478
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:44
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:1073
#define NEIGHBOUR_MAX_TIMEOUT
Neighbour discovery maximum timeout.
Definition: neighbour.c:50
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
#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:101
uint16_t delay
Forward delay.
Definition: stp.h:40
Neighbour discovery.
void * data
Start of data.
Definition: iobuf.h:52
static void neighbour_expired(struct retry_timer *timer, int over)
Handle neighbour timer expiry.
Definition: neighbour.c:316
struct net_device * netdev
Network device.
Definition: neighbour.h:44
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:367
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
static void neighbour_destroy(struct neighbour *neighbour, int rc)
Destroy neighbour cache entry.
Definition: neighbour.c:280
static void neighbour_free(struct refcnt *refcnt)
Free neighbour cache entry.
Definition: neighbour.c:74
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
A neighbour transmission delay pseudo-header.
Definition: neighbour.h:64
unsigned long currticks(void)
Get current system time in ticks.
Definition: timer.c:42
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
String functions.
#define TICKS_PER_MS
Number of ticks per millisecond.
Definition: timer.h:25
uint8_t net_source[MAX_NET_ADDR_LEN]
Network-layer source address (for discovery requests)
Definition: neighbour.h:55
static void neighbour_tx_queue(struct neighbour *neighbour)
Transmit deferred packets.
Definition: neighbour.c:184
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
static void neighbour_discover(struct neighbour *neighbour, struct neighbour_discovery *discovery, const void *net_source)
Start neighbour discovery.
Definition: neighbour.c:159
A persistent I/O buffer.
Definition: iobuf.h:37