]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[netdevice] Pass both link-layer addresses in net_tx() and net_rx()
authorMichael Brown <mcb30@ipxe.org>
Thu, 7 Oct 2010 15:03:16 +0000 (16:03 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 7 Oct 2010 18:15:04 +0000 (19:15 +0100)
FCoE requires the use of fabric-provided MAC addresses, which breaks
the assumption that the net device's MAC address is implicitly the
source address for net_tx() and the (unicast) destination address for
net_rx().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
13 files changed:
src/include/ipxe/eapol.h
src/include/ipxe/netdevice.h
src/net/80211/wpa.c
src/net/aoe.c
src/net/arp.c
src/net/eapol.c
src/net/eth_slow.c
src/net/fcoe.c
src/net/ipv4.c
src/net/ipv6.c
src/net/netdevice.c
src/net/rarp.c
src/usr/lotest.c

index 43d891c611084f79266341bd9bd79c9560d1a47c..3fad4428428d994b17262027692eb986c6804781 100644 (file)
@@ -90,7 +90,8 @@ struct eapol_handler
         *
         * @v iob       I/O buffer containing packet payload
         * @v netdev    Network device from which packet was received
-        * @v ll_source Source link-layer address from which packet was received
+        * @V ll_dest   Destination link-layer address
+        * @v ll_source Source link-layer address
         * @ret rc      Return status code
         *
         * The I/O buffer will have the EAPOL header pulled off it, so
@@ -99,7 +100,7 @@ struct eapol_handler
         * This function takes ownership of the I/O buffer passed to it.
         */
        int ( * rx ) ( struct io_buffer *iob, struct net_device *netdev,
-                      const void *ll_source );
+                      const void *ll_dest, const void *ll_source );
 };
 
 #define EAPOL_HANDLERS __table ( struct eapol_handler, "eapol_handlers" )
index 80bc1c6e2ce7a862ee5b0cbbb62eb6096321aef5..8cec33eee3ec04b777bc0df38f4b3bafb410e50b 100644 (file)
@@ -57,12 +57,13 @@ struct net_protocol {
         *
         * @v iobuf     I/O buffer
         * @v netdev    Network device
+        * @v ll_dest   Link-layer destination address
         * @v ll_source Link-layer source address
         *
         * This method takes ownership of the I/O buffer.
         */
        int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev,
-                      const void *ll_source );
+                      const void *ll_dest, const void *ll_source );
        /**
         * Transcribe network-layer address
         *
@@ -534,9 +535,11 @@ extern struct net_device * find_netdev_by_location ( unsigned int bus_type,
                                                     unsigned int location );
 extern struct net_device * last_opened_netdev ( void );
 extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
-                   struct net_protocol *net_protocol, const void *ll_dest );
+                   struct net_protocol *net_protocol, const void *ll_dest,
+                   const void *ll_source );
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
-                   uint16_t net_proto, const void *ll_source );
+                   uint16_t net_proto, const void *ll_dest,
+                   const void *ll_source );
 
 /**
  * Complete network transmission
index b676c63ffc520f62cc7739f54738acc0fea62bbc..38ddb911ba6dbc3a94d9550287fc4a483bb0a79d 100644 (file)
@@ -455,7 +455,7 @@ static int wpa_send_eapol ( struct io_buffer *iob, struct wpa_common_ctx *ctx,
                           pkt->mic );
 
        return net_tx ( iob, ctx->dev->netdev, &eapol_protocol,
-                       ctx->dev->bssid );
+                       ctx->dev->bssid, ctx->dev->netdev->ll_addr );
 }
 
 
@@ -757,9 +757,11 @@ static int wpa_handle_1_of_2 ( struct wpa_common_ctx *ctx,
  *
  * @v iob      I/O buffer
  * @v netdev   Network device
+ * @v ll_dest  Link-layer destination address
  * @v ll_source        Source link-layer address
  */
 static int eapol_key_rx ( struct io_buffer *iob, struct net_device *netdev,
+                         const void *ll_dest __unused,
                          const void *ll_source )
 {
        struct net80211_device *dev = net80211_get ( netdev );
index 8ee1f8bd2a0e96f899868a0b18b0b06a0fe61927..3b1953a2fda5ac3488d89abd46eeee5b63ea1e66 100644 (file)
@@ -249,13 +249,14 @@ static void aoecmd_close ( struct aoe_command *aoecmd, int rc ) {
  */
 static int aoecmd_tx ( struct aoe_command *aoecmd ) {
        struct aoe_device *aoedev = aoecmd->aoedev;
+       struct net_device *netdev = aoedev->netdev;
        struct io_buffer *iobuf;
        struct aoehdr *aoehdr;
        size_t cmd_len;
        int rc;
 
        /* Sanity check */
-       assert ( aoedev->netdev != NULL );
+       assert ( netdev != NULL );
 
        /* If we are transmitting anything that requires a response,
          * start the retransmission timer.  Do this before attempting
@@ -281,8 +282,8 @@ static int aoecmd_tx ( struct aoe_command *aoecmd ) {
        aoecmd->type->cmd ( aoecmd, iobuf->data, iob_len ( iobuf ) );
 
        /* Send packet */
-       if ( ( rc = net_tx ( iobuf, aoedev->netdev, &aoe_protocol,
-                            aoedev->target ) ) != 0 ) {
+       if ( ( rc = net_tx ( iobuf, netdev, &aoe_protocol, aoedev->target,
+                            netdev->ll_addr ) ) != 0 ) {
                DBGC ( aoedev, "AoE %s/%08x could not transmit: %s\n",
                       aoedev_name ( aoedev ), aoecmd->tag,
                       strerror ( rc ) );
@@ -903,12 +904,14 @@ static int aoedev_open ( struct interface *parent, struct net_device *netdev,
  *
  * @v iobuf            I/O buffer
  * @v netdev           Network device
+ * @v ll_dest          Link-layer destination address
  * @v ll_source                Link-layer source address
  * @ret rc             Return status code
  *
  */
 static int aoe_rx ( struct io_buffer *iobuf,
                    struct net_device *netdev __unused,
+                   const void *ll_dest __unused,
                    const void *ll_source ) {
        struct aoehdr *aoehdr = iobuf->data;
        struct aoe_command *aoecmd;
index 714b471bdfbff10c3cb4da58d0bf425ba32b77db..9b5fd220efd7a9311376dc40be3541012a22ea16 100644 (file)
@@ -155,8 +155,8 @@ int arp_resolve ( struct net_device *netdev, struct net_protocol *net_protocol,
                 dest_net_addr, net_protocol->net_addr_len );
 
        /* Transmit ARP request */
-       if ( ( rc = net_tx ( iobuf, netdev, &arp_protocol, 
-                            netdev->ll_broadcast ) ) != 0 )
+       if ( ( rc = net_tx ( iobuf, netdev, &arp_protocol,
+                            netdev->ll_broadcast, netdev->ll_addr ) ) != 0 )
                return rc;
 
        return -ENOENT;
@@ -195,6 +195,7 @@ static struct arp_net_protocol * arp_find_protocol ( uint16_t net_proto ) {
  * details.
  */
 static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev,
+                   const void *ll_dest __unused,
                    const void *ll_source __unused ) {
        struct arphdr *arphdr = iobuf->data;
        struct arp_net_protocol *arp_net_protocol;
@@ -261,7 +262,7 @@ static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev,
 
        /* Send reply */
        net_tx ( iob_disown ( iobuf ), netdev, &arp_protocol,
-                arp_target_ha ( arphdr ) );
+                arp_target_ha ( arphdr ), netdev->ll_addr );
 
  done:
        free_iob ( iobuf );
index 7246c7b8aba920da39d87092f4998aac3b0b8986..9e5f2640157a57f52214c136af3f816db645039d 100644 (file)
@@ -36,13 +36,13 @@ FILE_LICENCE ( GPL2_OR_LATER );
  *
  * @v iob      I/O buffer
  * @v netdev   Network device
+ * @v ll_dest  Link-layer destination address
  * @v ll_source        Link-layer source address
  *
  * This function takes ownership of the I/O buffer passed to it.
  */
 static int eapol_rx ( struct io_buffer *iob, struct net_device *netdev,
-                     const void *ll_source )
-{
+                     const void *ll_dest, const void *ll_source ) {
        struct eapol_frame *eapol = iob->data;
        struct eapol_handler *handler;
 
@@ -54,7 +54,7 @@ static int eapol_rx ( struct io_buffer *iob, struct net_device *netdev,
        for_each_table_entry ( handler, EAPOL_HANDLERS ) {
                if ( handler->type == eapol->type ) {
                        iob_pull ( iob, EAPOL_HDR_LEN );
-                       return handler->rx ( iob, netdev, ll_source );
+                       return handler->rx ( iob, netdev, ll_dest, ll_source );
                }
        }
 
index 4b2df28006eb6cf5a6f22f2407049aa1560f6d28..e5c7ec9d19beb4f6f5f26c1231deb6158474433c 100644 (file)
@@ -174,7 +174,8 @@ static int eth_slow_lacp_rx ( struct io_buffer *iobuf,
 
        /* Send response */
        eth_slow_lacp_dump ( iobuf, netdev, "TX" );
-       return net_tx ( iobuf, netdev, &eth_slow_protocol, eth_slow_address );
+       return net_tx ( iobuf, netdev, &eth_slow_protocol, eth_slow_address,
+                       netdev->ll_addr );
 }
 
 /**
@@ -218,7 +219,7 @@ static int eth_slow_marker_rx ( struct io_buffer *iobuf,
                marker->marker.tlv.type = ETH_SLOW_TLV_MARKER_RESPONSE;
                eth_slow_marker_dump ( iobuf, netdev, "TX" );
                return net_tx ( iobuf, netdev, &eth_slow_protocol,
-                               eth_slow_address );
+                               eth_slow_address, netdev->ll_addr );
        } else {
                /* Discard all other marker packets */
                free_iob ( iobuf );
@@ -231,11 +232,13 @@ static int eth_slow_marker_rx ( struct io_buffer *iobuf,
  *
  * @v iobuf            I/O buffer
  * @v netdev           Network device
+ * @v ll_dest          Link-layer destination address
  * @v ll_source                Link-layer source address
  * @ret rc             Return status code
  */
 static int eth_slow_rx ( struct io_buffer *iobuf,
                         struct net_device *netdev,
+                        const void *ll_dest __unused,
                         const void *ll_source __unused ) {
        union eth_slow_packet *eth_slow = iobuf->data;
 
index 87726044ed4bc4ef45695689059c17a15ea8d062..11acfca219bc74395b16987e875be30b9ed0c9cb 100644 (file)
@@ -129,7 +129,7 @@ static int fcoe_deliver ( struct fcoe_port *fcoe,
 
        /* Transmit packet */
        if ( ( rc = net_tx ( iob_disown ( iobuf ), fcoe->netdev, &fcoe_protocol,
-                            fcoe->fcf_ll_addr ) ) != 0 ) {
+                            fcoe->fcf_ll_addr, fcoe->netdev->ll_addr )) != 0){
                DBGC ( fcoe, "FCoE %s could not transmit: %s\n",
                       fcoe->netdev->name, strerror ( rc ) );
                goto done;
@@ -164,12 +164,12 @@ static struct io_buffer * fcoe_alloc_iob ( struct fcoe_port *fcoe __unused,
  *
  * @v iobuf            I/O buffer
  * @v netdev           Network device
+ * @v ll_dest          Link-layer destination address
  * @v ll_source                Link-layer source address
  * @ret rc             Return status code
  */
-static int fcoe_rx ( struct io_buffer *iobuf,
-                    struct net_device *netdev,
-                    const void *ll_source ) {
+static int fcoe_rx ( struct io_buffer *iobuf, struct net_device *netdev,
+                    const void *ll_dest __unused, const void *ll_source ) {
        struct fcoe_header *fcoehdr;
        struct fcoe_footer *fcoeftr;
        struct fcoe_port *fcoe;
index 5918bbecf5e6b26504725029ae48d059837989ea..f6a1e6e0f84d3dc5a2310f4170c0a5fdc25b9b60 100644 (file)
@@ -355,7 +355,8 @@ static int ipv4_tx ( struct io_buffer *iobuf,
              ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
 
        /* Hand off to link layer */
-       if ( ( rc = net_tx ( iobuf, netdev, &ipv4_protocol, ll_dest ) ) != 0 ) {
+       if ( ( rc = net_tx ( iobuf, netdev, &ipv4_protocol, ll_dest,
+                            netdev->ll_addr ) ) != 0 ) {
                DBG ( "IPv4 could not transmit packet via %s: %s\n",
                      netdev->name, strerror ( rc ) );
                return rc;
@@ -373,12 +374,15 @@ static int ipv4_tx ( struct io_buffer *iobuf,
  *
  * @v iobuf    I/O buffer
  * @v netdev   Network device
+ * @v ll_dest  Link-layer destination address
  * @v ll_source        Link-layer destination source
  *
  * This function expects an IP4 network datagram. It processes the headers 
  * and sends it to the transport layer.
  */
-static int ipv4_rx ( struct io_buffer *iobuf, struct net_device *netdev __unused,
+static int ipv4_rx ( struct io_buffer *iobuf,
+                    struct net_device *netdev __unused,
+                    const void *ll_dest __unused,
                     const void *ll_source __unused ) {
        struct iphdr *iphdr = iobuf->data;
        size_t hdrlen;
index ffaa558bf05428e2bf765c1e6509089c591e2459..712aa49e5459de2db9cc059747c6c6080dde6e17 100644 (file)
@@ -242,7 +242,8 @@ static int ipv6_tx ( struct io_buffer *iobuf,
        }
 
        /* Transmit packet */
-       return net_tx ( iobuf, netdev, &ipv6_protocol, ll_dest );
+       return net_tx ( iobuf, netdev, &ipv6_protocol, ll_dest,
+                       netdev->ll_addr );
 
   err:
        free_iob ( iobuf );
@@ -285,12 +286,14 @@ static int ipv6_process_nxt_hdr ( struct io_buffer *iobuf, uint8_t nxt_hdr,
  *
  * @v iobuf            I/O buffer
  * @v netdev           Network device
+ * @v ll_dest          Link-layer destination address
  * @v ll_source                Link-layer source address
  *
  * This function processes a IPv6 packet
  */
 static int ipv6_rx ( struct io_buffer *iobuf,
                     __unused struct net_device *netdev,
+                    __unused const void *ll_dest,
                     __unused const void *ll_source ) {
 
        struct ip6_header *ip6hdr = iobuf->data;
index bb8a5b28130b82864a26b690775cc154bc4e1bcd..894b7e7904d0ff8a43d62c623b7d9143de4a01a7 100644 (file)
@@ -607,6 +607,7 @@ struct net_device * last_opened_netdev ( void ) {
  * @v netdev           Network device
  * @v net_protocol     Network-layer protocol
  * @v ll_dest          Destination link-layer address
+ * @v ll_source                Source link-layer address
  * @ret rc             Return status code
  *
  * Prepends link-layer headers to the I/O buffer and transmits the
@@ -614,7 +615,8 @@ struct net_device * last_opened_netdev ( void ) {
  * ownership of the I/O buffer.
  */
 int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
-            struct net_protocol *net_protocol, const void *ll_dest ) {
+            struct net_protocol *net_protocol, const void *ll_dest,
+            const void *ll_source ) {
        struct ll_protocol *ll_protocol = netdev->ll_protocol;
        int rc;
 
@@ -626,7 +628,7 @@ int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
        netdev_poll ( netdev );
 
        /* Add link-layer header */
-       if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest, netdev->ll_addr,
+       if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest, ll_source,
                                        net_protocol->net_proto ) ) != 0 ) {
                free_iob ( iobuf );
                return rc;
@@ -642,17 +644,19 @@ int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
  * @v iobuf            I/O buffer
  * @v netdev           Network device
  * @v net_proto                Network-layer protocol, in network-byte order
+ * @v ll_dest          Destination link-layer address
  * @v ll_source                Source link-layer address
  * @ret rc             Return status code
  */
 int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
-            uint16_t net_proto, const void *ll_source ) {
+            uint16_t net_proto, const void *ll_dest, const void *ll_source ) {
        struct net_protocol *net_protocol;
 
        /* Hand off to network-layer protocol, if any */
        for_each_table_entry ( net_protocol, NET_PROTOCOLS ) {
                if ( net_protocol->net_proto == net_proto )
-                       return net_protocol->rx ( iobuf, netdev, ll_source );
+                       return net_protocol->rx ( iobuf, netdev, ll_dest,
+                                                 ll_source );
        }
 
        DBGC ( netdev, "NETDEV %p unknown network protocol %04x\n",
@@ -707,7 +711,8 @@ static void net_step ( struct process *process __unused ) {
 
                        /* Hand packet to network layer */
                        if ( ( rc = net_rx ( iob_disown ( iobuf ), netdev,
-                                            net_proto, ll_source ) ) != 0 ) {
+                                            net_proto, ll_dest,
+                                            ll_source ) ) != 0 ) {
                                /* Record error for diagnosis */
                                netdev_rx_err ( netdev, NULL, rc );
                        }
index bf2e7f0ae91683e5acf383cc17c6a9ec52717df1..da67c459dba2a9b9e0fba0029e97503f02b66f4b 100644 (file)
@@ -36,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
  *
  * @v iobuf            I/O buffer
  * @v netdev           Network device
+ * @v ll_dest          Link-layer destination address
  * @v ll_source                Link-layer source address
  * @ret rc             Return status code
  *
@@ -43,6 +44,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
  */
 static int rarp_rx ( struct io_buffer *iobuf,
                     struct net_device *netdev __unused,
+                    const void *ll_dest __unused,
                     const void *ll_source __unused ) {
        free_iob ( iobuf );
        return 0;
index 8bbda51a48532dcfe4f37461a7dec782c66a5a6f..407f68443d225350f25213c98280f67611e90b08 100644 (file)
@@ -45,11 +45,13 @@ FILE_LICENCE ( GPL2_OR_LATER );
  *
  * @v iobuf            I/O buffer
  * @v netdev           Network device
+ * @v ll_dest          Link-layer destination address
  * @v ll_source                Link-layer source address
  * @ret rc             Return status code
  */
 static int lotest_rx ( struct io_buffer *iobuf,
                       struct net_device *netdev __unused,
+                      const void *ll_dest __unused,
                       const void *ll_source __unused ) {
        free_iob ( iobuf );
        return -ENOTSUP;
@@ -138,8 +140,8 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
 
                /* Transmit packet */
                if ( ( rc = net_tx ( iob_disown ( iobuf ), sender,
-                                    &lotest_protocol,
-                                    receiver->ll_addr ) ) != 0 ) {
+                                    &lotest_protocol, receiver->ll_addr,
+                                    sender->ll_addr ) ) != 0 ) {
                        printf ( "\nFailed to transmit packet: %s",
                                 strerror ( rc ) );
                        goto done;