[ovs-dev] [PATCH] ofproto-dpif: treat patch ports as local port for OFPT_PACKET_OUT

Andy Zhou azhou at nicira.com
Wed Apr 30 09:09:40 UTC 2014


When controller send OFPT_PACKET_OUT message, with its input port set
to a patch port, and the packet handling requires recirculation,
the post recirculation flow is never set up since the xlate layer
rejects the up call triggered by such packet, on the bases those
up calls don't have valid datapath input port. Patch ports don't
have corresponding datapath ports.

A reasonable solution is by injecting the packet into datapath
using LOCAL port's datapath port id. This patch implements
such solution. It works against a test case provided by Simon.

Reported-by: Simon Horman <horms at verge.net.au>
Signed-off-by: Andy Zhou <azhou at nicira.com>
---
 ofproto/ofproto-dpif.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 4cebd77..afc2f21 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -195,6 +195,8 @@ static void vsp_add(struct ofport_dpif *, ofp_port_t realdev_ofp_port, int vid);
 
 static odp_port_t ofp_port_to_odp_port(const struct ofproto_dpif *,
                                        ofp_port_t);
+static odp_port_t packet_out_odp_port(const struct ofproto_dpif *,
+                                       ofp_port_t);
 
 static ofp_port_t odp_port_to_ofp_port(const struct ofproto_dpif *,
                                        odp_port_t);
@@ -3145,7 +3147,7 @@ ofproto_dpif_execute_actions(struct ofproto_dpif *ofproto,
     execute.md.tunnel = flow->tunnel;
     execute.md.skb_priority = flow->skb_priority;
     execute.md.pkt_mark = flow->pkt_mark;
-    execute.md.in_port.odp_port = ofp_port_to_odp_port(ofproto, in_port);
+    execute.md.in_port.odp_port = packet_out_odp_port(ofproto, in_port);
     execute.needs_help = (xout.slow & SLOW_ACTION) != 0;
 
     error = dpif_execute(ofproto->backer->dpif, &execute);
@@ -4745,6 +4747,21 @@ ofp_port_to_odp_port(const struct ofproto_dpif *ofproto, ofp_port_t ofp_port)
     return ofport ? ofport->odp_port : ODPP_NONE;
 }
 
+/* Converts ofp port to odp port, similar to ofp_port_to_odp_port.
+ * This function treats patch ports as LOCAL port, that is safe to send
+ * into the datapatch.  */
+static odp_port_t
+packet_out_odp_port(const struct ofproto_dpif *ofproto, ofp_port_t ofp_port)
+{
+    const struct ofport_dpif *ofport = get_ofp_port(ofproto, ofp_port);
+    if (ofport && netdev_vport_is_patch(ofport->up.netdev)) {
+        ofport = get_ofp_port(ofproto, OFPP_LOCAL);
+    }
+
+    return ofport ? ofport->odp_port : ODPP_NONE;
+}
+
+
 struct ofport_dpif *
 odp_port_to_ofport(const struct dpif_backer *backer, odp_port_t odp_port)
 {
-- 
1.9.1




More information about the dev mailing list