[ovs-dev] [PATCH 2/2] ofproto-dpif: Store patch port peer in struct ofport_dpif.

Ethan Jackson ethan at nicira.com
Mon Jun 17 22:12:53 UTC 2013


This removes ofproto-dpif-xlate's dependency on ofport_get_peer()
which, while cleaner in-and-of itself, will become more important
as ofproto-dpif_xlate modularizes.

Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
 lib/netdev-vport.c           |    2 +-
 ofproto/ofproto-dpif-xlate.c |   25 +++++++++---------
 ofproto/ofproto-dpif.c       |   58 ++++++++++++++++++++++++++++++++----------
 ofproto/ofproto-dpif.h       |    3 +--
 4 files changed, 59 insertions(+), 29 deletions(-)

diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index bdb0c4d..885bf5e 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -607,7 +607,7 @@ set_patch_config(struct netdev *dev_, const struct smap *args)
 
     free(dev->peer);
     dev->peer = xstrdup(peer);
-
+    netdev_vport_poll_notify(dev);
     return 0;
 }
 
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 0a577b1..ecba91b 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -817,16 +817,11 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
         return;
     }
 
-    if (netdev_vport_is_patch(ofport->up.netdev)) {
-        struct ofport_dpif *peer = ofport_get_peer(ofport);
+    if (ofport->peer) {
+        struct ofport_dpif *peer = ofport->peer;
         struct flow old_flow = ctx->xin->flow;
         enum slow_path_reason special;
 
-        if (!peer) {
-            xlate_report(ctx, "Nonexistent patch port peer");
-            return;
-        }
-
         ctx->ofproto = ofproto_dpif_cast(peer->up.ofproto);
         flow->in_port = peer->up.ofp_port;
         flow->metadata = htonll(0);
@@ -906,17 +901,21 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
         }
         flow->skb_mark &= ~IPSEC_MARK;
     }
-    commit_odp_actions(flow, &ctx->base_flow, &ctx->xout->odp_actions);
-    nl_msg_put_u32(&ctx->xout->odp_actions, OVS_ACTION_ATTR_OUTPUT, out_port);
 
-    ctx->sflow_odp_port = odp_port;
-    ctx->sflow_n_outputs++;
-    ctx->xout->nf_output_iface = ofp_port;
+    if (out_port != OVSP_NONE) {
+        commit_odp_actions(flow, &ctx->base_flow, &ctx->xout->odp_actions);
+        nl_msg_put_u32(&ctx->xout->odp_actions, OVS_ACTION_ATTR_OUTPUT,
+                       out_port);
+
+        ctx->sflow_odp_port = odp_port;
+        ctx->sflow_n_outputs++;
+        ctx->xout->nf_output_iface = ofp_port;
+    }
 
+ out:
     /* Restore flow */
     flow->vlan_tci = flow_vlan_tci;
     flow->skb_mark = flow_skb_mark;
- out:
     flow->nw_tos = flow_nw_tos;
 }
 
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index c68577a..4d7f911 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -301,6 +301,7 @@ static void port_wait(struct ofport_dpif *);
 static int set_bfd(struct ofport *, const struct smap *);
 static int set_cfm(struct ofport *, const struct cfm_settings *);
 static void ofport_clear_priorities(struct ofport_dpif *);
+static void ofport_update_peer(struct ofport_dpif *);
 static void run_fast_rl(void);
 
 struct dpif_completion {
@@ -1455,6 +1456,7 @@ port_construct(struct ofport *port_)
     port->stp_port = NULL;
     port->stp_state = STP_DISABLED;
     port->tnl_port = NULL;
+    port->peer = NULL;
     hmap_init(&port->priorities);
     port->realdev_ofp_port = 0;
     port->vlandev_vid = 0;
@@ -1467,6 +1469,7 @@ port_construct(struct ofport *port_)
 	 * to be "internal" to the switch as a whole, and therefore not an
 	 * candidate for counter polling. */
         port->odp_port = OVSP_NONE;
+        ofport_update_peer(port);
         return 0;
     }
 
@@ -1526,6 +1529,11 @@ port_destruct(struct ofport *port_)
         ofproto->backer->need_revalidate = REV_RECONFIGURE;
     }
 
+    if (port->peer) {
+        port->peer->peer = NULL;
+        port->peer = NULL;
+    }
+
     if (port->odp_port != OVSP_NONE && !port->tnl_port) {
         hmap_remove(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node);
     }
@@ -1562,6 +1570,8 @@ port_modified(struct ofport *port_)
                                                &port->tnl_port)) {
         ofproto_dpif_cast(port->up.ofproto)->backer->need_revalidate = true;
     }
+
+    ofport_update_peer(port);
 }
 
 static void
@@ -2831,32 +2841,54 @@ ofproto_port_from_dpif_port(struct ofproto_dpif *ofproto,
     ofproto_port->ofp_port = odp_port_to_ofp_port(ofproto, dpif_port->port_no);
 }
 
-struct ofport_dpif *
-ofport_get_peer(const struct ofport_dpif *ofport_dpif)
+static void
+ofport_update_peer(struct ofport_dpif *ofport)
 {
     const struct ofproto_dpif *ofproto;
-    const struct dpif_backer *backer;
-    const char *peer;
+    struct dpif_backer *backer;
+    const char *peer_name;
 
-    peer = netdev_vport_patch_peer(ofport_dpif->up.netdev);
-    if (!peer) {
-        return NULL;
+    if (!netdev_vport_is_patch(ofport->up.netdev)) {
+        return;
+    }
+
+    backer = ofproto_dpif_cast(ofport->up.ofproto)->backer;
+    backer->need_revalidate = true;
+
+    if (ofport->peer) {
+        ofport->peer->peer = NULL;
+        ofport->peer = NULL;
+    }
+
+    peer_name = netdev_vport_patch_peer(ofport->up.netdev);
+    if (!peer_name) {
+        return;
     }
 
-    backer = ofproto_dpif_cast(ofport_dpif->up.ofproto)->backer;
     HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
-        struct ofport *ofport;
+        struct ofport *peer_ofport;
+        struct ofport_dpif *peer;
+        const char *peer_peer;
 
         if (ofproto->backer != backer) {
             continue;
         }
 
-        ofport = shash_find_data(&ofproto->up.port_by_name, peer);
-        if (ofport) {
-            return ofport_dpif_cast(ofport);
+        peer_ofport = shash_find_data(&ofproto->up.port_by_name, peer_name);
+        if (!peer_ofport) {
+            continue;
         }
+
+        peer = ofport_dpif_cast(peer_ofport);
+        peer_peer = netdev_vport_patch_peer(peer->up.netdev);
+        if (peer_peer && !strcmp(netdev_get_name(ofport->up.netdev),
+                                 peer_peer)) {
+            ofport->peer = peer;
+            ofport->peer->peer = ofport;
+        }
+
+        return;
     }
-    return NULL;
 }
 
 static void
diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
index 52e9639..480a1dd 100644
--- a/ofproto/ofproto-dpif.h
+++ b/ofproto/ofproto-dpif.h
@@ -136,6 +136,7 @@ struct ofport_dpif {
     bool may_enable;            /* May be enabled in bonds. */
     long long int carrier_seq;  /* Carrier status changes. */
     struct tnl_port *tnl_port;  /* Tunnel handle, or null. */
+    struct ofport_dpif *peer;   /* Peer if patch port. */
 
     /* Spanning tree. */
     struct stp_port *stp_port;  /* Spanning Tree Protocol, if any. */
@@ -232,8 +233,6 @@ struct ofport_dpif *get_ofp_port(const struct ofproto_dpif *,
 struct ofport_dpif *get_odp_port(const struct ofproto_dpif *,
                                         uint32_t odp_port);
 
-struct ofport_dpif *ofport_get_peer(const struct ofport_dpif *);
-
 uint32_t ofp_port_to_odp_port(const struct ofproto_dpif *, uint16_t ofp_port);
 
 struct rule_dpif *rule_dpif_lookup_in_table(struct ofproto_dpif *,
-- 
1.7.9.5




More information about the dev mailing list