ndp.c File Reference

Neighbour Discovery Protocol. More...

#include <stdint.h>
#include <string.h>
#include <byteswap.h>
#include <errno.h>
#include <gpxe/if_ether.h>
#include <gpxe/iobuf.h>
#include <gpxe/ndp.h>
#include <gpxe/icmp6.h>
#include <gpxe/ip6.h>
#include <gpxe/netdevice.h>

Go to the source code of this file.

Data Structures

struct  ndp_entry

Defines

#define NUM_NDP_ENTRIES   4
 Number of entries in the neighbour cache table.
#define ndp_table_end   &ndp_table[NUM_NDP_ENTRIES]

Functions

static struct ndp_entryndp_find_entry (struct in6_addr *in6)
 Find entry in the neighbour cache.
static void add_ndp_entry (struct net_device *netdev, struct in6_addr *in6, void *ll_addr, int state)
 Add NDP entry.
int ndp_resolve (struct net_device *netdev, struct in6_addr *dest, struct in6_addr *src, void *dest_ll_addr)
 Resolve the link-layer address.
int ndp_process_advert (struct io_buffer *iobuf, struct sockaddr_tcpip *st_src __unused, struct sockaddr_tcpip *st_dest __unused)
 Process neighbour advertisement.

Variables

static struct ndp_entry ndp_table [NUM_NDP_ENTRIES]
 The neighbour cache table.
static unsigned int next_new_ndp_entry = 0


Detailed Description

Neighbour Discovery Protocol.

This file implements address resolution as specified by the neighbour discovery protocol in RFC2461. This protocol is part of the IPv6 protocol family.

Definition in file ndp.c.


Define Documentation

#define NUM_NDP_ENTRIES   4

Number of entries in the neighbour cache table.

Definition at line 34 of file ndp.c.

Referenced by add_ndp_entry().

#define ndp_table_end   &ndp_table[NUM_NDP_ENTRIES]

Definition at line 38 of file ndp.c.

Referenced by ndp_find_entry().


Function Documentation

static struct ndp_entry* ndp_find_entry ( struct in6_addr in6  )  [static, read]

Find entry in the neighbour cache.

Parameters:
in6 IP6 address

Definition at line 48 of file ndp.c.

References ndp_entry::in6, IP6_EQUAL, NDP_STATE_INVALID, ndp_table, ndp_table_end, NULL, and ndp_entry::state.

Referenced by ndp_process_advert(), and ndp_resolve().

00048                                         {
00049         struct ndp_entry *ndp;
00050 
00051         for ( ndp = ndp_table ; ndp < ndp_table_end ; ndp++ ) {
00052                 if ( IP6_EQUAL ( ( *in6 ), ndp->in6 ) && 
00053                      ( ndp->state != NDP_STATE_INVALID ) ) {
00054                         return ndp;
00055                 }
00056         }
00057         return NULL;
00058 }

static void add_ndp_entry ( struct net_device netdev,
struct in6_addr in6,
void *  ll_addr,
int  state 
) [static]

Add NDP entry.

Parameters:
netdev Network device
in6 IP6 address
ll_addr Link-layer address
state State of the entry - one of the NDP_STATE_XXX values

Definition at line 69 of file ndp.c.

References DBG, ndp_entry::in6, inet6_ntoa(), ndp_entry::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, ndp_entry::ll_protocol, memcpy, memset(), ll_protocol::name, ndp_table, next_new_ndp_entry, ll_protocol::ntoa, NUM_NDP_ENTRIES, and ndp_entry::state.

Referenced by ndp_resolve().

00070                                            {
00071         struct ndp_entry *ndp;
00072         ndp = &ndp_table[next_new_ndp_entry++ % NUM_NDP_ENTRIES];
00073 
00074         /* Fill up entry */
00075         ndp->ll_protocol = netdev->ll_protocol;
00076         memcpy ( &ndp->in6, &( *in6 ), sizeof ( *in6 ) );
00077         if ( ll_addr ) {
00078                 memcpy ( ndp->ll_addr, ll_addr, netdev->ll_protocol->ll_addr_len );
00079         } else {
00080                 memset ( ndp->ll_addr, 0, netdev->ll_protocol->ll_addr_len );
00081         }
00082         ndp->state = state;
00083         DBG ( "New neighbour cache entry: IP6 %s => %s %s\n",
00084               inet6_ntoa ( ndp->in6 ), netdev->ll_protocol->name,
00085               netdev->ll_protocol->ntoa ( ndp->ll_addr ) );
00086 }

int ndp_resolve ( struct net_device netdev,
struct in6_addr dest,
struct in6_addr src,
void *  dest_ll_addr 
)

Resolve the link-layer address.

Parameters:
netdev Network device
dest Destination address
src Source address
Return values:
dest_ll_addr Destination link-layer address or NULL
rc Status
This function looks up the neighbour cache for an entry corresponding to the destination address. If it finds a valid entry, it fills up dest_ll_addr and returns 0. Otherwise it sends a neighbour solicitation to the solicited multicast address.

Definition at line 102 of file ndp.c.

References add_ndp_entry(), DBG, ENOENT, icmp6_send_solicit(), inet6_ntoa(), ndp_entry::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, memcpy, ll_protocol::name, ndp_find_entry(), NDP_STATE_INCOMPLETE, NDP_STATE_REACHABLE, ll_protocol::ntoa, NULL, and ndp_entry::state.

Referenced by ipv6_tx().

00103                                                              {
00104         struct ll_protocol *ll_protocol = netdev->ll_protocol;
00105         struct ndp_entry *ndp;
00106         int rc;
00107 
00108         ndp = ndp_find_entry ( dest );
00109         /* Check if the entry is valid */
00110         if ( ndp && ndp->state == NDP_STATE_REACHABLE ) {
00111                 DBG ( "Neighbour cache hit: IP6 %s => %s %s\n",
00112                       inet6_ntoa ( *dest ), ll_protocol->name,
00113                       ll_protocol->ntoa ( ndp->ll_addr ) );
00114                 memcpy ( dest_ll_addr, ndp->ll_addr, ll_protocol->ll_addr_len );
00115                 return 0;
00116         }
00117 
00118         /* Check if the entry was already created */
00119         if ( ndp ) {
00120                 DBG ( "Awaiting neighbour advertisement\n" );
00121                 /* For test */
00122 //              ndp->state = NDP_STATE_REACHABLE;
00123 //              memcpy ( ndp->ll_addr, netdev->ll_addr, 6 );
00124 //              assert ( ndp->ll_protocol->ll_addr_len == 6 );
00125 //              icmp6_test_nadvert ( netdev, dest, ndp->ll_addr );
00126 //              assert ( ndp->state == NDP_STATE_REACHABLE );
00127                 /* Take it out till here */
00128                 return -ENOENT;
00129         }
00130         DBG ( "Neighbour cache miss: IP6 %s\n", inet6_ntoa ( *dest ) );
00131 
00132         /* Add entry in the neighbour cache */
00133         add_ndp_entry ( netdev, dest, NULL, NDP_STATE_INCOMPLETE );
00134 
00135         /* Send neighbour solicitation */
00136         if ( ( rc = icmp6_send_solicit ( netdev, src, dest ) ) != 0 ) {
00137                 return rc;
00138         }
00139         return -ENOENT;
00140 }

int ndp_process_advert ( struct io_buffer iobuf,
struct sockaddr_tcpip *st_src  __unused,
struct sockaddr_tcpip *st_dest  __unused 
)

Process neighbour advertisement.

Parameters:
iobuf I/O buffer
st_src Source address
st_dest Destination address

Definition at line 149 of file ndp.c.

References assert, neighbour_advert::code, io_buffer::data, DBG, EINVAL, neighbour_advert::flags, ICMP6_FLAGS_SOLICITED, ndp_entry::in6, iob_len(), IP6_EQUAL, ndp_entry::ll_addr, ll_protocol::ll_addr_len, ndp_entry::ll_protocol, memcpy, ndp_find_entry(), NDP_STATE_REACHABLE, neighbour_advert::opt_len, neighbour_advert::opt_ll_addr, neighbour_advert::opt_type, ndp_entry::state, and neighbour_advert::target.

Referenced by icmp6_rx().

00150                                                                      {
00151         struct neighbour_advert *nadvert = iobuf->data;
00152         struct ndp_entry *ndp;
00153 
00154         /* Sanity check */
00155         if ( iob_len ( iobuf ) < sizeof ( *nadvert ) ) {
00156                 DBG ( "Packet too short (%zd bytes)\n", iob_len ( iobuf ) );
00157                 return -EINVAL;
00158         }
00159 
00160         assert ( nadvert->code == 0 );
00161         assert ( nadvert->flags & ICMP6_FLAGS_SOLICITED );
00162         assert ( nadvert->opt_type == 2 );
00163 
00164         /* Update the neighbour cache, if entry is present */
00165         ndp = ndp_find_entry ( &nadvert->target );
00166         if ( ndp ) {
00167 
00168         assert ( nadvert->opt_len ==
00169                         ( ( 2 + ndp->ll_protocol->ll_addr_len ) / 8 ) );
00170 
00171                 if ( IP6_EQUAL ( ndp->in6, nadvert->target ) ) {
00172                         memcpy ( ndp->ll_addr, nadvert->opt_ll_addr,
00173                                  ndp->ll_protocol->ll_addr_len );
00174                         ndp->state = NDP_STATE_REACHABLE;
00175                         return 0;
00176                 }
00177         }
00178         DBG ( "Unsolicited advertisement (dropping packet)\n" );
00179         return 0;
00180 }


Variable Documentation

struct ndp_entry ndp_table[NUM_NDP_ENTRIES] [static]

The neighbour cache table.

Definition at line 37 of file ndp.c.

Referenced by add_ndp_entry(), and ndp_find_entry().

unsigned int next_new_ndp_entry = 0 [static]

Definition at line 40 of file ndp.c.

Referenced by add_ndp_entry().


Generated on Tue Apr 6 20:01:55 2010 for gPXE by  doxygen 1.5.7.1