[ipv6] Implement router solicitations and integrate with the "ipv6" command
authorMatthew Iselin <matthew@theiselins.net>
Sat, 4 Jun 2011 02:10:23 +0000 (12:10 +1000)
committerMarty Connor <mdc@etherboot.org>
Thu, 21 Jul 2011 00:56:55 +0000 (20:56 -0400)
Signed-off-by: Matthew Iselin <matthew@theiselins.net>
Signed-off-by: Marty Connor <mdc@etherboot.org>
src/include/gpxe/icmp6.h
src/include/gpxe/ndp.h
src/net/icmpv6.c
src/usr/ip6mgmt.c

index 6040258..23b7b56 100644 (file)
@@ -65,6 +65,8 @@ int icmp6_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src,
 
 int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src, struct in6_addr *dest );
 
 
 int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src, struct in6_addr *dest );
 
+int icmp6_send_rsolicit ( struct net_device *netdev );
+
 int icmp6_send_advert ( struct net_device *netdev, struct in6_addr *src, struct in6_addr *dest );
 
 #endif /* _GPXE_ICMP6_H */
 int icmp6_send_advert ( struct net_device *netdev, struct in6_addr *src, struct in6_addr *dest );
 
 #endif /* _GPXE_ICMP6_H */
index 6830362..be387ce 100644 (file)
@@ -4,13 +4,14 @@
 #include <stdint.h>
 #include <byteswap.h>
 #include <string.h>
 #include <stdint.h>
 #include <byteswap.h>
 #include <string.h>
-#include <gpxe/icmp6.h>
 #include <gpxe/ip6.h>
 #include <gpxe/in.h>
 #include <gpxe/netdevice.h>
 #include <gpxe/iobuf.h>
 #include <gpxe/tcpip.h>
 
 #include <gpxe/ip6.h>
 #include <gpxe/in.h>
 #include <gpxe/netdevice.h>
 #include <gpxe/iobuf.h>
 #include <gpxe/tcpip.h>
 
+struct icmp6_net_protocol;
+
 #define NDP_STATE_INVALID 0
 #define NDP_STATE_INCOMPLETE 1
 #define NDP_STATE_REACHABLE 2
 #define NDP_STATE_INVALID 0
 #define NDP_STATE_INCOMPLETE 1
 #define NDP_STATE_REACHABLE 2
index fb4d9ea..dcc5851 100644 (file)
@@ -64,7 +64,49 @@ int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src __unuse
 
        /* Send packet over IP6 */
        return tcpip_tx ( iobuf, &icmp6_protocol, NULL, &st_dest.st,
 
        /* Send packet over IP6 */
        return tcpip_tx ( iobuf, &icmp6_protocol, NULL, &st_dest.st,
-                         NULL, &nsolicit->csum );
+                         netdev, &nsolicit->csum );
+}
+
+/**
+ * Send router solicitation packet
+ *
+ * @v netdev   Network device
+ * @v src      Source address
+ * @v dest     Destination address
+ *
+ * This function prepares a neighbour solicitation packet and sends it to the
+ * network layer.
+ */
+int icmp6_send_rsolicit ( struct net_device *netdev ) {
+       union {
+               struct sockaddr_in6 sin6;
+               struct sockaddr_tcpip st;
+       } st_dest;
+       struct router_solicit *solicit;
+       struct io_buffer *iobuf = alloc_iob ( sizeof ( *solicit ) + MIN_IOB_LEN );
+       
+       iob_reserve ( iobuf, MAX_HDR_LEN );
+       solicit = iob_put ( iobuf, sizeof ( *solicit ) );
+
+       /* Fill up the headers */
+       memset ( solicit, 0, sizeof ( *solicit ) );
+       solicit->type = ICMP6_ROUTER_SOLICIT;
+       solicit->code = 0;
+       
+       /* Partial checksum */
+       solicit->csum = 0;
+       solicit->csum = tcpip_chksum ( solicit, sizeof ( *solicit ) );
+
+       /* Solicited multicast address - FF02::2 (all routers on local network) */
+       memset(&st_dest.sin6, 0, sizeof(st_dest.sin6));
+       st_dest.sin6.sin_family = AF_INET6;
+       st_dest.sin6.sin6_addr.in6_u.u6_addr8[0] = 0xff;
+       st_dest.sin6.sin6_addr.in6_u.u6_addr8[1] = 0x2;
+       st_dest.sin6.sin6_addr.in6_u.u6_addr8[15] = 0x2;
+
+       /* Send packet over IP6 */
+       return tcpip_tx ( iobuf, &icmp6_protocol, NULL, &st_dest.st,
+                         netdev, &solicit->csum );
 }
 
 /**
 }
 
 /**
index f0b69d4..4f8cebb 100644 (file)
@@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <gpxe/netdevice.h>
 #include <gpxe/in.h>
 #include <gpxe/ip6.h>
 #include <gpxe/netdevice.h>
 #include <gpxe/in.h>
 #include <gpxe/ip6.h>
+#include <gpxe/icmp6.h>
 #include <gpxe/monojob.h>
 #include <gpxe/process.h>
 #include <usr/ifmgmt.h>
 #include <gpxe/monojob.h>
 #include <gpxe/process.h>
 #include <usr/ifmgmt.h>
@@ -78,6 +79,9 @@ int ip6_autoconf ( struct net_device *netdev ) {
        /* Add as a route. */
        add_ipv6_address ( netdev, ip6addr, 10, ip6addr, ip6zero );
        
        /* Add as a route. */
        add_ipv6_address ( netdev, ip6addr, 10, ip6addr, ip6zero );
        
+       /* Solicit routers on the network. */
+       icmp6_send_rsolicit ( netdev );
+       
        return 0;
 }
 
        return 0;
 }