blob: 38ceb0331c549e3783c0add9d17037ebe481fe50 [file] [log] [blame]
Zack Williams9731cdc2019-11-22 15:42:30 -07001#
2# Copyright 2017 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17"""
18Convert loxi objects to openflow_13 messages and back.
19"""
20from copy import copy
21
22from google.protobuf.descriptor import FieldDescriptor
23
24import loxi.of13 as of13
25from protobuf_to_dict import protobuf_to_dict, TYPE_CALLABLE_MAP
26from voltha_protos import openflow_13_pb2 as pb2
Andrea Campanella4461a582020-02-20 15:05:19 +010027from utils import RESERVED_TRANSPARENT_VLAN
Zack Williams9731cdc2019-11-22 15:42:30 -070028
29
30type_callable_map = copy(TYPE_CALLABLE_MAP)
31type_callable_map.update({
32 FieldDescriptor.TYPE_STRING: str
33})
34
35def pb2dict(pb):
36 """
37 Convert protobuf to a dict of values good for instantiating
38 loxi objects (or any other objects). We specialize the protobuf_to_dict
39 library call with our modified decoders.
40 :param pb: protobuf as loaded into Python
41 :return: dict of values
42 """
43 return protobuf_to_dict(pb, type_callable_map)
44
45def to_loxi(grpc_object):
46 cls = grpc_object.__class__
47 converter = to_loxi_converters[cls.__name__]
48 return converter(grpc_object)
49
50def to_grpc(loxi_object):
51 cls = loxi_object.__class__
52 converter = to_grpc_converters[cls]
53 return converter(loxi_object)
54
55def ofp_port_to_loxi_port_desc(pb):
56 kw = pb2dict(pb)
57 return of13.common.port_desc(**kw)
58
59def ofp_port_status_to_loxi_port_status(pb):
60 return of13.message.port_status(
61 reason=pb.reason,
62 desc=ofp_port_to_loxi_port_desc(pb.desc)
63 )
64
65def ofp_port_stats_to_loxi_port_stats(pb):
66 kw = pb2dict(pb)
67 return of13.port_stats_entry(**kw)
68
69
70def ofp_meter_stats_to_loxi_meter_stats(pb):
71 return of13.meter_stats(
72 meter_id=pb.meter_id,
73 flow_count=pb.flow_count,
74 packet_in_count=pb.packet_in_count,
75 byte_in_count=pb.byte_in_count,
76 duration_sec=pb.duration_sec,
77 duration_nsec=pb.duration_nsec,
78 band_stats=[to_loxi(band_stat) for band_stat in pb.band_stats])
79
80
81def ofp_meter_band_stats_to_loxi_meter_stats(pb):
82 return of13.meter_band_stats(
83 packet_band_count=pb.packet_band_count,
84 byte_band_count=pb.byte_band_count
85 )
86
87def make_loxi_field(oxm_field):
88 assert oxm_field['oxm_class'] == pb2.OFPXMC_OPENFLOW_BASIC
89 ofb_field = oxm_field['ofb_field']
90 field_type = ofb_field.get('type', 0)
Zack Williams9731cdc2019-11-22 15:42:30 -070091 if field_type == pb2.OFPXMT_OFB_ETH_TYPE:
92 return (
93 of13.oxm.eth_type(value=ofb_field['eth_type']))
94
95 elif field_type == pb2.OFPXMT_OFB_IN_PORT:
96 return (
97 of13.oxm.in_port(value=ofb_field['port']))
98
99 elif field_type == pb2.OFPXMT_OFB_IP_PROTO:
100 return (
101 of13.oxm.ip_proto(value=ofb_field['ip_proto']))
102
103 elif field_type == pb2.OFPXMT_OFB_VLAN_VID:
Andrea Campanella4461a582020-02-20 15:05:19 +0100104 if ofb_field.get('vlan_vid') == RESERVED_TRANSPARENT_VLAN and ofb_field['vlan_vid_mask'] == RESERVED_TRANSPARENT_VLAN:
105 return (
106 of13.oxm.vlan_vid_masked(value=ofb_field['vlan_vid_mask'], value_mask=ofb_field['vlan_vid_mask']))
107 else:
108 return (
109 of13.oxm.vlan_vid(value=ofb_field['vlan_vid']))
Zack Williams9731cdc2019-11-22 15:42:30 -0700110
111 elif field_type == pb2.OFPXMT_OFB_VLAN_PCP:
112 return (
113 of13.oxm.vlan_pcp(value=ofb_field['vlan_pcp']))
114
115 elif field_type == pb2.OFPXMT_OFB_IPV4_SRC:
116 return (
117 of13.oxm.ipv4_src(value=ofb_field['ipv4_src']))
118
119 elif field_type == pb2.OFPXMT_OFB_IPV4_DST:
120 return (
121 of13.oxm.ipv4_dst(value=ofb_field['ipv4_dst']))
122
123 elif field_type == pb2.OFPXMT_OFB_UDP_SRC:
124 return (
125 of13.oxm.udp_src(value=ofb_field['udp_src']))
126
127 elif field_type == pb2.OFPXMT_OFB_UDP_DST:
128 return (
129 of13.oxm.udp_dst(value=ofb_field['udp_dst']))
130
131 elif field_type == pb2.OFPXMT_OFB_METADATA:
132 return (
133 of13.oxm.metadata(value=ofb_field['table_metadata']))
134
135 else:
136 raise NotImplementedError(
137 'OXM match field for type %s' % field_type)
138
139def make_loxi_match(match):
140 assert match.get('type', pb2.OFPMT_STANDARD) == pb2.OFPMT_OXM
141 loxi_match_fields = []
142 for oxm_field in match.get('oxm_fields', []):
143 loxi_match_fields.append(make_loxi_field(oxm_field))
144 return of13.match_v3(oxm_list=loxi_match_fields)
145
146
147def make_loxi_action(a):
148 if type(a) is not dict:
149 a = pb2dict(a)
150
151 typ = a.get('type', 0)
152
153 if typ == pb2.OFPAT_OUTPUT:
154 output_kws = a['output']
155 return of13.action.output(**output_kws)
156
157 elif typ == pb2.OFPAT_POP_VLAN:
158 return of13.action.pop_vlan()
159
160 elif typ == pb2.OFPAT_PUSH_VLAN:
161 push_vlan_kws = a['push']
162 return of13.action.push_vlan(**push_vlan_kws)
163
164 elif typ == pb2.OFPAT_SET_FIELD:
165 loxi_field = make_loxi_field(a['set_field']['field'])
166 return of13.action.set_field(loxi_field)
167
168 elif typ == pb2.OFPAT_GROUP:
169 group_kws = a['group']
170 return of13.action.group(**group_kws)
171
172 else:
173 raise NotImplementedError(
174 'Action decoder for action OFPAT_* %d' % typ)
175
176
177def ofp_flow_stats_to_loxi_flow_stats(pb):
178 kw = pb2dict(pb)
179
180 def make_loxi_instruction(inst):
181 type = inst['type']
182 if type == pb2.OFPIT_APPLY_ACTIONS:
183 return of13.instruction.apply_actions(
184 actions=[make_loxi_action(a)
185 for a in inst['actions']['actions']])
186 elif type == pb2.OFPIT_CLEAR_ACTIONS:
187 return of13.instruction.clear_actions()
188 elif type == pb2.OFPIT_GOTO_TABLE:
189 return of13.instruction.goto_table(
190 table_id=inst['goto_table']['table_id'])
191 elif type == pb2.OFPIT_WRITE_ACTIONS:
192 return of13.instruction.write_actions(
193 actions=[make_loxi_action(a)
194 for a in inst['actions']['actions']])
195 elif type == pb2.OFPIT_WRITE_METADATA:
196 if 'metadata' in inst['write_metadata']:
197 return of13.instruction.write_metadata(
198 metadata=inst['write_metadata']['metadata'])
199 else:
200 return of13.instruction.write_metadata(0)
201 elif type == pb2.OFPIT_METER:
202 return of13.instruction.meter(
203 meter_id=inst['meter']['meter_id'])
204
205 else:
206 raise NotImplementedError('Instruction type %d' % type)
207
208 kw['match'] = make_loxi_match(kw['match'])
209 # if the flow action is drop, then the instruction is not found in the dict
210 if 'instructions' in kw:
211 kw['instructions'] = [make_loxi_instruction(i) for i in kw['instructions']]
212 del kw['id']
213 return of13.flow_stats_entry(**kw)
214
215
216def ofp_packet_in_to_loxi_packet_in(pb):
217 packet_in = of13.message.packet_in(
218 buffer_id=pb.buffer_id,
219 reason=pb.reason,
220 table_id=pb.table_id,
221 cookie=pb.cookie,
222 match=make_loxi_match(pb2dict(pb.match)),
223 data=pb.data
224 )
225 return packet_in
226
227def ofp_group_desc_to_loxi_group_desc(pb):
228 return of13.group_desc_stats_entry(
229 group_type=pb.type,
230 group_id=pb.group_id,
231 buckets=[to_loxi(bucket) for bucket in pb.buckets])
232
233
234def ofp_group_stats_to_loxi_group_stats(pb):
235 return of13.group_stats_entry(
236 group_id=pb.group_id,
237 ref_count=pb.ref_count,
238 packet_count=pb.packet_count,
239 byte_count=pb.byte_count,
240 duration_sec=pb.duration_sec,
241 duration_nsec=pb.duration_nsec,
242 bucket_stats=[to_loxi(bstat) for bstat in pb.bucket_stats])
243
244
245def ofp_bucket_counter_to_loxy_bucket_counter(pb):
246 return of13.bucket_counter(
247 packet_count=pb.packet_count,
248 byte_count=pb.byte_count)
249
250
251def ofp_bucket_to_loxi_bucket(pb):
252 return of13.bucket(
253 weight=pb.weight,
254 watch_port=pb.watch_port,
255 watch_group=pb.watch_group,
256 actions=[to_loxi(action) for action in pb.actions]
257 )
258
259
260to_loxi_converters = {
261 'ofp_port': ofp_port_to_loxi_port_desc,
262 'ofp_port_status': ofp_port_status_to_loxi_port_status,
263 'ofp_flow_stats': ofp_flow_stats_to_loxi_flow_stats,
264 'ofp_packet_in': ofp_packet_in_to_loxi_packet_in,
265 'ofp_group_stats': ofp_group_stats_to_loxi_group_stats,
266 'ofp_group_desc': ofp_group_desc_to_loxi_group_desc,
267 'ofp_bucket_counter': ofp_bucket_counter_to_loxy_bucket_counter,
268 'ofp_bucket': ofp_bucket_to_loxi_bucket,
269 'ofp_action': make_loxi_action,
270 'ofp_port_stats': ofp_port_stats_to_loxi_port_stats,
271 'ofp_meter_stats': ofp_meter_stats_to_loxi_meter_stats,
272 'ofp_meter_band_stats': ofp_meter_band_stats_to_loxi_meter_stats
273}
274
275
276def loxi_flow_mod_to_ofp_flow_mod(lo):
277 return pb2.ofp_flow_mod(
278 cookie=lo.cookie,
279 cookie_mask=lo.cookie_mask,
280 table_id=lo.table_id,
281 command=lo._command,
282 idle_timeout=lo.idle_timeout,
283 hard_timeout=lo.hard_timeout,
284 priority=lo.priority,
285 buffer_id=lo.buffer_id,
286 out_port=lo.out_port,
287 out_group=lo.out_group,
288 flags=lo.flags,
289 match=to_grpc(lo.match),
290 instructions=[to_grpc(i) for i in lo.instructions])
291
292def loxi_meter_mod_to_ofp_meter_mod(lo):
293 return pb2.ofp_meter_mod(
294 command=lo.command,
295 flags=lo.flags,
296 meter_id=lo.meter_id,
297 bands=[to_grpc(i) for i in lo.meters])
298
299
300def loxi_meter_band_drop_to_ofp_meter_band_drop(lo):
301 return pb2.ofp_meter_band_header(
302 type=lo.type,
303 rate=lo.rate,
304 burst_size=lo.burst_size)
305
306
307def loxi_meter_band_dscp_remark_to_ofp_meter_band_dscp_remark(lo):
308 return pb2.ofp_meter_band_header(
309 type=lo.type,
310 rate=lo.rate,
311 burst_size=lo.burst_size,
312 dscp_remark=pb2.ofp_meter_band_dscp_remark(prec_level=lo.prec_level))
313
314
315def loxi_meter_band_experimenter_to_ofp_meter_band_experimenter(lo):
316 return pb2.ofp_meter_band_header(
317 type=lo.type,
318 rate=lo.rate,
319 burst_size=lo.burst_size,
320 experimenter=pb2.ofp_meter_band_experimenter(experimenter=lo.experimenter))
321
322
323def loxi_meter_multipart_request_to_ofp_meter_multipart_request(lo):
324 return pb2.ofp_meter_multipart_request(
325 meter_id=lo.meter_id)
326
327
328def loxi_meter_stats_to_ofp_meter_stats(lo):
329 return pb2.ofp_meter_stats(
330 meter_id=lo.meter_id,
331 flow_count=lo.flow_count,
332 packet_in_count =lo.packet_in_count,
333 byte_in_count=lo.byte_in_count,
334 duration_sec=lo.duration_sec,
335 duration_nsec=lo.duration_nsec,
336 band_stats=lo.band_stats)
337
338
339def loxi_meter_mod_to_ofp_meter_mod(lo):
340 return pb2.ofp_meter_mod(
341 command=lo.command,
342 flags=lo.flags,
343 meter_id=lo.meter_id,
344 bands=[to_grpc(i) for i in lo.meters])
345
346
347def loxi_meter_band_drop_to_ofp_meter_band_drop(lo):
348 return pb2.ofp_meter_band_header(
349 type=lo.type,
350 rate=lo.rate,
351 burst_size=lo.burst_size)
352
353
354def loxi_meter_band_dscp_remark_to_ofp_meter_band_dscp_remark(lo):
355 return pb2.ofp_meter_band_header(
356 type=lo.type,
357 rate=lo.rate,
358 burst_size=lo.burst_size,
359 dscp_remark=pb2.ofp_meter_band_dscp_remark(prec_level=lo.prec_level))
360
361
362def loxi_meter_band_experimenter_to_ofp_meter_band_experimenter(lo):
363 return pb2.ofp_meter_band_header(
364 type=lo.type,
365 rate=lo.rate,
366 burst_size=lo.burst_size,
367 experimenter=pb2.ofp_meter_band_experimenter(experimenter=lo.experimenter))
368
369
370def loxi_meter_multipart_request_to_ofp_meter_multipart_request(lo):
371 return pb2.ofp_meter_multipart_request(
372 meter_id=lo.meter_id)
373
374def loxi_meter_stats_to_ofp_meter_stats(lo):
375 return pb2.ofp_meter_stats(
376 meter_id=lo.meter_id,
377 flow_count=lo.flow_count,
378 packet_in_count =lo.packet_in_count,
379 byte_in_count=lo.byte_in_count,
380 duration_sec=lo.duration_sec,
381 duration_nsec=lo.duration_nsec,
382 band_stats=lo.band_stats)
383
384def loxi_group_mod_to_ofp_group_mod(lo):
385 return pb2.ofp_group_mod(
386 command=lo.command,
387 type=lo.group_type,
388 group_id=lo.group_id,
389 buckets=[to_grpc(b) for b in lo.buckets])
390
391
392def loxi_packet_out_to_ofp_packet_out(lo):
393 return pb2.ofp_packet_out(
394 buffer_id=lo.buffer_id,
395 in_port=lo.in_port,
396 actions=[to_grpc(a) for a in lo.actions],
397 data=lo.data)
398
399
400def loxi_match_v3_to_ofp_match(lo):
401 return pb2.ofp_match(
402 type=pb2.OFPMT_OXM,
403 oxm_fields=[to_grpc(f) for f in lo.oxm_list])
404
405
406def loxi_bucket_to_ofp_bucket(lo):
407 return pb2.ofp_bucket(
408 weight=lo.weight,
409 watch_port=lo.watch_port,
410 watch_group=lo.watch_group,
411 actions=[to_grpc(a) for a in lo.actions])
412
413
414def loxi_oxm_eth_type_to_ofp_oxm(lo):
415 return pb2.ofp_oxm_field(
416 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
417 ofb_field=pb2.ofp_oxm_ofb_field(
418 type=pb2.OFPXMT_OFB_ETH_TYPE,
419 eth_type=lo.value))
420
421
422def loxi_oxm_in_port_to_ofp_oxm(lo):
423 return pb2.ofp_oxm_field(
424 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
425 ofb_field=pb2.ofp_oxm_ofb_field(
426 type=pb2.OFPXMT_OFB_IN_PORT,
427 port=lo.value))
428
429
430def loxi_oxm_ip_proto_to_ofp_oxm(lo):
431 return pb2.ofp_oxm_field(
432 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
433 ofb_field=pb2.ofp_oxm_ofb_field(
434 type=pb2.OFPXMT_OFB_IP_PROTO,
435 ip_proto=lo.value))
436
437
438def loxi_oxm_vlan_vid_to_ofp_oxm(lo):
439 return pb2.ofp_oxm_field(
440 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
441 ofb_field=pb2.ofp_oxm_ofb_field(
442 type=pb2.OFPXMT_OFB_VLAN_VID,
443 vlan_vid=lo.value))
444
445
446def loxi_oxm_vlan_pcp_to_ofp_oxm(lo):
447 return pb2.ofp_oxm_field(
448 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
449 ofb_field=pb2.ofp_oxm_ofb_field(
450 type=pb2.OFPXMT_OFB_VLAN_PCP,
451 vlan_pcp=lo.value))
452
453
454def loxi_oxm_ipv4_dst_to_ofp_oxm(lo):
455 return pb2.ofp_oxm_field(
456 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
457 ofb_field=pb2.ofp_oxm_ofb_field(
458 type=pb2.OFPXMT_OFB_IPV4_DST,
459 ipv4_dst=lo.value))
460
461
462def loxi_oxm_udp_dst_to_ofp_oxm(lo):
463 return pb2.ofp_oxm_field(
464 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
465 ofb_field=pb2.ofp_oxm_ofb_field(
466 type=pb2.OFPXMT_OFB_UDP_DST,
467 udp_dst=lo.value))
468
469
470def loxi_oxm_udp_src_to_ofp_oxm(lo):
471 return pb2.ofp_oxm_field(
472 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
473 ofb_field=pb2.ofp_oxm_ofb_field(
474 type=pb2.OFPXMT_OFB_UDP_SRC,
475 udp_src=lo.value))
476
477
478def loxi_oxm_metadata_to_ofp_oxm(lo):
479 return pb2.ofp_oxm_field(
480 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
481 ofb_field=pb2.ofp_oxm_ofb_field(
482 type=pb2.OFPXMT_OFB_METADATA,
483 table_metadata=lo.value))
484
Andrea Campanella4461a582020-02-20 15:05:19 +0100485def loxi_oxm_vlan_vid_masked_to_ofp_oxm(lo):
486 return pb2.ofp_oxm_field(
487 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
488 ofb_field=pb2.ofp_oxm_ofb_field(
489 type=pb2.OFPXMT_OFB_VLAN_VID,
490 vlan_vid=lo.value,
491 vlan_vid_mask=lo.value))
492
Zack Williams9731cdc2019-11-22 15:42:30 -0700493
494def loxi_apply_actions_to_ofp_instruction(lo):
495 return pb2.ofp_instruction(
496 type=pb2.OFPIT_APPLY_ACTIONS,
497 actions=pb2.ofp_instruction_actions(
498 actions=[to_grpc(a) for a in lo.actions]))
499
500def loxi_clear_actions_to_ofp_instruction(lo):
501 return pb2.ofp_instruction(
502 type=pb2.OFPIT_CLEAR_ACTIONS)
503
504
505def loxi_goto_table_to_ofp_instruction(lo):
506 return pb2.ofp_instruction(
507 type=pb2.OFPIT_GOTO_TABLE,
508 goto_table=pb2.ofp_instruction_goto_table(table_id=lo.table_id))
509
510
511def loxi_write_metadata_to_ofp_instruction(lo):
512 return pb2.ofp_instruction(
513 type=pb2.OFPIT_WRITE_METADATA,
514 write_metadata=pb2.ofp_instruction_write_metadata(
515 metadata=lo.metadata,
516 metadata_mask=lo.metadata_mask))
517
518
519def loxi_meter_to_ofp_instruction(lo):
520 return pb2.ofp_instruction(
521 type=pb2.OFPIT_METER,
522 meter=pb2.ofp_instruction_meter(meter_id=lo.meter_id))
523
524
525def loxi_output_action_to_ofp_action(lo):
526 return pb2.ofp_action(
527 type=pb2.OFPAT_OUTPUT,
528 output=pb2.ofp_action_output(port=lo.port, max_len=lo.max_len))
529
530
531def loxi_write_actions_to_ofp_instruction(lo):
532 return pb2.ofp_instruction(
533 type=pb2.OFPIT_WRITE_ACTIONS,
534 actions=pb2.ofp_instruction_actions(
535 actions=[to_grpc(a) for a in lo.actions]))
536
537
538def loxi_meter_to_ofp_instruction(lo):
539 return pb2.ofp_instruction(
540 type=pb2.OFPIT_METER,
541 meter=pb2.ofp_instruction_meter(meter_id=lo.meter_id))
542
543
544def loxi_group_action_to_ofp_action(lo):
545 return pb2.ofp_action(
546 type=pb2.OFPAT_GROUP,
547 group=pb2.ofp_action_group(group_id=lo.group_id))
548
549
550def loxi_set_field_action_to_ofp_action(lo):
551 return pb2.ofp_action(
552 type=pb2.OFPAT_SET_FIELD,
553 set_field=pb2.ofp_action_set_field(field=to_grpc(lo.field)))
554
555
556def loxi_pop_vlan_action_to_ofp_action(lo):
557 return pb2.ofp_action(type=pb2.OFPAT_POP_VLAN)
558
559
560def loxi_push_vlan_action_to_ofp_action(lo):
561 return pb2.ofp_action(
562 type=pb2.OFPAT_PUSH_VLAN,
563 push=pb2.ofp_action_push(ethertype=lo.ethertype))
564
565
566to_grpc_converters = {
567
568 of13.message.flow_add: loxi_flow_mod_to_ofp_flow_mod,
569 of13.message.flow_delete: loxi_flow_mod_to_ofp_flow_mod,
570 of13.message.flow_delete_strict: loxi_flow_mod_to_ofp_flow_mod,
571 of13.message.flow_modify: loxi_flow_mod_to_ofp_flow_mod,
572 of13.message.flow_modify_strict: loxi_flow_mod_to_ofp_flow_mod,
573 of13.message.meter_mod: loxi_meter_mod_to_ofp_meter_mod,
574 of13.message.meter_stats_request: loxi_meter_stats_to_ofp_meter_stats,
575
576 of13.message.group_add: loxi_group_mod_to_ofp_group_mod,
577 of13.message.group_delete: loxi_group_mod_to_ofp_group_mod,
578 of13.message.group_modify: loxi_group_mod_to_ofp_group_mod,
579 of13.message.packet_out: loxi_packet_out_to_ofp_packet_out,
580
581 of13.meter_band.drop: loxi_meter_band_drop_to_ofp_meter_band_drop,
582 of13.meter_band.dscp_remark: loxi_meter_band_dscp_remark_to_ofp_meter_band_dscp_remark,
583 of13.meter_band.experimenter: loxi_meter_band_experimenter_to_ofp_meter_band_experimenter,
584
585 of13.common.match_v3: loxi_match_v3_to_ofp_match,
586 of13.common.bucket: loxi_bucket_to_ofp_bucket,
587
588 of13.oxm.eth_type: loxi_oxm_eth_type_to_ofp_oxm,
589 of13.oxm.in_port: loxi_oxm_in_port_to_ofp_oxm,
590 of13.oxm.ip_proto: loxi_oxm_ip_proto_to_ofp_oxm,
591 of13.oxm.vlan_vid: loxi_oxm_vlan_vid_to_ofp_oxm,
592 of13.oxm.vlan_pcp: loxi_oxm_vlan_pcp_to_ofp_oxm,
593 of13.oxm.ipv4_dst: loxi_oxm_ipv4_dst_to_ofp_oxm,
594 of13.oxm.udp_src: loxi_oxm_udp_src_to_ofp_oxm,
595 of13.oxm.udp_dst: loxi_oxm_udp_dst_to_ofp_oxm,
596 of13.oxm.metadata: loxi_oxm_metadata_to_ofp_oxm,
Andrea Campanella4461a582020-02-20 15:05:19 +0100597 of13.oxm.vlan_vid_masked: loxi_oxm_vlan_vid_masked_to_ofp_oxm,
Zack Williams9731cdc2019-11-22 15:42:30 -0700598
599 of13.instruction.apply_actions: loxi_apply_actions_to_ofp_instruction,
600 of13.instruction.clear_actions: loxi_clear_actions_to_ofp_instruction,
601 of13.instruction.write_actions: loxi_write_actions_to_ofp_instruction,
602 of13.instruction.goto_table: loxi_goto_table_to_ofp_instruction,
603 of13.instruction.write_metadata: loxi_write_metadata_to_ofp_instruction,
604 of13.instruction.meter: loxi_meter_to_ofp_instruction,
605
606 of13.action.output: loxi_output_action_to_ofp_action,
607 of13.action.group: loxi_group_action_to_ofp_action,
608 of13.action.set_field: loxi_set_field_action_to_ofp_action,
609 of13.action.pop_vlan: loxi_pop_vlan_action_to_ofp_action,
610 of13.action.push_vlan: loxi_push_vlan_action_to_ofp_action,
611}