mirror of https://github.com/ipxe/ipxe.git
IPv6 minirouting table entries hold persistent references to net devices.
parent
b22d4405c0
commit
b29861a5aa
|
@ -69,5 +69,10 @@ extern struct net_protocol ipv6_protocol;
|
||||||
extern struct tcpip_net_protocol ipv6_tcpip_protocol;
|
extern struct tcpip_net_protocol ipv6_tcpip_protocol;
|
||||||
extern char * inet6_ntoa ( struct in6_addr in6 );
|
extern char * inet6_ntoa ( struct in6_addr in6 );
|
||||||
|
|
||||||
|
extern int add_ipv6_address ( struct net_device *netdev,
|
||||||
|
struct in6_addr prefix, int prefix_len,
|
||||||
|
struct in6_addr address,
|
||||||
|
struct in6_addr gateway );
|
||||||
|
extern void del_ipv6_address ( struct net_device *netdev );
|
||||||
|
|
||||||
#endif /* _GPXE_IP6_H */
|
#endif /* _GPXE_IP6_H */
|
||||||
|
|
|
@ -30,8 +30,12 @@ static struct in6_addr ip6_none = {
|
||||||
struct ipv6_miniroute {
|
struct ipv6_miniroute {
|
||||||
/* List of miniroutes */
|
/* List of miniroutes */
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
||||||
/* Network device */
|
/* Network device */
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
|
/** Reference to network device */
|
||||||
|
struct reference netdev_ref;
|
||||||
|
|
||||||
/* Destination prefix */
|
/* Destination prefix */
|
||||||
struct in6_addr prefix;
|
struct in6_addr prefix;
|
||||||
/* Prefix length */
|
/* Prefix length */
|
||||||
|
@ -45,6 +49,71 @@ struct ipv6_miniroute {
|
||||||
/** List of IPv6 miniroutes */
|
/** List of IPv6 miniroutes */
|
||||||
static LIST_HEAD ( miniroutes );
|
static LIST_HEAD ( miniroutes );
|
||||||
|
|
||||||
|
static void ipv6_forget_netdev ( struct reference *ref );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add IPv6 minirouting table entry
|
||||||
|
*
|
||||||
|
* @v netdev Network device
|
||||||
|
* @v prefix Destination prefix
|
||||||
|
* @v address Address of the interface
|
||||||
|
* @v gateway Gateway address (or ::0 for no gateway)
|
||||||
|
* @ret miniroute Routing table entry, or NULL
|
||||||
|
*/
|
||||||
|
static struct ipv6_miniroute * add_ipv6_miniroute ( struct net_device *netdev,
|
||||||
|
struct in6_addr prefix,
|
||||||
|
int prefix_len,
|
||||||
|
struct in6_addr address,
|
||||||
|
struct in6_addr gateway ) {
|
||||||
|
struct ipv6_miniroute *miniroute;
|
||||||
|
|
||||||
|
miniroute = malloc ( sizeof ( *miniroute ) );
|
||||||
|
if ( miniroute ) {
|
||||||
|
/* Record routing information */
|
||||||
|
miniroute->netdev = netdev;
|
||||||
|
miniroute->prefix = prefix;
|
||||||
|
miniroute->prefix_len = prefix_len;
|
||||||
|
miniroute->address = address;
|
||||||
|
miniroute->gateway = gateway;
|
||||||
|
|
||||||
|
/* Add miniroute to list of miniroutes */
|
||||||
|
if ( !IP6_EQUAL ( gateway, ip6_none ) ) {
|
||||||
|
list_add_tail ( &miniroute->list, &miniroutes );
|
||||||
|
} else {
|
||||||
|
list_add ( &miniroute->list, &miniroutes );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Record reference to net_device */
|
||||||
|
miniroute->netdev_ref.forget = ipv6_forget_netdev;
|
||||||
|
ref_add ( &miniroute->netdev_ref, &netdev->references );
|
||||||
|
}
|
||||||
|
|
||||||
|
return miniroute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete IPv6 minirouting table entry
|
||||||
|
*
|
||||||
|
* @v miniroute Routing table entry
|
||||||
|
*/
|
||||||
|
static void del_ipv6_miniroute ( struct ipv6_miniroute *miniroute ) {
|
||||||
|
ref_del ( &miniroute->netdev_ref );
|
||||||
|
list_del ( &miniroute->list );
|
||||||
|
free ( miniroute );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forget reference to net_device
|
||||||
|
*
|
||||||
|
* @v ref Persistent reference
|
||||||
|
*/
|
||||||
|
static void ipv6_forget_netdev ( struct reference *ref ) {
|
||||||
|
struct ipv6_miniroute *miniroute
|
||||||
|
= container_of ( ref, struct ipv6_miniroute, netdev_ref );
|
||||||
|
|
||||||
|
del_ipv6_miniroute ( miniroute );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add IPv6 interface
|
* Add IPv6 interface
|
||||||
*
|
*
|
||||||
|
@ -58,23 +127,15 @@ int add_ipv6_address ( struct net_device *netdev, struct in6_addr prefix,
|
||||||
struct in6_addr gateway ) {
|
struct in6_addr gateway ) {
|
||||||
struct ipv6_miniroute *miniroute;
|
struct ipv6_miniroute *miniroute;
|
||||||
|
|
||||||
miniroute = malloc ( sizeof ( *miniroute ) );
|
/* Clear any existing address for this net device */
|
||||||
if ( !miniroute ) {
|
del_ipv6_address ( netdev );
|
||||||
DBG ( "Not enough memory\n" );
|
|
||||||
return -ENOMEM;
|
/* Add new miniroute */
|
||||||
}
|
miniroute = add_ipv6_miniroute ( netdev, prefix, prefix_len, address,
|
||||||
miniroute->netdev = netdev;
|
gateway );
|
||||||
miniroute->prefix = prefix;
|
if ( ! miniroute )
|
||||||
miniroute->prefix_len = prefix_len;
|
return -ENOMEM;
|
||||||
miniroute->address = address;
|
|
||||||
miniroute->gateway = gateway;
|
|
||||||
|
|
||||||
/* Add miniroute to list of miniroutes */
|
|
||||||
if ( !IP6_EQUAL ( gateway, ip6_none ) ) {
|
|
||||||
list_add_tail ( &miniroute->list, &miniroutes );
|
|
||||||
} else {
|
|
||||||
list_add ( &miniroute->list, &miniroutes );
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +149,7 @@ void del_ipv6_address ( struct net_device *netdev ) {
|
||||||
|
|
||||||
list_for_each_entry ( miniroute, &miniroutes, list ) {
|
list_for_each_entry ( miniroute, &miniroutes, list ) {
|
||||||
if ( miniroute->netdev == netdev ) {
|
if ( miniroute->netdev == netdev ) {
|
||||||
list_del ( &miniroute->list );
|
del_ipv6_miniroute ( miniroute );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue