[gPXE-devel] [PATCH 25/31] [ipv6] add a dedicated function for prefix matching

matthew at theiselins.net matthew at theiselins.net
Fri Jul 8 10:28:34 EDT 2011


From: Matthew Iselin <matthew at theiselins.net>

Signed-off-by: Matthew Iselin <matthew at theiselins.net>
---
 src/include/gpxe/ip6.h |    2 +
 src/net/ipv6.c         |   67 ++++++++++++++++++++++++++++++-----------------
 2 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/src/include/gpxe/ip6.h b/src/include/gpxe/ip6.h
index 6204b03..5fc0d02 100644
--- a/src/include/gpxe/ip6.h
+++ b/src/include/gpxe/ip6.h
@@ -74,6 +74,8 @@ extern int inet6_aton ( const char *cp, struct in6_addr *inp );
 
 void ipv6_generate_eui64 ( uint8_t *out, uint8_t *ll );
 
+int ipv6_match_prefix ( struct in6_addr *p1, struct in6_addr *p2, size_t len );
+
 extern int add_ipv6_address ( struct net_device *netdev,
 			      struct in6_addr prefix, int prefix_len,
 			      struct in6_addr address,
diff --git a/src/net/ipv6.c b/src/net/ipv6.c
index 9d63ce8..6e6fe3f 100644
--- a/src/net/ipv6.c
+++ b/src/net/ipv6.c
@@ -66,6 +66,46 @@ void ipv6_generate_eui64 ( uint8_t *out, uint8_t *ll ) {
 }
 
 /**
+ * Verifies that a prefix matches another one.
+ *
+ * @v p1		first prefix
+ * @v p2		second prefix
+ * @v len		prefix length in bits to compare
+ * @ret int		0 if a match, nonzero otherwise
+ */
+int ipv6_match_prefix ( struct in6_addr *p1, struct in6_addr *p2, size_t len ) {
+	uint8_t ip1, ip2;
+	size_t offset, bits;
+	int rc = 0;
+
+	/* Check for a prefix match on the route. */
+	if ( ! memcmp ( p1, p2, len / 8 ) ) {
+		rc = 0;
+
+		/* Handle extra bits in the prefix. */
+		if ( ( len % 8 ) ||
+		     ( len < 8 ) ) {
+			DBG ( "ipv6: prefix is not aligned to a byte.\n" );
+
+			/* Compare the remaining bits. */
+			offset = len / 8;
+			bits = len % 8;
+
+			ip1 = p1->in6_u.u6_addr8[offset];
+			ip2 = p2->in6_u.u6_addr8[offset];
+			if ( ! ( ( ip1 & (0xFF >> (8 - bits)) ) &
+			     ( ip2 ) ) ) {
+				rc = 1;
+			}
+		}
+	} else {
+		rc = 1;
+	}
+
+	return rc;
+}
+
+/**
  * Add IPv6 minirouting table entry
  *
  * @v netdev		Network device
@@ -214,9 +254,9 @@ static int ipv6_tx ( struct io_buffer *iobuf,
 	struct sockaddr_in6 *dest = ( struct sockaddr_in6* ) st_dest;
 	struct in6_addr next_hop, gateway = ip6_none;
 	struct ipv6_miniroute *miniroute;
-	uint8_t ll_dest_buf[MAX_LL_ADDR_LEN], ip1, ip2;
+	uint8_t ll_dest_buf[MAX_LL_ADDR_LEN];
 	const uint8_t *ll_dest = ll_dest_buf;
-	int rc, multicast, linklocal, bits, offset;
+	int rc, multicast, linklocal;
 	
 	/* Check for multicast transmission. */
 	multicast = dest->sin6_addr.in6_u.u6_addr8[0] == 0xFF;
@@ -265,28 +305,7 @@ static int ipv6_tx ( struct io_buffer *iobuf,
 		}
 		
 		/* Check for a prefix match on the route. */
-		if ( ! memcmp ( &next_hop, &miniroute->prefix, miniroute->prefix_len / 8 ) ) {
-			rc = 0;
-			
-			/* Handle extra bits in the prefix. */
-			if ( ( miniroute->prefix_len % 8 ) ||
-			     ( miniroute->prefix_len < 8 ) ) {
-				DBG ( "ipv6: prefix is not aligned to a byte.\n" );
-			
-				/* Compare the remaining bits. */
-				offset = miniroute->prefix_len / 8;
-				bits = miniroute->prefix_len % 8;
-				
-				ip1 = next_hop.in6_u.u6_addr8[offset];
-				ip2 = miniroute->prefix.in6_u.u6_addr8[offset];
-				if ( ! ( ( ip1 & (0xFF >> (8 - bits)) ) &
-				     ( ip2 ) ) ) {
-					rc = 1;
-				}
-			}
-		} else {
-			rc = 1;
-		}
+		rc = ipv6_match_prefix ( &next_hop, &miniroute->prefix, miniroute->prefix_len );
 		
 		/* Matched? */
 		if( rc == 0 ) {
-- 
1.7.2.5



More information about the gPXE-devel mailing list