Merge pull request #360 from coreemu/enhancement/coretk-global-ip6
updates for coretk to default to assigning global ip6 addresses
This commit is contained in:
commit
7cc52f13d6
2 changed files with 80 additions and 46 deletions
|
@ -803,18 +803,26 @@ class CoreClient:
|
||||||
|
|
||||||
def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
||||||
node = canvas_node.core_node
|
node = canvas_node.core_node
|
||||||
ip4, ip6, prefix = self.interfaces_manager.get_ips(node.id)
|
ip4, ip6 = self.interfaces_manager.get_ips(node.id)
|
||||||
|
ip4_mask = self.interfaces_manager.ip4_mask
|
||||||
|
ip6_mask = self.interfaces_manager.ip6_mask
|
||||||
interface_id = len(canvas_node.interfaces)
|
interface_id = len(canvas_node.interfaces)
|
||||||
name = f"eth{interface_id}"
|
name = f"eth{interface_id}"
|
||||||
interface = core_pb2.Interface(
|
interface = core_pb2.Interface(
|
||||||
id=interface_id, name=name, ip4=ip4, ip4mask=prefix, ip6=ip6, ip6mask=prefix
|
id=interface_id,
|
||||||
|
name=name,
|
||||||
|
ip4=ip4,
|
||||||
|
ip4mask=ip4_mask,
|
||||||
|
ip6=ip6,
|
||||||
|
ip6mask=ip6_mask,
|
||||||
)
|
)
|
||||||
canvas_node.interfaces.append(interface)
|
canvas_node.interfaces.append(interface)
|
||||||
logging.debug(
|
logging.debug(
|
||||||
"create node(%s) interface IPv4: %s, name: %s",
|
"create node(%s) interface(%s) IPv4(%s) IPv6(%s)",
|
||||||
node.name,
|
node.name,
|
||||||
interface.ip4,
|
|
||||||
interface.name,
|
interface.name,
|
||||||
|
interface.ip4,
|
||||||
|
interface.ip6,
|
||||||
)
|
)
|
||||||
return interface
|
return interface
|
||||||
|
|
||||||
|
@ -829,7 +837,7 @@ class CoreClient:
|
||||||
dst_node = canvas_dst_node.core_node
|
dst_node = canvas_dst_node.core_node
|
||||||
|
|
||||||
# determine subnet
|
# determine subnet
|
||||||
self.interfaces_manager.determine_subnet(canvas_src_node, canvas_dst_node)
|
self.interfaces_manager.determine_subnets(canvas_src_node, canvas_dst_node)
|
||||||
|
|
||||||
src_interface = None
|
src_interface = None
|
||||||
if NodeUtils.is_container_node(src_node.type):
|
if NodeUtils.is_container_node(src_node.type):
|
||||||
|
|
|
@ -16,45 +16,71 @@ def random_mac():
|
||||||
return ("{:02x}" * 6).format(*[random.randrange(256) for _ in range(6)])
|
return ("{:02x}" * 6).format(*[random.randrange(256) for _ in range(6)])
|
||||||
|
|
||||||
|
|
||||||
class InterfaceManager:
|
class Subnets:
|
||||||
def __init__(self, app: "Application", address: str = "10.0.0.0", mask: int = 24):
|
def __init__(self, ip4: IPNetwork, ip6: IPNetwork) -> None:
|
||||||
self.app = app
|
self.ip4 = ip4
|
||||||
self.mask = mask
|
self.ip6 = ip6
|
||||||
self.base_prefix = max(self.mask - 8, 0)
|
|
||||||
self.subnets = IPNetwork(f"{address}/{self.base_prefix}")
|
|
||||||
self.current_subnet = None
|
|
||||||
|
|
||||||
def next_subnet(self) -> IPNetwork:
|
def __eq__(self, other: "Subnets") -> bool:
|
||||||
|
return (self.ip4, self.ip6) == (other.ip4, other.ip6)
|
||||||
|
|
||||||
|
def __hash__(self) -> int:
|
||||||
|
return hash((self.ip4, self.ip6))
|
||||||
|
|
||||||
|
def next(self) -> "Subnets":
|
||||||
|
return Subnets(self.ip4.next(), self.ip6.next())
|
||||||
|
|
||||||
|
|
||||||
|
class InterfaceManager:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
app: "Application",
|
||||||
|
ip4: str = "10.0.0.0",
|
||||||
|
ip4_mask: int = 24,
|
||||||
|
ip6: str = "2001::",
|
||||||
|
ip6_mask=64,
|
||||||
|
) -> None:
|
||||||
|
self.app = app
|
||||||
|
self.ip4_mask = ip4_mask
|
||||||
|
self.ip6_mask = ip6_mask
|
||||||
|
self.ip4_subnets = IPNetwork(f"{ip4}/{ip4_mask}")
|
||||||
|
self.ip6_subnets = IPNetwork(f"{ip6}/{ip6_mask}")
|
||||||
|
self.current_subnets = None
|
||||||
|
|
||||||
|
def next_subnets(self) -> Subnets:
|
||||||
# define currently used subnets
|
# define currently used subnets
|
||||||
used_subnets = set()
|
used_subnets = set()
|
||||||
for edge in self.app.core.links.values():
|
for edge in self.app.core.links.values():
|
||||||
link = edge.link
|
link = edge.link
|
||||||
|
subnets = None
|
||||||
if link.HasField("interface_one"):
|
if link.HasField("interface_one"):
|
||||||
subnet = self.get_subnet(link.interface_one)
|
subnets = self.get_subnets(link.interface_one)
|
||||||
used_subnets.add(subnet)
|
|
||||||
if link.HasField("interface_two"):
|
if link.HasField("interface_two"):
|
||||||
subnet = self.get_subnet(link.interface_two)
|
subnets = self.get_subnets(link.interface_two)
|
||||||
used_subnets.add(subnet)
|
if subnets:
|
||||||
|
used_subnets.add(subnets)
|
||||||
|
|
||||||
# find next available subnet
|
# find next available subnets
|
||||||
for i in self.subnets.subnet(self.mask):
|
subnets = Subnets(self.ip4_subnets, self.ip6_subnets)
|
||||||
if i not in used_subnets:
|
while subnets in used_subnets:
|
||||||
return i
|
subnets = subnets.next()
|
||||||
|
return subnets
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.current_subnet = None
|
self.current_subnets = None
|
||||||
|
|
||||||
def get_ips(self, node_id: int) -> [str, str, int]:
|
def get_ips(self, node_id: int) -> [str, str]:
|
||||||
ip4 = self.current_subnet[node_id]
|
ip4 = self.current_subnets.ip4[node_id]
|
||||||
ip6 = ip4.ipv6()
|
ip6 = self.current_subnets.ip6[node_id]
|
||||||
prefix = self.current_subnet.prefixlen
|
return str(ip4), str(ip6)
|
||||||
return str(ip4), str(ip6), prefix
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_subnet(cls, interface: "core_pb2.Interface") -> IPNetwork:
|
def get_subnets(cls, interface: "core_pb2.Interface") -> Subnets:
|
||||||
return IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr
|
ip4_subnet = IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr
|
||||||
|
ip6_subnet = IPNetwork(f"{interface.ip6}/{interface.ip6mask}").cidr
|
||||||
|
return Subnets(ip4_subnet, ip6_subnet)
|
||||||
|
|
||||||
def determine_subnet(
|
def determine_subnets(
|
||||||
self, canvas_src_node: "CanvasNode", canvas_dst_node: "CanvasNode"
|
self, canvas_src_node: "CanvasNode", canvas_dst_node: "CanvasNode"
|
||||||
):
|
):
|
||||||
src_node = canvas_src_node.core_node
|
src_node = canvas_src_node.core_node
|
||||||
|
@ -62,28 +88,28 @@ class InterfaceManager:
|
||||||
is_src_container = NodeUtils.is_container_node(src_node.type)
|
is_src_container = NodeUtils.is_container_node(src_node.type)
|
||||||
is_dst_container = NodeUtils.is_container_node(dst_node.type)
|
is_dst_container = NodeUtils.is_container_node(dst_node.type)
|
||||||
if is_src_container and is_dst_container:
|
if is_src_container and is_dst_container:
|
||||||
self.current_subnet = self.next_subnet()
|
self.current_subnets = self.next_subnets()
|
||||||
elif is_src_container and not is_dst_container:
|
elif is_src_container and not is_dst_container:
|
||||||
subnet = self.find_subnet(canvas_dst_node, visited={src_node.id})
|
subnets = self.find_subnets(canvas_dst_node, visited={src_node.id})
|
||||||
if subnet:
|
if subnets:
|
||||||
self.current_subnet = subnet
|
self.current_subnets = subnets
|
||||||
else:
|
else:
|
||||||
self.current_subnet = self.next_subnet()
|
self.current_subnets = self.next_subnets()
|
||||||
elif not is_src_container and is_dst_container:
|
elif not is_src_container and is_dst_container:
|
||||||
subnet = self.find_subnet(canvas_src_node, visited={dst_node.id})
|
subnets = self.find_subnets(canvas_src_node, visited={dst_node.id})
|
||||||
if subnet:
|
if subnets:
|
||||||
self.current_subnet = subnet
|
self.current_subnets = subnets
|
||||||
else:
|
else:
|
||||||
self.current_subnet = self.next_subnet()
|
self.current_subnets = self.next_subnets()
|
||||||
else:
|
else:
|
||||||
logging.info("ignoring subnet change for link between network nodes")
|
logging.info("ignoring subnet change for link between network nodes")
|
||||||
|
|
||||||
def find_subnet(
|
def find_subnets(
|
||||||
self, canvas_node: "CanvasNode", visited: Set[int] = None
|
self, canvas_node: "CanvasNode", visited: Set[int] = None
|
||||||
) -> Union[IPNetwork, None]:
|
) -> Union[IPNetwork, None]:
|
||||||
logging.info("finding subnet for node: %s", canvas_node.core_node.name)
|
logging.info("finding subnet for node: %s", canvas_node.core_node.name)
|
||||||
canvas = self.app.canvas
|
canvas = self.app.canvas
|
||||||
cidr = None
|
subnets = None
|
||||||
if not visited:
|
if not visited:
|
||||||
visited = set()
|
visited = set()
|
||||||
visited.add(canvas_node.core_node.id)
|
visited.add(canvas_node.core_node.id)
|
||||||
|
@ -99,10 +125,10 @@ class InterfaceManager:
|
||||||
continue
|
continue
|
||||||
visited.add(check_node.core_node.id)
|
visited.add(check_node.core_node.id)
|
||||||
if interface:
|
if interface:
|
||||||
cidr = self.get_subnet(interface)
|
subnets = self.get_subnets(interface)
|
||||||
else:
|
else:
|
||||||
cidr = self.find_subnet(check_node, visited)
|
subnets = self.find_subnets(check_node, visited)
|
||||||
if cidr:
|
if subnets:
|
||||||
logging.info("found subnet: %s", cidr)
|
logging.info("found subnets: %s", subnets)
|
||||||
break
|
break
|
||||||
return cidr
|
return subnets
|
||||||
|
|
Loading…
Add table
Reference in a new issue