summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/map/examples/mapalgs.py
diff options
context:
space:
mode:
authorOle Troan <ot@cisco.com>2016-01-05 20:05:52 +0100
committerOle Troan <ot@cisco.com>2016-01-05 20:05:52 +0100
commit92be0df475f3165ef0d82da35250c77a223f2954 (patch)
tree89f9d74991e02a30954d90323bccbc5d86444cd2 /vnet/vnet/map/examples/mapalgs.py
parentce853c4838c173fb389f26d59511b1af5ca3d8ce (diff)
Clean up script to generate LW46 bindings / MAP-E rules.
Change-Id: I3a3949e728f4e4875efddd4f02a55746c998a5ed Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'vnet/vnet/map/examples/mapalgs.py')
-rw-r--r--vnet/vnet/map/examples/mapalgs.py327
1 files changed, 0 insertions, 327 deletions
diff --git a/vnet/vnet/map/examples/mapalgs.py b/vnet/vnet/map/examples/mapalgs.py
deleted file mode 100644
index 50a0ed0a3ee..00000000000
--- a/vnet/vnet/map/examples/mapalgs.py
+++ /dev/null
@@ -1,327 +0,0 @@
-#!/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)