|
@@ -378,6 +378,42 @@ static int ipv4_tx ( struct io_buffer *iobuf,
|
378
|
378
|
return rc;
|
379
|
379
|
}
|
380
|
380
|
|
|
381
|
+/**
|
|
382
|
+ * Check if network device has any IPv4 address
|
|
383
|
+ *
|
|
384
|
+ * @v netdev Network device
|
|
385
|
+ * @ret has_any_addr Network device has any IPv4 address
|
|
386
|
+ */
|
|
387
|
+static int ipv4_has_any_addr ( struct net_device *netdev ) {
|
|
388
|
+ struct ipv4_miniroute *miniroute;
|
|
389
|
+
|
|
390
|
+ list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
|
|
391
|
+ if ( miniroute->netdev == netdev )
|
|
392
|
+ return 1;
|
|
393
|
+ }
|
|
394
|
+ return 0;
|
|
395
|
+}
|
|
396
|
+
|
|
397
|
+/**
|
|
398
|
+ * Check if network device has a specific IPv4 address
|
|
399
|
+ *
|
|
400
|
+ * @v netdev Network device
|
|
401
|
+ * @v addr IPv4 address
|
|
402
|
+ * @ret has_addr Network device has this IPv4 address
|
|
403
|
+ */
|
|
404
|
+static int ipv4_has_addr ( struct net_device *netdev, struct in_addr addr ) {
|
|
405
|
+ struct ipv4_miniroute *miniroute;
|
|
406
|
+
|
|
407
|
+ list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
|
|
408
|
+ if ( ( miniroute->netdev == netdev ) &&
|
|
409
|
+ ( miniroute->address.s_addr == addr.s_addr ) ) {
|
|
410
|
+ /* Found matching address */
|
|
411
|
+ return 1;
|
|
412
|
+ }
|
|
413
|
+ }
|
|
414
|
+ return 0;
|
|
415
|
+}
|
|
416
|
+
|
381
|
417
|
/**
|
382
|
418
|
* Process incoming packets
|
383
|
419
|
*
|
|
@@ -392,10 +428,10 @@ static int ipv4_tx ( struct io_buffer *iobuf,
|
392
|
428
|
* and sends it to the transport layer.
|
393
|
429
|
*/
|
394
|
430
|
static int ipv4_rx ( struct io_buffer *iobuf,
|
395
|
|
- struct net_device *netdev __unused,
|
|
431
|
+ struct net_device *netdev,
|
396
|
432
|
const void *ll_dest __unused,
|
397
|
433
|
const void *ll_source __unused,
|
398
|
|
- unsigned int flags __unused ) {
|
|
434
|
+ unsigned int flags ) {
|
399
|
435
|
struct iphdr *iphdr = iobuf->data;
|
400
|
436
|
size_t hdrlen;
|
401
|
437
|
size_t len;
|
|
@@ -451,6 +487,15 @@ static int ipv4_rx ( struct io_buffer *iobuf,
|
451
|
487
|
inet_ntoa ( iphdr->src ), ntohs ( iphdr->len ), iphdr->protocol,
|
452
|
488
|
ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
|
453
|
489
|
|
|
490
|
+ /* Discard unicast packets not destined for us */
|
|
491
|
+ if ( ( ! ( flags & LL_MULTICAST ) ) &&
|
|
492
|
+ ipv4_has_any_addr ( netdev ) &&
|
|
493
|
+ ( ! ipv4_has_addr ( netdev, iphdr->dest ) ) ) {
|
|
494
|
+ DBG ( "IPv4 discarding non-local unicast packet for %s\n",
|
|
495
|
+ inet_ntoa ( iphdr->dest ) );
|
|
496
|
+ goto err;
|
|
497
|
+ }
|
|
498
|
+
|
454
|
499
|
/* Truncate packet to correct length, calculate pseudo-header
|
455
|
500
|
* checksum and then strip off the IPv4 header.
|
456
|
501
|
*/
|
|
@@ -499,15 +544,10 @@ static int ipv4_rx ( struct io_buffer *iobuf,
|
499
|
544
|
*/
|
500
|
545
|
static int ipv4_arp_check ( struct net_device *netdev, const void *net_addr ) {
|
501
|
546
|
const struct in_addr *address = net_addr;
|
502
|
|
- struct ipv4_miniroute *miniroute;
|
503
|
547
|
|
504
|
|
- list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
|
505
|
|
- if ( ( miniroute->netdev == netdev ) &&
|
506
|
|
- ( miniroute->address.s_addr == address->s_addr ) ) {
|
507
|
|
- /* Found matching address */
|
508
|
|
- return 0;
|
509
|
|
- }
|
510
|
|
- }
|
|
548
|
+ if ( ipv4_has_addr ( netdev, *address ) )
|
|
549
|
+ return 0;
|
|
550
|
+
|
511
|
551
|
return -ENOENT;
|
512
|
552
|
}
|
513
|
553
|
|