mirror of
https://github.com/ipxe/ipxe
synced 2026-01-21 18:30:56 +03:00
[neighbour] Use discovery protocol field to identify incomplete neighbours
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>
This commit is contained in:
@@ -49,9 +49,9 @@ struct neighbour {
|
|||||||
/** Link-layer destination address */
|
/** Link-layer destination address */
|
||||||
uint8_t ll_dest[MAX_LL_ADDR_LEN];
|
uint8_t ll_dest[MAX_LL_ADDR_LEN];
|
||||||
|
|
||||||
/** Neighbour discovery protocol (if any) */
|
/** Neighbour discovery protocol (if discovery is ongoing) */
|
||||||
struct neighbour_discovery *discovery;
|
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];
|
uint8_t net_source[MAX_NET_ADDR_LEN];
|
||||||
/** Retransmission timer */
|
/** Retransmission timer */
|
||||||
struct retry_timer timer;
|
struct retry_timer timer;
|
||||||
@@ -60,17 +60,6 @@ struct neighbour {
|
|||||||
struct list_head tx_queue;
|
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 struct list_head neighbours;
|
||||||
|
|
||||||
extern int neighbour_tx ( struct io_buffer *iobuf, struct net_device *netdev,
|
extern int neighbour_tx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||||
|
|||||||
@@ -186,6 +186,9 @@ static void neighbour_discovered ( struct neighbour *neighbour,
|
|||||||
/* Stop retransmission timer */
|
/* Stop retransmission timer */
|
||||||
stop_timer ( &neighbour->timer );
|
stop_timer ( &neighbour->timer );
|
||||||
|
|
||||||
|
/* Mark discovery as complete */
|
||||||
|
neighbour->discovery = NULL;
|
||||||
|
|
||||||
/* Transmit any packets in queue. Take out a temporary
|
/* Transmit any packets in queue. Take out a temporary
|
||||||
* reference on the entry to prevent it from going out of
|
* reference on the entry to prevent it from going out of
|
||||||
* scope during the call to net_tx().
|
* 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,
|
struct neighbour_discovery *discovery,
|
||||||
const void *net_source ) {
|
const void *net_source ) {
|
||||||
struct neighbour *neighbour;
|
struct neighbour *neighbour;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* Find or create neighbour cache entry */
|
/* Find or create neighbour cache entry */
|
||||||
neighbour = neighbour_find ( netdev, net_protocol, net_dest );
|
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 );
|
neighbour_discover ( neighbour, discovery, net_source );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a link-layer address is available then transmit
|
/* If discovery is still in progress then queue for later
|
||||||
* immediately, otherwise queue for later transmission.
|
* transmission.
|
||||||
*/
|
*/
|
||||||
if ( neighbour_has_ll_dest ( neighbour ) ) {
|
if ( neighbour->discovery ) {
|
||||||
return net_tx ( iobuf, netdev, net_protocol, neighbour->ll_dest,
|
|
||||||
netdev->ll_addr );
|
|
||||||
} else {
|
|
||||||
DBGC2 ( neighbour, "NEIGHBOUR %s %s %s deferring packet\n",
|
DBGC2 ( neighbour, "NEIGHBOUR %s %s %s deferring packet\n",
|
||||||
netdev->name, net_protocol->name,
|
netdev->name, net_protocol->name,
|
||||||
net_protocol->ntoa ( net_dest ) );
|
net_protocol->ntoa ( net_dest ) );
|
||||||
list_add_tail ( &iobuf->list, &neighbour->tx_queue );
|
list_add_tail ( &iobuf->list, &neighbour->tx_queue );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Otherwise, transmit immediately */
|
||||||
|
if ( ( rc = net_tx ( iobuf, netdev, net_protocol, neighbour->ll_dest,
|
||||||
|
netdev->ll_addr ) ) != 0 ) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -50,9 +50,8 @@ void nstat ( void ) {
|
|||||||
printf ( "%s %s %s is %s %s", netdev->name, net_protocol->name,
|
printf ( "%s %s %s is %s %s", netdev->name, net_protocol->name,
|
||||||
net_protocol->ntoa ( neighbour->net_dest ),
|
net_protocol->ntoa ( neighbour->net_dest ),
|
||||||
ll_protocol->name,
|
ll_protocol->name,
|
||||||
( neighbour_has_ll_dest ( neighbour ) ?
|
( neighbour->discovery ? "(incomplete)" :
|
||||||
ll_protocol->ntoa ( neighbour->ll_dest ) :
|
ll_protocol->ntoa ( neighbour->ll_dest ) ) );
|
||||||
"(incomplete)" ) );
|
|
||||||
if ( neighbour->discovery )
|
if ( neighbour->discovery )
|
||||||
printf ( " (%s)", neighbour->discovery->name );
|
printf ( " (%s)", neighbour->discovery->name );
|
||||||
printf ( "\n" );
|
printf ( "\n" );
|
||||||
|
|||||||
Reference in New Issue
Block a user