This patch solves the following bugs:
* For the EAPOL trap flow, ONOS sends flow-mod including the meter id before the related meter-mod. Because of this, Voltha sends wrong flow count for the meter stats reply
* Getting the tech profile id & inner vlan id from the write metadata instruction
* ofp_flow_removed implementation is added
Change-Id: Ib74c7b80db85506f675c2d7ff25bf644c64e5398
diff --git a/ofagent/agent.py b/ofagent/agent.py
index 6117c8f..5c2da16 100644
--- a/ofagent/agent.py
+++ b/ofagent/agent.py
@@ -160,9 +160,11 @@
def forward_change_event(self, event):
# assert isinstance(event, ChangeEvent)
log.info('got-change-event', change_event=event)
- if event.HasField("port_status"):
- if self.proto_handler is not None:
+ if self.proto_handler is not None:
+ if event.HasField("port_status"):
self.proto_handler.forward_port_status(event.port_status)
+ elif event.HasField("flow_removed"):
+ self.proto_handler.forward_flow_removed(event.flow_removed)
else:
log.error('unknown-change-event', change_event=event)
diff --git a/ofagent/converter.py b/ofagent/converter.py
index 7156d60..1bebc4f 100644
--- a/ofagent/converter.py
+++ b/ofagent/converter.py
@@ -66,6 +66,14 @@
desc=ofp_port_to_loxi_port_desc(pb.desc)
)
+def ofp_flow_removed_to_loxi_flow_removed(pb):
+ return of13.message.flow_removed(
+ cookie=pb.cookie,
+ priority=pb.priority,
+ reason=pb.reason,
+ table_id=pb.table_id,
+ match=make_loxi_match(pb2dict(pb.match))
+ )
def ofp_port_stats_to_loxi_port_stats(pb):
kw = pb2dict(pb)
@@ -265,6 +273,7 @@
to_loxi_converters = {
'ofp_port': ofp_port_to_loxi_port_desc,
'ofp_port_status': ofp_port_status_to_loxi_port_status,
+ 'ofp_flow_removed': ofp_flow_removed_to_loxi_flow_removed,
'ofp_flow_stats': ofp_flow_stats_to_loxi_flow_stats,
'ofp_packet_in': ofp_packet_in_to_loxi_packet_in,
'ofp_group_stats': ofp_group_stats_to_loxi_group_stats,
diff --git a/ofagent/of_protocol_handler.py b/ofagent/of_protocol_handler.py
index 813c8a8..7deee6d 100644
--- a/ofagent/of_protocol_handler.py
+++ b/ofagent/of_protocol_handler.py
@@ -347,3 +347,6 @@
def forward_port_status(self, ofp_port_status):
self.cxn.send(to_loxi(ofp_port_status))
+
+ def forward_flow_removed(self, ofp_flow_removed):
+ self.cxn.send(to_loxi(ofp_flow_removed))
diff --git a/voltha/core/flow_decomposer.py b/voltha/core/flow_decomposer.py
index cef33c1..29c5e34 100644
--- a/voltha/core/flow_decomposer.py
+++ b/voltha/core/flow_decomposer.py
@@ -347,6 +347,10 @@
return None
+def get_tp_id_from_metadata(write_metadata_value):
+ return (write_metadata_value >> 32) & 0xffff
+
+
def get_inner_tag_from_write_metadata(flow):
"""
Write metadata instruction value (metadata) is 8 bytes:
@@ -359,7 +363,7 @@
metadata = get_metadata_from_write_metadata(flow)
log.debug("The metadata for inner tag", metadata=metadata)
if metadata is not None:
- inner_tag = (metadata >> 48) & 0xffffffff
+ inner_tag = (metadata >> 48) & 0xffff
log.debug("Found inner tag", inner_tag=inner_tag)
return inner_tag
return None
diff --git a/voltha/core/local_handler.py b/voltha/core/local_handler.py
index b88a7b5..39f550e 100644
--- a/voltha/core/local_handler.py
+++ b/voltha/core/local_handler.py
@@ -25,7 +25,7 @@
from common.utils.id_generation import create_cluster_device_id
from voltha.core.config.config_root import ConfigRoot
from voltha.protos.openflow_13_pb2 import PacketIn, Flows, FlowGroups, \
- Meters, ofp_port_status
+ Meters, ofp_port_status, ofp_flow_removed
from voltha.protos.voltha_pb2_grpc import \
add_VolthaLocalServiceServicer_to_server, VolthaLocalServiceServicer
from voltha.protos.voltha_pb2 import \
@@ -1156,6 +1156,10 @@
event = ChangeEvent(id=device_id, port_status=port_status)
self.core.change_event_queue.put(event)
+ def send_flow_removed_event(self, device_id, flow_removed):
+ assert isinstance(flow_removed, ofp_flow_removed)
+ event = ChangeEvent(id=device_id, flow_removed=flow_removed)
+ self.core.change_event_queue.put(event)
@twisted_async
def ListAlarmFilters(self, request, context):
diff --git a/voltha/core/logical_device_agent.py b/voltha/core/logical_device_agent.py
index 16b4ff8..a40d215 100644
--- a/voltha/core/logical_device_agent.py
+++ b/voltha/core/logical_device_agent.py
@@ -86,6 +86,7 @@
self._flows_ids_to_add = []
self._flows_ids_to_remove = []
self._flows_to_remove = []
+ self._flow_with_unknown_meter = dict()
self.accepts_direct_logical_flows = False
self.device_id = self.self_proxy.get('/').root_device_id
@@ -141,13 +142,22 @@
self.log.debug('stopped')
- def announce_flows_deleted(self, flows):
+ def announce_flows_deleted(self, flows, reason=ofp.OFPRR_DELETE):
for f in flows:
- self.announce_flow_deleted(f)
+ self.announce_flow_deleted(f, reason)
- def announce_flow_deleted(self, flow):
+ def announce_flow_deleted(self, flow, reason=ofp.OFPRR_DELETE):
if flow.flags & ofp.OFPFF_SEND_FLOW_REM:
- raise NotImplementedError("announce_flow_deleted")
+ self.local_handler.send_flow_removed_event(
+ device_id=self.logical_device_id,
+ flow_removed=ofp.ofp_flow_removed(
+ cookie=flow.cookie,
+ priority=flow.priority,
+ reason=reason,
+ table_id=flow.table_id,
+ match=flow.match
+ )
+ )
def signal_flow_mod_error(self, code, flow_mod):
pass # TODO
@@ -224,6 +234,8 @@
self.signal_meter_mod_error(ofp.OFPMMFC_METER_EXISTS, meter_mod)
else:
meter_entry = meter_entry_from_meter_mod(meter_mod)
+ meter_entry.stats.flow_count = self._flow_with_unknown_meter.get(meter_mod.meter_id, 0)
+ self._flow_with_unknown_meter.pop(meter_mod.meter_id, None)
meters[meter_mod.meter_id] = meter_entry
changed = True
@@ -352,6 +364,8 @@
meters=meters.values())
except KeyError:
self.log.warn("meter id is not found in meters", meter_id=meter_id)
+ self._flow_with_unknown_meter[meter_id] = \
+ self._flow_with_unknown_meter.get(meter_id, 0) + 1
def flow_delete(self, mod):
@@ -402,6 +416,8 @@
if changed:
self.flows_proxy.update('/', Flows(items=flows))
self.log.debug("flow deleted strictly", mod=mod)
+ if isinstance(mod, ofp.ofp_flow_mod):
+ self.announce_flow_deleted(flow)
def flow_modify(self, mod):
raise NotImplementedError()
@@ -552,7 +568,7 @@
flows = to_keep
# send notification to deleted ones
- self.announce_flows_deleted(to_delete)
+ self.announce_flows_deleted(to_delete, reason=ofp.OFPRR_GROUP_DELETE)
return bool(to_delete), flows
@@ -567,6 +583,7 @@
to_keep.append(f)
flows = to_keep
+ # we cant use OFPRR_MELETE_DELETE for 1.3.x
self.announce_flows_deleted(flows)
return bool(to_delete), flows
diff --git a/voltha/protos/openflow_13.proto b/voltha/protos/openflow_13.proto
index 3de3829..3c7e858 100644
--- a/voltha/protos/openflow_13.proto
+++ b/voltha/protos/openflow_13.proto
@@ -2305,5 +2305,6 @@
string id = 1; // LogicalDevice.id
oneof event {
ofp_port_status port_status = 2;
+ ofp_flow_removed flow_removed = 3;
}
}