Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
P4Runtime manager.
"""
import enum
import os
import queue
import time
import logging
from collections import Counter, OrderedDict
from threading import Thread
from tabulate import tabulate
from p4.v1 import p4runtime_pb2
from p4.config.v1 import p4info_pb2
try:
from .p4_client import P4RuntimeClient, P4RuntimeException,\
P4RuntimeWriteException, WriteOperation, parse_p4runtime_error
from .p4_context import P4RuntimeEntity, P4Type, Context
from .p4_global_options import make_canonical_if_option_set
from .p4_common import encode,\
parse_resource_string_from_json, parse_resource_integer_from_json,\
parse_resource_bytes_from_json, parse_match_operations_from_json,\
parse_action_parameters_from_json, parse_integer_list_from_json
from .p4_exception import UserError, InvalidP4InfoError
except ImportError:
from p4_client import P4RuntimeClient, P4RuntimeException,\
P4RuntimeWriteException, WriteOperation, parse_p4runtime_error
from p4_context import P4RuntimeEntity, P4Type, Context
from p4_global_options import make_canonical_if_option_set
from p4_common import encode,\
parse_resource_string_from_json, parse_resource_integer_from_json,\
parse_resource_bytes_from_json, parse_match_operations_from_json,\
parse_action_parameters_from_json, parse_integer_list_from_json
from p4_exception import UserError, InvalidP4InfoError
# Logger instance
LOGGER = logging.getLogger(__name__)
# Global P4Runtime context
CONTEXT = Context()
# Global P4Runtime client
CLIENT = None
# Constant P4 entities
KEY_TABLE = "table"
KEY_ACTION = "action"
KEY_ACTION_PROFILE = "action_profile"
KEY_COUNTER = "counter"
KEY_DIR_COUNTER = "direct_counter"
KEY_METER = "meter"
KEY_DIR_METER = "direct_meter"
KEY_CTL_PKT_METADATA = "controller_packet_metadata"
def get_context():
"""
Return P4 context.
:return: context object
"""
return CONTEXT
def get_client():
"""
Return P4 client.
:return: P4Runtime client object
"""
return CLIENT
def get_api_version():
"""
Get the supported P4Runtime API version.
:return: API version
"""
return CLIENT.api_version()
def get_table_type(table):
"""
Assess the type of P4 table based upon the matching scheme.
:param table: P4 table
:return: P4 table type
"""
for m_f in table.match_fields:
if m_f.match_type == p4info_pb2.MatchField.EXACT:
return p4info_pb2.MatchField.EXACT
if m_f.match_type == p4info_pb2.MatchField.LPM:
return p4info_pb2.MatchField.LPM
if m_f.match_type == p4info_pb2.MatchField.TERNARY:
return p4info_pb2.MatchField.TERNARY
if m_f.match_type == p4info_pb2.MatchField.RANGE:
return p4info_pb2.MatchField.RANGE
if m_f.match_type == p4info_pb2.MatchField.OPTIONAL:
return p4info_pb2.MatchField.OPTIONAL
return None
def match_type_to_str(match_type):
"""
Convert table match type to string.
:param match_type: table match type object
:return: table match type string
"""
if match_type == p4info_pb2.MatchField.EXACT:
return "Exact"
if match_type == p4info_pb2.MatchField.LPM:
return "LPM"
if match_type == p4info_pb2.MatchField.TERNARY:
return "Ternary"
if match_type == p4info_pb2.MatchField.RANGE:
return "Range"
if match_type == p4info_pb2.MatchField.OPTIONAL:
return "Optional"
return None
def insert_table_entry_exact(
table_name, match_map, action_name, action_params, metadata,
cnt_pkt=-1, cnt_byte=-1):
"""
Insert an entry into an exact match table.
:param table_name: P4 table name
:param match_map: Map of match operations
:param action_name: Action name
:param action_params: Map of action parameters
:param metadata: table metadata
:param cnt_pkt: packet count
:param cnt_byte: byte count
:return: inserted entry
"""
assert match_map, "Table entry without match operations is not accepted"
assert action_name, "Table entry without action is not accepted"
table_entry = TableEntry(table_name)(action=action_name)
for match_k, match_v in match_map.items():
table_entry.match[match_k] = match_v
for action_k, action_v in action_params.items():
table_entry.action[action_k] = action_v
if metadata:
table_entry.metadata = metadata
if cnt_pkt > 0:
table_entry.counter_data.packet_count = cnt_pkt
if cnt_byte > 0:
table_entry.counter_data.byte_count = cnt_byte
ex_msg = ""
try:
table_entry.insert()
LOGGER.info("Inserted exact table entry: %s", table_entry)
except P4RuntimeWriteException as ex:
ex_msg = str(ex)
except P4RuntimeException as ex:
raise P4RuntimeException from ex
# Table entry exists, needs to be modified
if "ALREADY_EXISTS" in ex_msg:
table_entry.modify()
LOGGER.info("Updated exact table entry: %s", table_entry)
return table_entry
def insert_table_entry_ternary(
table_name, match_map, action_name, action_params, metadata,
priority, cnt_pkt=-1, cnt_byte=-1):
"""
Insert an entry into a ternary match table.
:param table_name: P4 table name
:param match_map: Map of match operations
:param action_name: Action name
:param action_params: Map of action parameters
Loading
Loading full blame…