48
/** ARP minimum timeout */
49
#define ARP_MIN_TIMEOUT ( TICKS_PER_SEC / 8 )
51
/** ARP maximum timeout */
52
#define ARP_MAX_TIMEOUT ( TICKS_PER_SEC * 3 )
41
54
/** An ARP cache entry */
56
/** Reference count */
58
/** List of ARP cache entries */
59
struct list_head list;
61
struct net_device *netdev;
43
62
/** Network-layer protocol */
44
63
struct net_protocol *net_protocol;
45
/** Link-layer protocol */
46
struct ll_protocol *ll_protocol;
47
/** Network-layer address */
48
uint8_t net_addr[MAX_NET_ADDR_LEN];
49
/** Link-layer address */
50
uint8_t ll_addr[MAX_LL_ADDR_LEN];
64
/** Network-layer destination address */
65
uint8_t net_dest[MAX_NET_ADDR_LEN];
66
/** Network-layer source address */
67
uint8_t net_source[MAX_NET_ADDR_LEN];
68
/** Link-layer destination address */
69
uint8_t ll_dest[MAX_LL_ADDR_LEN];
70
/** Retransmission timer */
71
struct retry_timer timer;
72
/** Pending I/O buffers */
73
struct list_head tx_queue;
53
/** Number of entries in the ARP cache
55
* This is a global cache, covering all network interfaces,
56
* network-layer protocols and link-layer protocols.
58
#define NUM_ARP_ENTRIES 4
60
76
/** The ARP cache */
61
static struct arp_entry arp_table[NUM_ARP_ENTRIES];
62
#define arp_table_end &arp_table[NUM_ARP_ENTRIES]
64
static unsigned int next_new_arp_entry = 0;
77
static LIST_HEAD ( arp_entries );
66
79
struct net_protocol arp_protocol __net_protocol;
81
static void arp_expired ( struct retry_timer *timer, int over );
84
* Free ARP cache entry
86
* @v refcnt Reference count
88
static void arp_free ( struct refcnt *refcnt ) {
89
struct arp_entry *arp =
90
container_of ( refcnt, struct arp_entry, refcnt );
93
assert ( list_empty ( &arp->tx_queue ) );
95
/* Drop reference to network device */
96
netdev_put ( arp->netdev );
103
* Create ARP cache entry
105
* @v netdev Network device
106
* @v net_protocol Network-layer protocol
107
* @v net_dest Destination network-layer address
108
* @v net_source Source network-layer address
109
* @ret arp ARP cache entry, or NULL if allocation failed
111
static struct arp_entry * arp_create ( struct net_device *netdev,
112
struct net_protocol *net_protocol,
113
const void *net_dest,
114
const void *net_source ) {
115
struct arp_entry *arp;
117
/* Allocate and initialise entry */
118
arp = zalloc ( sizeof ( *arp ) );
121
ref_init ( &arp->refcnt, arp_free );
122
arp->netdev = netdev_get ( netdev );
123
arp->net_protocol = net_protocol;
124
memcpy ( arp->net_dest, net_dest,
125
net_protocol->net_addr_len );
126
memcpy ( arp->net_source, net_source,
127
net_protocol->net_addr_len );
128
timer_init ( &arp->timer, arp_expired, &arp->refcnt );
129
arp->timer.min_timeout = ARP_MIN_TIMEOUT;
130
arp->timer.max_timeout = ARP_MAX_TIMEOUT;
131
INIT_LIST_HEAD ( &arp->tx_queue );
133
/* Start timer running to trigger initial transmission */
134
start_timer_nodelay ( &arp->timer );
136
/* Transfer ownership to cache */
137
list_add ( &arp->list, &arp_entries );
139
DBGC ( arp, "ARP %p %s %s %s created\n", arp, netdev->name,
140
net_protocol->name, net_protocol->ntoa ( net_dest ) );
69
145
* Find entry in the ARP cache
71
* @v ll_protocol Link-layer protocol
147
* @v netdev Network device
72
148
* @v net_protocol Network-layer protocol
73
* @v net_addr Network-layer address
149
* @v net_dest Destination network-layer address
74
150
* @ret arp ARP cache entry, or NULL if not found
77
static struct arp_entry *
78
arp_find_entry ( struct ll_protocol *ll_protocol,
79
struct net_protocol *net_protocol,
80
const void *net_addr ) {
152
static struct arp_entry * arp_find ( struct net_device *netdev,
153
struct net_protocol *net_protocol,
154
const void *net_dest ) {
81
155
struct arp_entry *arp;
83
for ( arp = arp_table ; arp < arp_table_end ; arp++ ) {
84
if ( ( arp->ll_protocol == ll_protocol ) &&
157
list_for_each_entry ( arp, &arp_entries, list ) {
158
if ( ( arp->netdev == netdev ) &&
85
159
( arp->net_protocol == net_protocol ) &&
86
( memcmp ( arp->net_addr, net_addr,
87
net_protocol->net_addr_len ) == 0 ) )
160
( memcmp ( arp->net_dest, net_dest,
161
net_protocol->net_addr_len ) == 0 ) ) {
163
/* Move to start of cache */
164
list_del ( &arp->list );
165
list_add ( &arp->list, &arp_entries );
94
* Look up media-specific link-layer address in the ARP cache
174
* Destroy ARP cache entry
176
* @v arp ARP cache entry
177
* @v rc Reason for destruction
179
static void arp_destroy ( struct arp_entry *arp, int rc ) {
180
struct net_device *netdev = arp->netdev;
181
struct net_protocol *net_protocol = arp->net_protocol;
182
struct io_buffer *iobuf;
184
/* Take ownership from cache */
185
list_del ( &arp->list );
188
stop_timer ( &arp->timer );
190
/* Discard any outstanding I/O buffers */
191
while ( ( iobuf = list_first_entry ( &arp->tx_queue, struct io_buffer,
193
DBGC2 ( arp, "ARP %p %s %s %s discarding deferred packet: "
194
"%s\n", arp, netdev->name, net_protocol->name,
195
net_protocol->ntoa ( arp->net_dest ), strerror ( rc ) );
196
list_del ( &iobuf->list );
197
netdev_tx_err ( arp->netdev, iobuf, rc );
200
DBGC ( arp, "ARP %p %s %s %s destroyed: %s\n", arp, netdev->name,
201
net_protocol->name, net_protocol->ntoa ( arp->net_dest ),
204
/* Drop remaining reference */
205
ref_put ( &arp->refcnt );
209
* Test if ARP cache entry has a valid link-layer address
211
* @v arp ARP cache entry
212
* @ret resolved ARP cache entry is resolved
214
static inline int arp_resolved ( struct arp_entry *arp ) {
215
return ( ! timer_running ( &arp->timer ) );
219
* Transmit packet, determining link-layer address via ARP
221
* @v iobuf I/O buffer
96
222
* @v netdev Network device
97
223
* @v net_protocol Network-layer protocol
98
* @v dest_net_addr Destination network-layer address
99
* @v source_net_addr Source network-layer address
100
* @ret dest_ll_addr Destination link layer address
224
* @v net_dest Destination network-layer address
225
* @v net_source Source network-layer address
226
* @v ll_source Source link-layer address
101
227
* @ret rc Return status code
103
* This function will use the ARP cache to look up the link-layer
104
* address for the link-layer protocol associated with the network
105
* device and the given network-layer protocol and addresses. If
106
* found, the destination link-layer address will be filled in in @c
109
* If no address is found in the ARP cache, an ARP request will be
110
* transmitted on the specified network device and -ENOENT will be
113
int arp_resolve ( struct net_device *netdev, struct net_protocol *net_protocol,
114
const void *dest_net_addr, const void *source_net_addr,
115
void *dest_ll_addr ) {
116
struct ll_protocol *ll_protocol = netdev->ll_protocol;
117
const struct arp_entry *arp;
229
int arp_tx ( struct io_buffer *iobuf, struct net_device *netdev,
230
struct net_protocol *net_protocol, const void *net_dest,
231
const void *net_source, const void *ll_source ) {
232
struct arp_entry *arp;
234
/* Find or create ARP cache entry */
235
arp = arp_find ( netdev, net_protocol, net_dest );
237
arp = arp_create ( netdev, net_protocol, net_dest,
243
/* If a link-layer address is available then transmit
244
* immediately, otherwise queue for later transmission.
246
if ( arp_resolved ( arp ) ) {
247
return net_tx ( iobuf, netdev, net_protocol, arp->ll_dest,
250
DBGC2 ( arp, "ARP %p %s %s %s deferring packet\n",
251
arp, netdev->name, net_protocol->name,
252
net_protocol->ntoa ( net_dest ) );
253
list_add_tail ( &iobuf->list, &arp->tx_queue );
259
* Update ARP cache entry
261
* @v arp ARP cache entry
262
* @v ll_dest Destination link-layer address
264
static void arp_update ( struct arp_entry *arp, const void *ll_dest ) {
265
struct net_device *netdev = arp->netdev;
266
struct ll_protocol *ll_protocol = netdev->ll_protocol;
267
struct net_protocol *net_protocol = arp->net_protocol;
268
struct io_buffer *iobuf;
271
DBGC ( arp, "ARP %p %s %s %s updated => %s\n", arp, netdev->name,
272
net_protocol->name, net_protocol->ntoa ( arp->net_dest ),
273
ll_protocol->ntoa ( ll_dest ) );
275
/* Fill in link-layer address */
276
memcpy ( arp->ll_dest, ll_dest, ll_protocol->ll_addr_len );
278
/* Stop retransmission timer */
279
stop_timer ( &arp->timer );
281
/* Transmit any packets in queue. Take out a temporary
282
* reference on the entry to prevent it from going out of
283
* scope during the call to net_tx().
285
ref_get ( &arp->refcnt );
286
while ( ( iobuf = list_first_entry ( &arp->tx_queue, struct io_buffer,
288
DBGC2 ( arp, "ARP %p %s %s %s transmitting deferred packet\n",
289
arp, netdev->name, net_protocol->name,
290
net_protocol->ntoa ( arp->net_dest ) );
291
list_del ( &iobuf->list );
292
if ( ( rc = net_tx ( iobuf, netdev, net_protocol, ll_dest,
293
netdev->ll_addr ) ) != 0 ) {
294
DBGC ( arp, "ARP %p could not transmit deferred "
295
"packet: %s\n", arp, strerror ( rc ) );
296
/* Ignore error and continue */
299
ref_put ( &arp->refcnt );
303
* Handle ARP timer expiry
305
* @v timer Retry timer
306
* @v fail Failure indicator
308
static void arp_expired ( struct retry_timer *timer, int fail ) {
309
struct arp_entry *arp = container_of ( timer, struct arp_entry, timer );
310
struct net_device *netdev = arp->netdev;
311
struct ll_protocol *ll_protocol = netdev->ll_protocol;
312
struct net_protocol *net_protocol = arp->net_protocol;
118
313
struct io_buffer *iobuf;
119
314
struct arphdr *arphdr;
122
/* Look for existing entry in ARP table */
123
arp = arp_find_entry ( ll_protocol, net_protocol, dest_net_addr );
125
DBG ( "ARP cache hit: %s %s => %s %s\n",
126
net_protocol->name, net_protocol->ntoa ( arp->net_addr ),
127
ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) );
128
memcpy ( dest_ll_addr, arp->ll_addr, ll_protocol->ll_addr_len);
317
/* If we have failed, destroy the cache entry */
319
arp_destroy ( arp, -ETIMEDOUT );
131
DBG ( "ARP cache miss: %s %s\n", net_protocol->name,
132
net_protocol->ntoa ( dest_net_addr ) );
323
/* Restart the timer */
324
start_timer ( &arp->timer );
134
326
/* Allocate ARP packet */
135
327
iobuf = alloc_iob ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) +
136
2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) );
328
( 2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) ) );
330
/* Leave timer running and try again later */
139
333
iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
141
335
/* Build up ARP request */
204
393
struct net_protocol *net_protocol;
205
394
struct ll_protocol *ll_protocol;
206
395
struct arp_entry *arp;
209
398
/* Identify network-layer and link-layer protocols */
210
399
arp_net_protocol = arp_find_protocol ( arphdr->ar_pro );
211
if ( ! arp_net_protocol )
400
if ( ! arp_net_protocol ) {
401
rc = -EPROTONOSUPPORT;
213
404
net_protocol = arp_net_protocol->net_protocol;
214
405
ll_protocol = netdev->ll_protocol;
216
407
/* Sanity checks */
217
408
if ( ( arphdr->ar_hrd != ll_protocol->ll_proto ) ||
218
409
( arphdr->ar_hln != ll_protocol->ll_addr_len ) ||
219
( arphdr->ar_pln != net_protocol->net_addr_len ) )
410
( arphdr->ar_pln != net_protocol->net_addr_len ) ) {
222
415
/* See if we have an entry for this sender, and update it if so */
223
arp = arp_find_entry ( ll_protocol, net_protocol,
224
arp_sender_pa ( arphdr ) );
416
arp = arp_find ( netdev, net_protocol, arp_sender_pa ( arphdr ) );
226
memcpy ( arp->ll_addr, arp_sender_ha ( arphdr ),
229
DBG ( "ARP cache update: %s %s => %s %s\n",
230
net_protocol->name, net_protocol->ntoa ( arp->net_addr ),
231
ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) );
418
arp_update ( arp, arp_sender_ha ( arphdr ) );
421
/* If it's not a request, there's nothing more to do */
422
if ( arphdr->ar_op != htons ( ARPOP_REQUEST ) ) {
234
427
/* See if we own the target protocol address */
235
if ( arp_net_protocol->check ( netdev, arp_target_pa ( arphdr ) ) != 0)
428
if ( arp_net_protocol->check ( netdev, arp_target_pa ( arphdr ) ) != 0){
238
/* Create new ARP table entry if necessary */
240
arp = &arp_table[next_new_arp_entry++ % NUM_ARP_ENTRIES];
241
arp->ll_protocol = ll_protocol;
242
arp->net_protocol = net_protocol;
243
memcpy ( arp->ll_addr, arp_sender_ha ( arphdr ),
245
memcpy ( arp->net_addr, arp_sender_pa ( arphdr ),
247
DBG ( "ARP cache add: %s %s => %s %s\n",
248
net_protocol->name, net_protocol->ntoa ( arp->net_addr ),
249
ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) );
252
/* If it's not a request, there's nothing more to do */
253
if ( arphdr->ar_op != htons ( ARPOP_REQUEST ) )
256
433
/* Change request to a reply */
257
DBG ( "ARP reply: %s %s => %s %s\n", net_protocol->name,
258
net_protocol->ntoa ( arp_target_pa ( arphdr ) ),
259
ll_protocol->name, ll_protocol->ntoa ( netdev->ll_addr ) );
434
DBGC ( netdev, "ARP reply %s %s %s => %s %s\n",
435
netdev->name, net_protocol->name,
436
net_protocol->ntoa ( arp_target_pa ( arphdr ) ),
437
ll_protocol->name, ll_protocol->ntoa ( netdev->ll_addr ) );
260
438
arphdr->ar_op = htons ( ARPOP_REPLY );
261
439
memswap ( arp_sender_ha ( arphdr ), arp_target_ha ( arphdr ),
262
440
arphdr->ar_hln + arphdr->ar_pln );
263
441
memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
266
net_tx ( iob_disown ( iobuf ), netdev, &arp_protocol,
267
arp_target_ha ( arphdr ), netdev->ll_addr );
444
if ( ( rc = net_tx ( iob_disown ( iobuf ), netdev, &arp_protocol,
445
arp_target_ha ( arphdr ),
446
netdev->ll_addr ) ) != 0 ) {
447
DBGC ( netdev, "ARP could not transmit reply via %s: %s\n",
448
netdev->name, strerror ( rc ) );
270
456
free_iob ( iobuf );