|
@@ -33,8 +33,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
33
|
33
|
#include <ipxe/errortab.h>
|
34
|
34
|
#include <ipxe/malloc.h>
|
35
|
35
|
#include <ipxe/if_arp.h>
|
|
36
|
+#include <ipxe/arp.h>
|
36
|
37
|
#include <ipxe/if_ether.h>
|
37
|
38
|
#include <ipxe/ethernet.h>
|
|
39
|
+#include <ipxe/ip.h>
|
38
|
40
|
#include <ipxe/iobuf.h>
|
39
|
41
|
#include <ipxe/netdevice.h>
|
40
|
42
|
#include <ipxe/infiniband.h>
|
|
@@ -48,6 +50,20 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
48
|
50
|
* IP over Infiniband
|
49
|
51
|
*/
|
50
|
52
|
|
|
53
|
+/* Disambiguate the various error causes */
|
|
54
|
+#define ENXIO_ARP_REPLY __einfo_error ( EINFO_ENXIO_ARP_REPLY )
|
|
55
|
+#define EINFO_ENXIO_ARP_REPLY \
|
|
56
|
+ __einfo_uniqify ( EINFO_ENXIO, 0x01, \
|
|
57
|
+ "Missing REMAC for ARP reply target address" )
|
|
58
|
+#define ENXIO_NON_IPV4 __einfo_error ( EINFO_ENXIO_NON_IPV4 )
|
|
59
|
+#define EINFO_ENXIO_NON_IPV4 \
|
|
60
|
+ __einfo_uniqify ( EINFO_ENXIO, 0x02, \
|
|
61
|
+ "Missing REMAC for non-IPv4 packet" )
|
|
62
|
+#define ENXIO_ARP_SENT __einfo_error ( EINFO_ENXIO_ARP_SENT )
|
|
63
|
+#define EINFO_ENXIO_ARP_SENT \
|
|
64
|
+ __einfo_uniqify ( EINFO_ENXIO, 0x03, \
|
|
65
|
+ "Missing REMAC for IPv4 packet (ARP sent)" )
|
|
66
|
+
|
51
|
67
|
/** Number of IPoIB send work queue entries */
|
52
|
68
|
#define IPOIB_NUM_SEND_WQES 2
|
53
|
69
|
|
|
@@ -336,8 +352,11 @@ static int ipoib_translate_tx_arp ( struct net_device *netdev,
|
336
|
352
|
/* Look up REMAC, if applicable */
|
337
|
353
|
if ( arphdr->ar_op == ARPOP_REPLY ) {
|
338
|
354
|
target_ha = ipoib_find_remac ( ipoib, arp_target_pa ( arphdr ));
|
339
|
|
- if ( ! target_ha )
|
340
|
|
- return -ENXIO;
|
|
355
|
+ if ( ! target_ha ) {
|
|
356
|
+ DBGC ( ipoib, "IPoIB %p no REMAC for %s ARP reply\n",
|
|
357
|
+ ipoib, eth_ntoa ( arp_target_pa ( arphdr ) ) );
|
|
358
|
+ return -ENXIO_ARP_REPLY;
|
|
359
|
+ }
|
341
|
360
|
}
|
342
|
361
|
|
343
|
362
|
/* Construct new packet */
|
|
@@ -473,6 +492,7 @@ static int ipoib_transmit ( struct net_device *netdev,
|
473
|
492
|
struct ipoib_device *ipoib = netdev->priv;
|
474
|
493
|
struct ib_device *ibdev = ipoib->ibdev;
|
475
|
494
|
struct ethhdr *ethhdr;
|
|
495
|
+ struct iphdr *iphdr;
|
476
|
496
|
struct ipoib_hdr *ipoib_hdr;
|
477
|
497
|
struct ipoib_mac *mac;
|
478
|
498
|
struct ib_address_vector dest;
|
|
@@ -497,9 +517,34 @@ static int ipoib_transmit ( struct net_device *netdev,
|
497
|
517
|
iob_pull ( iobuf, sizeof ( *ethhdr ) );
|
498
|
518
|
|
499
|
519
|
/* Identify destination address */
|
500
|
|
- mac = ipoib_find_remac ( ipoib, ( ( void *) ethhdr->h_dest ) );
|
501
|
|
- if ( ! mac )
|
502
|
|
- return -ENXIO;
|
|
520
|
+ mac = ipoib_find_remac ( ipoib, ( ( void * ) ethhdr->h_dest ) );
|
|
521
|
+ if ( ! mac ) {
|
|
522
|
+ /* Generate a new ARP request (if possible) to trigger
|
|
523
|
+ * population of the REMAC cache entry.
|
|
524
|
+ */
|
|
525
|
+ if ( ( net_proto != htons ( ETH_P_IP ) ) ||
|
|
526
|
+ ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) ) {
|
|
527
|
+ DBGC ( ipoib, "IPoIB %p no REMAC for %s non-IPv4 "
|
|
528
|
+ "packet type %04x\n", ipoib,
|
|
529
|
+ eth_ntoa ( ethhdr->h_dest ),
|
|
530
|
+ ntohs ( net_proto ) );
|
|
531
|
+ return -ENXIO_NON_IPV4;
|
|
532
|
+ }
|
|
533
|
+ iphdr = iobuf->data;
|
|
534
|
+ if ( ( rc = arp_tx_request ( netdev, &ipv4_protocol,
|
|
535
|
+ &iphdr->dest, &iphdr->src ) ) !=0){
|
|
536
|
+ DBGC ( ipoib, "IPoIB %p could not ARP for %s/%s/",
|
|
537
|
+ ipoib, eth_ntoa ( ethhdr->h_dest ),
|
|
538
|
+ inet_ntoa ( iphdr->dest ) );
|
|
539
|
+ DBGC ( ipoib, "%s: %s\n", inet_ntoa ( iphdr->src ),
|
|
540
|
+ strerror ( rc ) );
|
|
541
|
+ return rc;
|
|
542
|
+ }
|
|
543
|
+ DBGC ( ipoib, "IPoIB %p no REMAC for %s/%s/", ipoib,
|
|
544
|
+ eth_ntoa ( ethhdr->h_dest ), inet_ntoa ( iphdr->dest ) );
|
|
545
|
+ DBGC ( ipoib, "%s\n", inet_ntoa ( iphdr->src ) );
|
|
546
|
+ return -ENXIO_ARP_SENT;
|
|
547
|
+ }
|
503
|
548
|
|
504
|
549
|
/* Translate packet if applicable */
|
505
|
550
|
if ( ( rc = ipoib_translate_tx ( netdev, iobuf, net_proto ) ) != 0 )
|