2016-09-13 07:47:22 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# Copyright (C) 2016 GNS3 Technologies Inc.
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2020-10-02 06:37:50 +00:00
|
|
|
from gns3server.controller.controller_error import ControllerError
|
2018-04-06 06:19:17 +00:00
|
|
|
from gns3server.utils import macaddress_to_int, int_to_macaddress
|
2016-09-13 07:47:22 +00:00
|
|
|
from .atm_port import ATMPort
|
|
|
|
from .frame_relay_port import FrameRelayPort
|
|
|
|
from .gigabitethernet_port import GigabitEthernetPort
|
|
|
|
from .fastethernet_port import FastEthernetPort
|
|
|
|
from .ethernet_port import EthernetPort
|
|
|
|
from .serial_port import SerialPort
|
|
|
|
from .pos_port import POSPort
|
|
|
|
|
2020-10-02 06:37:50 +00:00
|
|
|
|
2016-09-13 07:47:22 +00:00
|
|
|
import logging
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
PORTS = {
|
|
|
|
'atm': ATMPort,
|
|
|
|
'frame_relay': FrameRelayPort,
|
|
|
|
'fastethernet': FastEthernetPort,
|
|
|
|
'gigabitethernet': GigabitEthernetPort,
|
|
|
|
'ethernet': EthernetPort,
|
|
|
|
'serial': SerialPort
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class PortFactory:
|
|
|
|
"""
|
|
|
|
Factory to create an Port object based on the type
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __new__(cls, name, interface_number, adapter_number, port_number, port_type, **kwargs):
|
|
|
|
return PORTS[port_type](name, interface_number, adapter_number, port_number, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
class StandardPortFactory:
|
|
|
|
"""
|
|
|
|
Create ports for standard device
|
|
|
|
"""
|
2018-04-02 15:27:12 +00:00
|
|
|
def __new__(cls, properties, port_by_adapter, first_port_name, port_name_format, port_segment_size, custom_adapters):
|
2016-09-13 07:47:22 +00:00
|
|
|
ports = []
|
2016-09-15 09:49:41 +00:00
|
|
|
adapter_number = interface_number = segment_number = 0
|
2016-09-13 07:47:22 +00:00
|
|
|
|
|
|
|
if "ethernet_adapters" in properties:
|
|
|
|
ethernet_adapters = properties["ethernet_adapters"]
|
|
|
|
else:
|
|
|
|
ethernet_adapters = properties.get("adapters", 1)
|
|
|
|
|
2016-09-15 09:49:41 +00:00
|
|
|
for adapter_number in range(adapter_number, ethernet_adapters + adapter_number):
|
2018-04-02 15:27:12 +00:00
|
|
|
|
|
|
|
custom_adapter_settings = {}
|
|
|
|
for custom_adapter in custom_adapters:
|
|
|
|
if custom_adapter["adapter_number"] == adapter_number:
|
|
|
|
custom_adapter_settings = custom_adapter
|
|
|
|
break
|
|
|
|
|
2016-09-13 07:47:22 +00:00
|
|
|
for port_number in range(0, port_by_adapter):
|
|
|
|
if first_port_name and adapter_number == 0:
|
2018-04-02 15:27:12 +00:00
|
|
|
port_name = custom_adapter_settings.get("port_name", first_port_name)
|
2018-08-13 15:06:44 +00:00
|
|
|
port = PortFactory(port_name, segment_number, adapter_number, port_number, "ethernet", short_name=port_name)
|
2016-09-13 07:47:22 +00:00
|
|
|
else:
|
2017-02-22 17:01:59 +00:00
|
|
|
try:
|
|
|
|
port_name = port_name_format.format(
|
|
|
|
interface_number,
|
|
|
|
segment_number,
|
|
|
|
adapter=adapter_number,
|
|
|
|
**cls._generate_replacement(interface_number, segment_number))
|
2018-09-05 05:35:42 +00:00
|
|
|
except (IndexError, ValueError, KeyError) as e:
|
2021-04-13 09:07:58 +00:00
|
|
|
raise ControllerError(f"Invalid port name format {port_name_format}: {str(e)}")
|
2018-04-02 15:27:12 +00:00
|
|
|
|
|
|
|
port_name = custom_adapter_settings.get("port_name", port_name)
|
2016-09-15 09:49:41 +00:00
|
|
|
port = PortFactory(port_name, segment_number, adapter_number, port_number, "ethernet")
|
2016-09-13 07:47:22 +00:00
|
|
|
interface_number += 1
|
2016-09-15 09:49:41 +00:00
|
|
|
if port_segment_size:
|
|
|
|
if interface_number % port_segment_size == 0:
|
|
|
|
segment_number += 1
|
|
|
|
interface_number = 0
|
|
|
|
else:
|
2016-09-13 07:47:22 +00:00
|
|
|
segment_number += 1
|
|
|
|
|
2018-04-06 06:19:17 +00:00
|
|
|
port.adapter_type = custom_adapter_settings.get("adapter_type", properties.get("adapter_type", None))
|
|
|
|
mac_address = custom_adapter_settings.get("mac_address")
|
|
|
|
if not mac_address and "mac_address" in properties:
|
|
|
|
mac_address = int_to_macaddress(macaddress_to_int(properties["mac_address"]) + adapter_number)
|
|
|
|
port.mac_address = mac_address
|
2016-09-15 09:49:41 +00:00
|
|
|
ports.append(port)
|
2016-10-16 22:06:34 +00:00
|
|
|
|
|
|
|
if len(ports):
|
|
|
|
adapter_number += 1
|
|
|
|
|
|
|
|
if "serial_adapters" in properties:
|
|
|
|
for adapter_number in range(adapter_number, properties["serial_adapters"] + adapter_number):
|
|
|
|
for port_number in range(0, port_by_adapter):
|
2021-04-13 09:07:58 +00:00
|
|
|
ports.append(PortFactory(f"Serial{segment_number}/{port_number}", segment_number, adapter_number, port_number, "serial"))
|
2016-10-16 22:06:34 +00:00
|
|
|
segment_number += 1
|
|
|
|
|
2016-09-13 07:47:22 +00:00
|
|
|
return ports
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def _generate_replacement(interface_number, segment_number):
|
|
|
|
"""
|
|
|
|
This will generate replacement string for
|
|
|
|
{port0} => {port9}
|
|
|
|
{segment0} => {segment9}
|
|
|
|
"""
|
2018-03-15 07:17:39 +00:00
|
|
|
|
2016-09-13 07:47:22 +00:00
|
|
|
replacements = {}
|
|
|
|
for i in range(0, 9):
|
|
|
|
replacements["port" + str(i)] = interface_number + i
|
|
|
|
replacements["segment" + str(i)] = segment_number + i
|
|
|
|
return replacements
|
|
|
|
|
|
|
|
|
|
|
|
class DynamipsPortFactory:
|
|
|
|
"""
|
|
|
|
Create port for dynamips devices
|
|
|
|
"""
|
2018-03-15 07:17:39 +00:00
|
|
|
|
2016-09-13 07:47:22 +00:00
|
|
|
ADAPTER_MATRIX = {
|
|
|
|
"C1700-MB-1FE": {"nb_ports": 1,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"C1700-MB-WIC1": {"nb_ports": 0,
|
|
|
|
"port": None},
|
|
|
|
"C2600-MB-1E": {"nb_ports": 1,
|
|
|
|
"port": EthernetPort},
|
|
|
|
"C2600-MB-1FE": {"nb_ports": 1,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"C2600-MB-2E": {"nb_ports": 2,
|
|
|
|
"port": EthernetPort},
|
|
|
|
"C2600-MB-2FE": {"nb_ports": 2,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"C7200-IO-2FE": {"nb_ports": 2,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"C7200-IO-FE": {"nb_ports": 1,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"C7200-IO-GE-E": {"nb_ports": 1,
|
|
|
|
"port": GigabitEthernetPort},
|
|
|
|
"GT96100-FE": {"nb_ports": 2,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"Leopard-2FE": {"nb_ports": 2,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"NM-16ESW": {"nb_ports": 16,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"NM-1E": {"nb_ports": 1,
|
|
|
|
"port": EthernetPort},
|
|
|
|
"NM-1FE-TX": {"nb_ports": 1,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"NM-4E": {"nb_ports": 4,
|
|
|
|
"port": EthernetPort},
|
|
|
|
"NM-4T": {"nb_ports": 4,
|
|
|
|
"port": SerialPort},
|
|
|
|
"PA-2FE-TX": {"nb_ports": 2,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"PA-4E": {"nb_ports": 4,
|
|
|
|
"port": EthernetPort},
|
|
|
|
"PA-4T+": {"nb_ports": 4,
|
|
|
|
"port": SerialPort},
|
|
|
|
"PA-8E": {"nb_ports": 8,
|
|
|
|
"port": EthernetPort},
|
|
|
|
"PA-8T": {"nb_ports": 8,
|
|
|
|
"port": SerialPort},
|
|
|
|
"PA-A1": {"nb_ports": 1,
|
|
|
|
"port": ATMPort},
|
|
|
|
"PA-FE-TX": {"nb_ports": 1,
|
|
|
|
"port": FastEthernetPort},
|
|
|
|
"PA-GE": {"nb_ports": 1,
|
|
|
|
"port": GigabitEthernetPort},
|
|
|
|
"PA-POS-OC3": {"nb_ports": 1,
|
|
|
|
"port": POSPort},
|
|
|
|
}
|
|
|
|
|
|
|
|
WIC_MATRIX = {"WIC-1ENET": {"nb_ports": 1,
|
|
|
|
"port": EthernetPort},
|
|
|
|
|
|
|
|
"WIC-1T": {"nb_ports": 1,
|
|
|
|
"port": SerialPort},
|
|
|
|
|
|
|
|
"WIC-2T": {"nb_ports": 2,
|
|
|
|
"port": SerialPort}
|
|
|
|
}
|
|
|
|
|
|
|
|
def __new__(cls, properties):
|
2018-03-15 07:17:39 +00:00
|
|
|
|
2016-09-13 07:47:22 +00:00
|
|
|
ports = []
|
|
|
|
adapter_number = 0
|
2017-05-12 12:12:24 +00:00
|
|
|
wic_slot = 1
|
|
|
|
wic_port_number = wic_slot * 16
|
|
|
|
display_wic_port_number = 0
|
2016-09-13 07:47:22 +00:00
|
|
|
for name in sorted(properties.keys()):
|
2020-06-29 10:30:30 +00:00
|
|
|
if name.startswith("slot"):
|
|
|
|
if properties[name]:
|
|
|
|
port_class = cls.ADAPTER_MATRIX[properties[name]]["port"]
|
2016-09-13 07:47:22 +00:00
|
|
|
for port_number in range(0, cls.ADAPTER_MATRIX[properties[name]]["nb_ports"]):
|
2021-04-13 09:07:58 +00:00
|
|
|
name = f"{port_class.long_name_type()}{adapter_number}/{port_number}"
|
2018-08-13 08:10:21 +00:00
|
|
|
port = port_class(name, adapter_number, adapter_number, port_number)
|
2021-04-13 09:07:58 +00:00
|
|
|
port.short_name = f"{port_class.short_name_type()}{adapter_number}/{port_number}"
|
2018-08-13 08:10:21 +00:00
|
|
|
ports.append(port)
|
2016-09-13 07:47:22 +00:00
|
|
|
adapter_number += 1
|
2020-06-29 10:30:30 +00:00
|
|
|
elif name.startswith("wic"):
|
|
|
|
if properties[name]:
|
|
|
|
port_class = cls.WIC_MATRIX[properties[name]]["port"]
|
2016-09-13 07:47:22 +00:00
|
|
|
for port_number in range(0, cls.WIC_MATRIX[properties[name]]["nb_ports"]):
|
2021-04-13 09:07:58 +00:00
|
|
|
name = f"{port_class.long_name_type()}{0}/{display_wic_port_number}"
|
2017-05-12 07:48:05 +00:00
|
|
|
port = port_class(name, 0, 0, wic_port_number)
|
2021-04-13 09:07:58 +00:00
|
|
|
port.short_name = f"{port_class.short_name_type()}{0}/{display_wic_port_number}"
|
2017-05-12 07:48:05 +00:00
|
|
|
ports.append(port)
|
2017-05-12 12:12:24 +00:00
|
|
|
display_wic_port_number += 1
|
2016-09-13 07:47:22 +00:00
|
|
|
wic_port_number += 1
|
2020-06-29 10:30:30 +00:00
|
|
|
wic_slot += 1
|
|
|
|
wic_port_number = wic_slot * 16
|
2017-05-12 12:12:24 +00:00
|
|
|
|
2016-09-13 07:47:22 +00:00
|
|
|
return ports
|