4 ## Copyright (c) 2010-2017 Intel Corporation
6 ## Licensed under the Apache License, Version 2.0 (the "License");
7 ## you may not use this file except in compliance with the License.
8 ## You may obtain a copy of the License at
10 ## http://www.apache.org/licenses/LICENSE-2.0
12 ## Unless required by applicable law or agreed to in writing, software
13 ## distributed under the License is distributed on an "AS IS" BASIS,
14 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ## See the License for the specific language governing permissions and
16 ## limitations under the License.
25 ipv6_tun_bindings.pl [-n <num_entries>] [-tun_ip <ipv6>] [-mac <next_hop_mac>]
26 [-pub_ip <ipv4>] [-port <begin>-<end>] [-set <num_ports>]
27 [-suffix <suffix>] [-test <num_entries>] [-sym|-nosym]
32 This script can be used to generate a binding table for the IPv6 Tunnel
33 task implemented in PROX (ipv6_encap and ipv6_decap).
34 The entries in this table bind a specific tunnel endpoint (lwB4 in lw4over6
35 architecture) to a public IPv4 address and port set.
36 The port set is actually derived from the port specified in the table
37 and a port bitmask in the PROX task configuration ("lookup port mask").
39 The ipv6_encap task uses the binding table to know where to tunnel IPv4
40 traffic to. The ipv6_decap task uses the table to verify tunnel packets
41 have a valid public IPv4 and port combination for the originating tunnel.
43 The table uses the Lua syntax so it can be loaded into PROX. Example:
45 {ip6 = ip6("fe80:0000:0000:0000:0200:00ff:fe00:0000"), mac = mac("fe:80:00:00:00:00"), ip = ip("171.205.239.1"), port = 4608},
46 {ip6 = ip6("fe80:0000:0000:0000:0200:00ff:fe00:0001"), mac = mac("fe:80:00:00:00:00"), ip = ip("171.205.239.1"), port = 4672},
47 {ip6 = ip6("fe80:0000:0000:0000:0200:00ff:fe00:0002"), mac = mac("fe:80:00:00:00:00"), ip = ip("171.205.239.1"), port = 4736},
48 {ip6 = ip6("fe80:0000:0000:0000:0200:00ff:fe00:0003"), mac = mac("fe:80:00:00:00:00"), ip = ip("171.205.239.1"), port = 4800},
51 The script generates consecutive entries, starting from a given IP address
52 and assigning ports within a given range, increasing the port number by a
53 fixed amount which should correspond to the port lookup mask being used.
55 UDF table: In addition to the binding table itself, the script can optionally
56 generate accompanying UDF tables for generating test traffic matching the
57 binding table. Such UDF tables can then be used in a traffic generation tool.
63 =item -n <num_entries>
65 How many entries in the binding table
69 Starting tunnel endpoint IPv6 address (will be incremented)
71 =item -mac <next_hop_mac>
73 MAC address of the next hop to reach the tunnel endpoints
77 Starting public IPv4 address
79 =item -port <begin>-<end>
81 Range of ports where to assign Port Sets
83 =item -set <num_ports>
85 Number of ports in set (should be a power of 2 because bitmasking is used
88 =item -suffix <suffix>
90 Filename suffix to use for the generated file(s)
92 =item -test <num_entries>
94 Number of random entries to put into test UDF table
98 Whether the same random entry from the table should be inserted into both
99 traffic sides or if different entries should be used
103 Shows the full script documentation.
109 Copyright(c) 2010-2017 Intel Corporation.
118 use Socket qw(AF_INET AF_INET6 inet_ntop inet_pton);
122 my ($str, $ip_ref, $family) = @_;
124 my $packed = inet_pton($family, $str);
125 return 0 if (!defined($packed));
127 if ($family == AF_INET6) {
128 #print unpack("H*", $packed). "\n";
129 my @w = unpack("NNNN", $packed);
130 my ($high, $low) = (($w[0] << 32) | $w[1], ($w[2] << 32) | $w[3]);
131 @$ip_ref = ($high, $low);
134 $$ip_ref = unpack("N", $packed);
142 my $packed = pack('NNNN', $in->[0] >> 32, $in->[0] & 0xffffffff,
143 $in->[1] >> 32, $in->[1] & 0xffffffff);
144 return inet_ntop(AF_INET6, $packed);
150 return sprintf('%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x',
151 ($in->[0] >> 48) & 0xffff, ($in->[0] >> 32) & 0xffff,
152 ($in->[0] >> 16) & 0xffff, ($in->[0] ) & 0xffff,
153 ($in->[1] >> 48) & 0xffff, ($in->[1] >> 32) & 0xffff,
154 ($in->[1] >> 16) & 0xffff, ($in->[1] ) & 0xffff);
157 my ($tun_ip_str, $pub_ip_str, $ports_str);
160 'help' => sub () { Pod::Usage::pod2usage( -verbose => 2 ); exit; },
161 'n=i' => \(my $num_B4s = 10),
162 'tun_ip=s' => \(my $tun_ip_str = 'fe80:0000:0000:0000:0200:00ff:0000:0000'),
163 'pub_ip=s' => \(my $pub_ip_str = '171.205.239.1'),
164 'mac=s' => \(my $next_hop_mac = 'fe:80:00:00:00:00'),
165 'port=s' => \(my $ports_str='4608-11968'),
166 'set=n' => \(my $port_set_sz = 64),
167 'suffix=s' => \(my $suffix = ''),
168 'test=n' => \(my $num_test_lines = 200000),
169 'sym!' => \(my $symmetric_traffic = TRUE),
170 ) or pod2usage(-verbose => 1) && exit;
173 parse_ip($tun_ip_str, \@tun_ip, AF_INET6) or print("Invalid starting tunnel IP: $tun_ip_str\n") && pod2usage(-verbose => 1) && exit;
174 parse_ip($pub_ip_str, \(my $pub_ip), AF_INET) or print("Invalid starting public IP: $pub_ip_str\n") && pod2usage(-verbose => 1) && exit;
176 if ($ports_str =~ /^([^d]+)\s*\-\s*([^d]+)$/) {
177 @port_range = ($1, $2);
179 else { print "Invalid port range: $ports_str\n"; pod2usage(-verbose => 1); exit }
181 # Summary of input data
182 print "File suffix: $suffix\n" if ($suffix);
183 print "Starting Tunnel IP: " . ntop6(\@tun_ip) . "\n";
184 print "Starting Public IP: ".inet_ntop(AF_INET, pack("N", $pub_ip)) . "\n";
185 print "Public Port Range: $port_range[0]-$port_range[1] by blocks of $port_set_sz\n";
187 my @data; # Holds generated binding table, so we can later generate test traffic for it
189 # Binding table for PROX IPv6 Tunnel
190 my $filename = 'ip6_tun_bind'.$suffix.'.lua';
191 print "\nGenerating binding table with $num_B4s entries into $filename ... ";
192 open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
193 print $fh "-- Bindings for lwaftr: lwB4 IPv6 address, next hop MAC address\n";
194 print $fh "-- towards lwB4, IPv4 Public address, IPv4 Public Port Set\n";
196 print $fh "return {" . "\n";
197 my $port = $port_range[0];
198 for (my $B4_id = 0; $B4_id < $num_B4s; $B4_id++) {
199 $data[$B4_id]{'b4_ipv6'} = ntop6_expanded(\@tun_ip);
200 $data[$B4_id]{'pub_ipv4'} = "" . (($pub_ip >> 24) & 0xff) . "." . (($pub_ip >> 16) & 0xff) . "." . (($pub_ip >> 8) & 0xff) . "." . ($pub_ip & 0xff);
201 $data[$B4_id]{'pub_port'} = $port;
202 $data[$B4_id]{'next_hop_mac'} = $next_hop_mac;
205 print $fh "ip6 = ip6(\"" . $data[$B4_id]{'b4_ipv6'} . "\")";
206 print $fh ", mac = mac(\"" . $data[$B4_id]{'next_hop_mac'} . "\")";
207 print $fh ", ip = ip(\"" . $data[$B4_id]{'pub_ipv4'} . "\")";
208 print $fh ", port = " . $data[$B4_id]{'pub_port'};
211 $port += $port_set_sz;
212 if ($port > $port_range[1]) {
214 $port = $port_range[0];
217 # Move to next Tunnel address
218 if (@tun_ip[1] < 0xffffffffffffffff) {
225 print $fh "}" . "\n";
229 # Test traffic "UDF Tables"
230 if ($num_test_lines) {
231 print "Generating $num_test_lines lines of test UDF table into lwAFTR_tun|inet".$suffix.".csv ... ";
233 # Tunnel Packets from B4 to lwAFTR
234 my $filename = 'lwAFTR_tun' . $suffix . '.csv';
235 open(my $fh_tun, '>', $filename) or die "Could not open file '$filename' $!";
236 print $fh_tun "b4_ip,pub_ip,pub_port\n";
237 print $fh_tun "22,66,74\n"; # Offsets
238 print $fh_tun "16,4,2\n"; # Sizes
239 print $fh_tun "6,5,3\n"; # Format (IPv6, IPv4, Decimal)
240 print $fh_tun ",,\n";
242 # Internet Packets towards the lwAFTR, to be sent to corresp lwB4 over tunnel
243 my $filename = 'lwAFTR_inet' . $suffix . '.csv';
244 open(my $fh_inet, '>', $filename) or die "Could not open file '$filename' $!";
245 print $fh_inet "pub_ip,pub_port\n";
246 print $fh_inet "30,36\n"; # Offsets
247 print $fh_inet "4,2\n"; # Sizes
248 print $fh_inet "5,3\n"; # Format (IPv6, IPv4, Decimal)
249 print $fh_inet ",,\n";
251 for (my $i = 0; $i < $num_test_lines; $i++) {
252 my $B4_id = int(rand($num_B4s));
253 my $port = $data[$B4_id]{'pub_port'} + int(rand($port_set_sz));
254 printf $fh_tun $data[$B4_id]{'b4_ipv6'} . "," . $data[$B4_id]{'pub_ipv4'} . "," . $port . "\n";
256 if (! $symmetric_traffic) {
257 $B4_id = int(rand($num_B4s));
258 $port = $data[$B4_id]{'pub_port'} + int(rand($port_set_sz));
260 printf $fh_inet $data[$B4_id]{'pub_ipv4'} . "," . $port . "\n";