mirror of
https://github.com/openvswitch/ovs
synced 2025-09-02 15:25:22 +00:00
python: Add flow base class.
It simplifies the implementation of different types of flows by creating the concept of Section (e.g: match, action) and automatic accessors for all the provided Sections Acked-by: Eelco Chaudron <echaudro@redhat.com> Signed-off-by: Adrian Moreno <amorenoz@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
committed by
Ilya Maximets
parent
61e040fc23
commit
1215cf1334
@@ -28,6 +28,7 @@ ovs_pyfiles = \
|
|||||||
python/ovs/fcntl_win.py \
|
python/ovs/fcntl_win.py \
|
||||||
python/ovs/flow/__init__.py \
|
python/ovs/flow/__init__.py \
|
||||||
python/ovs/flow/decoders.py \
|
python/ovs/flow/decoders.py \
|
||||||
|
python/ovs/flow/flow.py \
|
||||||
python/ovs/flow/kv.py \
|
python/ovs/flow/kv.py \
|
||||||
python/ovs/flow/list.py \
|
python/ovs/flow/list.py \
|
||||||
python/ovs/flow/ofp_fields.py \
|
python/ovs/flow/ofp_fields.py \
|
||||||
|
125
python/ovs/flow/flow.py
Normal file
125
python/ovs/flow/flow.py
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
""" Defines the Flow class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Section(object):
|
||||||
|
"""A flow can be seen as composed of different sections, e.g:
|
||||||
|
|
||||||
|
[info] [match] actions=[actions]
|
||||||
|
|
||||||
|
This class represents each of those sections.
|
||||||
|
|
||||||
|
A section is basically a set of Key-Value pairs. Typically, they can be
|
||||||
|
expressed as a dictionary, for instance the "match" part of a flow can be
|
||||||
|
expressed as:
|
||||||
|
{
|
||||||
|
"nw_src": "192.168.1.1",
|
||||||
|
"nw_dst": "192.168.1.2",
|
||||||
|
}
|
||||||
|
However, some of them must be expressed as a list which allows for
|
||||||
|
duplicated keys. For instance, the "actions" section could be:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"output": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"output": 33
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
The is_list flag is used to discriminate this.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str): Name of the section.
|
||||||
|
pos (int): Position within the overall flow string.
|
||||||
|
string (str): Section string.
|
||||||
|
data (list[KeyValue]): Parsed data of the section.
|
||||||
|
is_list (bool): Whether the key-values shall be expressed as a list
|
||||||
|
(i.e: it allows repeated keys).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name, pos, string, data, is_list=False):
|
||||||
|
self.name = name
|
||||||
|
self.pos = pos
|
||||||
|
self.string = string
|
||||||
|
self.data = data
|
||||||
|
self.is_list = is_list
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "{} (at {}): {}".format(self.name, self.pos, self.string)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "%s('%s')" % (self.__class__.__name__, self)
|
||||||
|
|
||||||
|
def dict(self):
|
||||||
|
return {self.name: self.format_data()}
|
||||||
|
|
||||||
|
def format_data(self):
|
||||||
|
"""Returns the section's key-values formatted in a dictionary or list
|
||||||
|
depending on the value of is_list flag.
|
||||||
|
"""
|
||||||
|
if self.is_list:
|
||||||
|
return [{item.key: item.value} for item in self.data]
|
||||||
|
else:
|
||||||
|
return {item.key: item.value for item in self.data}
|
||||||
|
|
||||||
|
|
||||||
|
class Flow(object):
|
||||||
|
"""The Flow class is a base class for other types of concrete flows
|
||||||
|
(such as OFproto Flows or DPIF Flows).
|
||||||
|
|
||||||
|
A flow is basically comprised of a number of sections.
|
||||||
|
For each section named {section_name}, the flow object will have the
|
||||||
|
following attributes:
|
||||||
|
- {section_name} will return the sections data in a formatted way.
|
||||||
|
- {section_name}_kv will return the sections data as a list of KeyValues.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sections (list[Section]): List of sections that comprise the flow
|
||||||
|
orig (str): Original flow string.
|
||||||
|
id (Any): Optional; identifier that clients can use to uniquely
|
||||||
|
identify this flow.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, sections, orig="", id=None):
|
||||||
|
self._sections = sections
|
||||||
|
self._orig = orig
|
||||||
|
self._id = id
|
||||||
|
for section in sections:
|
||||||
|
setattr(
|
||||||
|
self, section.name, self.section(section.name).format_data()
|
||||||
|
)
|
||||||
|
setattr(
|
||||||
|
self,
|
||||||
|
"{}_kv".format(section.name),
|
||||||
|
self.section(section.name).data,
|
||||||
|
)
|
||||||
|
|
||||||
|
def section(self, name):
|
||||||
|
"""Return the section by name."""
|
||||||
|
return next(
|
||||||
|
(sect for sect in self._sections if sect.name == name), None
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self):
|
||||||
|
"""Return the Flow ID."""
|
||||||
|
return self._id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sections(self):
|
||||||
|
"""Return the all the sections in a list."""
|
||||||
|
return self._sections
|
||||||
|
|
||||||
|
@property
|
||||||
|
def orig(self):
|
||||||
|
"""Return the original flow string."""
|
||||||
|
return self._orig
|
||||||
|
|
||||||
|
def dict(self):
|
||||||
|
"""Returns the Flow information in a dictionary."""
|
||||||
|
flow_dict = {"orig": self.orig}
|
||||||
|
for section in self.sections:
|
||||||
|
flow_dict.update(section.dict())
|
||||||
|
|
||||||
|
return flow_dict
|
Reference in New Issue
Block a user