Suppose I have C_IP address : 12.120.29.25
and I have list of following IP addresses :
212.120.128.0|19;
12.120.0.0|15;
12.120.16.0|20;
12.120.72.0|22;
12.120.96.0|20;
12.120.40.0|21;
12.120.0.0|21;
12.120.192.0|19;
12.120.16.0|22;
12.120.36.0|22;
12.120.80.0|20;
194.212.120.0|21;
212.120.32.0|19;
212.120.64.0|18;
212.120.192.0|19;
213.3.12.120|29;
116.212.120.0|24;
12.120.24.0|21;
Now I need to map C_IP to list with longest prefix match. (As u can
there are many IP address with 12.120. but I need to map to one with
longest prefix match)
Ok, I searched LPM. Routing table lookup.
This is the key: (C_IP address) 12.120.29.25
32 bit key = 12<<24 + 120<<16 + 29<<8 + 25
Loop(Entries)
{
Example table entry:
12.120.24.0 | 21;
^^^^^^^^^^^
32 bits
^^
Bitmask (the bits to mask) = ((2 ** 21)-1) << (32-21)
32 bit entry = 12<<24 + 120<<16 + 24<<8 + 0
Masked key = 32 bit key & Bitmask;
Masked entry = 32 bit entry & Bitmask;
if (Masked key == Masked entry && Bitmask > LargestBitmask)
{
LPM = 32 bit entry;
LargestBitmask = Bitmask;
}
}
Print the LPM..
Source (there were many, but this seamed easiest):
http://www.xilinx.com/support/documentation/application_notes/xapp738.pdf
For an entry to be considered a match to the search key, it must satisfy these three conditions
(refer also to the numbers in Figure 2):
1. The entry’s Valid bit must be set.
2. The entry’s masked IP address and the masked search key are equal to each other.
An IP address is masked by performing a bitwise AND of the mask and the IP address.
3. The entry’s mask is greater than or equal to the mask of any previously matched entry.
------------------------------------------------------
# output:
# Found possible match 12.120.192.0|19;
# Found possible match 212.120.128.0|19;
# Found possible match 12.120.0.0|15;
# Found possible match 12.120.72.0|22;
# Found possible match 12.120.96.0|20;
# Found possible match 12.120.40.0|21;
# Found possible match 12.120.0.0|21;
# Found possible match 12.120.192.0|19;
# Found possible match 12.120.36.0|22;
# Found possible match 212.120.32.0|19;
# Found possible match 212.120.64.0|18;
# Found possible match 212.120.192.0|19;
# Found possible match 213.3.12.120|29;
# Found possible match 12.120.24.0|21;
#
# LPM = 213.3.12.120|29;
use strict;
use warnings;
use sort 'stable';
my $LPM = '';
my $LargestMask = 0;
my $Key32 = 12<<24 + 120<<16 + 29<<8 + 25;
while (<DATA>)
{
chomp;
if (/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\|(\d*)/)
{
my $Entry32 = $1<<24 + $2<<16 + $3<<8 + $4;
my $Mask = ((2 ** $5)-1) << (32-$5);
my $MaskedKey = $Key32 & $Mask;
my $MaskedEntry = $Entry32 & $Mask;
if ($MaskedKey == $MaskedEntry)
{
print "Found possible match $_\n";
if ($Mask > $LargestMask) {
$LPM = $_;
$LargestMask = $Mask;
}
}
}
}
if (length($LPM)) {
print "LPM = $LPM\n";
} else {
print "Did not find LMP match in list\n";
}
__DATA__
12.120.192.0|19;
212.120.128.0|19;
12.120.0.0|15;
12.120.16.0|20;
12.120.72.0|22;
12.120.96.0|20;
12.120.40.0|21;
12.120.0.0|21;
12.120.192.0|19;
12.120.16.0|22;
12.120.36.0|22;
12.120.80.0|20;
194.212.120.0|21;
212.120.32.0|19;
212.120.64.0|18;
212.120.192.0|19;
213.3.12.120|29;
116.212.120.0|24;
12.120.24.0|21;