Skip to content

Commit

Permalink
Merge pull request #206 from fabric-testbed/205-allow-portmirror-serv…
Browse files Browse the repository at this point in the history
…ice-for-basic-nics

205 allow portmirror service for basic nics
  • Loading branch information
kthare10 authored Jun 27, 2024
2 parents 959cf32 + eaf0459 commit e6e033b
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 83 deletions.
2 changes: 1 addition & 1 deletion fim/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
FABRIC Information Model library and utilities
"""
__VERSION__ = "1.7.0b6"
__VERSION__ = "1.7.0b10"
__version__ = __VERSION__
18 changes: 5 additions & 13 deletions fim/graph/abc_property_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class ABCPropertyGraph(ABCPropertyGraphConstants):
"controller_url": ABCPropertyGraphConstants.PROP_CONTROLLER_URL,
"gateway": ABCPropertyGraphConstants.PROP_GATEWAY,
"mirror_port": ABCPropertyGraphConstants.PROP_MIRROR_PORT,
"mirror_vlan": ABCPropertyGraphConstants.PROP_MIRROR_VLAN,
"mirror_direction": ABCPropertyGraphConstants.PROP_MIRROR_DIRECTION,
"peer_labels": ABCPropertyGraphConstants.PROP_PEER_LABELS,
"mf_data": ABCPropertyGraphConstants.PROP_MEAS_DATA,
Expand Down Expand Up @@ -335,18 +336,6 @@ def get_nodes_on_shortest_path(self, *, node_a: str, node_z: str, rel: str = Non
:return:
"""

def get_nodes_on_path_with_hops(self, *, node_a: str, node_z: str, hops: List[str], cut_off: int = 100) -> List:
"""
Get a list of node ids that lie on a path between two nodes with the specified hops. Return empty
list if no path can be found. Optionally specify the type of relationship that path
should consist of.
:param node_a: Starting node ID.
:param node_z: Ending node ID.
:param hops: List of hops that must be present in the path.
:param cut_off: Optional Depth to stop the search. Only paths of length <= cutoff are returned.
:return: Path with specified hops and no loops exists, empty list otherwise.
"""

@abstractmethod
def get_first_neighbor(self, *, node_id: str, rel: str, node_label: str) -> List:
"""
Expand Down Expand Up @@ -636,6 +625,8 @@ def network_service_sliver_to_graph_properties_dict(sliver: NetworkServiceSliver
prop_dict[ABCPropertyGraph.PROP_GATEWAY] = sliver.gateway.to_json()
if hasattr(sliver, 'mirror_port') and sliver.mirror_port is not None:
prop_dict[ABCPropertyGraph.PROP_MIRROR_PORT] = sliver.mirror_port
if hasattr(sliver, 'mirror_vlan') and sliver.mirror_vlan is not None:
prop_dict[ABCPropertyGraph.PROP_MIRROR_VLAN] = sliver.mirror_vlan
if hasattr(sliver, 'mirror_direction') and sliver.mirror_direction is not None:
prop_dict[ABCPropertyGraph.PROP_MIRROR_DIRECTION] = str(sliver.mirror_direction)

Expand Down Expand Up @@ -677,7 +668,7 @@ def sliver_to_dict(sliver) -> Dict[str, Any]:

if sliver.network_service_info is not None:
nss = list()
for ns in sliver.network_service_info.list_services():
for ns in sliver.network_service_info.list_network_services():
nss.append(ABCPropertyGraph.sliver_to_dict(ns))
d['network_services'] = nss

Expand Down Expand Up @@ -822,6 +813,7 @@ def network_service_sliver_from_graph_properties_dict(d: Dict[str, str]) -> Netw
site=d.get(ABCPropertyGraphConstants.PROP_SITE, None),
gateway=Gateway.from_json(d.get(ABCPropertyGraphConstants.PROP_GATEWAY, None)),
mirror_port=d.get(ABCPropertyGraphConstants.PROP_MIRROR_PORT, None),
mirror_vlan=d.get(ABCPropertyGraphConstants.PROP_MIRROR_VLAN, None),
mirror_direction=MirrorDirection.from_string(
d.get(ABCPropertyGraphConstants.PROP_MIRROR_DIRECTION, None))
)
Expand Down
1 change: 1 addition & 0 deletions fim/graph/abc_property_graph_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class ABCPropertyGraphConstants(ABC):
PROP_CONTROLLER_URL = "ControllerURL"
PROP_GATEWAY = "Gateway"
PROP_MIRROR_PORT = "MirrorPort"
PROP_MIRROR_VLAN = "MirrorVlan"
PROP_MIRROR_DIRECTION = "MirrorDirection"
PROP_PEER_LABELS = "PeerLabels"
PROP_TAGS = "Tags"
Expand Down
6 changes: 3 additions & 3 deletions fim/slivers/capacities_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,8 @@ def to_latlon(self) -> Tuple[float, float]:
return self.lat, self.lon
url = 'https://nominatim.openstreetmap.org/search?q=' + urllib.parse.quote(self.postal) + '&format=json'
# per terms of service set user agent
headers = {'User-Agent': 'FABRIC FIM Utility v2'}
response = requests.get(url, headers)
headers = {'User-Agent': 'FABRIC FIM Utility'}
response = requests.get(url, headers=headers)
if response.status_code != 200:
raise LocationException(f"Unable to convert address to Lat/Lon via OpenStreetmaps due "
f"to: {response.reason}")
Expand Down Expand Up @@ -720,4 +720,4 @@ class FlagException(Exception):
"""
def __init__(self, msg: str):
assert msg is not None
super().__init__(f"Flag exception: {msg}")
super().__init__(f"Flag exception: {msg}")
39 changes: 23 additions & 16 deletions fim/slivers/network_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,21 +131,21 @@ class NetworkServiceSliver(BaseSliver):
ServiceType.P4: ServiceConstraintRecord(layer=NSLayer.L2, min_interfaces=1,
num_interfaces=NO_LIMIT, num_sites=1,
num_instances=NO_LIMIT, required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction'],
required_interface_types=[],
desc='A P4 service.'),
ServiceType.OVS: ServiceConstraintRecord(layer=NSLayer.L2, min_interfaces=1,
num_interfaces=NO_LIMIT, num_sites=1,
num_instances=NO_LIMIT, required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction'],
required_interface_types=[],
desc='An OVS generic service.'),
ServiceType.VLAN: ServiceConstraintRecord(layer=NSLayer.L2, min_interfaces=1,
num_interfaces=NO_LIMIT, num_sites=1,
num_instances=NO_LIMIT, required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[],
Expand All @@ -154,7 +154,7 @@ class NetworkServiceSliver(BaseSliver):
num_interfaces=NO_LIMIT, num_sites=1,
num_instances=NO_LIMIT, desc='An MPLS generic service',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[]),
Expand All @@ -163,7 +163,7 @@ class NetworkServiceSliver(BaseSliver):
num_instances=NO_LIMIT,
desc='A provider L2 Path e.g. from ESnet or Internet2.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[]),
Expand All @@ -172,7 +172,7 @@ class NetworkServiceSliver(BaseSliver):
num_instances=NO_LIMIT,
desc='A Site-to-Site service in FABRIC.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url',
"ero"],
Expand All @@ -182,7 +182,7 @@ class NetworkServiceSliver(BaseSliver):
num_instances=NO_LIMIT,
desc='A Port-to-Port service in FABRIC.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[InterfaceType.DedicatedPort,
Expand All @@ -192,7 +192,7 @@ class NetworkServiceSliver(BaseSliver):
num_instances=NO_LIMIT,
desc='A Multi-Site L2 service in FABRIC.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[]),
Expand All @@ -201,7 +201,7 @@ class NetworkServiceSliver(BaseSliver):
num_instances=NO_LIMIT,
desc='An L2 bridge service within a single FABRIC site.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[]),
Expand All @@ -210,7 +210,7 @@ class NetworkServiceSliver(BaseSliver):
num_instances=NO_LIMIT,
desc='A routed IPv4 (RFC1918 addressed) FABRIC network.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[]),
Expand All @@ -219,24 +219,24 @@ class NetworkServiceSliver(BaseSliver):
num_instances=NO_LIMIT,
desc='A routed IPv6 (publicly addressed) FABRIC network.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[]),
ServiceType.PortMirror: ServiceConstraintRecord(layer=NSLayer.L2, min_interfaces=1,
num_interfaces=1, num_sites=1,
num_instances=NO_LIMIT,
desc='A port mirroring service in a FABRIC site.',
required_properties=['mirror_port',
required_properties=['mirror_port', 'mirror_vlan',
'mirror_direction', 'site'],
forbidden_properties=['controller_url'],
required_interface_types=[InterfaceType.DedicatedPort]),
required_interface_types=[]),
ServiceType.L3VPN: ServiceConstraintRecord(layer=NSLayer.L3, min_interfaces=1,
num_interfaces=NO_LIMIT, num_sites=NO_LIMIT,
num_instances=NO_LIMIT,
desc='A L3 VPN service connecting to FABRIC.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[]),
Expand All @@ -246,7 +246,7 @@ class NetworkServiceSliver(BaseSliver):
desc='A routed IPv4 publicly addressed FABRIC '
'network capable of external connectivity.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[]),
Expand All @@ -256,7 +256,7 @@ class NetworkServiceSliver(BaseSliver):
desc='A routed IPv6 publicly addressed FABRIC network '
'capable of external connectivity.',
required_properties=[],
forbidden_properties=['mirror_port',
forbidden_properties=['mirror_port', 'mirror_vlan',
'mirror_direction',
'controller_url'],
required_interface_types=[])
Expand All @@ -274,6 +274,7 @@ def __init__(self):
self.site = None
self.gateway = None
self.mirror_port = None
self.mirror_vlan = None
self.mirror_direction = None

#
Expand Down Expand Up @@ -333,6 +334,12 @@ def set_mirror_port(self, mirror_port: str):
def get_mirror_port(self) -> str:
return self.mirror_port

def set_mirror_vlan(self, mirror_vlan: str):
self.mirror_vlan = mirror_vlan

def get_mirror_vlan(self) -> str:
return self.mirror_vlan

def set_mirror_direction(self, mirror_direction: MirrorDirection):
self.mirror_direction = mirror_direction

Expand Down
22 changes: 16 additions & 6 deletions fim/user/network_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ def mirror_port(self, value):
if self.__dict__.get('topo', None) is not None:
self.set_property('mirror_port', value)

@property
def mirror_vlan(self):
return self.get_property('mirror_vlan') if self.__dict__.get('topo', None) is not None else None

@mirror_vlan.setter
def mirror_vlan(self, value):
if self.__dict__.get('topo', None) is not None:
self.set_property('mirror_vlan', value)

@property
def mirror_direction(self):
return self.get_property('mirror_direction') if self.__dict__.get('topo', None) is not None else None
Expand Down Expand Up @@ -562,7 +571,7 @@ class PortMirrorService(NetworkService):
def __init__(self, *, name: str, node_id: str = None, topo: Any,
etype: ElementType = ElementType.EXISTING,
parent_node_id: str = None, direction: MirrorDirection = MirrorDirection.Both,
from_interface_name: str = None, to_interface: Interface = None,
from_interface_name: str = None, from_interface_vlan: str = None, to_interface: Interface = None,
check_existing: bool = False,
**kwargs):
if etype == ElementType.NEW:
Expand All @@ -573,14 +582,11 @@ def __init__(self, *, name: str, node_id: str = None, topo: Any,
# the 'from_interface' is connected to something else
# to_interface has to be a full-rate interface

# make sure that to_interface is a DedicatedPort
if to_interface.type != InterfaceType.DedicatedPort:
raise TopologyException(f'Adding PortMirrorService {name} failed - only dedicated '
f'ports belonging to SmartNICs can be attached.')
super().__init__(name=name, node_id=node_id, topo=topo, etype=etype,
parent_node_id=parent_node_id, interfaces=[to_interface],
nstype=ServiceType.PortMirror, technology=None,
mirror_port=from_interface_name, mirror_direction=direction,
mirror_port=from_interface_name, mirror_vlan=from_interface_vlan,
mirror_direction=direction,
**kwargs)
else:
assert node_id is not None
Expand All @@ -605,6 +611,10 @@ def __init__(self, *, name: str, node_id: str = None, topo: Any,
def mirror_port(self):
return self.get_property('mirror_port') if self.__dict__.get('topo', None) is not None else None

@property
def mirror_vlan(self):
return self.get_property('mirror_vlan') if self.__dict__.get('topo', None) is not None else None

@property
def mirror_direction(self):
return self.get_property('mirror_direction') if self.__dict__.get('topo', None) is not None else None
Loading

0 comments on commit e6e033b

Please sign in to comment.