summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/map/examples
diff options
context:
space:
mode:
Diffstat (limited to 'vnet/vnet/map/examples')
-rwxr-xr-xvnet/vnet/map/examples/gen-rules.py213
-rwxr-xr-xvnet/vnet/map/examples/map-test.py214
-rw-r--r--vnet/vnet/map/examples/mapalgs.py327
-rw-r--r--vnet/vnet/map/examples/mt-test.py80
4 files changed, 834 insertions, 0 deletions
diff --git a/vnet/vnet/map/examples/gen-rules.py b/vnet/vnet/map/examples/gen-rules.py
new file mode 100755
index 00000000000..d6746f79af4
--- /dev/null
+++ b/vnet/vnet/map/examples/gen-rules.py
@@ -0,0 +1,213 @@
+#!/usr/bin/env python3.4
+
+# Copyright (c) 2015 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import ipaddress
+import argparse
+import sys
+
+# map add domain ip4-pfx <pfx> ip6-pfx ::/0 ip6-src <ip6-src> ea-bits-len 0 psid-offset 6 psid-len 6
+# map add rule index <0> psid <psid> ip6-dst <ip6-dst>
+
+parser = argparse.ArgumentParser(description='MAP VPP configuration generator')
+parser.add_argument('-t', action="store", dest="mapmode")
+args = parser.parse_args()
+
+#
+# 1:1 Shared IPv4 address, shared BR, Terastream
+#
+def terastream():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/22')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 6
+ ip6_src = ipaddress.ip_address('cccc:bbbb::')
+ for i in range(ip4_pfx.num_addresses):
+ if not i % 64:
+ ip6_src = ip6_src + 1
+ print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-src " + str(ip6_src) +
+ " ea-bits-len 0 psid-offset 0 psid-len", psid_len)
+ for psid in range(0x1 << psid_len):
+ print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid])
+
+#
+# 1:1 Shared IPv4 address, shared BR, OTE
+#
+def oteshared11():
+ ip4_pfx = ipaddress.ip_network('2.84.63.0/24')
+ dst = list(ipaddress.ip_network('2a02:580:8c00::/40').subnets(new_prefix=56))
+ psid_len = 6
+ ip6_src = ipaddress.ip_address('2a02::')
+ for i in range(ip4_pfx.num_addresses):
+ if not i % 64:
+ ip6_src = ip6_src + 1
+ print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-src " + str(ip6_src) +
+ " ea-bits-len 0 psid-offset 6 psid-len", psid_len)
+ for psid in range(0x1 << psid_len):
+ enduserprefix = list(dst.pop(0).subnets(new_prefix=64))[255-1]
+ print("map add rule index", i, "psid", psid, "ip6-dst", enduserprefix[(i * (0x1<<psid_len)) + psid])
+
+
+#
+# 1:1 Shared IPv4 address, shared BR, Terastream
+#
+def confdterastream():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/22')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 6
+ ip6_src = ipaddress.ip_address('cccc:bbbb::')
+ for i in range(ip4_pfx.num_addresses):
+ if not i % 64:
+ ip6_src = ip6_src + 1
+ print("vpp softwire softwire-instances softwire-instance", i, "br-ipv6 " + str(ip6_src) + " ipv6-prefix ::/0" + " ipv4-prefix " + str(ip4_pfx[i]) +
+ "/32 ea-len 0 psid-offset 6 psid-len", psid_len)
+# print("vpp softwire softwire-instances softwire-instance", i, "ipv4-pfx " + str(ip4_pfx[i]) + "/32 ipv6-pfx ::/0 br-ipv6 " + str(ip6_src) +
+# " ea-len 0 psid-offset 6 psid-len", psid_len)
+ for psid in range(0x1 << psid_len):
+ print("binding", psid, "ipv6-addr", ip6_dst[(i * (0x1<<psid_len)) + psid])
+
+def shared11br_yang():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/16')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 6
+ for i in range(ip4_pfx.num_addresses):
+ print("vpp softwire softwire-instances softwire-instance " + str(i) + " ipv4-prefix " + str(ip4_pfx[i]) + "/32 " +
+ "ipv6-prefix ::/0 ea-len 0 psid-offset 6 tunnel-mtu 1234 psid-len", psid_len)
+ #print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-shared-src cccc:bbbb::1",
+ # "ea-bits-len 0 psid-offset 6 psid-len", psid_len)
+ for psid in range(0x1 << psid_len):
+ # print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid])
+ print("binding", psid, "ipv6-addr", ip6_dst[(i * (0x1<<psid_len)) + psid])
+
+def shared11br_xml():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/32')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ ip6_src = ipaddress.ip_address('cccc:bbbb::')
+ psid_len = 6
+ print('<vpp xmlns="http://www.cisco.com/yang/cisco-vpp"><softwire><softwire-instances>');
+ count = 1024;
+ for i in range(ip4_pfx.num_addresses):
+ if not i % 64:
+ ip6_src = ip6_src + 1
+ if count == 0:
+ break;
+ count = count - 1;
+ print('<softwire-instance>')
+ print(' <id>'+ str(i)+ '</id>')
+ print(' <ipv4-prefix>'+ str(ip4_pfx[i])+ '/32</ipv4-prefix>')
+ print(' <ipv6-prefix>::/0</ipv6-prefix>')
+ print(' <ea-len>0</ea-len>')
+ print(' <psid-offset>0</psid-offset>')
+ print(' <psid-len>'+ str(psid_len) + '</psid-len>')
+ for psid in range(0x1 << psid_len):
+ print(' <binding>')
+ print(' <psid>', psid, '</psid>')
+ print(' <ipv6-addr>'+ str(ip6_dst[(i * (0x1<<psid_len)) + psid]) + '</ipv6-addr>')
+ print(' </binding>')
+ print('</softwire-instance>')
+ print('</softwire-instances></softwire>')
+ print('</vpp>')
+
+#
+# 1:1 Shared IPv4 address, shared BR
+#
+def shared11br():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/16')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 6
+ for i in range(ip4_pfx.num_addresses):
+ print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-shared-src cccc:bbbb::1",
+ "ea-bits-len 0 psid-offset 6 psid-len", psid_len)
+ for psid in range(0x1 << psid_len):
+ print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid])
+
+#
+# 1:1 Shared IPv4 address, shared BR
+#
+def shared11br():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/16')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 6
+ for i in range(ip4_pfx.num_addresses):
+ print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-shared-src cccc:bbbb::1",
+ "ea-bits-len 0 psid-offset 6 psid-len", psid_len)
+ for psid in range(0x1 << psid_len):
+ print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid])
+
+
+#
+# 1:1 Shared IPv4 address
+#
+def shared11():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/16')
+ ip6_src = ipaddress.ip_network('cccc:bbbb::/64')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 6
+ for i in range(ip4_pfx.num_addresses):
+ print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-src", ip6_src[i],
+ "ea-bits-len 0 psid-offset 6 psid-len", psid_len)
+ for psid in range(0x1 << psid_len):
+ print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid])
+
+#
+# 1:1 Shared IPv4 address small
+#
+def smallshared11():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/24')
+ ip6_src = ipaddress.ip_network('cccc:bbbb::/64')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 6
+ for i in range(ip4_pfx.num_addresses):
+ print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx ::/0 ip6-src", ip6_src[i],
+ "ea-bits-len 0 psid-offset 6 psid-len", psid_len)
+ for psid in range(0x1 << psid_len):
+ print("map add rule index", i, "psid", psid, "ip6-dst", ip6_dst[(i * (0x1<<psid_len)) + psid])
+
+#
+# 1:1 Full IPv4 address
+#
+def full11():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/16')
+ ip6_src = ipaddress.ip_network('cccc:bbbb::/64')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 0
+ for i in range(ip4_pfx.num_addresses):
+ print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx " + str(ip6_dst[i]) + "/128 ip6-src", ip6_src[i],
+ "ea-bits-len 0 psid-offset 0 psid-len 0")
+def full11br():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/16')
+ ip6_dst = ipaddress.ip_network('bbbb::/32')
+ psid_len = 0
+ for i in range(ip4_pfx.num_addresses):
+ print("map add domain ip4-pfx " + str(ip4_pfx[i]) + "/32 ip6-pfx " + str(ip6_dst[i]) + "/128 ip6-shared-src cccc:bbbb::1",
+ "ea-bits-len 0 psid-offset 0 psid-len 0")
+
+#
+# Algorithmic mapping Shared IPv4 address
+#
+def algo():
+ print("map add domain ip4-pfx 20.0.0.0/24 ip6-pfx bbbb::/32 ip6-src cccc:bbbb::1 ea-bits-len 16 psid-offset 6 psid-len 8")
+ print("map add domain ip4-pfx 20.0.1.0/24 ip6-pfx bbbb:1::/32 ip6-src cccc:bbbb::2 ea-bits-len 8 psid-offset 0 psid-len 0")
+
+#
+# IP4 forwarding
+#
+def ip4():
+ ip4_pfx = ipaddress.ip_network('20.0.0.0/16')
+ for i in range(ip4_pfx.num_addresses):
+ print("ip route add " + str(ip4_pfx[i]) + "/32 via 172.16.0.2")
+
+
+globals()[args.mapmode]()
+
+
diff --git a/vnet/vnet/map/examples/map-test.py b/vnet/vnet/map/examples/map-test.py
new file mode 100755
index 00000000000..01f377fb6ee
--- /dev/null
+++ b/vnet/vnet/map/examples/map-test.py
@@ -0,0 +1,214 @@
+#!/usr/bin/env python
+# Copyright (c) 2015 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys, time
+from scapy.all import *
+
+import mapalgs
+
+
+ifname = "vpp-tap"
+
+loc_v4_mac = "aa:aa:aa:aa:aa:a4"
+loc_v6_mac = "aa:aa:aa:aa:aa:a6"
+vpp_mac = "aa:aa:aa:aa:00:00"
+
+map_t = 1
+
+fragsize = 0
+map_mtu = 200
+
+def mac_to_vppmac(mac):
+ mac = mac.replace(':', '')
+ return mac[0:4]+"."+mac[4:8]+"."+mac[8:12]
+
+
+map = mapalgs.MapCalc( rulev6 = 'bbbb::/32',
+ rulev4 = '20.0.0.0/24',
+ ratio = 256);
+
+dmr = mapalgs.DmrCalc('cccc:bbbb::/96')
+
+
+ICMP_TYPES_CODES = {
+ 0: 0,
+ 3: 15,
+ 4: 0,
+ 5: 3,
+ 6: 0,
+ 8: 0,
+ 9: 0,
+ 10: 0,
+ 11: 1,
+ 12: 2,
+ 13: 0,
+ 14: 0,
+ 15: 0,
+ 16: 0,
+ 17: 0,
+ 18: 0
+}
+
+ICMP6_TYPES_CODES = {
+ 1: 7,
+ 2: 0,
+ 3: 1,
+ 4: 3,
+}
+
+def net_conf():
+ c = ""
+ c += "tap connect "+ifname+" hwaddr "+mac_to_vppmac(vpp_mac)+" \n"
+ c += "set int state tap-0 up \n"
+ c += "set ip6 neighbor tap-0 2001:f00d::1 "+mac_to_vppmac(loc_v6_mac)+" \n"
+ c += "set ip arp tap-0 10.0.0.1 "+mac_to_vppmac(loc_v4_mac)+" \n"
+ c += "ip route add ::/0 via 2001:f00d::1 tap-0 \n"
+ c += "ip route add 0.0.0.0/0 via 10.0.0.1 tap-0 \n"
+ return c
+
+def conf():
+ c = net_conf()
+ c += "map add domain ip4-pfx 20.0.0.0/24 ip6-pfx bbbb::/32 ea-bits-len 16 psid-offset 6 psid-len 8"
+ if map_mtu != 0:
+ c += " mtu "+str(map_mtu)
+ if map_t:
+ c += " ip6-src cccc:bbbb::/96 map-t"
+ else:
+ c += " ip6-src cccc:bbbb::ffff"
+
+ c += "\n"
+ return c
+
+def send_packet(ip_header, ip_content):
+ print("Send packet")
+ if fragsize != 0:
+ if ip_header.version == 4:
+ frags = fragment(ip_header/ip_content, fragsize=fragsize)
+ for f in frags:
+ print("Fragmented IPv4 packet")
+ sendp(Ether(dst=vpp_mac, src=loc_v4_mac)/f, iface=ifname)
+ elif ip_header.version == 6:
+ frags = fragment6(ip_header/IPv6ExtHdrFragment()/ip_content, fragsize)
+ for f in frags:
+ print("Fragmented IPv6 packet")
+ sendp(Ether(dst=vpp_mac, src=loc_v6_mac)/f, iface=ifname)
+ else:
+ sendp(Ether(dst=vpp_mac)/ip_header/ip_content, iface=ifname)
+
+def send_packet_frag_inner(packet, inner_header, inner_content):
+ print("Send packet with inner ICMP packet")
+ if fragsize != 0:
+ if packet.version == 4:
+ frags = fragment(inner_header/inner_content, fragsize=fragsize)
+ for f in frags:
+ print("Fragmented IPv4 inner packet")
+ sendp(Ether(dst=vpp_mac, src=loc_v4_mac)/packet/f, iface=ifname)
+ elif packet.version == 6:
+ frags = fragment6(inner_header/IPv6ExtHdrFragment()/inner_content, fragsize)
+ for f in frags:
+ print("Fragmented IPv6 inner packet")
+ sendp(Ether(dst=vpp_mac, src=loc_v6_mac)/packet/f, iface=ifname)
+ else:
+ sendp(Ether(dst=vpp_mac)/packet/inner_header/inner_content, iface=ifname)
+
+
+def sendv6udp(src, dst, port):
+ psid = map.gen_psid(port)
+ ceaddr = str(map.get_mapce_addr(src, psid))
+ dst = str(dmr.embed_6052addr(dst))
+ send_packet(IPv6(dst=dst, src=ceaddr), UDP(sport=port)/('X'*900))
+
+def sendv6tcp(src, dst, port):
+ psid = map.gen_psid(port)
+ ceaddr = str(map.get_mapce_addr(src, psid))
+ dst = str(dmr.embed_6052addr(dst))
+ send_packet(IPv6(dst=dst, src=ceaddr), TCP(sport=port)/('X'*900))
+
+def sendv4udp(src, dst, port):
+ send_packet(IP(dst=dst, src=src), UDP(dport=port)/('X'*900))
+
+def sendv4tcp(src, dst, port):
+ send_packet(IP(dst=dst, src=src), TCP(dport=port)/('X'*900))
+
+def sendv6ping(src, dst, id):
+ psid = map.gen_psid(id)
+ ceaddr = str(map.get_mapce_addr(src, psid))
+ dst = str(dmr.embed_6052addr(dst))
+ send_packet(IPv6(dst=dst, src=ceaddr), ICMPv6EchoRequest(id=id, data='A'*500))
+ send_packet(IPv6(dst=dst, src=ceaddr), ICMPv6EchoReply(id=id, data='A'*500))
+
+def sendv4ping(src, dst, id):
+ send_packet(IP(dst=dst, src=src), ICMP(id=id, type=0)/('X'*500))
+ send_packet(IP(dst=dst, src=src), ICMP(id=id, type=8)/('X'*500))
+
+def sendv4icmperr(src, dst, type, code, port, inner_src, inner_dst, payload_length):
+ inner = IP(dst=inner_dst, src=inner_src)/TCP(sport=port, dport=8888)/('X'*payload_length)
+ send_packet_frag_inner(IP(dst=dst, src=src)/ICMP(type=type, code=code), IP(dst=inner_dst, src=inner_src), TCP(sport=port, dport=8888)/('X'*payload_length))
+ #send_packet(IP(dst=dst, src=src)/ICMP(type=type, code=code)/inner)
+
+def sendv6icmperr(src, dst, type, code, port, payload_length):
+ psid = map.gen_psid(port)
+ src = str(map.get_mapce_addr(src, psid))
+ dst = str(dmr.embed_6052addr(dst))
+ inner_header = IPv6(dst=src, src=dst)
+ inner_content = TCP(sport=8888, dport=port)/('X'*payload_length)
+ send_packet_frag_inner(IPv6(dst=dst, src=src)/ICMPv6DestUnreach(type=type, code=code), inner_header, inner_content)
+ #send_packet(IPv6(dst=dst, src=src)/ICMPv6DestUnreach(type=type, code=code)/inner)
+
+def sendv4icmp_errors(src, dst, port, inner_src, inner_dst, payload_length):
+ for type in ICMP_TYPES_CODES:
+ for code in range(0, ICMP_TYPES_CODES[type] + 1):
+ sendv4icmperr(src, dst, type, code, port, inner_src, inner_dst, payload_length)
+ #sendv4icmperr(src, dst, type, ICMP_TYPES_CODES[type] + 2, port, inner_src, inner_dst, payload_length)
+ #sendv4icmperr(src, dst, type, 255, port, inner_src, inner_dst, payload_length)
+ #sendv4icmperr(src, dst, 1, 0, port, inner_src, inner_dst, payload_length)
+ #sendv4icmperr(src, dst, 2, 10, port, inner_src, inner_dst, payload_length)
+ #sendv4icmperr(src, dst, 255, 255, port, inner_src, inner_dst, payload_length)
+
+ #TODO: Check wrong paramater with different pointer values
+
+def sendv6icmp_errors(src, dst, port, payload_length):
+ for type in ICMP6_TYPES_CODES:
+ for code in range(0, ICMP6_TYPES_CODES[type] + 1):
+ sendv6icmperr(src, dst, type, code, port, payload_length)
+ #sendv6icmperr(src, dst, type, ICMP6_TYPES_CODES[type] + 2, port, payload_length)
+ #sendv6icmperr(src, dst, type, 255, port, payload_length)
+
+
+def traffic():
+ delay = 2.0
+ while 1:
+ #sendp(Ether(dst="bb:bb:bb:bb:bb:b4")/IP(dst="20.0.0.1")/UDP(chksum=0)/('X'*900), iface="vpp-tapv4")
+ #sendp(Ether(dst="bb:bb:bb:bb:bb:b6")/IPv6(dst="cccc:bbbb::a000:0001")/ICMPv6EchoRequest()/('X'*900), iface="vpp-tapv6")
+ #sendp(Ether(dst="bb:bb:bb:bb:bb:b6")/IPv6(dst="cccc:bbbb::a000:0001")/UDP()/('X'*900), iface="vpp-tapv6")
+ sendv6udp("20.0.0.1", "10.0.0.1", 12001)
+ sendv6tcp("20.0.0.1", "10.0.0.1", 12002)
+ sendv4udp("10.0.0.1", "20.0.0.1", 12003)
+ sendv4tcp("10.0.0.1", "20.0.0.1", 12004)
+ sendv6ping("20.0.0.1", "10.0.0.1", 12005)
+ sendv4ping("10.0.0.1", "20.0.0.1", 12006)
+ sendv4icmp_errors("10.0.0.1", "20.0.0.1", 12006, "20.0.0.1", "10.0.0.1", 500)
+ sendv4icmp_errors("10.0.0.1", "20.0.0.1", 12006, "20.0.0.1", "10.0.0.1", 1500)
+ sendv6icmp_errors("20.0.0.1", "10.0.0.1", 12006, 500)
+ time.sleep(delay)
+ delay *= 0.9
+
+if len(sys.argv) <= 1:
+ print("Usage: conf|traffic")
+ exit(1)
+
+if sys.argv[1] == "conf":
+ print(conf())
+elif sys.argv[1] == "traffic":
+ traffic() \ No newline at end of file
diff --git a/vnet/vnet/map/examples/mapalgs.py b/vnet/vnet/map/examples/mapalgs.py
new file mode 100644
index 00000000000..50a0ed0a3ee
--- /dev/null
+++ b/vnet/vnet/map/examples/mapalgs.py
@@ -0,0 +1,327 @@
+#!/usr/bin/env python3
+
+# The MIT License (MIT)
+#
+# Copyright (c) 2015
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+# File included from https://github.com/ejordangottlieb/pyswmap
+# Thanks to jordan ;)
+# - Pierre
+#
+
+# There is still a great deal of work required on this module. Please
+# use with caution.
+# -Jordan
+
+import sys
+from ipaddress import (
+ IPv6Address,
+ IPv6Network,
+ ip_network,
+ ip_address,
+ )
+from math import (
+ log,
+ )
+
+class MapCalc(object):
+
+ def __init__(self,**bmr):
+ #rulev6,rulev4):
+ self.portranges = False
+
+ # Validate and set BMR and BMR derived values
+ self._check_bmr_values(bmr)
+
+ def _check_bmr_values(self,bmr):
+ # Assume these values have not been supplied. Validate later.
+ self.ealen = False
+ self.ratio = False
+
+ # Validate that a proper PSID Offset has been set
+ if 'psidoffset' not in bmr:
+ # Set Default PSID Offset of 6 if it is not set
+ self.psidoffset = 6
+ else:
+ self.psidoffset = self._psid_offset(bmr['psidoffset'])
+
+ # Validate that a proper IPv4 rule prefix is defined
+ if 'rulev4' not in bmr:
+ print("The rule IPv4 prefix has not been set")
+ sys.exit(1)
+ else:
+ self.rulev4 = self._ipv4_rule(bmr['rulev4'])
+
+ # Validate that a proper IPv6 rule prefix is defined
+ if 'rulev6' not in bmr:
+ print("The rule IPv6 prefix has not been set")
+ sys.exit(1)
+ else:
+ self.rulev6 = self._ipv6_rule(bmr['rulev6'])
+
+ # Check if EA length was passed
+ if 'ealen' not in bmr:
+ self.ealen = False
+ else:
+ self.ealen = bmr['ealen']
+ self.ratio = self._calc_ratio(bmr['ealen'])
+
+ # Check if sharing ratio was passed or calculated by _calc_ratio
+ if 'ratio' not in bmr:
+ # Skip if we have already calculated ratio
+ if not (self.ratio):
+ self.ratio = False
+ else:
+ if (self.ealen):
+ # Check to see if supplied EA length contradicts supplied ratio
+ if ( bmr['ratio'] != self.ratio ):
+ eavalue = "EA value {}".format(self.ealen)
+ sharingratio = "sharing ratio {}".format(bmr['ratio'])
+ print("Supplied {} and {} are contradictory".format(
+ eavalue,
+ sharingratio)
+ )
+ sys.exit(1)
+ else:
+ self.ratio = bmr['ratio']
+ self.ealen = self._calc_ea(bmr['ratio'])
+
+ # EA length or sharing ratio must be set
+ if not ( self.ealen or self.ratio):
+ print("The BMR must include an EA length or sharing ratio")
+ sys.exit(1)
+
+ # Since we have not hit an exception we can calculate the port bits
+ self.portbits = self._calc_port_bits()
+
+ def _ipv4_rule(self,rulev4):
+ try:
+ self.rulev4mask = ip_network(
+ rulev4,
+ strict=False
+ ).prefixlen
+ except ValueError:
+ print("Invalid IPv4 prefix {}".format(rulev4))
+ sys.exit(1)
+
+ self.rulev4object = ip_network(rulev4)
+
+ return rulev4
+
+ def _ipv6_rule(self,rulev6):
+ try:
+ self.rulev6mask = IPv6Network(
+ rulev6,
+ strict=False
+ ).prefixlen
+ except ValueError:
+ print("Invalid IPv6 prefix {}".format(rulev6))
+ sys.exit(1)
+
+ return rulev6
+
+ def _psid_offset(self,psidoffset):
+ PSIDOFFSET_MAX = 6
+ if psidoffset in range(0,PSIDOFFSET_MAX+1):
+ return psidoffset
+ else:
+ print("Invalid PSID Offset value: {}".format(psidoffset))
+ sys.exit(1)
+
+ def _psid_range(self,x):
+ rset = []
+ for i in range(0,x+1):
+ rset.append(2**i)
+ return rset
+
+ def _calc_port_bits(self):
+ portbits = 16 - self.psidoffset - self.psidbits
+ return portbits
+
+ def _calc_ea(self,ratio):
+ if ratio not in ( self._psid_range(16) ):
+ print("Invalid ratio {}".format(ratio))
+ print("Ratio between 2 to the power of 0 thru 16")
+ sys.exit(1)
+
+ if ( 1 == ratio):
+ self.psidbits = 0
+ else:
+ self.psidbits = int(log(ratio,2))
+ ealen = self.psidbits + ( 32 - self.rulev4mask )
+ return ealen
+
+ def _calc_ratio(self,ealen):
+ maskbits = 32 - self.rulev4mask
+ if ( ealen < maskbits ):
+ print("EA of {} incompatible with rule IPv4 prefix {}".format(
+ ealen,
+ self.rulev4,
+ )
+ )
+ print("EA length must be at least {} bits".format(
+ maskbits,
+ )
+ )
+ sys.exit(1)
+
+ self.psidbits = ealen - ( 32 - self.rulev4mask )
+ if ( self.psidbits > 16):
+ print("EA length of {} is too large".format(
+ ealen,
+ )
+ )
+ print("EA should not exceed {} for rule IPv4 prefix {}".format(
+ maskbits + 16,
+ self.rulev4,
+ )
+ )
+ sys.exit(1)
+ ratio = 2**self.psidbits
+ return ratio
+
+ def gen_psid(self,portnum):
+ if ( portnum < self.start_port() ):
+ print("port value is less than allowed by PSID Offset")
+ sys.exit(1)
+ psid = (portnum & ((2**self.psidbits - 1) << self.portbits))
+ psid = psid >> self.portbits
+ return psid
+
+ def port_ranges(self):
+ return 2**self.psidoffset - 1
+
+ def start_port(self):
+ if self.psidoffset == 0: return 0
+ return 2**(16 - self.psidoffset)
+
+ def port_list(self,psid):
+ startrange = psid * (2**self.portbits) + self.start_port()
+ increment = (2**self.psidbits) * (2**self.portbits)
+ portlist = [ ]
+ for port in range(startrange,startrange + 2**self.portbits):
+ if port >= 65536: continue
+ portlist.append(port)
+ for x in range(1,self.port_ranges()):
+ startrange += increment
+ for port in range(startrange,startrange + 2**self.portbits):
+ portlist.append(port)
+ return portlist
+
+ def ipv4_index(self,ipv4addr):
+ if ip_address(ipv4addr) in ip_network(self.rulev4):
+ x = ip_address(ipv4addr)
+ y = ip_network(self.rulev4,strict=False).network_address
+ self.ipv4addr = x
+ return ( int(x) - int(y) )
+ else:
+ print("Error: IPv4 address {} not in Rule IPv4 subnet {}".format(
+ ipv4add,
+ ip_network(self.rulev4,strict=False).network_address))
+ sys.exit(1)
+
+ def _calc_ipv6bit_pos(self):
+ addroffset = 128 - (self.rulev6mask + ( self.ealen - self.psidbits))
+ psidshift = 128 - ( self.rulev6mask + self.ealen )
+ return [addroffset,psidshift]
+
+ def _append_map_eabits(self,ipv4index,addroffset,psidshift,psid):
+ rulev6base = IPv6Network(self.rulev6,strict=False).network_address
+ map_prefix = int(rulev6base) | ( ipv4index << addroffset )
+ map_fullprefix = map_prefix | ( psid << psidshift)
+ return map_fullprefix
+
+
+ def get_mapce_addr(self,ipv4addr,psid):
+ ipv4index = self.ipv4_index(ipv4addr)
+ (addroffset,psidshift) = self._calc_ipv6bit_pos()
+ map_fullprefix = self._append_map_eabits(ipv4index,
+ addroffset,
+ psidshift,
+ psid)
+ mapv4iid = map_fullprefix | ( int(self.ipv4addr) << 16 )
+ map_full_address = mapv4iid | psid
+ mapce_address = "{}".format(IPv6Address(map_full_address))
+ return mapce_address
+
+ def get_mapce_prefix(self,ipv4addr,psid):
+ ipv4index = self.ipv4_index(ipv4addr)
+ (addroffset,psidshift) = self._calc_ipv6bit_pos()
+ map_fullprefix = self._append_map_eabits(ipv4index,
+ addroffset,
+ psidshift,
+ psid)
+ mapce_prefix = "{}/{}".format(
+ IPv6Address(map_fullprefix),
+ self.rulev6mask + self.ealen
+ )
+ return mapce_prefix
+
+ def get_map_ipv4(self,mapce_address):
+ ipv4 = (int(IPv6Address(mapce_address)) & ( 0xffffffff << 16 )) >> 16
+ return ip_address(ipv4)
+
+
+
+class DmrCalc(object):
+
+ def __init__(self,dmr):
+
+ # Validate and set BMR and BMR derived values
+ self.dmrprefix = self._check_dmr_prefix(dmr)
+
+ def embed_6052addr(self,ipv4addr):
+
+ try:
+ ipv4addrint = int(ip_address(ipv4addr))
+ except ValueError:
+ print("Invalid IPv4 address {}".format(ipv4addr))
+ sys.exit(1)
+
+ if ( self.dmrprefix.prefixlen == 64 ):
+ ipv6int = ipv4addrint << 24
+ ipv6int += int(self.dmrprefix.network_address)
+ return IPv6Address(ipv6int)
+
+ if ( self.dmrprefix.prefixlen == 96 ):
+ ipv6int = ipv4addrint
+ ipv6int += int(self.dmrprefix.network_address)
+ return IPv6Address(ipv6int)
+
+ def _check_dmr_prefix(self,dmrprefix):
+ try:
+ self.dmrmask = IPv6Network(
+ dmrprefix,
+ strict=False
+ ).prefixlen
+ except ValueError:
+ print("Invalid IPv6 prefix {}".format(prefix))
+ sys.exit(1)
+
+ if self.dmrmask not in (32,40,48,56,64,96):
+ print("Invalid prefix mask /{}".format(self.dmrmask))
+ sys.exit(1)
+
+ return IPv6Network(dmrprefix)
+
+if __name__ == "__main__":
+ m = DmrCalc('fd80::/48')
+ print(m.dmrprefix)
diff --git a/vnet/vnet/map/examples/mt-test.py b/vnet/vnet/map/examples/mt-test.py
new file mode 100644
index 00000000000..62d269c7a13
--- /dev/null
+++ b/vnet/vnet/map/examples/mt-test.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2009-2014 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import threading
+import time
+from scapy.all import *
+from Queue import *
+
+iface = 'veth1'
+
+class SnifferThread(threading.Thread) :
+ def __init__(self,q,iface,flt,timeout) :
+ threading.Thread.__init__(self)
+ self.q = q
+ self.iface = iface
+ self.timeout = timeout
+ self.flt = flt
+ print("Sniffers reporting for service on ",self.iface)
+
+ def run(self) :
+ conf.iface=self.iface
+ conf.iface6=self.iface
+
+ r = sniff(filter=self.flt,iface=self.iface,timeout=self.timeout,prn=lambda x: x.summary())
+ self.q.put(r)
+
+
+
+# New "SR" function
+# Fire off thread with filter and expected answer packet(s).
+# Fire off sniffer thread, main thread sends packet
+# Returns true if found
+
+def sr2(answer, *args, **kwargs):
+ q = Queue()
+ print("Creating SnifferThreadWorkerThread")
+ flt='ip proto 41'
+ iface='veth1'
+ sniffer = SnifferThread(q,iface,flt,1)
+ sniffer.setDaemon(True)
+ sniffer.start()
+
+ print "Sending packet:"
+ send(*args, **kwargs)
+ sniffer.join()
+ ps = q.get()
+
+# ps.summary()
+ print "Number of packets sniffed:", len(ps)
+
+ for p in ps:
+ ip = p.getlayer(1)
+ print "Comparing", ip.summary(), "and", answer.summary()
+ if ip == answer:
+ print "We have a match!!"
+ return True
+ return False
+
+aip6 = IPv6(dst='2002:0a0a:0a0a::12')/ICMPv6EchoRequest()
+answer= IP(src="10.0.0.100",dst="10.10.10.10",ttl=63)/aip6
+packet = IPv6(dst='2002:0a0a:0a0a::12')/ICMPv6EchoRequest()
+
+# From IPv6
+sr2(answer, packet,iface='veth1')
+
+#From IPv4
+packet = IP(src='10.10.10.10',dst='10.0.0.100')/IPv6(src='2002:0a0a:0a0a::12',dst='1::2')/ICMPv6EchoRequest()
+sr2(answer, packet,iface='veth1')