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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_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
72static void neighbour_expired ( struct retry_timer *timer, int over );
73
74/**
75 * Free neighbour cache entry
76 *
77 * @v refcnt Reference count
78 */
79static void neighbour_free ( struct refcnt *refcnt ) {
80 struct neighbour *neighbour =
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 */
101static struct neighbour * neighbour_create ( struct net_device *netdev,
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 */
136static struct neighbour * neighbour_find ( struct net_device *netdev,
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 */
166 const void *net_source ) {
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}
183
184/**
185 * Transmit deferred packets
186 *
187 * @v neighbour Neighbour cache entry
188 */
189static void neighbour_tx_queue ( struct neighbour *neighbour ) {
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}
256
257/**
258 * Drop a deferred packet
259 *
260 * @v neighbour Neighbour cache entry
261 * @v rc Reason for drop
262 * @ret dropped Number of deferred packets dropped
263 */
264static unsigned int neighbour_drop ( struct neighbour *neighbour, int rc ) {
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}
286
287/**
288 * Complete neighbour discovery
289 *
290 * @v neighbour Neighbour cache entry
291 * @v ll_dest Destination link-layer address
292 */
294 const void *ll_dest ) {
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}
311
312/**
313 * Destroy neighbour cache entry
314 *
315 * @v neighbour Neighbour cache entry
316 * @v rc Reason for destruction
317 */
318static void neighbour_destroy ( struct neighbour *neighbour, int rc ) {
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}
338
339/**
340 * Handle neighbour timer expiry
341 *
342 * @v timer Retry timer
343 * @v fail Failure indicator
344 */
345static void neighbour_expired ( struct retry_timer *timer, int fail ) {
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}
384
385/**
386 * Transmit packet, determining link-layer address via neighbour discovery
387 *
388 * @v iobuf I/O buffer
389 * @v netdev Network device
390 * @v discovery Neighbour discovery protocol
391 * @v net_protocol Network-layer protocol
392 * @v net_dest Destination network-layer address
393 * @v net_source Source network-layer address
394 * @ret rc Return status code
395 */
396int neighbour_tx ( struct io_buffer *iobuf, struct net_device *netdev,
397 struct net_protocol *net_protocol, const void *net_dest,
398 struct neighbour_discovery *discovery,
399 const void *net_source ) {
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}
450
451/**
452 * Update existing neighbour cache entry
453 *
454 * @v netdev Network device
455 * @v net_protocol Network-layer protocol
456 * @v net_dest Destination network-layer address
457 * @v ll_dest Destination link-layer address
458 * @ret rc Return status code
459 */
462 const void *net_dest, const void *ll_dest ) {
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}
475
476/**
477 * Define neighbour cache entry
478 *
479 * @v netdev Network device
480 * @v net_protocol Network-layer protocol
481 * @v net_dest Destination network-layer address
482 * @v ll_dest Destination link-layer address, if known
483 * @ret rc Return status code
484 */
487 const void *net_dest, const void *ll_dest ) {
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}
503
504/**
505 * Update neighbour cache on network device state change or removal
506 *
507 * @v netdev Network device
508 * @v priv Private data
509 */
510static void neighbour_flush ( struct net_device *netdev, void *priv __unused ) {
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}
520
521/** Neighbour driver (for net device notifications) */
522struct net_driver neighbour_net_driver __net_driver = {
523 .name = "Neighbour",
524 .notify = neighbour_flush,
525 .remove = neighbour_flush,
526};
527
528/**
529 * Discard some deferred packets from neighbour cache entries
530 *
531 * @ret discarded Number of cached items discarded
532 */
533static unsigned int neighbour_queue_discard ( void ) {
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}
543
544/** Neighbour cache deferred packet discarder */
545struct cache_discarder
546neighbour_queue_discarder __cache_discarder ( CACHE_NORMAL ) = {
547 .discard = neighbour_queue_discard,
548};
549
550/**
551 * Discard some complete neighbour cache entries
552 *
553 * @ret discarded Number of cached items discarded
554 */
555static unsigned int neighbour_discard ( void ) {
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}
571
572/**
573 * Neighbour cache discarder
574 *
575 * Neighbour cache entries are deemed to have a high replacement cost,
576 * since flushing an active neighbour cache entry midway through a TCP
577 * transfer will cause substantial disruption.
578 */
580 .discard = neighbour_discard,
581};
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
Fault injection.
#define NEIGHBOUR_DELAY_MS
Definition fault.h:19
#define delay(nanosec)
Definition epic100.c:49
Error codes.
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:598
#define CACHE_NORMAL
Items with a normal replacement cost.
Definition malloc.h:114
#define CACHE_EXPENSIVE
Items with a high replacement cost.
Definition malloc.h:115
#define DBGC2(...)
Definition compiler.h:547
#define DBGC(...)
Definition compiler.h:530
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define ENOENT
No such file or directory.
Definition errno.h:558
#define ETIMEDOUT
Connection timed out.
Definition errno.h:713
#define ENOMEM
Not enough space.
Definition errno.h:578
#define ENOBUFS
No buffer space available.
Definition errno.h:542
#define ENODEV
No such device.
Definition errno.h:553
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
iPXE timers
#define TICKS_PER_MS
Number of ticks per millisecond.
Definition timer.h:26
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
I/O buffers.
#define iob_push(iobuf, len)
Definition iobuf.h:149
#define iob_pull(iobuf, len)
Definition iobuf.h:167
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
#define list_last_entry(list, type, member)
Get the container of the last entry in a list.
Definition list.h:347
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
#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
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#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
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
#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:718
Dynamic memory allocation.
#define __cache_discarder(cost)
Declare a cache discarder.
Definition malloc.h:106
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:396
static void neighbour_expired(struct retry_timer *timer, int over)
Handle neighbour timer expiry.
Definition neighbour.c:345
static unsigned int neighbour_drop(struct neighbour *neighbour, int rc)
Drop a deferred packet.
Definition neighbour.c:264
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
#define NEIGHBOUR_MAX_TIMEOUT
Neighbour discovery maximum timeout.
Definition neighbour.c:52
struct list_head neighbours
The neighbour cache.
Definition neighbour.c:67
static void neighbour_destroy(struct neighbour *neighbour, int rc)
Destroy neighbour cache entry.
Definition neighbour.c:318
static void neighbour_discovered(struct neighbour *neighbour, const void *ll_dest)
Complete neighbour discovery.
Definition neighbour.c:293
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:460
static unsigned int neighbour_queue_discard(void)
Discard some deferred packets from neighbour cache entries.
Definition neighbour.c:533
static struct pending_operation neighbour_delayed
Pending operation for delayed transmissions.
Definition neighbour.c:70
#define NEIGHBOUR_MIN_TIMEOUT
Neighbour discovery minimum timeout.
Definition neighbour.c:49
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
static void neighbour_tx_queue(struct neighbour *neighbour)
Transmit deferred packets.
Definition neighbour.c:189
#define NEIGHBOUR_DELAY_MAX_BURST
Neighbour discovery maximum burst count for delayed transmissions.
Definition neighbour.c:64
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:485
static void neighbour_free(struct refcnt *refcnt)
Free neighbour cache entry.
Definition neighbour.c:79
static void neighbour_discover(struct neighbour *neighbour, struct neighbour_discovery *discovery, const void *net_source)
Start neighbour discovery.
Definition neighbour.c:164
static unsigned int neighbour_discard(void)
Discard some complete neighbour cache entries.
Definition neighbour.c:555
Neighbour discovery.
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 netdev_tx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard transmitted packet.
Definition netdevice.c:441
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:568
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:665
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:579
#define __net_driver
Declare a network driver.
Definition netdevice.h:510
void pending_put(struct pending_operation *pending)
Mark an operation as no longer pending.
Definition pending.c:59
void pending_get(struct pending_operation *pending)
Mark an operation as pending.
Definition pending.c:46
Pending operations.
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#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
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
void start_timer(struct retry_timer *timer)
Start timer.
Definition retry.c:94
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
Retry timers.
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition retry.h:100
#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
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
A cache discarder.
Definition malloc.h:93
A persistent I/O buffer.
Definition iobuf.h:98
void * data
Start of data.
Definition iobuf.h:113
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:105
A doubly-linked list entry (or list head).
Definition list.h:19
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
A neighbour transmission delay pseudo-header.
Definition neighbour.h:65
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 list_head tx_queue
Pending I/O buffers.
Definition neighbour.h:61
struct refcnt refcnt
Reference count.
Definition neighbour.h:40
struct net_protocol * net_protocol
Network-layer protocol.
Definition neighbour.h:47
struct net_device * netdev
Network device.
Definition neighbour.h:45
uint8_t ll_dest[MAX_LL_ADDR_LEN]
Link-layer destination address.
Definition neighbour.h:51
uint8_t net_dest[MAX_NET_ADDR_LEN]
Network-layer destination address.
Definition neighbour.h:49
struct list_head list
List of neighbour cache entries.
Definition neighbour.h:42
A network device.
Definition netdevice.h:353
A network upper-layer driver.
Definition netdevice.h:480
A network-layer protocol.
Definition netdevice.h:65
const char * name
Protocol name.
Definition netdevice.h:67
uint8_t net_addr_len
Network-layer address length.
Definition netdevice.h:102
const char *(* ntoa)(const void *net_addr)
Transcribe network-layer address.
Definition netdevice.h:95
A pending operation.
Definition pending.h:14
A reference counter.
Definition refcnt.h:27
A retry timer.
Definition retry.h:22
A timer.
Definition timer.h:29
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43
static struct tlan_private * priv
Definition tlan.c:225