From: Ethan Jackson Date: Mon, 17 Jun 2013 21:04:36 +0000 (-0700) Subject: ofproto-dpif: Store patch port peer in struct ofport_dpif. X-Git-Tag: sliver-openvswitch-1.10.90-3~6^2~96 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=6cbbf4fa07f12f7f3977a1b3b63783220f4db3ea;p=sliver-openvswitch.git ofproto-dpif: Store patch port peer in struct ofport_dpif. 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 Acked-by: Ben Pfaff --- diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index bdb0c4da3..885bf5e3a 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 f5877a46b..1c234ec63 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -855,16 +855,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); @@ -944,17 +939,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 5b4def07e..1b3b1e3bb 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 @@ -2833,32 +2843,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 3852fa8d8..12a9d7e43 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 *,