blob: 769627b5d40839760efe8a99023422579f384d54 [file] [log] [blame]
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -07001#
2# Copyright 2016 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 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]
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
Zsolt Haraszticd22adc2016-10-25 00:13:06 -070058def make_loxi_match(match):
59 assert match['type'] == pb2.OFPMT_OXM
60 loxi_match_fields = []
61 for oxm_field in match['oxm_fields']:
62 assert oxm_field['oxm_class'] == pb2.OFPXMC_OPENFLOW_BASIC
63 ofb_field = oxm_field['ofb_field']
64 field_type = ofb_field.get('type', 0)
65 if field_type == pb2.OFPXMT_OFB_ETH_TYPE:
66 loxi_match_fields.append(
67 of13.oxm.eth_type(value=ofb_field['eth_type']))
68 else:
69 raise NotImplementedError(
70 'OXM match field for type %s' % field_type)
71 return of13.match_v3(oxm_list=loxi_match_fields)
72
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -070073def ofp_flow_stats_to_loxi_flow_stats(pb):
74 kw = pb2dict(pb)
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -070075
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -070076 def make_loxi_action(a):
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -070077 type = a.get('type', 0)
78 if type == pb2.OFPAT_OUTPUT:
79 output = a['output']
80 return of13.action.output(**output)
81 else:
82 raise NotImplementedError(
83 'Action decoder for action OFPAT_* %d' % type)
84
85 def make_loxi_instruction(inst):
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -070086 type = inst['type']
87 if type == pb2.OFPIT_APPLY_ACTIONS:
88 return of13.instruction.apply_actions(
89 actions=[make_loxi_action(a)
90 for a in inst['actions']['actions']])
91 else:
92 raise NotImplementedError('Instruction type %d' % type)
93
94 kw['match'] = make_loxi_match(kw['match'])
95 kw['instructions'] = [make_loxi_instruction(i) for i in kw['instructions']]
96 return of13.flow_stats_entry(**kw)
97
Zsolt Haraszticd22adc2016-10-25 00:13:06 -070098def ofp_packet_in_to_loxi_packet_in(pb):
99 kw = pb2dict(pb)
100 if 'match' in kw:
101 kw['match'] = make_loxi_match(kw['match'])
102 return of13.message.packet_in(**kw)
103
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700104
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700105to_loxi_converters = {
106 pb2.ofp_port: ofp_port_to_loxi_port_desc,
Zsolt Haraszticd22adc2016-10-25 00:13:06 -0700107 pb2.ofp_flow_stats: ofp_flow_stats_to_loxi_flow_stats,
108 pb2.ofp_packet_in: ofp_packet_in_to_loxi_packet_in,
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700109}
110
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700111
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700112def loxi_flow_mod_to_ofp_flow_mod(lo):
113 return pb2.ofp_flow_mod(
114 cookie=lo.cookie,
115 cookie_mask=lo.cookie_mask,
116 table_id=lo.table_id,
117 command=lo._command,
118 idle_timeout=lo.idle_timeout,
119 hard_timeout=lo.hard_timeout,
120 priority=lo.priority,
121 buffer_id=lo.buffer_id,
122 out_port=lo.out_port,
123 out_group=lo.out_group,
124 flags=lo.flags,
125 match=to_grpc(lo.match),
126 instructions=[to_grpc(i) for i in lo.instructions])
127
128
129def loxi_group_mod_to_ofp_group_mod(lo):
130 return pb2.ofp_group_mod(
131 command=lo.command,
Zsolt Haraszti9125b1a2016-10-24 22:54:33 -0700132 type=lo.group_type,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700133 group_id=lo.group_id,
134 buckets=[to_grpc(b) for b in lo.buckets])
135
136
Zsolt Haraszticd22adc2016-10-25 00:13:06 -0700137def loxi_packet_out_to_ofp_packet_out(lo):
138 return pb2.ofp_packet_out(
139 buffer_id=lo.buffer_id,
140 in_port=lo.in_port,
141 actions=[to_grpc(a) for a in lo.actions],
142 data=lo.data)
143
144
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700145def loxi_match_v3_to_ofp_match(lo):
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700146 return pb2.ofp_match(
147 type=pb2.OFPMT_OXM,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700148 oxm_fields=[to_grpc(f) for f in lo.oxm_list])
149
150
151def loxi_bucket_to_ofp_bucket(lo):
152 return pb2.ofp_bucket(
153 weight=lo.weight,
154 watch_port=lo.watch_port,
155 watch_group=lo.watch_group,
Zsolt Haraszticd22adc2016-10-25 00:13:06 -0700156 actions=[to_grpc(a) for a in lo.actions])
157
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700158
159def loxi_oxm_eth_type_to_ofp_oxm(lo):
160 return pb2.ofp_oxm_field(
161 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
162 ofb_field=pb2.ofp_oxm_ofb_field(
163 type=pb2.OFPXMT_OFB_ETH_TYPE,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700164 eth_type=lo.value))
165
166
167def loxi_oxm_in_port_to_ofp_oxm(lo):
168 return pb2.ofp_oxm_field(
169 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
170 ofb_field=pb2.ofp_oxm_ofb_field(
171 type=pb2.OFPXMT_OFB_IN_PORT,
172 port=lo.value))
173
174
175def loxi_oxm_ip_proto_to_ofp_oxm(lo):
176 return pb2.ofp_oxm_field(
177 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
178 ofb_field=pb2.ofp_oxm_ofb_field(
179 type=pb2.OFPXMT_OFB_IP_PROTO,
180 ip_proto=lo.value))
181
182
183def loxi_oxm_vlan_vid_to_ofp_oxm(lo):
184 return pb2.ofp_oxm_field(
185 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
186 ofb_field=pb2.ofp_oxm_ofb_field(
187 type=pb2.OFPXMT_OFB_VLAN_VID,
188 vlan_vid=lo.value))
189
190
191def loxi_oxm_vlan_pcp_to_ofp_oxm(lo):
192 return pb2.ofp_oxm_field(
193 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
194 ofb_field=pb2.ofp_oxm_ofb_field(
195 type=pb2.OFPXMT_OFB_VLAN_PCP,
196 vlan_pcp=lo.value))
197
198
199def loxi_oxm_ipv4_dst_to_ofp_oxm(lo):
200 return pb2.ofp_oxm_field(
201 oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
202 ofb_field=pb2.ofp_oxm_ofb_field(
203 type=pb2.OFPXMT_OFB_IPV4_DST,
204 ipv4_dst=lo.value))
205
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700206
207def loxi_apply_actions_to_ofp_instruction(lo):
208 return pb2.ofp_instruction(
209 type=pb2.OFPIT_APPLY_ACTIONS,
210 actions=pb2.ofp_instruction_actions(
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700211 actions=[to_grpc(a) for a in lo.actions]))
212
213
214def loxi_goto_table_to_ofp_instruction(lo):
215 return pb2.ofp_instruction(
216 type=pb2.OFPIT_GOTO_TABLE,
217 goto_table=pb2.ofp_instruction_goto_table(table_id=lo.table_id))
218
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700219
220def loxi_output_action_to_ofp_action(lo):
221 return pb2.ofp_action(
222 type=pb2.OFPAT_OUTPUT,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700223 output=pb2.ofp_action_output(port=lo.port, max_len=lo.max_len))
224
225
226def loxi_group_action_to_ofp_action(lo):
227 return pb2.ofp_action(
228 type=pb2.OFPAT_GROUP,
229 group=pb2.ofp_action_group(group_id=lo.group_id))
230
231
232def loxi_set_field_action_to_ofp_action(lo):
233 return pb2.ofp_action(
234 type=pb2.OFPAT_SET_FIELD,
235 set_field=pb2.ofp_action_set_field(field=to_grpc(lo.field)))
236
237
238def loxi_pop_vlan_action_to_ofp_action(lo):
239 return pb2.ofp_action(type=pb2.OFPAT_POP_VLAN)
240
241
242def loxi_push_vlan_action_to_ofp_action(lo):
243 return pb2.ofp_action(
244 type=pb2.OFPAT_PUSH_VLAN,
245 push=pb2.ofp_action_push(ethertype=lo.ethertype))
246
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700247
248to_grpc_converters = {
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700249
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700250 of13.message.flow_add: loxi_flow_mod_to_ofp_flow_mod,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700251 of13.message.flow_delete: loxi_flow_mod_to_ofp_flow_mod,
252 of13.message.flow_delete_strict: loxi_flow_mod_to_ofp_flow_mod,
253 of13.message.flow_modify: loxi_flow_mod_to_ofp_flow_mod,
254 of13.message.flow_modify_strict: loxi_flow_mod_to_ofp_flow_mod,
255
256 of13.message.group_add: loxi_group_mod_to_ofp_group_mod,
257 of13.message.group_delete: loxi_group_mod_to_ofp_group_mod,
258 of13.message.group_modify: loxi_group_mod_to_ofp_group_mod,
Zsolt Haraszticd22adc2016-10-25 00:13:06 -0700259 of13.message.packet_out: loxi_packet_out_to_ofp_packet_out,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700260
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700261 of13.common.match_v3: loxi_match_v3_to_ofp_match,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700262 of13.common.bucket: loxi_bucket_to_ofp_bucket,
263
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700264 of13.oxm.eth_type: loxi_oxm_eth_type_to_ofp_oxm,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700265 of13.oxm.in_port: loxi_oxm_in_port_to_ofp_oxm,
266 of13.oxm.ip_proto: loxi_oxm_ip_proto_to_ofp_oxm,
267 of13.oxm.vlan_vid: loxi_oxm_vlan_vid_to_ofp_oxm,
268 of13.oxm.vlan_pcp: loxi_oxm_vlan_pcp_to_ofp_oxm,
269 of13.oxm.ipv4_dst: loxi_oxm_ipv4_dst_to_ofp_oxm,
270
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700271 of13.instruction.apply_actions: loxi_apply_actions_to_ofp_instruction,
Zsolt Haraszti8a774382016-10-24 18:25:54 -0700272 of13.instruction.goto_table: loxi_goto_table_to_ofp_instruction,
273
274 of13.action.output: loxi_output_action_to_ofp_action,
275 of13.action.group: loxi_group_action_to_ofp_action,
276 of13.action.set_field: loxi_set_field_action_to_ofp_action,
277 of13.action.pop_vlan: loxi_pop_vlan_action_to_ofp_action,
278 of13.action.push_vlan: loxi_push_vlan_action_to_ofp_action,
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -0700279}