X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto-dpif.c;h=afdd08501c579adbe051425215cf22def04a6070;hb=fd19297bb3d61789aa2a8871e3316b2a4e3e34c3;hp=3e92493c29e551b82f4889fbed0ad9722a6f9749;hpb=edb0540bbcc624675b8745f52e085ef15d0fa023;p=openvswitch diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 3e92493c..afdd0850 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -145,6 +145,7 @@ struct ofbundle { * NULL if all VLANs are trunked. */ struct lacp *lacp; /* LACP if LACP is enabled, otherwise NULL. */ struct bond *bond; /* Nonnull iff more than one port. */ + bool use_priority_tags; /* Use 802.1p tag for frames in VLAN 0? */ /* Status. */ bool floodable; /* True if no port has OFPPC_NO_FLOOD set. */ @@ -1229,8 +1230,7 @@ bundle_update(struct ofbundle *bundle) bundle->floodable = true; LIST_FOR_EACH (port, bundle_node, &bundle->ports) { - if (port->up.opp.config & htonl(OFPPC_NO_FLOOD) - || !stp_forward_in_state(port->stp_state)) { + if (port->up.opp.config & htonl(OFPPC_NO_FLOOD)) { bundle->floodable = false; break; } @@ -1277,8 +1277,7 @@ bundle_add_port(struct ofbundle *bundle, uint32_t ofp_port, port->bundle = bundle; list_push_back(&bundle->ports, &port->bundle_node); - if (port->up.opp.config & htonl(OFPPC_NO_FLOOD) - || !stp_forward_in_state(port->stp_state)) { + if (port->up.opp.config & htonl(OFPPC_NO_FLOOD)) { bundle->floodable = false; } } @@ -1364,6 +1363,7 @@ bundle_set(struct ofproto *ofproto_, void *aux, bundle->vlan_mode = PORT_VLAN_TRUNK; bundle->vlan = -1; bundle->trunks = NULL; + bundle->use_priority_tags = s->use_priority_tags; bundle->lacp = NULL; bundle->bond = NULL; @@ -1422,8 +1422,10 @@ bundle_set(struct ofproto *ofproto_, void *aux, } /* Set VLAN tagging mode */ - if (s->vlan_mode != bundle->vlan_mode) { + if (s->vlan_mode != bundle->vlan_mode + || s->use_priority_tags != bundle->use_priority_tags) { bundle->vlan_mode = s->vlan_mode; + bundle->use_priority_tags = s->use_priority_tags; need_flush = true; } @@ -3769,35 +3771,41 @@ commit_odp_actions(struct action_xlate_ctx *ctx) } static void -compose_output_action(struct action_xlate_ctx *ctx, uint16_t odp_port) +force_compose_output_action(struct action_xlate_ctx *ctx, uint16_t ofp_port) { + const struct ofport_dpif *ofport = get_ofp_port(ctx->ofproto, ofp_port); + uint16_t odp_port = ofp_port_to_odp_port(ofp_port); + + if (ofport && ofport->up.opp.config & htonl(OFPPC_NO_FWD)) { + return; + } + nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_OUTPUT, odp_port); ctx->sflow_odp_port = odp_port; ctx->sflow_n_outputs++; } static void -add_output_action(struct action_xlate_ctx *ctx, uint16_t ofp_port) +compose_output_action(struct action_xlate_ctx *ctx, uint16_t ofp_port) { - const struct ofport_dpif *ofport = get_ofp_port(ctx->ofproto, ofp_port); - uint16_t odp_port = ofp_port_to_odp_port(ofp_port); + struct ofport_dpif *ofport = get_ofp_port(ctx->ofproto, ofp_port); - if (ofport) { - if (ofport->up.opp.config & htonl(OFPPC_NO_FWD) - || !stp_forward_in_state(ofport->stp_state)) { - /* Forwarding disabled on port. */ - return; - } - } else { - /* - * We don't have an ofport record for this port, but it doesn't hurt to - * allow forwarding to it anyhow. Maybe such a port will appear later - * and we're pre-populating the flow table. - */ + if (ofport && !stp_forward_in_state(ofport->stp_state)) { + /* Forwarding disabled on port. */ + return; } + /* We may not have an ofport record for this port, but it doesn't hurt to + * allow forwarding to it anyhow. Maybe such a port will appear later and + * we're pre-populating the flow table. */ + force_compose_output_action(ctx, ofp_port); +} + +static void +commit_output_action(struct action_xlate_ctx *ctx, uint16_t ofp_port) +{ commit_odp_actions(ctx); - compose_output_action(ctx, odp_port); + compose_output_action(ctx, ofp_port); ctx->nf_output_iface = ofp_port; } @@ -3870,17 +3878,22 @@ xlate_resubmit_table(struct action_xlate_ctx *ctx, } static void -flood_packets(struct action_xlate_ctx *ctx, ovs_be32 mask) +flood_packets(struct action_xlate_ctx *ctx, bool all) { struct ofport_dpif *ofport; commit_odp_actions(ctx); HMAP_FOR_EACH (ofport, up.hmap_node, &ctx->ofproto->up.ports) { uint16_t ofp_port = ofport->up.ofp_port; - if (ofp_port != ctx->flow.in_port - && !(ofport->up.opp.config & mask) - && stp_forward_in_state(ofport->stp_state)) { - compose_output_action(ctx, ofport->odp_port); + + if (ofp_port == ctx->flow.in_port) { + continue; + } + + if (all) { + force_compose_output_action(ctx, ofp_port); + } else if (!(ofport->up.opp.config & htonl(OFPPC_NO_FLOOD))) { + compose_output_action(ctx, ofp_port); } } @@ -3909,7 +3922,7 @@ xlate_output_action__(struct action_xlate_ctx *ctx, switch (port) { case OFPP_IN_PORT: - add_output_action(ctx, ctx->flow.in_port); + commit_output_action(ctx, ctx->flow.in_port); break; case OFPP_TABLE: xlate_table_action(ctx, ctx->flow.in_port, ctx->table_id); @@ -3918,23 +3931,23 @@ xlate_output_action__(struct action_xlate_ctx *ctx, xlate_normal(ctx); break; case OFPP_FLOOD: - flood_packets(ctx, htonl(OFPPC_NO_FLOOD)); + flood_packets(ctx, false); break; case OFPP_ALL: - flood_packets(ctx, htonl(0)); + flood_packets(ctx, true); break; case OFPP_CONTROLLER: commit_odp_actions(ctx); compose_controller_action(ctx, max_len); break; case OFPP_LOCAL: - add_output_action(ctx, OFPP_LOCAL); + commit_output_action(ctx, OFPP_LOCAL); break; case OFPP_NONE: break; default: if (port != ctx->flow.in_port) { - add_output_action(ctx, port); + commit_output_action(ctx, port); } break; } @@ -3973,7 +3986,7 @@ static void xlate_enqueue_action(struct action_xlate_ctx *ctx, const struct ofp_action_enqueue *oae) { - uint16_t ofp_port, odp_port; + uint16_t ofp_port; uint32_t flow_priority, priority; int error; @@ -3992,17 +4005,16 @@ xlate_enqueue_action(struct action_xlate_ctx *ctx, } else if (ofp_port == ctx->flow.in_port) { return; } - odp_port = ofp_port_to_odp_port(ofp_port); /* Add datapath actions. */ flow_priority = ctx->flow.priority; ctx->flow.priority = priority; - add_output_action(ctx, odp_port); + commit_output_action(ctx, ofp_port); ctx->flow.priority = flow_priority; /* Update NetFlow output port. */ if (ctx->nf_output_iface == NF_OUT_DROP) { - ctx->nf_output_iface = odp_port; + ctx->nf_output_iface = ofp_port; } else if (ctx->nf_output_iface != NF_OUT_FLOOD) { ctx->nf_output_iface = NF_OUT_MULTI; } @@ -4360,7 +4372,7 @@ xlate_actions(struct action_xlate_ctx *ctx, if (ctx->packet && connmgr_msg_in_hook(ctx->ofproto->up.connmgr, &ctx->flow, ctx->packet)) { - compose_output_action(ctx, OVSP_LOCAL); + compose_output_action(ctx, OFPP_LOCAL); } } fix_sflow_action(ctx); @@ -4497,14 +4509,17 @@ output_normal(struct action_xlate_ctx *ctx, const struct ofbundle *out_bundle, } } - tci = htons(vid) | (ctx->flow.vlan_tci & htons(VLAN_PCP_MASK)); - if (tci) { - tci |= htons(VLAN_CFI); + tci = htons(vid); + if (tci || out_bundle->use_priority_tags) { + tci |= ctx->flow.vlan_tci & htons(VLAN_PCP_MASK); + if (tci) { + tci |= htons(VLAN_CFI); + } } commit_vlan_action(ctx, tci); - compose_output_action(ctx, port->odp_port); - ctx->nf_output_iface = port->odp_port; + compose_output_action(ctx, port->up.ofp_port); + ctx->nf_output_iface = port->up.ofp_port; } static int @@ -4617,14 +4632,12 @@ output_mirrors(struct action_xlate_ctx *ctx, { struct ofproto_dpif *ofproto = ctx->ofproto; mirror_mask_t mirrors; - uint16_t flow_vid; mirrors = in_bundle->src_mirrors | dst_mirrors; if (!mirrors) { return; } - flow_vid = vlan_tci_to_vid(ctx->flow.vlan_tci); while (mirrors) { struct ofmirror *m; @@ -5320,7 +5333,7 @@ ofproto_dpif_unixctl_init(void) unixctl_command_register("fdb/flush", "bridge", ofproto_unixctl_fdb_flush, NULL); unixctl_command_register("fdb/show", "bridge", ofproto_unixctl_fdb_show, - NULL); + NULL); unixctl_command_register("ofproto/clog", "", ofproto_dpif_clog, NULL); unixctl_command_register("ofproto/unclog", "", ofproto_dpif_unclog, NULL); }