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