]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[neighbour] Use discovery protocol field to identify incomplete neighbours
authorMichael Brown <mcb30@ipxe.org>
Mon, 5 Jan 2026 15:46:52 +0000 (15:46 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 6 Jan 2026 15:19:15 +0000 (15:19 +0000)
Use the discovery protocol pointer field (rather than the running
state of the discovery timer) to determine whether or not neighbour
discovery is ongoing, as a precursor to allowing the timer to be
(ab)used for adding deliberate latency to transmitted packets.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/neighbour.h
src/net/neighbour.c
src/usr/neighmgmt.c

index 1ca0ee33355a759c64219516bb27504db6430f60..7e7fac277e3ff4c8bfdc93b98a69a2e222109595 100644 (file)
@@ -49,9 +49,9 @@ struct neighbour {
        /** Link-layer destination address */
        uint8_t ll_dest[MAX_LL_ADDR_LEN];
 
-       /** Neighbour discovery protocol (if any) */
+       /** Neighbour discovery protocol (if discovery is ongoing) */
        struct neighbour_discovery *discovery;
-       /** Network-layer source address (if any) */
+       /** Network-layer source address (for discovery requests) */
        uint8_t net_source[MAX_NET_ADDR_LEN];
        /** Retransmission timer */
        struct retry_timer timer;
@@ -60,17 +60,6 @@ struct neighbour {
        struct list_head tx_queue;
 };
 
-/**
- * Test if neighbour cache entry has a valid link-layer address
- *
- * @v neighbour                Neighbour cache entry
- * @ret has_ll_dest    Neighbour cache entry has a valid link-layer address
- */
-static inline __attribute__ (( always_inline )) int
-neighbour_has_ll_dest ( struct neighbour *neighbour ) {
-       return ( ! timer_running ( &neighbour->timer ) );
-}
-
 extern struct list_head neighbours;
 
 extern int neighbour_tx ( struct io_buffer *iobuf, struct net_device *netdev,
index 253cdc0e6751ace3ee76ac491693cf8054faeed3..908f8e4b213766407e06d3f226e257999964f300 100644 (file)
@@ -186,6 +186,9 @@ static void neighbour_discovered ( struct neighbour *neighbour,
        /* Stop retransmission timer */
        stop_timer ( &neighbour->timer );
 
+       /* Mark discovery as complete */
+       neighbour->discovery = NULL;
+
        /* Transmit any packets in queue.  Take out a temporary
         * reference on the entry to prevent it from going out of
         * scope during the call to net_tx().
@@ -300,6 +303,7 @@ int neighbour_tx ( struct io_buffer *iobuf, struct net_device *netdev,
                   struct neighbour_discovery *discovery,
                   const void *net_source ) {
        struct neighbour *neighbour;
+       int rc;
 
        /* Find or create neighbour cache entry */
        neighbour = neighbour_find ( netdev, net_protocol, net_dest );
@@ -310,19 +314,24 @@ int neighbour_tx ( struct io_buffer *iobuf, struct net_device *netdev,
                neighbour_discover ( neighbour, discovery, net_source );
        }
 
-       /* If a link-layer address is available then transmit
-        * immediately, otherwise queue for later transmission.
+       /* If discovery is still in progress then queue for later
+        * transmission.
         */
-       if ( neighbour_has_ll_dest ( neighbour ) ) {
-               return net_tx ( iobuf, netdev, net_protocol, neighbour->ll_dest,
-                               netdev->ll_addr );
-       } else {
+       if ( neighbour->discovery ) {
                DBGC2 ( neighbour, "NEIGHBOUR %s %s %s deferring packet\n",
                        netdev->name, net_protocol->name,
                        net_protocol->ntoa ( net_dest ) );
                list_add_tail ( &iobuf->list, &neighbour->tx_queue );
                return 0;
        }
+
+       /* Otherwise, transmit immediately */
+       if ( ( rc = net_tx ( iobuf, netdev, net_protocol, neighbour->ll_dest,
+                            netdev->ll_addr ) ) != 0 ) {
+               return rc;
+       }
+
+       return 0;
 }
 
 /**
index 9fd88f82b79543d2bad0be0eb5a2fd19778589d9..fcdcbbfbbf57a05d1a8ead7e69c9aeb2de8d0490 100644 (file)
@@ -50,9 +50,8 @@ void nstat ( void ) {
                printf ( "%s %s %s is %s %s", netdev->name, net_protocol->name,
                         net_protocol->ntoa ( neighbour->net_dest ),
                         ll_protocol->name,
-                        ( neighbour_has_ll_dest ( neighbour ) ?
-                          ll_protocol->ntoa ( neighbour->ll_dest ) :
-                          "(incomplete)" ) );
+                        ( neighbour->discovery ? "(incomplete)" :
+                          ll_protocol->ntoa ( neighbour->ll_dest ) ) );
                if ( neighbour->discovery )
                        printf ( " (%s)", neighbour->discovery->name );
                printf ( "\n" );