VOL-1201 Workaround for Broadcom downstream flow bug
Broadcom requires a downstream flow to exist in order to do a packet out to an ONU
While setting the EAP flow, the adapter used to create an extra downstream flow always using the same default vlan.
It results in the creation of a multicast group by the BAL API and this sometimes fails and cannot be recovered without restarting the OLT drivers
To go around this the extra flow pushed use a vlan unique per ONU per PON port (4000 - onu_id), this makes the vlan 3743 to 3999 "special" and may render them unusable for regular traffic
We are waiting for an answer from Broadcom
Change-Id: I7b9cbad48ec7a8fb97af749d7e2903ade114b1a7
diff --git a/voltha/adapters/openolt/openolt_flow_mgr.py b/voltha/adapters/openolt/openolt_flow_mgr.py
index edf9028..96afa0f 100644
--- a/voltha/adapters/openolt/openolt_flow_mgr.py
+++ b/voltha/adapters/openolt/openolt_flow_mgr.py
@@ -281,6 +281,7 @@
# To-Do right now only one GEM port is supported, so below method
# will take care of handling all the p bits.
# We need to revisit when mulitple gem port per p bits is needed.
+ # Waiting for Technology profile
def add_hsia_flow(self, intf_id, onu_id, classifier, action,
direction, hsia_id, logical_flow):
@@ -350,14 +351,7 @@
downlink_eapol_id=EAPOL_DOWNLINK_FLOW_INDEX,
vlan_id=DEFAULT_MGMT_VLAN):
- downlink_classifier = {}
- downlink_classifier['eth_type'] = EAP_ETH_TYPE
- downlink_classifier['pkt_tag_type'] = 'single_tag'
- downlink_classifier['vlan_vid'] = vlan_id
- downlink_action = {}
- downlink_action['push_vlan'] = True
- downlink_action['vlan_vid'] = vlan_id
uplink_classifier = {}
uplink_classifier['eth_type'] = EAP_ETH_TYPE
@@ -387,31 +381,43 @@
self.add_flow_to_device(upstream_flow, logical_flow)
- # Add Downstream EAPOL Flow.
- downlink_flow_id = platform.mk_flow_id(intf_id, onu_id,
- downlink_eapol_id)
+ if vlan_id == DEFAULT_MGMT_VLAN:
- downstream_flow = openolt_pb2.Flow(
- onu_id=onu_id, flow_id=downlink_flow_id, flow_type="downstream",
- access_intf_id=intf_id, gemport_id=gemport_id,
- priority=logical_flow.priority,
- classifier=self.mk_classifier(downlink_classifier),
- action=self.mk_action(downlink_action))
+ # Add Downstream EAPOL Flow, Only for first EAP flow
- downstream_logical_flow = ofp_flow_stats(id=logical_flow.id,
- cookie=logical_flow.cookie, table_id=logical_flow.table_id,
- priority=logical_flow.priority, flags=logical_flow.flags)
+ downlink_classifier = {}
+ downlink_classifier['pkt_tag_type'] = 'single_tag'
+ downlink_classifier['vlan_vid'] = 4000 - onu_id
- downstream_logical_flow.match.oxm_fields.extend(fd.mk_oxm_fields([
- fd.in_port(fd.get_out_port(logical_flow)),
- fd.eth_type(EAP_ETH_TYPE), fd.vlan_vid(vlan_id | 0x1000)]))
- downstream_logical_flow.match.type = OFPMT_OXM
- downstream_logical_flow.instructions.extend(
- fd.mk_instructions_from_actions([fd.output(
- platform.mk_uni_port_num(intf_id, onu_id))]))
+ downlink_action = {}
+ downlink_action['push_vlan'] = True
+ downlink_action['vlan_vid'] = vlan_id
- self.add_flow_to_device(downstream_flow, downstream_logical_flow)
+ downlink_flow_id = platform.mk_flow_id(intf_id, onu_id,
+ downlink_eapol_id)
+
+ downstream_flow = openolt_pb2.Flow(
+ onu_id=onu_id, flow_id=downlink_flow_id, flow_type="downstream",
+ access_intf_id=intf_id, gemport_id=gemport_id,
+ priority=logical_flow.priority,
+ classifier=self.mk_classifier(downlink_classifier),
+ action=self.mk_action(downlink_action))
+
+ downstream_logical_flow = ofp_flow_stats(id=logical_flow.id,
+ cookie=logical_flow.cookie, table_id=logical_flow.table_id,
+ priority=logical_flow.priority, flags=logical_flow.flags)
+
+ downstream_logical_flow.match.oxm_fields.extend(fd.mk_oxm_fields([
+ fd.in_port(fd.get_out_port(logical_flow)),
+ fd.vlan_vid((4000 - onu_id) | 0x1000)]))
+ downstream_logical_flow.match.type = OFPMT_OXM
+
+ downstream_logical_flow.instructions.extend(
+ fd.mk_instructions_from_actions([fd.output(
+ platform.mk_uni_port_num(intf_id, onu_id))]))
+
+ self.add_flow_to_device(downstream_flow, downstream_logical_flow)
def repush_all_different_flows(self):
# Check if the device is supposed to have flows, if so add them