Adding support for OLT side metadata field
Due to historic reasons, ONOS injects a metadata match field into one
of the downstream unicats flow rules, which was not yet handled by voltha.
That is fixed and tested now.
Change-Id: Ic8a47de515fa5837a70941be22da9e2d6539f614
diff --git a/cli/main.py b/cli/main.py
index fa778a1..12a157f 100755
--- a/cli/main.py
+++ b/cli/main.py
@@ -498,7 +498,8 @@
priority=500,
match_fields=[
in_port(nni_port_no),
- vlan_vid(4096 + 1000)
+ vlan_vid(4096 + 1000),
+ metadata(40) # here to mimic an ONOS artifact
],
actions=[pop_vlan()],
next_table_id=1
diff --git a/cli/utils.py b/cli/utils.py
index 0d677d1..7ea9c77 100644
--- a/cli/utils.py
+++ b/cli/utils.py
@@ -89,6 +89,7 @@
'UDP_DST': lambda f: (107, 'udp_dst', str(f['udp_dst'])),
'TCP_SRC': lambda f: (108, 'tcp_src', str(f['tcp_src'])),
'TCP_DST': lambda f: (109, 'tcp_dst', str(f['tcp_dst'])),
+ 'METADATA': lambda f: (110, 'metadata', str(f['table_metadata'])),
}
diff --git a/ofagent/converter.py b/ofagent/converter.py
index 59330bd..2b97055 100644
--- a/ofagent/converter.py
+++ b/ofagent/converter.py
@@ -128,6 +128,7 @@
duration_nsec=pb.stats.duration_nsec,
bucket_stats=[to_loxi(bstat) for bstat in pb.stats.bucket_stats])
+
def ofp_bucket_counter_to_loxy_bucket_counter(pb):
return of13.bucket_counter(
packet_count=pb.packet_count,
@@ -239,6 +240,22 @@
ipv4_dst=lo.value))
+def loxi_oxm_udp_dst_to_ofp_oxm(lo):
+ return pb2.ofp_oxm_field(
+ oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
+ ofb_field=pb2.ofp_oxm_ofb_field(
+ type=pb2.OFPXMT_OFB_UDP_DST,
+ udp_dst=lo.value))
+
+
+def loxi_oxm_metadata_to_ofp_oxm(lo):
+ return pb2.ofp_oxm_field(
+ oxm_class=pb2.OFPXMC_OPENFLOW_BASIC,
+ ofb_field=pb2.ofp_oxm_ofb_field(
+ type=pb2.OFPXMT_OFB_METADATA,
+ table_metadata=lo.value))
+
+
def loxi_apply_actions_to_ofp_instruction(lo):
return pb2.ofp_instruction(
type=pb2.OFPIT_APPLY_ACTIONS,
@@ -302,6 +319,8 @@
of13.oxm.vlan_vid: loxi_oxm_vlan_vid_to_ofp_oxm,
of13.oxm.vlan_pcp: loxi_oxm_vlan_pcp_to_ofp_oxm,
of13.oxm.ipv4_dst: loxi_oxm_ipv4_dst_to_ofp_oxm,
+ of13.oxm.udp_dst: loxi_oxm_udp_dst_to_ofp_oxm,
+ of13.oxm.metadata: loxi_oxm_metadata_to_ofp_oxm,
of13.instruction.apply_actions: loxi_apply_actions_to_ofp_instruction,
of13.instruction.goto_table: loxi_goto_table_to_ofp_instruction,
diff --git a/ofagent/of_protocol_handler.py b/ofagent/of_protocol_handler.py
index 0508d76..87feb37 100644
--- a/ofagent/of_protocol_handler.py
+++ b/ofagent/of_protocol_handler.py
@@ -104,9 +104,13 @@
def handle_experimenter_request(self, req):
raise NotImplementedError()
- @inlineCallbacks
def handle_flow_mod_request(self, req):
- yield self.rpc.update_flow_table(self.device_id, to_grpc(req))
+ try:
+ grpc_req = to_grpc(req)
+ except Exception, e:
+ log.exception('failed-to-convert', e=e)
+ else:
+ return self.rpc.update_flow_table(self.device_id, grpc_req)
def handle_get_async_request(self, req):
raise NotImplementedError()
diff --git a/ponsim/ponsim.py b/ponsim/ponsim.py
index c855e39..3086ff5 100644
--- a/ponsim/ponsim.py
+++ b/ponsim/ponsim.py
@@ -138,9 +138,12 @@
return False
elif field.type == UDP_DST:
- if field.udsp_dst != get_udp_dst(frame):
+ if field.udp_dst != get_udp_dst(frame):
return False
+ elif field.type == METADATA:
+ pass # safe to ignore
+
else:
raise NotImplementedError('field.type=%d' % field.type)
diff --git a/voltha/adapters/simulated_olt/simulated_olt.py b/voltha/adapters/simulated_olt/simulated_olt.py
index d5cd697..ec52c3a 100644
--- a/voltha/adapters/simulated_olt/simulated_olt.py
+++ b/voltha/adapters/simulated_olt/simulated_olt.py
@@ -389,6 +389,9 @@
_vlan_pcp = field.vlan_pcp
pass # construct VLAN PCP based filter condition here
+ elif field.type == METADATA:
+ pass # safe to ignore
+
# TODO
else:
raise NotImplementedError('field.type={}'.format(
diff --git a/voltha/adapters/tibit_olt/tibit_olt.py b/voltha/adapters/tibit_olt/tibit_olt.py
index f162a7d..615394b 100644
--- a/voltha/adapters/tibit_olt/tibit_olt.py
+++ b/voltha/adapters/tibit_olt/tibit_olt.py
@@ -455,6 +455,9 @@
log.info('#### field.type == UDP_DST ####')
pass # construct UDP SDT based filter here
+ elif field.type == METADATA:
+ pass # safe to ignore
+
else:
raise NotImplementedError('field.type={}'.format(
field.type))
diff --git a/voltha/core/flow_decomposer.py b/voltha/core/flow_decomposer.py
index b8221b5..6c72f07 100644
--- a/voltha/core/flow_decomposer.py
+++ b/voltha/core/flow_decomposer.py
@@ -221,6 +221,10 @@
def arp_tha(_arp_tha):
return ofb_field(type=ARP_THA, arp_tha=_arp_tha)
+def metadata(_table_metadata):
+ return ofb_field(type=METADATA, table_metadata=_table_metadata)
+
+
# TODO finish for rest of match fields