blob: e45b57d91ba14af32a52aee2a595b20452b9d03d [file] [log] [blame]
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08001#
Zsolt Haraszti3eb27a52017-01-03 21:56:48 -08002# Copyright 2017 the original author or authors.
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08003#
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"""
Steve Crooks3c2c7582017-01-10 15:02:26 -060018Broadcom OLT/ONU adapter.
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080019"""
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080020
Steve Crooks3c2c7582017-01-10 15:02:26 -060021from uuid import uuid4
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080022import structlog
Peter Shafikd7f33772017-05-17 13:56:34 -040023from twisted.internet import reactor, task
Steve Crooks3c2c7582017-01-10 15:02:26 -060024from twisted.internet.defer import DeferredQueue, inlineCallbacks
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080025from zope.interface import implementer
26
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080027from voltha.adapters.interface import IAdapterInterface
28from voltha.core.logical_device_agent import mac_str_to_tuple
Steve Crooksf248e182017-02-07 10:50:24 -050029import voltha.core.flow_decomposer as fd
Steve Crooks3c2c7582017-01-10 15:02:26 -060030from voltha.protos import third_party
31from voltha.protos.adapter_pb2 import Adapter
32from voltha.protos.adapter_pb2 import AdapterConfig
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080033from voltha.protos.common_pb2 import LogLevel, OperStatus, ConnectStatus, \
34 AdminState
ggowdru236bd952017-06-20 20:32:55 -070035from voltha.protos.device_pb2 import DeviceType, DeviceTypes, Port, Image
Steve Crooks3c2c7582017-01-10 15:02:26 -060036from voltha.protos.health_pb2 import HealthStatus
37from voltha.protos.logical_device_pb2 import LogicalPort
rshettyf4bf19e2017-09-19 01:28:27 +053038from voltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPF_FIBER, OFPPF_1GB_FD, OFPPS_LINK_DOWN
Steve Crooksf248e182017-02-07 10:50:24 -050039from voltha.protos.openflow_13_pb2 import OFPXMC_OPENFLOW_BASIC, ofp_port
rshetty1cc73982017-09-02 03:31:12 +053040from voltha.protos.bbf_fiber_base_pb2 import VEnetConfig
rshettyf4bf19e2017-09-19 01:28:27 +053041from voltha.protos.bbf_fiber_traffic_descriptor_profile_body_pb2 import \
42 TrafficDescriptorProfileData
43from voltha.protos.bbf_fiber_tcont_body_pb2 import TcontsConfigData
44from voltha.protos.bbf_fiber_gemport_body_pb2 import GemportsConfigData
rshetty1cc73982017-09-02 03:31:12 +053045
Steve Crooks3c2c7582017-01-10 15:02:26 -060046from common.frameio.frameio import hexify
47from voltha.extensions.omci.omci import *
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080048
Steve Crooks3c2c7582017-01-10 15:02:26 -060049_ = third_party
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080050log = structlog.get_logger()
51
52
rshettyf4bf19e2017-09-19 01:28:27 +053053BRDCM_DEFAULT_VLAN = 4091
54
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080055@implementer(IAdapterInterface)
56class BroadcomOnuAdapter(object):
57
58 name = 'broadcom_onu'
59
60 supported_device_types = [
61 DeviceType(
Steve Crooks3c2c7582017-01-10 15:02:26 -060062 id=name,
rshettyc26a3c32017-07-27 11:06:38 +053063 vendor_id='BRCM',
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080064 adapter=name,
65 accepts_bulk_flow_update=True
66 )
67 ]
68
69 def __init__(self, adapter_agent, config):
70 self.adapter_agent = adapter_agent
71 self.config = config
72 self.descriptor = Adapter(
73 id=self.name,
74 vendor='Voltha project',
Steve Crooks3c2c7582017-01-10 15:02:26 -060075 version='0.4',
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080076 config=AdapterConfig(log_level=LogLevel.INFO)
77 )
Steve Crooks3c2c7582017-01-10 15:02:26 -060078 self.devices_handlers = dict() # device_id -> BroadcomOnuHandler()
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080079
Peter Shafik9107f2e2017-05-02 15:54:39 -040080 # register for adapter messages
81 self.adapter_agent.register_for_inter_adapter_messages()
82
Zsolt Haraszticc153aa2016-12-14 02:28:59 -080083 def start(self):
84 log.debug('starting')
85 log.info('started')
86
87 def stop(self):
88 log.debug('stopping')
89 log.info('stopped')
90
91 def adapter_descriptor(self):
92 return self.descriptor
93
94 def device_types(self):
95 return DeviceTypes(items=self.supported_device_types)
96
97 def health(self):
98 return HealthStatus(state=HealthStatus.HealthState.HEALTHY)
99
100 def change_master_state(self, master):
101 raise NotImplementedError()
102
103 def adopt_device(self, device):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600104 log.info('adopt_device', device_id=device.id)
rshettyf4bf19e2017-09-19 01:28:27 +0530105 self.devices_handlers[device.id] = BroadcomOnuHandler(self, device.id)
106 reactor.callLater(0, self.devices_handlers[device.id].activate, device)
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800107 return device
108
khenaidoo032d3302017-06-09 14:50:04 -0400109 def reconcile_device(self, device):
110 raise NotImplementedError()
111
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800112 def abandon_device(self, device):
113 raise NotImplementedError()
114
Khen Nursimulud068d812017-03-06 11:44:18 -0500115 def disable_device(self, device):
116 raise NotImplementedError()
117
118 def reenable_device(self, device):
119 raise NotImplementedError()
120
121 def reboot_device(self, device):
122 raise NotImplementedError()
123
Lydia Fang01f2e852017-06-28 17:24:58 -0700124 def download_image(self, device, request):
125 raise NotImplementedError()
126
127 def get_image_download_status(self, device, request):
128 raise NotImplementedError()
129
130 def cancel_image_download(self, device, request):
131 raise NotImplementedError()
132
133 def activate_image_update(self, device, request):
134 raise NotImplementedError()
135
136 def revert_image_update(self, device, request):
137 raise NotImplementedError()
138
sathishg5ae86222017-06-28 15:16:29 +0530139 def self_test_device(self, device):
140 """
141 This is called to Self a device based on a NBI call.
142 :param device: A Voltha.Device object.
143 :return: Will return result of self test
144 """
145 log.info('self-test-device', device=device.id)
146 raise NotImplementedError()
147
Khen Nursimulud068d812017-03-06 11:44:18 -0500148 def delete_device(self, device):
149 raise NotImplementedError()
150
151 def get_device_details(self, device):
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800152 raise NotImplementedError()
153
Sergio Slobodrianec864c62017-03-09 11:41:43 -0500154 def update_pm_config(self, device, pm_configs):
155 raise NotImplementedError()
156
Steve Crooks3c2c7582017-01-10 15:02:26 -0600157 def update_flows_bulk(self, device, flows, groups):
rshettyf4bf19e2017-09-19 01:28:27 +0530158 '''
Steve Crooks3c2c7582017-01-10 15:02:26 -0600159 log.info('bulk-flow-update', device_id=device.id,
160 flows=flows, groups=groups)
rshettyf4bf19e2017-09-19 01:28:27 +0530161 '''
Steve Crooks3c2c7582017-01-10 15:02:26 -0600162 assert len(groups.items) == 0
rshettyf4bf19e2017-09-19 01:28:27 +0530163 handler = self.devices_handlers[device.id]
Steve Crooksf248e182017-02-07 10:50:24 -0500164 return handler.update_flow_table(device, flows.items)
Steve Crooks3c2c7582017-01-10 15:02:26 -0600165
166 def update_flows_incrementally(self, device, flow_changes, group_changes):
167 raise NotImplementedError()
168
169 def send_proxied_message(self, proxy_address, msg):
170 log.info('send-proxied-message', proxy_address=proxy_address, msg=msg)
171
172 def receive_proxied_message(self, proxy_address, msg):
173 log.info('receive-proxied-message', proxy_address=proxy_address,
174 device_id=proxy_address.device_id, msg=hexify(msg))
rshettyf4bf19e2017-09-19 01:28:27 +0530175 # Device_id from the proxy_address is the olt device id. We need to
176 # get the onu device id using the port number in the proxy_address
177 device = self.adapter_agent. \
178 get_child_device_with_proxy_address(proxy_address)
179 if device:
180 handler = self.devices_handlers[device.id]
181 handler.receive_message(msg)
Steve Crooks3c2c7582017-01-10 15:02:26 -0600182
183 def receive_packet_out(self, logical_device_id, egress_port_no, msg):
184 log.info('packet-out', logical_device_id=logical_device_id,
185 egress_port_no=egress_port_no, msg_len=len(msg))
186
Peter Shafik9107f2e2017-05-02 15:54:39 -0400187 def receive_inter_adapter_message(self, msg):
188 log.info('receive_inter_adapter_message', msg=msg)
Peter Shafikd7f33772017-05-17 13:56:34 -0400189 proxy_address = msg['proxy_address']
190 assert proxy_address is not None
rshettyf4bf19e2017-09-19 01:28:27 +0530191 # Device_id from the proxy_address is the olt device id. We need to
192 # get the onu device id using the port number in the proxy_address
193 device = self.adapter_agent. \
194 get_child_device_with_proxy_address(proxy_address)
195 if device:
196 handler = self.devices_handlers[device.id]
197 handler.event_messages.put(msg)
Peter Shafik9107f2e2017-05-02 15:54:39 -0400198
Nikolay Titov89004ec2017-06-19 18:22:42 -0400199 def create_interface(self, device, data):
rshettyc26a3c32017-07-27 11:06:38 +0530200 log.info('create-interface', device_id=device.id)
rshettyf4bf19e2017-09-19 01:28:27 +0530201 if device.id in self.devices_handlers:
202 handler = self.devices_handlers[device.id]
rshettyc26a3c32017-07-27 11:06:38 +0530203 if handler is not None:
204 handler.create_interface(data)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400205
206 def update_interface(self, device, data):
rshettyc26a3c32017-07-27 11:06:38 +0530207 log.info('update-interface', device_id=device.id)
rshettyf4bf19e2017-09-19 01:28:27 +0530208 if device.id in self.devices_handlers:
209 handler = self.devices_handlers[device.id]
rshettyc26a3c32017-07-27 11:06:38 +0530210 if handler is not None:
211 handler.update_interface(data)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400212
213 def remove_interface(self, device, data):
rshettyc26a3c32017-07-27 11:06:38 +0530214 log.info('remove-interface', device_id=device.id)
rshettyf4bf19e2017-09-19 01:28:27 +0530215 if device.id in self.devices_handlers:
216 handler = self.devices_handlers[device.id]
rshettyc26a3c32017-07-27 11:06:38 +0530217 if handler is not None:
218 handler.remove_interface(data)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400219
220 def receive_onu_detect_state(self, device_id, state):
221 raise NotImplementedError()
222
Nikolay Titov176f1db2017-08-10 12:38:43 -0400223 def create_tcont(self, device, tcont_data, traffic_descriptor_data):
rshettyf4bf19e2017-09-19 01:28:27 +0530224 log.info('create-tcont', device_id=device.id)
225 if device.id in self.devices_handlers:
226 handler = self.devices_handlers[device.id]
227 if handler is not None:
228 handler.create_tcont(tcont_data, traffic_descriptor_data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400229
230 def update_tcont(self, device, tcont_data, traffic_descriptor_data):
231 raise NotImplementedError()
232
233 def remove_tcont(self, device, tcont_data, traffic_descriptor_data):
234 raise NotImplementedError()
235
236 def create_gemport(self, device, data):
rshettyf4bf19e2017-09-19 01:28:27 +0530237 log.info('create-gemport', device_id=device.id)
238 if device.id in self.devices_handlers:
239 handler = self.devices_handlers[device.id]
240 if handler is not None:
241 handler.create_gemport(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400242
243 def update_gemport(self, device, data):
244 raise NotImplementedError()
245
246 def remove_gemport(self, device, data):
247 raise NotImplementedError()
248
249 def create_multicast_gemport(self, device, data):
rshettyf4bf19e2017-09-19 01:28:27 +0530250 log.info('create-multicast-gemport', device_id=device.id)
251 if device.id in self.devices_handlers:
252 handler = self.devices_handlers[device.id]
253 if handler is not None:
254 handler.create_multicast_gemport(data)
Nikolay Titov176f1db2017-08-10 12:38:43 -0400255
256 def update_multicast_gemport(self, device, data):
257 raise NotImplementedError()
258
259 def remove_multicast_gemport(self, device, data):
260 raise NotImplementedError()
261
262 def create_multicast_distribution_set(self, device, data):
263 raise NotImplementedError()
264
265 def update_multicast_distribution_set(self, device, data):
266 raise NotImplementedError()
267
268 def remove_multicast_distribution_set(self, device, data):
269 raise NotImplementedError()
270
271 def suppress_alarm(self, filter):
272 raise NotImplementedError()
273
Stephane Barbarie980a0912017-05-11 11:27:06 -0400274 def unsuppress_alarm(self, filter):
275 raise NotImplementedError()
Steve Crooks3c2c7582017-01-10 15:02:26 -0600276
277class BroadcomOnuHandler(object):
278
279 def __init__(self, adapter, device_id):
280 self.adapter = adapter
281 self.adapter_agent = adapter.adapter_agent
282 self.device_id = device_id
283 self.log = structlog.get_logger(device_id=device_id)
284 self.incoming_messages = DeferredQueue()
Peter Shafikd7f33772017-05-17 13:56:34 -0400285 self.event_messages = DeferredQueue()
Steve Crooks3c2c7582017-01-10 15:02:26 -0600286 self.proxy_address = None
287 self.tx_id = 0
288
Peter Shafikd7f33772017-05-17 13:56:34 -0400289 # Need to query ONU for number of supported uni ports
290 # For now, temporarily set number of ports to 1 - port #2
291 self.uni_ports = (2,)
292
293 # Handle received ONU event messages
294 reactor.callLater(0, self.handle_onu_events)
295
Steve Crooks3c2c7582017-01-10 15:02:26 -0600296 def receive_message(self, msg):
297 self.incoming_messages.put(msg)
298
Peter Shafikd7f33772017-05-17 13:56:34 -0400299 @inlineCallbacks
300 def handle_onu_events(self):
301 event_msg = yield self.event_messages.get()
302
303 if event_msg['event'] == 'activation-completed':
304
305 if event_msg['event_data']['activation_successful'] == True:
306 for uni in self.uni_ports:
307 port_no = self.proxy_address.channel_id + uni
308 reactor.callLater(1,
309 self.message_exchange,
310 self.proxy_address.onu_id,
311 self.proxy_address.onu_session_id,
312 port_no)
313
314 device = self.adapter_agent.get_device(self.device_id)
315 device.oper_status = OperStatus.ACTIVE
316 self.adapter_agent.update_device(device)
317
318 else:
319 device = self.adapter_agent.get_device(self.device_id)
320 device.oper_status = OperStatus.FAILED
321 self.adapter_agent.update_device(device)
322
323 elif event_msg['event'] == 'deactivation-completed':
324 device = self.adapter_agent.get_device(self.device_id)
325 device.oper_status = OperStatus.DISCOVERED
326 self.adapter_agent.update_device(device)
327
328 elif event_msg['event'] == 'ranging-completed':
329
330 if event_msg['event_data']['ranging_successful'] == True:
331 device = self.adapter_agent.get_device(self.device_id)
332 device.oper_status = OperStatus.ACTIVATING
333 self.adapter_agent.update_device(device)
334
335 else:
336 device = self.adapter_agent.get_device(self.device_id)
337 device.oper_status = OperStatus.FAILED
338 self.adapter_agent.update_device(device)
339
340 # Handle next event
341 reactor.callLater(0, self.handle_onu_events)
342
343
Steve Crooks3c2c7582017-01-10 15:02:26 -0600344 def activate(self, device):
345 self.log.info('activating')
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800346
347 # first we verify that we got parent reference and proxy info
348 assert device.parent_id
349 assert device.proxy_address.device_id
Steve Crooks9b160d72017-03-31 10:48:29 -0500350 #assert device.proxy_address.channel_id # c-vid
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800351
Steve Crooks3c2c7582017-01-10 15:02:26 -0600352 # register for proxied messages right away
353 self.proxy_address = device.proxy_address
354 self.adapter_agent.register_for_proxied_messages(device.proxy_address)
355
Peter Shafik9107f2e2017-05-02 15:54:39 -0400356
Steve Crooks3c2c7582017-01-10 15:02:26 -0600357 # populate device info
358 device.root = True
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800359 device.vendor = 'Broadcom'
Steve Crooks9e85ce82017-03-20 12:00:53 -0400360 device.model = 'n/a'
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800361 device.hardware_version = 'to be filled'
362 device.firmware_version = 'to be filled'
ggowdru236bd952017-06-20 20:32:55 -0700363 device.images.image.extend([
364 Image(version="to be filled")
365 ])
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800366 device.connect_status = ConnectStatus.REACHABLE
367 self.adapter_agent.update_device(device)
368
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800369 self.adapter_agent.add_port(device.id, Port(
Steve Crooks9b160d72017-03-31 10:48:29 -0500370 port_no=100,
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800371 label='PON port',
372 type=Port.PON_ONU,
373 admin_state=AdminState.ENABLED,
374 oper_status=OperStatus.ACTIVE,
375 peers=[
376 Port.PeerPort(
377 device_id=device.parent_id,
378 port_no=device.parent_port_no
379 )
380 ]
381 ))
382
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800383 parent_device = self.adapter_agent.get_device(device.parent_id)
384 logical_device_id = parent_device.parent_id
385 assert logical_device_id
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800386 device = self.adapter_agent.get_device(device.id)
Peter Shafikd7f33772017-05-17 13:56:34 -0400387 device.oper_status = OperStatus.DISCOVERED
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800388 self.adapter_agent.update_device(device)
389
Steve Crooks3c2c7582017-01-10 15:02:26 -0600390 @inlineCallbacks
Steve Crooksf248e182017-02-07 10:50:24 -0500391 def update_flow_table(self, device, flows):
392 #
393 # We need to proxy through the OLT to get to the ONU
394 # Configuration from here should be using OMCI
395 #
rshettyf4bf19e2017-09-19 01:28:27 +0530396 #self.log.info('bulk-flow-update', device_id=device.id, flows=flows)
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800397
Steve Crooksf248e182017-02-07 10:50:24 -0500398 def is_downstream(port):
Steve Crooks9b160d72017-03-31 10:48:29 -0500399 return port == 100 # Need a better way
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800400
Steve Crooksf248e182017-02-07 10:50:24 -0500401 def is_upstream(port):
402 return not is_downstream(port)
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800403
Steve Crooksf248e182017-02-07 10:50:24 -0500404 for flow in flows:
Steve Crooks9b160d72017-03-31 10:48:29 -0500405 _type = None
406 _port = None
407 _vlan_vid = None
408 _udp_dst = None
409 _udp_src = None
410 _ipv4_dst = None
411 _ipv4_src = None
412 _metadata = None
413 _output = None
414 _push_tpid = None
415 _field = None
416 _set_vlan_vid = None
rshettyf4bf19e2017-09-19 01:28:27 +0530417 self.log.info('bulk-flow-update', device_id=device.id, flow=flow)
Steve Crooksf248e182017-02-07 10:50:24 -0500418 try:
419 _in_port = fd.get_in_port(flow)
420 assert _in_port is not None
Steve Crooks3c2c7582017-01-10 15:02:26 -0600421
Steve Crooksf248e182017-02-07 10:50:24 -0500422 if is_downstream(_in_port):
423 self.log.info('downstream-flow')
424 elif is_upstream(_in_port):
425 self.log.info('upstream-flow')
426 else:
427 raise Exception('port should be 1 or 2 by our convention')
428
429 _out_port = fd.get_out_port(flow) # may be None
430 self.log.info('out-port', out_port=_out_port)
431
432 for field in fd.get_ofb_fields(flow):
433 if field.type == fd.ETH_TYPE:
434 _type = field.eth_type
435 self.log.info('field-type-eth-type',
436 eth_type=_type)
437
438 elif field.type == fd.IP_PROTO:
439 _proto = field.ip_proto
440 self.log.info('field-type-ip-proto',
441 ip_proto=_proto)
442
443 elif field.type == fd.IN_PORT:
444 _port = field.port
445 self.log.info('field-type-in-port',
446 in_port=_port)
447
448 elif field.type == fd.VLAN_VID:
449 _vlan_vid = field.vlan_vid & 0xfff
450 self.log.info('field-type-vlan-vid',
451 vlan=_vlan_vid)
452
453 elif field.type == fd.VLAN_PCP:
454 _vlan_pcp = field.vlan_pcp
455 self.log.info('field-type-vlan-pcp',
456 pcp=_vlan_pcp)
457
458 elif field.type == fd.UDP_DST:
459 _udp_dst = field.udp_dst
460 self.log.info('field-type-udp-dst',
461 udp_dst=_udp_dst)
462
463 elif field.type == fd.UDP_SRC:
464 _udp_src = field.udp_src
465 self.log.info('field-type-udp-src',
466 udp_src=_udp_src)
467
468 elif field.type == fd.IPV4_DST:
469 _ipv4_dst = field.ipv4_dst
470 self.log.info('field-type-ipv4-dst',
471 ipv4_dst=_ipv4_dst)
472
473 elif field.type == fd.IPV4_SRC:
474 _ipv4_src = field.ipv4_src
475 self.log.info('field-type-ipv4-src',
476 ipv4_dst=_ipv4_src)
477
478 elif field.type == fd.METADATA:
Steve Crooks9b160d72017-03-31 10:48:29 -0500479 _metadata = field.table_metadata
Steve Crooksf248e182017-02-07 10:50:24 -0500480 self.log.info('field-type-metadata',
481 metadata=_metadata)
482
483 else:
484 raise NotImplementedError('field.type={}'.format(
485 field.type))
486
487 for action in fd.get_actions(flow):
488
489 if action.type == fd.OUTPUT:
490 _output = action.output.port
491 self.log.info('action-type-output',
492 output=_output, in_port=_in_port)
493
494 elif action.type == fd.POP_VLAN:
495 self.log.info('action-type-pop-vlan',
496 in_port=_in_port)
497
498 elif action.type == fd.PUSH_VLAN:
499 _push_tpid = action.push.ethertype
500 log.info('action-type-push-vlan',
501 push_tpid=_push_tpid, in_port=_in_port)
502 if action.push.ethertype != 0x8100:
503 self.log.error('unhandled-tpid',
504 ethertype=action.push.ethertype)
505
506 elif action.type == fd.SET_FIELD:
507 _field = action.set_field.field.ofb_field
508 assert (action.set_field.field.oxm_class ==
509 OFPXMC_OPENFLOW_BASIC)
510 self.log.info('action-type-set-field',
511 field=_field, in_port=_in_port)
512 if _field.type == fd.VLAN_VID:
Steve Crooks9b160d72017-03-31 10:48:29 -0500513 _set_vlan_vid = _field.vlan_vid & 0xfff
514 self.log.info('set-field-type-valn-vid', _set_vlan_vid)
Steve Crooksf248e182017-02-07 10:50:24 -0500515 else:
516 self.log.error('unsupported-action-set-field-type',
517 field_type=_field.type)
518 else:
519 log.error('unsupported-action-type',
520 action_type=action.type, in_port=_in_port)
521
522 #
523 # All flows created from ONU adapter should be OMCI based
524 #
rshettyf4bf19e2017-09-19 01:28:27 +0530525 if _vlan_vid == 0 and _set_vlan_vid != None and _set_vlan_vid != 0:
Steve Crooks9b160d72017-03-31 10:48:29 -0500526 # allow priority tagged packets
527 # Set AR - ExtendedVlanTaggingOperationConfigData
528 # 514 - RxVlanTaggingOperationTable - add VLAN <cvid> to priority tagged pkts - c-vid
rshettyf4bf19e2017-09-19 01:28:27 +0530529
530 self.send_delete_vlan_tagging_filter_data(0x2102)
531 yield self.wait_for_response()
532
533 #self.send_set_vlan_tagging_filter_data(0x2102, _set_vlan_vid)
534 self.send_create_vlan_tagging_filter_data(0x2102, _set_vlan_vid)
535 yield self.wait_for_response()
536
537 self.send_set_extended_vlan_tagging_operation_vlan_configuration_data_untagged(0x202, 0x1000, _set_vlan_vid)
538 yield self.wait_for_response()
539
Steve Crooks9b160d72017-03-31 10:48:29 -0500540 self.send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(0x202, 8, 0, 0,
rshettyf4bf19e2017-09-19 01:28:27 +0530541 1, 8, _set_vlan_vid)
Steve Crooks9b160d72017-03-31 10:48:29 -0500542 yield self.wait_for_response()
543
544 # Set AR - ExtendedVlanTaggingOperationConfigData
545 # 514 - RxVlanTaggingOperationTable - add VLAN <cvid> to priority tagged pkts - c-vid
rshettyf4bf19e2017-09-19 01:28:27 +0530546 '''
Steve Crooks9b160d72017-03-31 10:48:29 -0500547 self.send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(0x205, 8, 0, 0,
rshettyf4bf19e2017-09-19 01:28:27 +0530548 1, 8, _set_vlan_vid)
Steve Crooks9b160d72017-03-31 10:48:29 -0500549 yield self.wait_for_response()
rshettyf4bf19e2017-09-19 01:28:27 +0530550 '''
Steve Crooksf248e182017-02-07 10:50:24 -0500551
552 except Exception as e:
553 log.exception('failed-to-install-flow', e=e, flow=flow)
554
Steve Crooks3c2c7582017-01-10 15:02:26 -0600555 def get_tx_id(self):
556 self.tx_id += 1
557 return self.tx_id
558
559 def send_omci_message(self, frame):
560 _frame = hexify(str(frame))
561 self.log.info('send-omci-message-%s' % _frame)
562 device = self.adapter_agent.get_device(self.device_id)
563 try:
564 self.adapter_agent.send_proxied_message(device.proxy_address, _frame)
565 except Exception as e:
566 self.log.info('send-omci-message-exception', exc=str(e))
567
568 def send_get_circuit_pack(self, entity_id=0):
569 frame = OmciFrame(
570 transaction_id=self.get_tx_id(),
571 message_type=OmciGet.message_id,
572 omci_message=OmciGet(
573 entity_class=CircuitPack.class_id,
574 entity_id=entity_id,
575 attributes_mask=CircuitPack.mask_for('vendor_id')
576 )
577 )
578 self.send_omci_message(frame)
579
580 def send_mib_reset(self, entity_id=0):
581 frame = OmciFrame(
582 transaction_id=self.get_tx_id(),
583 message_type=OmciMibReset.message_id,
584 omci_message=OmciMibReset(
585 entity_class=OntData.class_id,
586 entity_id=entity_id
587 )
588 )
589 self.send_omci_message(frame)
590
Steve Crooks9e85ce82017-03-20 12:00:53 -0400591 def send_create_gal_ethernet_profile(self,
592 entity_id,
593 max_gem_payload_size):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600594 frame = OmciFrame(
595 transaction_id=self.get_tx_id(),
596 message_type=OmciCreate.message_id,
597 omci_message=OmciCreate(
598 entity_class=GalEthernetProfile.class_id,
599 entity_id=entity_id,
600 data=dict(
601 max_gem_payload_size=max_gem_payload_size
602 )
603 )
604 )
605 self.send_omci_message(frame)
606
Steve Crooks9e85ce82017-03-20 12:00:53 -0400607 def send_set_tcont(self,
608 entity_id,
609 alloc_id):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600610 data = dict(
611 alloc_id=alloc_id
612 )
613 frame = OmciFrame(
614 transaction_id=self.get_tx_id(),
615 message_type=OmciSet.message_id,
616 omci_message=OmciSet(
617 entity_class=Tcont.class_id,
Steve Crooks9e85ce82017-03-20 12:00:53 -0400618 entity_id=entity_id,
Steve Crooks3c2c7582017-01-10 15:02:26 -0600619 attributes_mask=Tcont.mask_for(*data.keys()),
620 data=data
621 )
622 )
623 self.send_omci_message(frame)
624
Steve Crooks9e85ce82017-03-20 12:00:53 -0400625 def send_create_8021p_mapper_service_profile(self,
626 entity_id):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600627 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400628 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600629 message_type=OmciCreate.message_id,
630 omci_message=OmciCreate(
631 entity_class=Ieee8021pMapperServiceProfile.class_id,
632 entity_id=entity_id,
633 data=dict(
634 tp_pointer=OmciNullPointer,
635 interwork_tp_pointer_for_p_bit_priority_0=OmciNullPointer,
Steve Crooks9b160d72017-03-31 10:48:29 -0500636 interwork_tp_pointer_for_p_bit_priority_1=OmciNullPointer,
637 interwork_tp_pointer_for_p_bit_priority_2=OmciNullPointer,
638 interwork_tp_pointer_for_p_bit_priority_3=OmciNullPointer,
639 interwork_tp_pointer_for_p_bit_priority_4=OmciNullPointer,
640 interwork_tp_pointer_for_p_bit_priority_5=OmciNullPointer,
641 interwork_tp_pointer_for_p_bit_priority_6=OmciNullPointer,
642 interwork_tp_pointer_for_p_bit_priority_7=OmciNullPointer
Steve Crooks3c2c7582017-01-10 15:02:26 -0600643 )
644 )
645 )
646 self.send_omci_message(frame)
647
Steve Crooks9e85ce82017-03-20 12:00:53 -0400648 def send_create_mac_bridge_service_profile(self,
649 entity_id):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600650 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400651 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600652 message_type=OmciCreate.message_id,
653 omci_message=OmciCreate(
654 entity_class=MacBridgeServiceProfile.class_id,
655 entity_id=entity_id,
656 data=dict(
657 spanning_tree_ind=False,
658 learning_ind=True,
659 priority=0x8000,
660 max_age=20 * 256,
661 hello_time=2 * 256,
662 forward_delay=15 * 256,
663 unknown_mac_address_discard=True
664 )
665 )
666 )
667 self.send_omci_message(frame)
668
Steve Crooks9e85ce82017-03-20 12:00:53 -0400669 def send_create_gem_port_network_ctp(self,
670 entity_id,
671 port_id,
672 tcont_id,
673 direction,
674 tm):
675 _directions = {"upstream": 1, "downstream": 2, "bi-directional": 3}
676 if _directions.has_key(direction):
677 _direction = _directions[direction]
678 else:
679 self.log.error('invalid-gem-port-direction', direction=direction)
680 raise ValueError('Invalid GEM port direction: {_dir}'.format(_dir=direction))
681
Steve Crooks3c2c7582017-01-10 15:02:26 -0600682 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400683 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600684 message_type=OmciCreate.message_id,
685 omci_message=OmciCreate(
686 entity_class=GemPortNetworkCtp.class_id,
687 entity_id=entity_id,
688 data=dict(
689 port_id=port_id,
690 tcont_pointer=tcont_id,
Steve Crooks9e85ce82017-03-20 12:00:53 -0400691 direction=_direction,
692 traffic_management_pointer_upstream=tm
Steve Crooks3c2c7582017-01-10 15:02:26 -0600693 )
694 )
695 )
696 self.send_omci_message(frame)
697
Steve Crooks9e85ce82017-03-20 12:00:53 -0400698 def send_create_multicast_gem_interworking_tp(self,
699 entity_id,
700 gem_port_net_ctp_id):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600701 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400702 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600703 message_type=OmciCreate.message_id,
704 omci_message=OmciCreate(
705 entity_class=MulticastGemInterworkingTp.class_id,
706 entity_id=entity_id,
707 data=dict(
708 gem_port_network_ctp_pointer=gem_port_net_ctp_id,
709 interworking_option=0,
Steve Crooks9e85ce82017-03-20 12:00:53 -0400710 service_profile_pointer=0x1
Steve Crooks3c2c7582017-01-10 15:02:26 -0600711 )
712 )
713 )
714 self.send_omci_message(frame)
715
Steve Crooks9e85ce82017-03-20 12:00:53 -0400716 def send_create_gem_inteworking_tp(self,
717 entity_id,
718 gem_port_net_ctp_id,
719 service_profile_id):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600720 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400721 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600722 message_type=OmciCreate.message_id,
723 omci_message=OmciCreate(
724 entity_class=GemInterworkingTp.class_id,
725 entity_id=entity_id,
726 data=dict(
727 gem_port_network_ctp_pointer=gem_port_net_ctp_id,
728 interworking_option=5,
729 service_profile_pointer=service_profile_id,
730 interworking_tp_pointer=0x0,
731 gal_profile_pointer=0x1
732 )
733 )
734 )
735 self.send_omci_message(frame)
736
Steve Crooks9e85ce82017-03-20 12:00:53 -0400737 def send_set_8021p_mapper_service_profile(self,
738 entity_id,
739 interwork_tp_id):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600740 data = dict(
Steve Crooks9b160d72017-03-31 10:48:29 -0500741 interwork_tp_pointer_for_p_bit_priority_0=interwork_tp_id,
742 interwork_tp_pointer_for_p_bit_priority_1=interwork_tp_id,
743 interwork_tp_pointer_for_p_bit_priority_2=interwork_tp_id,
744 interwork_tp_pointer_for_p_bit_priority_3=interwork_tp_id,
745 interwork_tp_pointer_for_p_bit_priority_4=interwork_tp_id,
746 interwork_tp_pointer_for_p_bit_priority_5=interwork_tp_id,
747 interwork_tp_pointer_for_p_bit_priority_6=interwork_tp_id,
748 interwork_tp_pointer_for_p_bit_priority_7=interwork_tp_id
Steve Crooks3c2c7582017-01-10 15:02:26 -0600749 )
750 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400751 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600752 message_type=OmciSet.message_id,
753 omci_message=OmciSet(
754 entity_class=Ieee8021pMapperServiceProfile.class_id,
755 entity_id=entity_id,
756 attributes_mask=Ieee8021pMapperServiceProfile.mask_for(
757 *data.keys()),
758 data=data
759 )
760 )
761 self.send_omci_message(frame)
762
763 def send_create_mac_bridge_port_configuration_data(self,
764 entity_id,
765 bridge_id,
766 port_id,
767 tp_type,
768 tp_id):
769 frame = OmciFrame(
770 transaction_id=self.get_tx_id(),
771 message_type=OmciCreate.message_id,
772 omci_message=OmciCreate(
773 entity_class=MacBridgePortConfigurationData.class_id,
774 entity_id=entity_id,
775 data=dict(
776 bridge_id_pointer = bridge_id,
777 port_num=port_id,
778 tp_type=tp_type,
Steve Crooks9e85ce82017-03-20 12:00:53 -0400779 tp_pointer=tp_id
Steve Crooks3c2c7582017-01-10 15:02:26 -0600780 )
781 )
782 )
783 self.send_omci_message(frame)
784
Steve Crooks9e85ce82017-03-20 12:00:53 -0400785 def send_create_vlan_tagging_filter_data(self,
786 entity_id,
787 vlan_id):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600788 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400789 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600790 message_type=OmciCreate.message_id,
791 omci_message=OmciCreate(
792 entity_class=VlanTaggingFilterData.class_id,
793 entity_id=entity_id,
794 data=dict(
795 vlan_filter_0=vlan_id,
796 forward_operation=0x10,
797 number_of_entries=1
798 )
799 )
800 )
801 self.send_omci_message(frame)
802
rshettyf4bf19e2017-09-19 01:28:27 +0530803 def send_set_vlan_tagging_filter_data(self,
804 entity_id,
805 vlan_id):
806 data = dict(
807 vlan_filter_0=vlan_id,
808 forward_operation=0x10,
809 number_of_entries=1
810 )
811
812 frame = OmciFrame(
813 transaction_id=self.get_tx_id(),
814 message_type=OmciSet.message_id,
815 omci_message=OmciSet(
816 entity_class=VlanTaggingFilterData.class_id,
817 entity_id=entity_id,
818 attributes_mask=VlanTaggingFilterData.mask_for(
819 *data.keys()),
820 data=data
821 )
822 )
823 self.send_omci_message(frame)
824
825 def send_delete_vlan_tagging_filter_data(self,
826 entity_id):
827 frame = OmciFrame(
828 transaction_id=self.get_tx_id(),
829 message_type=OmciDelete.message_id,
830 omci_message=OmciDelete(
831 entity_class=VlanTaggingFilterData.class_id,
832 entity_id=entity_id
833 )
834 )
835 self.send_omci_message(frame)
836
Steve Crooks46d64302017-03-10 15:11:06 -0500837 def send_create_extended_vlan_tagging_operation_configuration_data(self,
838 entity_id,
839 assoc_type,
840 assoc_me):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600841 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400842 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600843 message_type=OmciCreate.message_id,
844 omci_message=OmciCreate(
845 entity_class=
846 ExtendedVlanTaggingOperationConfigurationData.class_id,
847 entity_id=entity_id,
848 data=dict(
Steve Crooks46d64302017-03-10 15:11:06 -0500849 association_type=assoc_type,
850 associated_me_pointer=assoc_me
Steve Crooks3c2c7582017-01-10 15:02:26 -0600851 )
852 )
853 )
854 self.send_omci_message(frame)
855
Steve Crooks9e85ce82017-03-20 12:00:53 -0400856 def send_set_extended_vlan_tagging_operation_tpid_configuration_data(self,
857 entity_id,
858 input_tpid,
859 output_tpid):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600860 data = dict(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400861 input_tpid=input_tpid,
862 output_tpid=output_tpid,
Steve Crooks3c2c7582017-01-10 15:02:26 -0600863 downstream_mode=0, # inverse of upstream
864 )
865 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400866 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600867 message_type=OmciSet.message_id,
868 omci_message=OmciSet(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400869 entity_class=
Steve Crooks3c2c7582017-01-10 15:02:26 -0600870 ExtendedVlanTaggingOperationConfigurationData.class_id,
871 entity_id=entity_id,
Steve Crooks9e85ce82017-03-20 12:00:53 -0400872 attributes_mask=
Steve Crooks3c2c7582017-01-10 15:02:26 -0600873 ExtendedVlanTaggingOperationConfigurationData.mask_for(
874 *data.keys()),
875 data=data
876 )
877 )
878 self.send_omci_message(frame)
879
Steve Crooksa9d0a7c2017-03-28 22:40:01 -0400880 def send_set_extended_vlan_tagging_operation_vlan_configuration_data_untagged(self,
881 entity_id,
882 filter_inner_vid,
883 treatment_inner_vid):
Steve Crooks3c2c7582017-01-10 15:02:26 -0600884 data = dict(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400885 received_frame_vlan_tagging_operation_table=
Steve Crooks3c2c7582017-01-10 15:02:26 -0600886 VlanTaggingOperation(
887 filter_outer_priority=15,
Steve Crooks46d64302017-03-10 15:11:06 -0500888 filter_outer_vid=4096,
889 filter_outer_tpid_de=0,
890
891 filter_inner_priority=15,
892 filter_inner_vid=filter_inner_vid,
893 filter_inner_tpid_de=0,
Steve Crooks3c2c7582017-01-10 15:02:26 -0600894 filter_ether_type=0,
Steve Crooks46d64302017-03-10 15:11:06 -0500895
896 treatment_tags_to_remove=0,
Steve Crooks3c2c7582017-01-10 15:02:26 -0600897 treatment_outer_priority=15,
Steve Crooks46d64302017-03-10 15:11:06 -0500898 treatment_outer_vid=0,
899 treatment_outer_tpid_de=0,
900
901 treatment_inner_priority=0,
902 treatment_inner_vid=treatment_inner_vid,
Steve Crooks3c2c7582017-01-10 15:02:26 -0600903 treatment_inner_tpid_de=4
904 )
905 )
906 frame = OmciFrame(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400907 transaction_id=self.get_tx_id(),
Steve Crooks3c2c7582017-01-10 15:02:26 -0600908 message_type=OmciSet.message_id,
909 omci_message=OmciSet(
Steve Crooks9e85ce82017-03-20 12:00:53 -0400910 entity_class=
Steve Crooks3c2c7582017-01-10 15:02:26 -0600911 ExtendedVlanTaggingOperationConfigurationData.class_id,
Steve Crooks9e85ce82017-03-20 12:00:53 -0400912 entity_id=entity_id,
913 attributes_mask=
Steve Crooks3c2c7582017-01-10 15:02:26 -0600914 ExtendedVlanTaggingOperationConfigurationData.mask_for(
915 *data.keys()),
916 data=data
917 )
918 )
919 self.send_omci_message(frame)
Zsolt Haraszticc153aa2016-12-14 02:28:59 -0800920
Steve Crooksa9d0a7c2017-03-28 22:40:01 -0400921 def send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(self,
922 entity_id,
923 filter_inner_priority,
924 filter_inner_vid,
925 filter_inner_tpid_de,
926 treatment_tags_to_remove,
927 treatment_inner_priority,
928 treatment_inner_vid):
929 data = dict(
930 received_frame_vlan_tagging_operation_table=
931 VlanTaggingOperation(
932 filter_outer_priority=15,
933 filter_outer_vid=4096,
934 filter_outer_tpid_de=0,
935
936 filter_inner_priority=filter_inner_priority,
937 filter_inner_vid=filter_inner_vid,
938 filter_inner_tpid_de=filter_inner_tpid_de,
939 filter_ether_type=0,
940
941 treatment_tags_to_remove=treatment_tags_to_remove,
942 treatment_outer_priority=15,
943 treatment_outer_vid=0,
944 treatment_outer_tpid_de=0,
945
946 treatment_inner_priority=treatment_inner_priority,
947 treatment_inner_vid=treatment_inner_vid,
948 treatment_inner_tpid_de=4
949 )
950 )
951 frame = OmciFrame(
952 transaction_id=self.get_tx_id(),
953 message_type=OmciSet.message_id,
954 omci_message=OmciSet(
955 entity_class=
956 ExtendedVlanTaggingOperationConfigurationData.class_id,
957 entity_id=entity_id,
958 attributes_mask=
959 ExtendedVlanTaggingOperationConfigurationData.mask_for(
960 *data.keys()),
961 data=data
962 )
963 )
964 self.send_omci_message(frame)
965
Steve Crooks9e85ce82017-03-20 12:00:53 -0400966 def send_create_multicast_operations_profile(self,
967 entity_id,
968 igmp_ver):
969 frame = OmciFrame(
970 transaction_id=self.get_tx_id(),
971 message_type=OmciCreate.message_id,
972 omci_message=OmciCreate(
973 entity_class=
974 MulticastOperationsProfile.class_id,
975 entity_id=entity_id,
976 data=dict(
977 igmp_version=igmp_ver,
978 igmp_function=0,
979 immediate_leave=0
980 )
981 )
982 )
983 self.send_omci_message(frame)
984
985 def send_set_multicast_operations_profile_acl_row0(self,
986 entity_id,
987 acl_table,
988 row_key,
989 gem_port,
990 vlan,
991 src_ip,
992 dst_ip_start,
993 dst_ip_end):
994 row0 = AccessControlRow0(
995 set_ctrl=1,
996 row_part_id=0,
997 test=0,
998 row_key=row_key,
999 gem_port_id=gem_port,
1000 vlan_id=vlan,
1001 src_ip=src_ip,
1002 dst_ip_start=dst_ip_start,
1003 dst_ip_end=dst_ip_end,
1004 ipm_group_bw=0
1005 )
1006
1007 if acl_table == 'dynamic':
1008 data = dict(
1009 dynamic_access_control_list_table=row0
1010 )
1011 else:
1012 data = dict(
1013 static_access_control_list_table=row0
1014 )
1015
1016 frame = OmciFrame(
1017 transaction_id=self.get_tx_id(),
1018 message_type=OmciSet.message_id,
1019 omci_message=OmciSet(
1020 entity_class=MulticastOperationsProfile.class_id,
1021 entity_id=entity_id,
1022 attributes_mask=MulticastOperationsProfile.mask_for(
1023 *data.keys()),
1024 data=data
1025 )
1026 )
1027 self.send_omci_message(frame)
1028
1029 def send_set_multicast_operations_profile_ds_igmp_mcast_tci(self,
1030 entity_id,
1031 ctrl_type,
1032 tci):
1033 data = dict(
1034 ds_igmp_mcast_tci=
1035 DownstreamIgmpMulticastTci(
1036 ctrl_type=ctrl_type,
1037 tci=tci
1038 )
1039 )
1040 frame = OmciFrame(
1041 transaction_id=self.get_tx_id(),
1042 message_type=OmciSet.message_id,
1043 omci_message=OmciSet(
1044 entity_class=MulticastOperationsProfile.class_id,
1045 entity_id=entity_id,
1046 attributes_mask=MulticastOperationsProfile.mask_for(
1047 *data.keys()),
1048 data=data
1049 )
1050 )
1051 self.send_omci_message(frame)
1052
1053 def send_create_multicast_subscriber_config_info(self,
1054 entity_id,
1055 me_type,
1056 mcast_oper_profile):
1057 frame = OmciFrame(
1058 transaction_id=self.get_tx_id(),
1059 message_type=OmciCreate.message_id,
1060 omci_message=OmciCreate(
1061 entity_class=
1062 MulticastSubscriberConfigInfo.class_id,
1063 entity_id=entity_id,
1064 data=dict(
1065 me_type=me_type,
1066 mcast_operations_profile_pointer=mcast_oper_profile
1067 )
1068 )
1069 )
1070 self.send_omci_message(frame)
1071
1072 def send_set_multicast_subscriber_config_info(self,
1073 entity_id,
1074 max_groups=0,
1075 max_mcast_bw=0,
1076 bw_enforcement=0):
1077 data = dict(
1078 max_simultaneous_groups=max_groups,
1079 max_multicast_bandwidth=max_mcast_bw,
1080 bandwidth_enforcement=bw_enforcement
1081 )
1082 frame = OmciFrame(
1083 transaction_id=self.get_tx_id(),
1084 message_type=OmciSet.message_id,
1085 omci_message=OmciSet(
1086 entity_class=MulticastSubscriberConfigInfo.class_id,
1087 entity_id=entity_id,
1088 attributes_mask=MulticastSubscriberConfigInfo.mask_for(
1089 *data.keys()),
1090 data=data
1091 )
1092 )
1093 self.send_omci_message(frame)
1094
1095 def send_set_multicast_service_package(self,
1096 entity_id,
1097 row_key,
1098 vid_uni,
1099 max_groups,
1100 max_mcast_bw,
1101 mcast_oper_profile):
1102 data = dict(
1103 multicast_service_package_table=
1104 MulticastServicePackage(
1105 set_ctrl=1,
1106 row_key=row_key,
1107
1108 vid_uni=vid_uni,
1109 max_simultaneous_groups=max_groups,
1110 max_multicast_bw=max_mcast_bw,
1111 mcast_operations_profile_pointer=mcast_oper_profile
1112 )
1113 )
1114 frame = OmciFrame(
1115 transaction_id=self.get_tx_id(),
1116 message_type=OmciSet.message_id,
1117 omci_message=OmciSet(
1118 entity_class=MulticastSubscriberConfigInfo.class_id,
1119 entity_id=entity_id,
1120 attributes_mask=MulticastSubscriberConfigInfo.mask_for(
1121 *data.keys()),
1122 data=data
1123 )
1124 )
1125 self.send_omci_message(frame)
1126
1127 def send_set_multicast_allowed_preview_groups_row0(self,
1128 entity_id,
1129 row_key,
1130 src_ip,
1131 vlan_id_ani,
1132 vlan_id_uni):
1133 data = dict(
1134 allowed_preview_groups_table=
1135 AllowedPreviewGroupsRow0(
1136 set_ctrl=1,
1137 row_part_id=0,
1138 row_key=row_key,
1139
1140 src_ip=src_ip,
1141 vlan_id_ani=vlan_id_ani,
1142 vlan_id_uni=vlan_id_uni
1143 )
1144 )
1145 frame = OmciFrame(
1146 transaction_id=self.get_tx_id(),
1147 message_type=OmciSet.message_id,
1148 omci_message=OmciSet(
1149 entity_class=MulticastSubscriberConfigInfo.class_id,
1150 entity_id=entity_id,
1151 attributes_mask=MulticastSubscriberConfigInfo.mask_for(
1152 *data.keys()),
1153 data=data
1154 )
1155 )
1156 self.send_omci_message(frame)
1157
1158 def send_set_multicast_allowed_preview_groups_row1(self,
1159 entity_id,
1160 row_key,
1161 dst_ip,
1162 duration,
1163 time_left):
1164 data = dict(
1165 allowed_preview_groups_table=
1166 AllowedPreviewGroupsRow1(
1167 set_ctrl=1,
1168 row_part_id=1,
1169 row_key=row_key,
1170
1171 dst_ip=dst_ip,
1172 duration=duration,
1173 time_left=time_left
1174 )
1175 )
1176 frame = OmciFrame(
1177 transaction_id=self.get_tx_id(),
1178 message_type=OmciSet.message_id,
1179 omci_message=OmciSet(
1180 entity_class=MulticastSubscriberConfigInfo.class_id,
1181 entity_id=entity_id,
1182 attributes_mask=MulticastSubscriberConfigInfo.mask_for(
1183 *data.keys()),
1184 data=data
1185 )
1186 )
1187 self.send_omci_message(frame)
1188
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08001189 @inlineCallbacks
Steve Crooks3c2c7582017-01-10 15:02:26 -06001190 def wait_for_response(self):
1191 log.info('wait-for-response')
1192 try:
1193 response = yield self.incoming_messages.get()
Steve Crooks9e85ce82017-03-20 12:00:53 -04001194 log.info('got-response')
1195 # resp = OmciFrame(response)
1196 # resp.show()
Steve Crooks3c2c7582017-01-10 15:02:26 -06001197 except Exception as e:
1198 self.log.info('wait-for-response-exception', exc=str(e))
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08001199
Steve Crooks3c2c7582017-01-10 15:02:26 -06001200 @inlineCallbacks
Steve Crooks9b160d72017-03-31 10:48:29 -05001201 def message_exchange(self, onu, gem, cvid):
1202 log.info('message_exchange', onu=onu, gem=gem, cvid=cvid)
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08001203 # reset incoming message queue
1204 while self.incoming_messages.pending:
1205 _ = yield self.incoming_messages.get()
1206
rshettyf4bf19e2017-09-19 01:28:27 +05301207 cvid = BRDCM_DEFAULT_VLAN
Steve Crooks9b160d72017-03-31 10:48:29 -05001208
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08001209 # construct message
Steve Crooks3c2c7582017-01-10 15:02:26 -06001210 # MIB Reset - OntData - 0
1211 self.send_mib_reset()
1212 yield self.wait_for_response()
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08001213
Steve Crooks3c2c7582017-01-10 15:02:26 -06001214 # Create AR - GalEthernetProfile - 1
1215 self.send_create_gal_ethernet_profile(1, 48)
1216 yield self.wait_for_response()
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08001217
rshettyf4bf19e2017-09-19 01:28:27 +05301218 # Port 2
1219 # Extended VLAN Tagging Operation config
1220 # Create AR - ExtendedVlanTaggingOperationConfigData - 514 - 2 - 0x102(Uni-Port-Num)
1221 # TODO: add entry here for additional UNI interfaces
1222 self.send_create_extended_vlan_tagging_operation_configuration_data(0x202, 2, 0x102)
Steve Crooks3c2c7582017-01-10 15:02:26 -06001223 yield self.wait_for_response()
Zsolt Haraszticc153aa2016-12-14 02:28:59 -08001224
rshettyf4bf19e2017-09-19 01:28:27 +05301225 # Set AR - ExtendedVlanTaggingOperationConfigData - 514 - 8100 - 8100
1226 self.send_set_extended_vlan_tagging_operation_tpid_configuration_data(0x202, 0x8100, 0x8100)
Steve Crooks3c2c7582017-01-10 15:02:26 -06001227 yield self.wait_for_response()
1228
Steve Crooks9b160d72017-03-31 10:48:29 -05001229 # MAC Bridge Service config
Steve Crooks3c2c7582017-01-10 15:02:26 -06001230 # Create AR - MacBridgeServiceProfile - 513
1231 self.send_create_mac_bridge_service_profile(0x201)
1232 yield self.wait_for_response()
1233
rshettyf4bf19e2017-09-19 01:28:27 +05301234 # Create AR - MacBridgePortConfigData - Entity_id -
1235 # bridge ID -
1236 # port num -
1237 # tp_type -
1238 # IEEE MApper poniter
1239 self.send_create_mac_bridge_port_configuration_data(0x201, 0x201, 2, 1, 0x102)
Steve Crooks9e85ce82017-03-20 12:00:53 -04001240 yield self.wait_for_response()
1241
rshettyf4bf19e2017-09-19 01:28:27 +05301242 # Mapper Service config
1243 # Create AR - 802.1pMapperServiceProfile - 32769
1244 self.send_create_8021p_mapper_service_profile(0x8001)
Steve Crooks3c2c7582017-01-10 15:02:26 -06001245 yield self.wait_for_response()
1246
Steve Crooks9b160d72017-03-31 10:48:29 -05001247 # MAC Bridge Port config
Steve Crooks3c2c7582017-01-10 15:02:26 -06001248 # Create AR - MacBridgePortConfigData - 8450 - 513 - 3 - 3 - 32769
1249 self.send_create_mac_bridge_port_configuration_data(0x2102, 0x201, 3, 3, 0x8001)
1250 yield self.wait_for_response()
1251
Steve Crooks9b160d72017-03-31 10:48:29 -05001252 # VLAN Tagging Filter config
1253 # Create AR - VlanTaggingFilterData - 8450 - c-vid
1254 self.send_create_vlan_tagging_filter_data(0x2102, cvid)
Steve Crooks3c2c7582017-01-10 15:02:26 -06001255 yield self.wait_for_response()
1256
rshettyf4bf19e2017-09-19 01:28:27 +05301257 # Set AR - ExtendedVlanTaggingOperationConfigData
1258 # 514 - RxVlanTaggingOperationTable - add VLAN <cvid> to priority tagged pkts - c-vid
1259 #self.send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(0x202, 8, 0, 0, 1, 8, cvid)
1260 #yield self.wait_for_response()
1261
1262 # Set AR - ExtendedVlanTaggingOperationConfigData
1263 # 514 - RxVlanTaggingOperationTable - add VLAN <cvid> to untagged pkts - c-vid
1264 self.send_set_extended_vlan_tagging_operation_vlan_configuration_data_untagged(0x202, 0x1000, cvid)
1265 yield self.wait_for_response()
1266
1267 # Multicast related MEs
1268 # Set AR - MulticastOperationsProfile - Dynamic Access Control List table
1269 # Create AR - MacBridgePortConfigData - 9000 - 513 - 6 - 6 - 6
1270 self.send_create_mac_bridge_port_configuration_data(0x2328, 0x201, 6, 6, 6)
1271 yield self.wait_for_response()
1272
Steve Crooks9b160d72017-03-31 10:48:29 -05001273 # Multicast Operation Profile config
Steve Crooks9e85ce82017-03-20 12:00:53 -04001274 # Create AR - MulticastOperationsProfile
1275 self.send_create_multicast_operations_profile(0x201, 3)
1276 yield self.wait_for_response()
1277
rshettyf4bf19e2017-09-19 01:28:27 +05301278 # Multicast Subscriber config
1279 # Create AR - MulticastSubscriberConfigInfo
1280 self.send_create_multicast_subscriber_config_info(0x201, 0, 0x201)
1281 yield self.wait_for_response()
1282
1283 # Create AR - GemPortNetworkCtp - 260 - 4000 - 0 Multicast
1284 self.send_create_gem_port_network_ctp(0x104, 0x0FA0, 0, "downstream", 0)
1285 yield self.wait_for_response()
1286
1287 # Multicast GEM Interworking config Multicast
1288 # Create AR - MulticastGemInterworkingTp - 6 - 260
1289 self.send_create_multicast_gem_interworking_tp(0x6, 0x104)
1290 yield self.wait_for_response()
1291
Steve Crooks9e85ce82017-03-20 12:00:53 -04001292 self.send_set_multicast_operations_profile_acl_row0(0x201,
1293 'dynamic',
1294 0,
1295 0x0fa0,
1296 0x0fa0,
1297 '0.0.0.0',
1298 '224.0.0.0',
1299 '239.255.255.255')
1300 yield self.wait_for_response()
1301
Steve Crooks9b160d72017-03-31 10:48:29 -05001302 # Multicast Operation Profile config
Steve Crooks9e85ce82017-03-20 12:00:53 -04001303 # Set AR - MulticastOperationsProfile - Downstream IGMP Multicast TCI
Steve Crooks9b160d72017-03-31 10:48:29 -05001304 self.send_set_multicast_operations_profile_ds_igmp_mcast_tci(0x201, 4, cvid)
Steve Crooks9e85ce82017-03-20 12:00:53 -04001305 yield self.wait_for_response()
1306
rshettyf4bf19e2017-09-19 01:28:27 +05301307 '''
Steve Crooks9b160d72017-03-31 10:48:29 -05001308 # Port 5
1309 # Extended VLAN Tagging Operation config
1310 # Create AR - ExtendedVlanTaggingOperationConfigData - 514 - 2 - 0x102
1311 # TODO: add entry here for additional UNI interfaces
1312 self.send_create_extended_vlan_tagging_operation_configuration_data(0x205, 2, 0x105)
1313 yield self.wait_for_response()
1314
1315 # Set AR - ExtendedVlanTaggingOperationConfigData - 514 - 8100 - 8100
1316 self.send_set_extended_vlan_tagging_operation_tpid_configuration_data(0x205, 0x8100, 0x8100)
1317 yield self.wait_for_response()
1318
1319 # Set AR - ExtendedVlanTaggingOperationConfigData
1320 # 514 - RxVlanTaggingOperationTable - add VLAN <cvid> to priority tagged pkts - c-vid
1321 #self.send_set_extended_vlan_tagging_operation_vlan_configuration_data_single_tag(0x205, 8, 0, 0, 1, 8, cvid)
1322 #yield self.wait_for_response()
1323
1324 # Set AR - ExtendedVlanTaggingOperationConfigData
1325 # 514 - RxVlanTaggingOperationTable - add VLAN <cvid> to untagged pkts - c-vid
1326 self.send_set_extended_vlan_tagging_operation_vlan_configuration_data_untagged(0x205, 0x1000, cvid)
1327 yield self.wait_for_response()
1328
1329 # MAC Bridge Port config
1330 # Create AR - MacBridgePortConfigData - 513 - 513 - 1 - 1 - 0x102
1331 # TODO: add more entries here for other UNI ports
1332 self.send_create_mac_bridge_port_configuration_data(0x205, 0x201, 5, 1, 0x105)
Steve Crooks3c2c7582017-01-10 15:02:26 -06001333 yield self.wait_for_response()
rshettyf4bf19e2017-09-19 01:28:27 +05301334 '''
1335
1336 def add_uni_port(self, device, parent_logical_device_id,
1337 name, parent_port_num=None):
1338 self.log.info('adding-logical-port', device_id=device.id,
1339 logical_device_id=parent_logical_device_id,
1340 name=name)
1341 if parent_port_num is not None:
1342 uni = parent_port_num
1343 port_no = parent_port_num
1344 else:
1345 uni = self.uni_ports[0]
1346 port_no = device.proxy_address.channel_id + uni
1347 # register physical ports
1348 uni_port = Port(
1349 port_no=uni,
1350 label='UNI facing Ethernet port '+str(uni),
1351 type=Port.ETHERNET_UNI,
1352 admin_state=AdminState.ENABLED,
1353 oper_status=OperStatus.ACTIVE
1354 )
1355 self.adapter_agent.add_port(device.id, uni_port)
1356 # add uni port to logical device
1357 cap = OFPPF_1GB_FD | OFPPF_FIBER
1358 self.adapter_agent.add_logical_port(parent_logical_device_id,
1359 LogicalPort(
1360 id='uni-{}'.format(port_no),
1361 ofp_port=ofp_port(
1362 port_no=port_no,
1363 hw_addr=mac_str_to_tuple('00:00:00:%02x:%02x:%02x' %
1364 (device.proxy_address.onu_id & 0xff,
1365 (port_no >> 8) & 0xff,
1366 port_no & 0xff)),
1367 #name='uni-{}'.format(port_no),
1368 name=name,
1369 config=0,
1370 state=OFPPS_LIVE,
1371 curr=cap,
1372 advertised=cap,
1373 peer=cap,
1374 curr_speed=OFPPF_1GB_FD,
1375 max_speed=OFPPF_1GB_FD
1376 ),
1377 device_id=device.id,
1378 device_port_no=uni_port.port_no
1379 ))
rshettyc26a3c32017-07-27 11:06:38 +05301380
1381 def create_interface(self, data):
rshetty1cc73982017-09-02 03:31:12 +05301382 if isinstance(data, VEnetConfig):
1383 parent_port_num = None
1384 onu_device = self.adapter_agent.get_device(self.device_id)
1385 ports = self.adapter_agent.get_ports(onu_device.parent_id, Port.ETHERNET_UNI)
1386 parent_port_num = None
1387 for port in ports:
1388 if port.label == data.interface.name:
1389 parent_port_num = port.port_no
1390 break
1391
rshettyf4bf19e2017-09-19 01:28:27 +05301392 parent_device = self.adapter_agent.get_device(onu_device.parent_id)
1393 logical_device_id = parent_device.parent_id
1394 assert logical_device_id
1395 self.add_uni_port(onu_device, logical_device_id,
1396 data.name, parent_port_num)
1397
1398 if parent_port_num is None:
rshetty1cc73982017-09-02 03:31:12 +05301399 self.log.error("matching-parent-uni-port-num-not-found")
1400 return
1401
1402 onu_ports = self.adapter_agent.get_ports(self.device_id, Port.PON_ONU)
1403 if onu_ports:
1404 # To-Do :
1405 # Assumed only one PON port and UNI port per ONU.
1406 pon_port = onu_ports[0]
1407 else:
1408 self.log.error("No-Pon-port-configured-yet")
1409 return
1410
1411 self.adapter_agent.delete_port_reference_from_parent(self.device_id,
1412 pon_port)
1413
1414 pon_port.peers[0].device_id = onu_device.parent_id
1415 pon_port.peers[0].port_no = parent_port_num
1416 self.adapter_agent.add_port_reference_to_parent(self.device_id,
1417 pon_port)
1418 else:
1419 self.log.info('Not handled Yet')
1420 return
rshettyc26a3c32017-07-27 11:06:38 +05301421
1422 def update_interface(self, data):
1423 self.log.info('Not Implemented yet')
rshetty1cc73982017-09-02 03:31:12 +05301424 return
rshettyc26a3c32017-07-27 11:06:38 +05301425
1426 def remove_interface(self, data):
1427 self.log.info('Not Implemented yet')
rshetty1cc73982017-09-02 03:31:12 +05301428 return
rshettyf4bf19e2017-09-19 01:28:27 +05301429
1430 @inlineCallbacks
1431 def create_gemport(self, data):
1432 log.info('create-gemport')
1433 gem_port= GemportsConfigData()
1434 gem_port.CopyFrom(data)
1435 if gem_port.tcont_ref is None:
1436 self.log.info('Recevied NULL Gem Port Data')
1437 else:
1438 #To-Do Need to see how the valuse 0x8001 is derived
1439 self.send_create_gem_port_network_ctp(gem_port.gemport_id,
1440 gem_port.gemport_id, 0x8001,
1441 "bi-directional", 0x100)
1442 yield self.wait_for_response()
1443
1444 # GEM Interworking config
1445 # Create AR - GemInterworkingTp - Gem_port,TP_pointer -
1446 # Gem port CTP pointer -
1447 # Mapper service profile id
1448 self.send_create_gem_inteworking_tp(gem_port.gemport_id,
1449 gem_port.gemport_id, 0x8001)
1450 yield self.wait_for_response()
1451
1452 # Mapper Service Profile config
1453 # Set AR - 802.1pMapperServiceProfile - Mapper_ profile_id -
1454 # gem_port_tp pointer
1455 self.send_set_8021p_mapper_service_profile(0x8001,
1456 gem_port.gemport_id)
1457 yield self.wait_for_response()
1458
1459
1460 @inlineCallbacks
1461 def create_tcont(self, tcont_data, traffic_descriptor_data):
1462 log.info('create-tcont')
1463 tcont = TcontsConfigData()
1464 tcont.CopyFrom(tcont_data)
1465 if (tcont.interface_reference is not None):
1466 self.log.info('tcont created is', tcont= tcont.alloc_id)
1467 self.send_set_tcont(0x8001, tcont.alloc_id)
1468 yield self.wait_for_response()
1469 else:
1470 self.log.info('Recevied NULL tcont Data', tcont= tcont.alloc_id)
1471
1472 def create_multicast_gemport(self, data):
1473 self.log.info('Send relevant OMCI message')