| 1 |  |  | """High-level abstraction for Flows of multiple OpenFlow versions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | Use common fields of FlowStats/FlowMod of supported OF versions. ``match`` and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | ``actions`` fields are different, so Flow, Action and Match related classes are | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | inherited in v0x01 and v0x04 modules. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 | 1 |  | import json | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 | 1 |  | from abc import ABC, abstractmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 | 1 |  | from hashlib import md5 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | # Note: FlowModCommand is the same in both v0x01 and v0x04 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 | 1 |  | from pyof.v0x04.controller2switch.flow_mod import FlowModCommand | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 | 1 |  | from napps.kytos.of_core import v0x01, v0x04 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 | 1 |  | class FlowFactory(ABC):  # pylint: disable=too-few-public-methods | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     """Choose the correct Flow according to OpenFlow version.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 | 1 |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |     def from_of_flow_stats(cls, of_flow_stats, switch): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |         """Return a Flow for the switch OpenFlow version.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 | 1 |  |         flow_class = cls.get_class(switch) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 | 1 |  |         return flow_class.from_of_flow_stats(of_flow_stats, switch) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 | 1 |  |     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     def get_class(switch): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |         """Return the Flow class for the switch OF version.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 | 1 |  |         of_version = switch.connection.protocol.version | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 | 1 |  |         if of_version == 0x01: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 | 1 |  |             return v0x01.flow.Flow | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 | 1 |  |         if of_version == 0x04: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 | 1 |  |             return v0x04.flow.Flow | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |         raise NotImplementedError(f'Unsupported OpenFlow version {of_version}') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 | 1 |  | class FlowBase(ABC):  # pylint: disable=too-many-instance-attributes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     """Class to abstract a Flow to switches. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     This class represents a Flow installed or to be installed inside the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     switch. A flow, in this case is represented by a Match object and a set of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |     actions that should occur in case any match happen. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |     # of_version number: 0x01, 0x04 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 | 1 |  |     of_version = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     # Subclasses must set their version-specific classes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 | 1 |  |     _action_factory = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 | 1 |  |     _flow_mod_class = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 | 1 |  |     _match_class = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 | 1 |  |     def __init__(self, switch, table_id=0xff, match=None, priority=0x8000, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |                  idle_timeout=0, hard_timeout=0, cookie=0, actions=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |                  stats=None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |         """Assign parameters to attributes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |         Args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |             switch (kytos.core.switch.Switch): Switch ID is used to uniquely | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |                 identify a flow. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |             table_id (int): The index of a single table or 0xff for all tables. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |             match (|match|): Match object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |             priority (int): Priority level of flow entry. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |             idle_timeout (int): Idle time before discarding, in seconds. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |             hard_timeout (int): Max time before discarding, in seconds. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |             cookie (int): Opaque controller-issued identifier. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |             actions (|list_of_actions|): List of actions to apply. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |             stats (Stats): Latest flow statistics. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         # pylint: disable=too-many-arguments,too-many-locals | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 | 1 |  |         self.switch = switch | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 | 1 |  |         self.table_id = table_id | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |         # Disable not-callable error as subclasses set a class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 | 1 |  |         self.match = match or self._match_class()  # pylint: disable=E1102 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 | 1 |  |         self.priority = priority | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 | 1 |  |         self.idle_timeout = idle_timeout | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 | 1 |  |         self.hard_timeout = hard_timeout | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 | 1 |  |         self.cookie = cookie | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 | 1 |  |         self.actions = actions or [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 | 1 |  |         self.stats = stats or FlowStats()  # pylint: disable=E1102 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 | 1 |  |     @property | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |     def id(self):  # pylint: disable=invalid-name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         """Return this flow unique identifier. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         Calculate an md5 hash based on this object's modified json string. The | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         json for ID calculation excludes ``stats`` attribute that changes over | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |         time. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |         Returns: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |             str: Flow unique identifier (md5sum). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 | 1 |  |         flow_str = self.as_json(sort_keys=True, include_id=False) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 | 1 |  |         md5sum = md5() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 | 1 |  |         md5sum.update(flow_str.encode('utf-8')) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 | 1 |  |         return md5sum.hexdigest() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 | 1 |  |     def as_dict(self, include_id=True): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |         """Return the Flow as a serializable Python dictionary. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |         Args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |             include_id (bool): Default is ``True``. Internally, it is set to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |                 ``False`` when calculating the flow ID that is based in this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |                 dictionary's JSON string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |         Returns: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |             dict: Serializable dictionary. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 | 1 |  |         flow_dict = { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |             'switch': self.switch.id, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |             'table_id': self.table_id, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |             'match': self.match.as_dict(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |             'priority': self.priority, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |             'idle_timeout': self.idle_timeout, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |             'hard_timeout': self.hard_timeout, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |             'cookie': self.cookie, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |             'actions': [action.as_dict() for action in self.actions]} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 | 1 |  |         if include_id: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |             # Avoid infinite recursion | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 | 1 |  |             flow_dict['id'] = self.id | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |             # Remove statistics that change over time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 | 1 |  |             flow_dict['stats'] = self.stats.as_dict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 | 1 |  |         return flow_dict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 | 1 |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |     def from_dict(cls, flow_dict, switch): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |         """Return an instance with values from ``flow_dict``.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 | 1 |  |         flow = cls(switch) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |         # Set attributes found in ``flow_dict`` | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 | 1 |  |         for attr_name, attr_value in flow_dict.items(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 | 1 |  |             if attr_name in vars(flow): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 | 1 |  |                 setattr(flow, attr_name, attr_value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 | 1 |  |         flow.switch = switch | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 | 1 |  |         if 'stats' in flow_dict: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 | 1 |  |             flow.stats = FlowStats.from_dict(flow_dict['stats']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |         # Version-specific attributes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 | 1 |  |         if 'match' in flow_dict: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 | 1 |  |             flow.match = cls._match_class.from_dict(flow_dict['match']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 | 1 |  |         if 'actions' in flow_dict: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 | 1 |  |             flow.actions = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 | 1 |  |             for action_dict in flow_dict['actions']: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 | 1 |  |                 action = cls._action_factory.from_dict(action_dict) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 | 1 |  |                 if action: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 | 1 |  |                     flow.actions.append(action) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 | 1 |  |         return flow | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 | 1 |  |     def as_json(self, sort_keys=False, include_id=True): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |         """Return the representation of a flow in JSON format. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |         Args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |             sort_keys (bool): ``False`` by default (Python's default). Sorting | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |                 is used, for example, to calculate the flow ID. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |             include_id (bool): ``True`` by default. Internally, the ID is not | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |                 included while calculating it. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |         Returns: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |             string: Flow JSON string representation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 | 1 |  |         return json.dumps(self.as_dict(include_id), sort_keys=sort_keys) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 | 1 |  |     def as_of_add_flow_mod(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |         """Return an OpenFlow add FlowMod.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 | 1 |  |         return self._as_of_flow_mod(FlowModCommand.OFPFC_ADD) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 | 1 |  |     def as_of_delete_flow_mod(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |         """Return an OpenFlow delete FlowMod.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 | 1 |  |         return self._as_of_flow_mod(FlowModCommand.OFPFC_DELETE) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 | 1 |  |     @abstractmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |     def _as_of_flow_mod(self, command): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |         """Return a pyof FlowMod with given ``command``.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |         # Disable not-callable error as subclasses will set a class | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 | 1 |  |         flow_mod = self._flow_mod_class()  # pylint: disable=E1102 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 | 1 |  |         flow_mod.match = self.match.as_of_match() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 | 1 |  |         flow_mod.cookie = self.cookie | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 | 1 |  |         flow_mod.command = command | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 | 1 |  |         flow_mod.idle_timeout = self.idle_timeout | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 | 1 |  |         flow_mod.hard_timeout = self.hard_timeout | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 | 1 |  |         flow_mod.priority = self.priority | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 | 1 |  |         return flow_mod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 | 1 |  |     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 | 1 |  |     @abstractmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |     def _get_of_actions(of_flow_stats): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |         """Return pyof actions from pyof FlowStats.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 | 1 |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |     def from_of_flow_stats(cls, of_flow_stats, switch): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |         """Create a flow with latest stats based on pyof FlowStats.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |         of_actions = cls._get_of_actions(of_flow_stats) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |         actions = (cls._action_factory.from_of_action(of_action) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |                    for of_action in of_actions) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |         non_none_actions = [action for action in actions if action] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |         return cls(switch, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |                    table_id=of_flow_stats.table_id.value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |                    match=cls._match_class.from_of_match(of_flow_stats.match), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |                    priority=of_flow_stats.priority.value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |                    idle_timeout=of_flow_stats.idle_timeout.value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |                    hard_timeout=of_flow_stats.hard_timeout.value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |                    cookie=of_flow_stats.cookie.value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |                    actions=non_none_actions, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |                    stats=FlowStats.from_of_flow_stats(of_flow_stats)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 | 1 |  | class ActionBase(ABC): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |     """Base class for a flow action.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 | 1 |  |     def as_dict(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |         """Return a dict that can be dumped as JSON.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 | 1 |  |         return vars(self) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 | 1 |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |     def from_dict(cls, action_dict): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |         """Return an action instance from attributes in a dictionary.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 | 1 |  |         action = cls(None) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 | 1 |  |         for attr_name, value in action_dict.items(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 | 1 |  |             if hasattr(action, attr_name): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 | 1 |  |                 setattr(action, attr_name, value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 | 1 |  |         return action | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 | 1 |  |     @abstractmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |     def as_of_action(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |         """Return a pyof action to be used by a FlowMod.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 | 1 |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 | 1 |  |     @abstractmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |     def from_of_action(cls, of_action): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |         """Return an action from a pyof action.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 | 1 |  | class ActionFactoryBase(ABC): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |     """Deal with different implementations of ActionBase.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |     # key: action_type or pyof class, value: ActionBase child | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 | 1 |  |     _action_class = { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |         'output': None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |         'set_vlan': None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |         # pyof class: ActionBase child | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 | 1 |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |     def from_dict(cls, action_dict): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |         """Build the proper Action from a dictionary. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |         Args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |             action_dict (dict): Action attributes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 | 1 |  |         action_type = action_dict.get('action_type') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 | 1 |  |         action_class = cls._action_class[action_type] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 | 1 |  |         return action_class.from_dict(action_dict) if action_class else None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 | 1 |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |     def from_of_action(cls, of_action): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |         """Build the proper Action from a pyof action. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |         Args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |             of_action (pyof action): Action from python-openflow. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |         of_class = type(of_action) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |         action_class = cls._action_class.get(of_class) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |         return action_class.from_of_action(of_action) if action_class else None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 | 1 |  | class MatchBase:  # pylint: disable=too-many-instance-attributes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |     """Base class with common high-level Match fields.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 | 1 |  |     def __init__(self, in_port=None, dl_src=None, dl_dst=None, dl_vlan=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  |                  dl_vlan_pcp=None, dl_type=None, nw_proto=None, nw_src=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |                  nw_dst=None, tp_src=None, tp_dst=None, in_phy_port=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |                  ip_dscp=None, ip_ecn=None, udp_src=None, udp_dst=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |                  sctp_src=None, sctp_dst=None, icmpv4_type=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |                  icmpv4_code=None, arp_op=None, arp_spa=None, arp_tpa=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |                  arp_sha=None, arp_tha=None, ipv6_src=None, ipv6_dst=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |                  ipv6_flabel=None, icmpv6_type=None, icmpv6_code=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |                  nd_tar=None, nd_sll=None, nd_tll=None, mpls_lab=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |                  mpls_tc=None, mpls_bos=None, pbb_isid=None, v6_hdr=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |                  metadata=None, tun_id=None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 | 1 |  |         """Make it possible to set all attributes from the constructor.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 | 1 |  |         # pylint: disable=too-many-arguments | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 | 1 |  |         # pylint: disable=too-many-locals | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 | 1 |  |         self.in_port = in_port | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 | 1 |  |         self.dl_src = dl_src | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 | 1 |  |         self.dl_dst = dl_dst | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 | 1 |  |         self.dl_vlan = dl_vlan | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 | 1 |  |         self.dl_vlan_pcp = dl_vlan_pcp | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 | 1 |  |         self.dl_type = dl_type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 | 1 |  |         self.nw_proto = nw_proto | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 | 1 |  |         self.nw_src = nw_src | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 | 1 |  |         self.nw_dst = nw_dst | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 | 1 |  |         self.tp_src = tp_src | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 | 1 |  |         self.tp_dst = tp_dst | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 | 1 |  |         self.in_phy_port = in_phy_port | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 | 1 |  |         self.ip_dscp = ip_dscp | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 | 1 |  |         self.ip_ecn = ip_ecn | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 | 1 |  |         self.udp_src = udp_src | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 | 1 |  |         self.udp_dst = udp_dst | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 | 1 |  |         self.sctp_src = sctp_src | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 | 1 |  |         self.sctp_dst = sctp_dst | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 | 1 |  |         self.icmpv4_type = icmpv4_type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 | 1 |  |         self.icmpv4_code = icmpv4_code | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 | 1 |  |         self.arp_op = arp_op | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 | 1 |  |         self.arp_spa = arp_spa | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 | 1 |  |         self.arp_tpa = arp_tpa | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 | 1 |  |         self.arp_sha = arp_sha | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |         self.arp_tha = arp_tha | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 | 1 |  |         self.ipv6_src = ipv6_src | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |         self.ipv6_dst = ipv6_dst | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 | 1 |  |         self.ipv6_flabel = ipv6_flabel | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |         self.icmpv6_type = icmpv6_type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 | 1 |  |         self.icmpv6_code = icmpv6_code | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |         self.nd_tar = nd_tar | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |         self.nd_sll = nd_sll | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 | 1 |  |         self.nd_tll = nd_tll | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 | 1 |  |         self.mpls_lab = mpls_lab | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 | 1 |  |         self.mpls_tc = mpls_tc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 | 1 |  |         self.mpls_bos = mpls_bos | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 | 1 |  |         self.pbb_isid = pbb_isid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 |  |  |         self.v6_hdr = v6_hdr | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 | 1 |  |         self.metadata = metadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 | 1 |  |         self.tun_id = tun_id | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |     def as_dict(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  |         """Return a dictionary excluding ``None`` values.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 | 1 |  |         return {k: v for k, v in self.__dict__.items() if v is not None} | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 333 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 334 |  |  |     @classmethod | 
            
                                                                        
                            
            
                                    
            
            
                | 335 |  |  |     def from_dict(cls, match_dict): | 
            
                                                                        
                            
            
                                    
            
            
                | 336 |  |  |         """Return a Match instance from a dictionary.""" | 
            
                                                                        
                            
            
                                    
            
            
                | 337 | 1 |  |         match = cls() | 
            
                                                                        
                            
            
                                    
            
            
                | 338 |  |  |         for key, value in match_dict.items(): | 
            
                                                                        
                            
            
                                    
            
            
                | 339 |  |  |             if key in match.__dict__: | 
            
                                                                        
                            
            
                                    
            
            
                | 340 | 1 |  |                 setattr(match, key, value) | 
            
                                                                        
                            
            
                                    
            
            
                | 341 |  |  |         return match | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 | 1 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  |     @abstractmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  |     def from_of_match(cls, of_match): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 | 1 |  |         """Return a Match instance from a pyof Match.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |     @abstractmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 | 1 |  |     def as_of_match(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 | 1 |  |         """Return a python-openflow Match.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 | 1 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 | 1 |  | class Stats: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |     """Simple class to store statistics as attributes and values.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |     def as_dict(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  |         """Return a dict excluding attributes with ``None`` value.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |         return {attribute: value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |                 for attribute, value in vars(self).items() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 | 1 |  |                 if value is not None} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |     def from_dict(cls, stats_dict): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |         """Return a statistics object from a dictionary.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |         stats = cls() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |         cls._update(stats, stats_dict.items()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |         return stats | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |     def from_of_flow_stats(cls, of_stats): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |         """Create an instance from a pyof FlowStats.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 | 1 |  |         stats = cls() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  |         stats.update(of_stats) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |         return stats | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 | 1 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |     def update(self, of_stats): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |         """Given a pyof stats object, update attributes' values. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |         Avoid object creation and memory leak. pyof values are GenericType | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 | 1 |  |         instances whose native values can be accessed by `.value`. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |         # Generator for GenericType values | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 | 1 |  |         attr_name_value = ((attr_name, gen_type.value) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                            
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |                            for attr_name, gen_type in vars(of_stats).items() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 | 1 |  |                            if attr_name in vars(self)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 | 1 |  |         self._update(self, attr_name_value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 | 1 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 | 1 |  |     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |     def _update(obj, iterable): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |         """From attribute name and value pairs, update ``obj``.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 | 1 |  |         for attr_name, value in iterable: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |             if hasattr(obj, attr_name): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |                 setattr(obj, attr_name, value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 | 1 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  | class FlowStats(Stats): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |     """Common fields for 1.0 and 1.3 FlowStats.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  |     def __init__(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 |  |  |         """Initialize all statistics as ``None``.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |         self.byte_count = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  |         self.duration_sec = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |         self.duration_nsec = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |         self.packet_count = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 |  |  | class PortStats(Stats):  # pylint: disable=too-many-instance-attributes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  |     """Common fields for 1.0 and 1.3 PortStats.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  |     def __init__(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 |  |  |         """Initialize all statistics as ``None``.""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 |  |  |         self.rx_packets = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 |  |  |         self.tx_packets = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |         self.rx_bytes = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |         self.tx_bytes = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  |         self.rx_dropped = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  |         self.tx_dropped = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  |         self.rx_errors = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |         self.tx_errors = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  |         self.rx_frame_err = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  |         self.rx_over_err = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 |  |  |         self.rx_crc_err = None | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 423 |  |  |         self.collisions = None | 
            
                                                        
            
                                    
            
            
                | 424 |  |  |  |