[ipv6] Enable ICMPv6 protocols to check addresses against network devices
[gpxe.git] / src / net / ipv6.c
index 5c6b942..c0ae68b 100644 (file)
@@ -60,8 +60,8 @@ add_ipv6_miniroute ( struct net_device *netdev, struct in6_addr prefix,
                     struct in6_addr gateway ) {
        struct ipv6_miniroute *miniroute;
        
-       DBG("ipv6 add: %s/%d ", inet6_ntoa(address), prefix_len);
-       DBG("gw %s\n", inet6_ntoa(gateway));
+       DBG( "ipv6 add: %s/%d ", inet6_ntoa ( address ), prefix_len );
+       DBG( "gw %s\n", inet6_ntoa( gateway ) );
 
        miniroute = malloc ( sizeof ( *miniroute ) );
        if ( miniroute ) {
@@ -329,13 +329,14 @@ static int ipv6_tx ( struct io_buffer *iobuf,
  * @v nxt_hdr  Next header number
  * @v src      Source socket address
  * @v dest     Destination socket address
+ * @v netdev   Net device the packet arrived on
  * @v phcsm Partial checksum over the IPv6 psuedo-header.
  *
  * Refer http://www.iana.org/assignments/ipv6-parameters for the numbers
  */
 static int ipv6_process_nxt_hdr ( struct io_buffer *iobuf, uint8_t nxt_hdr,
                struct sockaddr_tcpip *src, struct sockaddr_tcpip *dest,
-               uint16_t phcsm ) {
+               struct net_device *netdev, uint16_t phcsm ) {
        switch ( nxt_hdr ) {
        case IP6_HOPBYHOP:
        case IP6_ROUTING:
@@ -346,7 +347,7 @@ static int ipv6_process_nxt_hdr ( struct io_buffer *iobuf, uint8_t nxt_hdr,
                DBG ( "Function not implemented for header %d\n", nxt_hdr );
                return -ENOSYS;
        case IP6_ICMP6:
-               break;
+               return icmp6_rx ( iobuf, src, dest, netdev, phcsm );
        case IP6_NO_HEADER:
                DBG ( "No next header\n" );
                return 0;
@@ -418,7 +419,7 @@ static int ipv6_rx ( struct io_buffer *iobuf,
 
        /* Send it to the transport layer */
        return ipv6_process_nxt_hdr ( iobuf, ip6hdr->nxt_hdr, &src.st, &dest.st,
-                                     phcsm );
+                                     netdev, phcsm );
 
   drop:
        DBG ( "IP6 packet dropped\n" );
@@ -539,6 +540,20 @@ static const char * ipv6_ntoa ( const void *net_addr ) {
        return inet6_ntoa ( * ( ( struct in6_addr * ) net_addr ) );
 }
 
+static int ipv6_check ( struct net_device *netdev, const void *net_addr ) {
+       const struct in6_addr *address = net_addr;
+       struct ipv6_miniroute *miniroute;
+
+       list_for_each_entry ( miniroute, &miniroutes, list ) {
+               if ( ( miniroute->netdev == netdev ) &&
+                    ( ! memcmp ( &miniroute->address, address, 16 ) ) ) {
+                       /* Found matching address */
+                       return 0;
+               }
+       }
+       return -ENOENT;
+}
+
 /** IPv6 protocol */
 struct net_protocol ipv6_protocol __net_protocol = {
        .name = "IPV6",
@@ -554,3 +569,10 @@ struct tcpip_net_protocol ipv6_tcpip_protocol __tcpip_net_protocol = {
        .sa_family = AF_INET6,
        .tx = ipv6_tx,
 };
+
+/** IPv6 ICMPv6 protocol, for NDP */
+struct icmp6_net_protocol ipv6_icmp6_protocol __icmp6_net_protocol = {
+       .net_protocol = &ipv6_protocol,
+       .check = ipv6_check,
+};
+