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/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()