p4utils.utils.topology module¶
This module includes all the features needed to query the topology.json
file
generated by P4-Utils upon execution. Indeed, it allows the usage of topology
information in the controller code, so that the switches can be configured properly.
The topology file can be imported in a Python script by using the utility
load_topo()
, as shown in the following example:
from p4utils.utils.helper import load_topo
topo = load_topo('topology.json')
-
exception
p4utils.utils.topology.
IntfDoesNotExist
(arg1, arg2, mode=0)[source]¶ Bases:
Exception
Exception raised when an interface is not found.
Parameters: Possible mode values are the following:
0
, then arg1 is the name of the missing interface and arg2 is the name of the node to which the interface belongs.1
, then arg1 is the name of the node to which the interface belongs and arg2 is the name of the node that the interface is facing.
-
exception
p4utils.utils.topology.
InvalidHostIP
(ip)[source]¶ Bases:
Exception
Exception raised when a wrong host IP is provided.
-
class
p4utils.utils.topology.
NetworkGraph
(*args, **kwargs)[source]¶ Bases:
networkx.classes.graph.Graph
Querying API that allows retrieving information about the network topology. It also provides useful methods to perform graph computation (e.g. Dijkstra’s algorithm to get shortest paths).
Note
To use this class in your Python code, you need to import the network topology JSON file (automatically generated by any execution of P4-Utils). This can be easily done with the function
load_topo()
.-
edge_to_intf
[source]¶ stores interface information indexed by
[node1][node2]
, where the interface belongs tonode1
and is facingnode2
.Type: dict
-
node_to_intf
[source]¶ stores interface information indexed by
[node][intfName]
, where the interface belongs tonode
and is named according tointfName
.Type: dict
-
are_neighbors
(node1, node2)[source]¶ Checks if two nodes are direct neighbors.
Parameters: Returns: True if the node are neighbors, False otherwise.
Return type:
-
checkIntf
(node1, node2)[source]¶ Sanity check on interface existence.
Parameters: Raises: IntfDoesNotExist
– if the given interface does not exist.
-
checkNode
(name)[source]¶ Sanity check on node existence.
Parameters: name (str) – node name Raises: NodeDoesNotExist
– if the given node does not exist.
-
get_all_paths_between_nodes
(node1, node2)[source]¶ Compute all the simple paths (i.e. with no repeated nodes) between node1 and node2.
Parameters: - node1 – name of the starting node
- node2 – name of the ending node
Returns: list of paths.
Return type: Note
Each path is given as a
tuple
of node names from the first to the last one.
-
get_cpu_port_index
(name, quiet=False)[source]¶ Retrieves the P4 switch’s CPU port number, used for CPU packets.
Parameters: name (str) – name of the P4 switch Returns: port number of the P4 switch’s CPU interface. Return type: int Note
Returns None if no CPU port is found.
-
get_cpu_port_intf
(name, quiet=False)[source]¶ Retrieves the P4 switch’s CPU interface, used for CPU packets.
Parameters: name (str) – name of the P4 switch Returns: name of the P4 switch’s CPU interface. Return type: str Note
Returns None if no CPU port is found.
-
get_ctl_cpu_intf
(name)[source]¶ Gets the controller side CPU interface, used to listen for CPU packets.
Parameters: name (str) – name of the P4 switch Returns: name of the controller side CPU interface. Return type: str
-
get_direct_host_networks_from_switch
(name)[source]¶ Gets all the subnetworks a switch can reach directly.
Parameters: name (str) – switch name Returns: a set
of subnetworks.
-
get_grpc_ip
(name)[source]¶ Retrieves the P4Runtime switch’s IP where it listens for incoming gRPC connections.
Parameters: name (str) – name of the P4Runtime switch Returns: IP to connect to. Return type: str
-
get_grpc_port
(name)[source]¶ Retrieves the P4Runtime switch’s gRPC port number.
Parameters: name (str) – name of the P4Runtime switch Returns: gRPC port to connect to. Return type: int
-
get_host_first_interface
(name)[source]¶ Gets the first interface of a host.
Parameters: name (str) – host name Returns: interface name. Return type: str
-
get_host_gateway_name
(name)[source]¶ Gets host’s gateway.
Parameters: name (str) – host name Returns: gateway node name. Return type: str Warning
This method assumes that the gateway is connected to the host via its first interface.
-
get_host_ip
(name)[source]¶ Gets host’s IP address.
Parameters: name (str) – host name Returns: host’s IP address. Return type: str Warning
This method assumes that hosts are single-homed (i.e. with only one interface).
-
get_host_mac
(name)[source]¶ Gets host’s MAC address.
Parameters: name (str) – host name Returns: host’s MAC address. Return type: str Warning
This method assumes that hosts are single-homed (i.e. with only one interface).
-
get_host_name
(ip)[source]¶ Gets the host name from an IP address.
Parameters: ip – host IP without prefix length Returns: name of the host whose IP corresponds to the one provided. Return type: str Raises: InvalidHostIP
– if the IP provided does not match any host.
-
get_hosts
(fields=[])[source]¶ Retrieves all the hosts and their configuration parameters.
Parameters: fields (list) – optional list of str
that specifies which parameters need to be retrieved (and in which order)Returns: all the hosts configuration parameters if fields
is empty, or a dictionary of tuples, where the first one is indexed by host name and the second ones collect the values of the selected parameters in the exact order they are placed infields
.Return type: dict Note
If only one element is present in
fields
, then no tuple is created and the value is directly put in the dictionary.Example
Let us consider the following example to clarify:
>>> topo = NetworkGraph() >>> ... >>> print(topo.get_hosts()) {'h1':{'isHost': True, 'isSwitch': False, ...}, ...} >>> print(topo.get_hosts(fields=['isHost', 'isSwitch'])) {'h1': (True, False), ...} >>> print(topo.get_hosts(fields=['isHost'])) {'h1': True, ...}
-
get_hosts_connected_to
(name)[source]¶ Gets hosts directly connected to a node.
Parameters: name (str) – node name Returns: list of hosts names. Return type: list
-
get_interfaces
(name)[source]¶ Retrieves all the interfaces of a node.
Parameters: name (str) – node name Returns: list of interfaces names. Return type: list
-
get_interfaces_to_node
(node)[source]¶ Gets dictionary that associates every node’s interface to its connected neighbor.
Parameters: name (str) – node name. Returns: dictionary of node’s neighbors indexed by the corresponding node’s interfaces. Return type: dict
-
get_intfs
(fields=[])[source]¶ Retrieves all the interfaces and their configuration parameters using the nodes as indexes.
Parameters: fields (list) – optional list of str
that specifies which parameters need to be retrieved (and in which order)Returns: the attribute edge_to_intf
iffields
is empty, or a dictionary of dictionaries of tuples, where the first two dictionaries are indexed by node and the tuples contain the values of the specified interface configuration parameters in the exact order they are placed infields
.Return type: dict Note
If only one element is present in
fields
, then no tuple is created and the value is directly put in the inner dictionary.Example
Let us consider the following example to clarify:
>>> topo = NetworkGraph() >>> ... >>> print(topo.get_intfs()) {'h1': {'s2': {'port': 0, 'port_neigh': 1, ...}, ...}, ...} >>> print(topo.get_intfs(fields=['port', 'port_neigh'])) {'h1': {'s2': (0, 1), ...}, ...} >>> print(topo.get_intfs(fields=['port'])) {'h1': {'s2': 0, ...}, ...}
-
get_neighbors
(name)[source]¶ Retrieves the neighbors of a node.
Parameters: name (str) – node name Returns: list of neighbors names. Return type: list
-
get_node_intfs
(fields=[])[source]¶ Retrieves all the interfaces and their configuration parameters using node and interface name as indexes.
Parameters: fields (list) – optional list of str
that specifies which parameters need to be retrieved (and in which order)Returns: the attribute node_to_intf
iffields
is empty, or a dictionary of dictionaries of tuples, where the first dictionary is indexed by node, the second one by interface name and the tuples contain the values of the specified interface configuration parameters in the exact order they are placed infields
.Return type: dict Note
If only one element is present in
fields
, then no tuple is created and the value is directly put in the inner dictionary.Example
Let us consider the following example to clarify:
>>> topo = NetworkGraph() >>> ... >>> print(topo.get_node_intfs()) {'h1': {'h1-eth0':{'port': 0, 'port_neigh': 1, ...}, ...}, ...} >>> print(topo.get_node_intfs(fields=['port', 'port_neigh'])) {'h1': {'h1-eth0': (0, 1), ...}, ...} >>> print(topo.get_node_intfs(fields=['port'])) {'h1': {'h1-eth0': 0, ...}, ...}
-
get_nodes
(fields=[])[source]¶ Retrieves all the nodes and their configuration parameters.
Parameters: fields (list) – optional list of str
that specifies which parameters need to be retrieved (and in which order)Returns: all the nodes configuration parameters if fields
is empty, or a dictionary of tuples, where the first one is indexed by node name and the second ones collect the values of the selected parameters in the exact order they are placed infields
.Return type: dict Note
If only one element is present in
fields
, then no tuple is created and the value is directly put in the dictionary.Example
Let us consider the following example to clarify:
>>> topo = NetworkGraph() >>> ... >>> print(topo.get_nodes()) {'h1':{'isHost': True, 'isSwitch': False, ...}, ...} >>> print(topo.get_nodes(fields=['isHost', 'isSwitch'])) {'h1': (True, False), ...} >>> print(topo.get_nodes(fields=['isHost'])) {'h1': True, ...}
-
get_p4rtswitches
(fields=[])[source]¶ Retrieves all the P4Runtime switches and their configuration parameters.
Parameters: fields (list) – optional list of str
that specifies which parameters need to be retrieved (and in which order)Returns: all the switches configuration parameters if fields
is empty, or a dictionary of tuples, where the first one is indexed by switch name and the second ones collect the values of the selected parameters in the exact order they are placed infields
.Return type: dict Note
If only one element is present in
fields
, then no tuple is created and the value is directly put in the dictionary.Example
Let us consider the following example to clarify:
>>> topo = NetworkGraph() >>> ... >>> print(topo.get_p4rtswitches()) {'s1':{'isHost': False, 'isSwitch': True, ...}, ...} >>> print(topo.get_p4rtswitches(fields=['isHost', 'isSwitch'])) {'s1': (False, True), ...} >>> print(topo.get_p4rtswitches(fields=['isHost'])) {'s1': False, ...}
-
get_p4switch_id
(name)[source]¶ Gets the ID of a P4 switch.
Parameters: name (str) – P4 switch name in the topology Returns: ID of P4 switch as a string Return type: int
-
get_p4switches
(fields=[])[source]¶ Retrieves all the P4 switches and their configuration parameters.
Parameters: fields (list) – optional list of str
that specifies which parameters need to be retrieved (and in which order)Returns: all the switches configuration parameters if fields
is empty, or a dictionary of tuples, where the first one is indexed by switch name and the second ones collect the values of the selected parameters in the exact order they are placed infields
.Return type: dict Note
If only one element is present in
fields
, then no tuple is created and the value is directly put in the dictionary.Example
Let us consider the following example to clarify:
>>> topo = NetworkGraph() >>> ... >>> print(topo.get_p4switches()) {'s1':{'isHost': False, 'isSwitch': True, ...}, ...} >>> print(topo.get_p4switches(fields=['isHost', 'isSwitch'])) {'s1': (False, True), ...} >>> print(topo.get_p4switches(fields=['isHost'])) {'s1': False, ...}
-
get_p4switches_connected_to
(name)[source]¶ Gets the P4 switches directly connected to a node.
Parameters: name (str) – node name Returns: list of P4 switch names. Return type: list
-
get_routers
(fields=[])[source]¶ Retrieves all the routers and their configuration parameters.
Parameters: fields (list) – optional list of str
that specifies which parameters need to be retrieved (and in which order)Returns: all the routers configuration parameters if fields
is empty, or a dictionary of tuples, where the first one is indexed by router name and the second ones collect the values of the selected parameters in the exact order they are placed infields
.Return type: dict Note
If only one element is present in
fields
, then no tuple is created and the value is directly put in the dictionary.Example
Let us consider the following example to clarify:
>>> topo = NetworkGraph() >>> ... >>> print(topo.get_routers()) {'r1':{'isHost': False, 'isRouter': True, ...}, ...} >>> print(topo.get_routers(fields=['isHost', 'isRouter'])) {'r1': (False, True), ...} >>> print(topo.get_routers(fields=['isHost'])) {'r1': False, ...}
-
get_routers_connected_to
(name)[source]¶ Gets the routers directly connected to a node.
Parameters: name (str) – node name Returns: list of routers. Return type: list
-
get_shortest_paths_between_nodes
(node1, node2)[source]¶ Computes all the shortest paths between node1 and node2.
Parameters: - node1 – name of the starting node
- node2 – name of the ending node
Returns: list of paths.
Return type: Note
Each path is given as a
tuple
of node names from the first to the last one.
-
get_switches
(fields=[])[source]¶ Retrieves all the switches and their configuration parameters.
Parameters: fields (list) – optional list of str
that specifies which parameters need to be retrieved (and in which order)Returns: all the switches configuration parameters if fields
is empty, or a dictionary of tuples, where the first one is indexed by switch name and the second ones collect the values of the selected parameters in the exact order they are placed infields
.Return type: dict Note
If only one element is present in
fields
, then no tuple is created and the value is directly put in the dictionary.Example
Let us consider the following example to clarify:
>>> topo = NetworkGraph() >>> ... >>> print(topo.get_switches()) {'s1':{'isHost': False, 'isSwitch': True, ...}, ...} >>> print(topo.get_switches(fields=['isHost', 'isSwitch'])) {'s1': (False, True), ...} >>> print(topo.get_switches(fields=['isHost'])) {'s1': False, ...}
-
get_switches_connected_to
(name)[source]¶ Gets switches directly connected to a node.
Parameters: name (str) – node name Returns: list of switch names. Return type: list
-
get_thrift_ip
(name)[source]¶ Retrieves the P4 switch’s IP where it listens for incoming Thrift connections.
Parameters: name (str) – name of the P4 switch Returns: IP to connect to. Return type: str
-
get_thrift_port
(name)[source]¶ Retrieves the P4 switch’s Thrift port number.
Parameters: name (str) – name of the P4 switch Returns: Thrift port to connect to. Return type: int
-
interface_to_node
(node, intf)[source]¶ Gets name of the node’s neighbor attached to the specified interface.
Parameters: Returns: neighbor name.
Return type:
-
interface_to_port
(node, intf)[source]¶ Gets port number of the the specified interface of a node.
Parameters: Returns: port number.
Return type:
-
isHost
(name)[source]¶ Checks if a node is a host.
Parameters: name (str) – node name Returns: True if the node is a host, False otherwise. Return type: bool
-
isIntf
(node1, node2)[source]¶ Checks if the interface between node1 and node2 exists.
Parameters: Returns: True if the interface exists, False otherwise.
Return type:
-
isNode
(name)[source]¶ Checks if the node exists.
Parameters: name (str) – node name Returns: True if the node exists, False otherwise. Return type: bool
-
isP4RuntimeSwitch
(name)[source]¶ Checks if a node is a P4Runtime switch.
Parameters: name (str) – node name Returns: True if the node is a P4Runtime switch, False otherwise. Return type: bool
-
isP4Switch
(name)[source]¶ Checks if a node is a P4 switch.
Parameters: name (str) – node name Returns: True if the node is a P4 switch, False otherwise. Return type: bool
-
isRouter
(name)[source]¶ Checks if a node is a router.
Parameters: name (str) – node name Returns: True if the node is a router switch, False otherwise. Return type: bool
-
isSwitch
(name)[source]¶ Checks if a node is a switch.
Parameters: name (str) – node name Returns: True if the node is a switch, False otherwise. Return type: bool
-
isType
(name, node_type)[source]¶ Checks custom node type.
Parameters: Possible node_type values are the following:
host
switch
p4switch
p4rtswitch
router
Returns: True if the node type matches with node_type
, False otherwise.Return type: bool
-
keep_only_p4switches_and_hosts
()[source]¶ Returns a networkx subgraph including only hosts and P4 switches.
-
node_interface_bw
(node, intf)[source]¶ Gets the bandwidth of a give node’s interface.
Parameters: Returns: bandwidth capacity of the interface in Mbps.
Return type: Note
If the bandwidth is unlimited, this method returns
-1
.
-
node_interface_ip
(node, intf)[source]¶ Gets the IP address a given node’s interface.
Parameters: Returns: IP address of the interface
Return type:
-
node_to_node_interface_bw
(node1, node2)[source]¶ Gets the bandwidth of the interface of node1 facing node2.
Parameters: Returns: bandwidth capacity of the interface in Mbps.
Return type: Note
If the bandwidth is unlimited, this method returns
-1
.
-
node_to_node_interface_ip
(node1, node2)[source]¶ Gets the IP address and the subnet mask of the interface of node1 facing node2.
Parameters: Returns: IP / subnet mask of the interface.
Return type:
-
node_to_node_mac
(node1, node2)[source]¶ Gets the MAC address of the interface of node1 connected to node2.
Parameters: Returns: MAC address.
Return type:
-
node_to_node_port_num
(node1, node2)[source]¶ Gets the number of the port of node1 that is connected to node2.
Parameters: Returns: port number.
Return type:
-
port_to_node
(node, port)[source]¶ Gets the neighboring node of node connected to port.
Parameters: Returns: neighbor node.
Return type:
-
set_node_color
(node, color)[source]¶ Sets node’s color. Used when plotting the network.
Parameters: - name (str) – node name
- shape – color to assign
-
set_node_shape
(node, shape)[source]¶ Sets node’s shape. Used when plotting the network.
Parameters: - name (str) – node name
- shape – shape to assign
-
set_node_type_color
(node_type, color)[source]¶ Sets the color of the nodes filtered by type. Used when plotting the network.
Parameters: - node_type (str) – node type to select
- color – color to assign to nodes
Possible values for node_types are the following:
host
switch
p4switch
p4rtswitch
router
-
set_node_type_shape
(node_type, shape)[source]¶ Sets the shape of the nodes filtered by type. Used when plotting the network.
Parameters: - node_type (str) – node type to select
- shape – shape to assign to nodes
Possible values for node_types are the following:
host
switch
p4switch
p4rtswitch
router
-