#1715 - Added timestep int as a param to the apply_timestep function in core.py. Also added a reset_component_for_episode function. Updated docs with details of Link and NIC.
This commit is contained in:
BIN
docs/_static/node_nic_link_component_diagram.png
vendored
Normal file
BIN
docs/_static/node_nic_link_component_diagram.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
@@ -36,7 +36,6 @@ Head over to the :ref:`getting-started` page to install and setup PrimAITE!
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 8
|
:maxdepth: 8
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
:hidden:
|
|
||||||
|
|
||||||
source/getting_started
|
source/getting_started
|
||||||
source/about
|
source/about
|
||||||
|
|||||||
@@ -2,9 +2,18 @@
|
|||||||
|
|
||||||
© Crown-owned copyright 2023, Defence Science and Technology Laboratory UK
|
© Crown-owned copyright 2023, Defence Science and Technology Laboratory UK
|
||||||
|
|
||||||
Simulation Strucutre
|
|
||||||
====================
|
|
||||||
|
|
||||||
The simulation is made up of many smaller components which are related to each other in a tree-like structure. At the top level, there is an object called the ``SimulationController`` _(doesn't exist yet)_, which has a physical network and a software controller for managing software and users.
|
Simulation
|
||||||
|
==========
|
||||||
|
|
||||||
Each node of the simulation 'tree' has responsibility for creating, deleting, and updating its direct descendants.
|
.. TODO:: Add spiel here about what the simulation is.
|
||||||
|
|
||||||
|
|
||||||
|
Contents
|
||||||
|
########
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 8
|
||||||
|
|
||||||
|
simulation_structure
|
||||||
|
simulation_components/network/physical_layer
|
||||||
|
|||||||
75
docs/source/simulation_components/network/physical_layer.rst
Normal file
75
docs/source/simulation_components/network/physical_layer.rst
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
.. only:: comment
|
||||||
|
|
||||||
|
© Crown-owned copyright 2023, Defence Science and Technology Laboratory UK
|
||||||
|
|
||||||
|
Physical Layer
|
||||||
|
==============
|
||||||
|
|
||||||
|
The physical layer components are mode of a ``NIC`` (Network Interface Card) and a ``Link``. These components allow
|
||||||
|
modelling of layer 1 (physical layer) in the OSI model.
|
||||||
|
|
||||||
|
NIC
|
||||||
|
###
|
||||||
|
The ``NIC`` class is a realistic model of a Network Interface Card. The ``NIC`` acts as the interface between the
|
||||||
|
``Node`` and the ``Link``.
|
||||||
|
|
||||||
|
NICs have the following attributes:
|
||||||
|
|
||||||
|
- **ip_address:** The IPv4 address assigned to the NIC.
|
||||||
|
- **subnet_mask:** The subnet mask assigned to the NIC.
|
||||||
|
- **gateway:** The default gateway IP address for forwarding network traffic to other networks.
|
||||||
|
- **mac_address:** The MAC address of the NIC. Defaults to a randomly set MAC address.
|
||||||
|
- **speed:** The speed of the NIC in Mbps (default is 100 Mbps).
|
||||||
|
- **mtu:** The Maximum Transmission Unit (MTU) of the NIC in Bytes, representing the largest data packet size it can handle without fragmentation (default is 1500 B).
|
||||||
|
- **wake_on_lan:** Indicates if the NIC supports Wake-on-LAN functionality.
|
||||||
|
- **dns_servers:** List of IP addresses of DNS servers used for name resolution.
|
||||||
|
- **connected_link:** The link to which the NIC is connected.
|
||||||
|
- **enabled:** Indicates whether the NIC is enabled.
|
||||||
|
|
||||||
|
**Basic Example**
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
nic1 = NIC(
|
||||||
|
ip_address="192.168.1.100",
|
||||||
|
subnet_mask="255.255.255.0",
|
||||||
|
gateway="192.168.1.1"
|
||||||
|
)
|
||||||
|
|
||||||
|
Link
|
||||||
|
####
|
||||||
|
|
||||||
|
The ``Link`` class represents a physical link between two network endpoints.
|
||||||
|
|
||||||
|
Links have the following attributes:
|
||||||
|
|
||||||
|
- **endpoint_a:** The first NIC connected to the Link.
|
||||||
|
- **endpoint_b:** The second NIC connected to the Link.
|
||||||
|
- **bandwidth:** The bandwidth of the Link in Mbps (default is 100 Mbps).
|
||||||
|
- **current_load:** The current load on the link in Mbps.
|
||||||
|
|
||||||
|
**Basic Example**
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
nic1 = NIC(
|
||||||
|
ip_address="192.168.1.100",
|
||||||
|
subnet_mask="255.255.255.0",
|
||||||
|
gateway="192.168.1.1"
|
||||||
|
)
|
||||||
|
nic1 = NIC(
|
||||||
|
ip_address="192.168.1.101",
|
||||||
|
subnet_mask="255.255.255.0",
|
||||||
|
gateway="192.168.1.1"
|
||||||
|
)
|
||||||
|
|
||||||
|
link = Link(
|
||||||
|
endpoint_a=nic1,
|
||||||
|
endpoint_b=nic2,
|
||||||
|
bandwidth=1000
|
||||||
|
)
|
||||||
|
|
||||||
|
Link, NIC, Node Interface
|
||||||
|
#########################
|
||||||
|
|
||||||
|
.. image:: ../../../_static/node_nic_link_component_diagram.png
|
||||||
13
docs/source/simulation_structure.rst
Normal file
13
docs/source/simulation_structure.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.. only:: comment
|
||||||
|
|
||||||
|
© Crown-owned copyright 2023, Defence Science and Technology Laboratory UK
|
||||||
|
|
||||||
|
|
||||||
|
Simulation Structure
|
||||||
|
====================
|
||||||
|
|
||||||
|
The simulation is made up of many smaller components which are related to each other in a tree-like structure. At the
|
||||||
|
top level, there is an object called the ``SimulationController`` _(doesn't exist yet)_, which has a physical network
|
||||||
|
and a software controller for managing software and users.
|
||||||
|
|
||||||
|
Each node of the simulation 'tree' has responsibility for creating, deleting, and updating its direct descendants.
|
||||||
@@ -37,7 +37,7 @@ class SimComponent(BaseModel):
|
|||||||
possible_actions = self._possible_actions()
|
possible_actions = self._possible_actions()
|
||||||
if action[0] in possible_actions:
|
if action[0] in possible_actions:
|
||||||
# take the first element off the action list and pass the remaining arguments to the corresponding action
|
# take the first element off the action list and pass the remaining arguments to the corresponding action
|
||||||
# funciton
|
# function
|
||||||
possible_actions[action.pop(0)](action)
|
possible_actions[action.pop(0)](action)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"{self.__class__.__name__} received invalid action {action}")
|
raise ValueError(f"{self.__class__.__name__} received invalid action {action}")
|
||||||
@@ -45,7 +45,7 @@ class SimComponent(BaseModel):
|
|||||||
def _possible_actions(self) -> Dict[str, Callable[[List[str]], None]]:
|
def _possible_actions(self) -> Dict[str, Callable[[List[str]], None]]:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def apply_timestep(self) -> None:
|
def apply_timestep(self, timestep: int) -> None:
|
||||||
"""
|
"""
|
||||||
Apply a timestep evolution to this component.
|
Apply a timestep evolution to this component.
|
||||||
|
|
||||||
@@ -53,3 +53,11 @@ class SimComponent(BaseModel):
|
|||||||
sending data.
|
sending data.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def reset_component_for_episode(self):
|
||||||
|
"""
|
||||||
|
Reset this component to its original state for a new episode.
|
||||||
|
|
||||||
|
Override this method with anything that needs to happen within the component for it to be reset.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|||||||
@@ -43,76 +43,6 @@ def generate_mac_address(oui: Optional[str] = None) -> str:
|
|||||||
return ":".join(f"{b:02x}" for b in mac)
|
return ":".join(f"{b:02x}" for b in mac)
|
||||||
|
|
||||||
|
|
||||||
class Link(SimComponent):
|
|
||||||
"""
|
|
||||||
Represents a network link between two network interface cards (NICs).
|
|
||||||
|
|
||||||
:param endpoint_a: The first NIC connected to the Link.
|
|
||||||
:type endpoint_a: NIC
|
|
||||||
:param endpoint_b: The second NIC connected to the Link.
|
|
||||||
:type endpoint_b: NIC
|
|
||||||
:param bandwidth: The bandwidth of the Link in Mbps (default is 100 Mbps).
|
|
||||||
:type bandwidth: int
|
|
||||||
"""
|
|
||||||
|
|
||||||
endpoint_a: NIC
|
|
||||||
endpoint_b: NIC
|
|
||||||
bandwidth: int = 100
|
|
||||||
current_load: int = 0
|
|
||||||
|
|
||||||
def model_post_init(self, __context: Any) -> None:
|
|
||||||
"""
|
|
||||||
Ensure that endpoint_a and endpoint_b are not the same :class:`~primaite.simulator.network.physical_layer.NIC`.
|
|
||||||
|
|
||||||
:raises ValueError: If endpoint_a and endpoint_b are the same NIC.
|
|
||||||
"""
|
|
||||||
if self.endpoint_a == self.endpoint_b:
|
|
||||||
msg = "endpoint_a and endpoint_b cannot be the same NIC"
|
|
||||||
_LOGGER.error(msg)
|
|
||||||
raise ValueError(msg)
|
|
||||||
self.endpoint_a.connect_link(self)
|
|
||||||
self.endpoint_b.connect_link(self)
|
|
||||||
|
|
||||||
def send_frame(self, sender_nic: NIC, frame):
|
|
||||||
"""
|
|
||||||
Send a network frame from one NIC to another connected NIC.
|
|
||||||
|
|
||||||
:param sender_nic: The NIC sending the frame.
|
|
||||||
:type sender_nic: NIC
|
|
||||||
:param frame: The network frame to be sent.
|
|
||||||
:type frame: Frame
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def receive_frame(self, sender_nic: NIC, frame):
|
|
||||||
"""
|
|
||||||
Receive a network frame from a connected NIC.
|
|
||||||
|
|
||||||
:param sender_nic: The NIC sending the frame.
|
|
||||||
:type sender_nic: NIC
|
|
||||||
:param frame: The network frame being received.
|
|
||||||
:type frame: Frame
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def describe_state(self) -> Dict:
|
|
||||||
"""
|
|
||||||
Get the current state of the Libk as a dict.
|
|
||||||
|
|
||||||
:return: A dict containing the current state of the Link.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def apply_action(self, action: str):
|
|
||||||
"""
|
|
||||||
Apply an action to the Link.
|
|
||||||
|
|
||||||
:param action: The action to be applied.
|
|
||||||
:type action: str
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class NIC(SimComponent):
|
class NIC(SimComponent):
|
||||||
"""
|
"""
|
||||||
Models a Network Interface Card (NIC) in a computer or network device.
|
Models a Network Interface Card (NIC) in a computer or network device.
|
||||||
@@ -121,13 +51,11 @@ class NIC(SimComponent):
|
|||||||
:param subnet_mask: The subnet mask assigned to the NIC.
|
:param subnet_mask: The subnet mask assigned to the NIC.
|
||||||
:param gateway: The default gateway IP address for forwarding network traffic to other networks.
|
:param gateway: The default gateway IP address for forwarding network traffic to other networks.
|
||||||
:param mac_address: The MAC address of the NIC. Defaults to a randomly set MAC address.
|
:param mac_address: The MAC address of the NIC. Defaults to a randomly set MAC address.
|
||||||
:param speed: The speed of the NIC in Mbps.
|
:param speed: The speed of the NIC in Mbps (default is 100 Mbps).
|
||||||
:param mtu: The Maximum Transmission Unit (MTU) of the NIC in Bytes, representing the largest data packet size it
|
:param mtu: The Maximum Transmission Unit (MTU) of the NIC in Bytes, representing the largest data packet size it
|
||||||
can handle without fragmentation.
|
can handle without fragmentation (default is 1500 B).
|
||||||
:param wake_on_lan: Indicates if the NIC supports Wake-on-LAN functionality.
|
:param wake_on_lan: Indicates if the NIC supports Wake-on-LAN functionality.
|
||||||
:param dns_servers: List of IP addresses of DNS servers used for name resolution.
|
:param dns_servers: List of IP addresses of DNS servers used for name resolution.
|
||||||
:param connected_link: The link to which the NIC is connected (default is None).
|
|
||||||
:param enabled: Indicates whether the NIC is enabled.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ip_address: Union[str, IPv4Address]
|
ip_address: Union[str, IPv4Address]
|
||||||
@@ -204,7 +132,11 @@ class NIC(SimComponent):
|
|||||||
|
|
||||||
def disconnect_link(self):
|
def disconnect_link(self):
|
||||||
"""Disconnect the NIC from the connected :class:`~primaite.simulator.network.physical_layer.Link`."""
|
"""Disconnect the NIC from the connected :class:`~primaite.simulator.network.physical_layer.Link`."""
|
||||||
pass
|
if self.connected_link.endpoint_a == self:
|
||||||
|
self.connected_link.endpoint_a = None
|
||||||
|
if self.connected_link.endpoint_b == self:
|
||||||
|
self.connected_link.endpoint_b = None
|
||||||
|
self.connected_link = None
|
||||||
|
|
||||||
def add_dns_server(self, ip_address: IPv4Address):
|
def add_dns_server(self, ip_address: IPv4Address):
|
||||||
"""
|
"""
|
||||||
@@ -260,3 +192,77 @@ class NIC(SimComponent):
|
|||||||
:type action: str
|
:type action: str
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Link(SimComponent):
|
||||||
|
"""
|
||||||
|
Represents a network link between two network interface cards (NICs).
|
||||||
|
|
||||||
|
:param endpoint_a: The first NIC connected to the Link.
|
||||||
|
:type endpoint_a: NIC
|
||||||
|
:param endpoint_b: The second NIC connected to the Link.
|
||||||
|
:type endpoint_b: NIC
|
||||||
|
:param bandwidth: The bandwidth of the Link in Mbps (default is 100 Mbps).
|
||||||
|
:type bandwidth: int
|
||||||
|
"""
|
||||||
|
|
||||||
|
endpoint_a: NIC
|
||||||
|
"The first NIC connected to the Link."
|
||||||
|
endpoint_b: NIC
|
||||||
|
"The second NIC connected to the Link."
|
||||||
|
bandwidth: int = 100
|
||||||
|
"The bandwidth of the Link in Mbps (default is 100 Mbps)."
|
||||||
|
current_load: int = 0
|
||||||
|
"The current load on the link in Mbps."
|
||||||
|
|
||||||
|
def model_post_init(self, __context: Any) -> None:
|
||||||
|
"""
|
||||||
|
Ensure that endpoint_a and endpoint_b are not the same :class:`~primaite.simulator.network.physical_layer.NIC`.
|
||||||
|
|
||||||
|
:raises ValueError: If endpoint_a and endpoint_b are the same NIC.
|
||||||
|
"""
|
||||||
|
if self.endpoint_a == self.endpoint_b:
|
||||||
|
msg = "endpoint_a and endpoint_b cannot be the same NIC"
|
||||||
|
_LOGGER.error(msg)
|
||||||
|
raise ValueError(msg)
|
||||||
|
self.endpoint_a.connect_link(self)
|
||||||
|
self.endpoint_b.connect_link(self)
|
||||||
|
|
||||||
|
def send_frame(self, sender_nic: NIC, frame):
|
||||||
|
"""
|
||||||
|
Send a network frame from one NIC to another connected NIC.
|
||||||
|
|
||||||
|
:param sender_nic: The NIC sending the frame.
|
||||||
|
:type sender_nic: NIC
|
||||||
|
:param frame: The network frame to be sent.
|
||||||
|
:type frame: Frame
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def receive_frame(self, sender_nic: NIC, frame):
|
||||||
|
"""
|
||||||
|
Receive a network frame from a connected NIC.
|
||||||
|
|
||||||
|
:param sender_nic: The NIC sending the frame.
|
||||||
|
:type sender_nic: NIC
|
||||||
|
:param frame: The network frame being received.
|
||||||
|
:type frame: Frame
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def describe_state(self) -> Dict:
|
||||||
|
"""
|
||||||
|
Get the current state of the Libk as a dict.
|
||||||
|
|
||||||
|
:return: A dict containing the current state of the Link.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def apply_action(self, action: str):
|
||||||
|
"""
|
||||||
|
Apply an action to the Link.
|
||||||
|
|
||||||
|
:param action: The action to be applied.
|
||||||
|
:type action: str
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user