X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=66b957e1091a4a001031a6443f970f300e04ca38;hb=5136ce492c414f377f7be9ae32b259abb9f76580;hp=481d50b845768941c0611bd552d6c2ba669f3151;hpb=fa05809b7238ad2db6046ef23d02007f8e7beefc;p=sliver-openvswitch.git diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 481d50b84..66b957e10 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -57,13 +57,10 @@ #include "timeval.h" #include "unixctl.h" #include "vconn.h" +#include "vlog.h" #include "xtoxll.h" -#include /* XXX */ -#include /* XXX */ - -#define THIS_MODULE VLM_ofproto -#include "vlog.h" +VLOG_DEFINE_THIS_MODULE(ofproto) #include "sflow_api.h" @@ -2280,11 +2277,10 @@ add_output_group_action(struct odp_actions *actions, uint16_t group, } static void -add_controller_action(struct odp_actions *actions, - const struct ofp_action_output *oao) +add_controller_action(struct odp_actions *actions, uint16_t max_len) { union odp_action *a = odp_actions_add(actions, ODPAT_CONTROLLER); - a->controller.arg = ntohs(oao->max_len); + a->controller.arg = max_len; } struct action_xlate_ctx { @@ -2376,15 +2372,15 @@ xlate_table_action(struct action_xlate_ctx *ctx, uint16_t in_port) } static void -xlate_output_action(struct action_xlate_ctx *ctx, - const struct ofp_action_output *oao) +xlate_output_action__(struct action_xlate_ctx *ctx, + uint16_t port, uint16_t max_len) { uint16_t odp_port; uint16_t prev_nf_output_iface = ctx->nf_output_iface; ctx->nf_output_iface = NF_OUT_DROP; - switch (ntohs(oao->port)) { + switch (port) { case OFPP_IN_PORT: add_output_action(ctx, ctx->flow.in_port); break; @@ -2408,13 +2404,13 @@ xlate_output_action(struct action_xlate_ctx *ctx, add_output_group_action(ctx->out, DP_GROUP_ALL, &ctx->nf_output_iface); break; case OFPP_CONTROLLER: - add_controller_action(ctx->out, oao); + add_controller_action(ctx->out, max_len); break; case OFPP_LOCAL: add_output_action(ctx, ODPP_LOCAL); break; default: - odp_port = ofp_port_to_odp_port(ntohs(oao->port)); + odp_port = ofp_port_to_odp_port(port); if (odp_port != ctx->flow.in_port) { add_output_action(ctx, odp_port); } @@ -2431,6 +2427,13 @@ xlate_output_action(struct action_xlate_ctx *ctx, } } +static void +xlate_output_action(struct action_xlate_ctx *ctx, + const struct ofp_action_output *oao) +{ + xlate_output_action__(ctx, ntohs(oao->port), ntohs(oao->max_len)); +} + /* If the final ODP action in 'ctx' is "pop priority", drop it, as an * optimization, because we're going to add another action that sets the * priority immediately after, or because there are no actions following the @@ -2449,6 +2452,16 @@ xlate_enqueue_action(struct action_xlate_ctx *ctx, const struct ofp_action_enqueue *oae) { uint16_t ofp_port, odp_port; + uint32_t priority; + int error; + + error = dpif_queue_to_priority(ctx->ofproto->dpif, ntohl(oae->queue_id), + &priority); + if (error) { + /* Fall back to ordinary output action. */ + xlate_output_action__(ctx, ntohs(oae->port), 0); + return; + } /* Figure out ODP output port. */ ofp_port = ntohs(oae->port); @@ -2461,7 +2474,7 @@ xlate_enqueue_action(struct action_xlate_ctx *ctx, /* Add ODP actions. */ remove_pop_action(ctx); odp_actions_add(ctx->out, ODPAT_SET_PRIORITY)->priority.priority - = TC_H_MAKE(1, ntohl(oae->queue_id)); /* XXX */ + = priority; add_output_action(ctx, odp_port); odp_actions_add(ctx->out, ODPAT_POP_PRIORITY); @@ -3639,6 +3652,7 @@ static int handle_flow_mod(struct ofproto *p, struct ofconn *ofconn, struct ofp_flow_mod *ofm) { + struct ofp_match orig_match; size_t n_actions; int error; @@ -3660,7 +3674,25 @@ handle_flow_mod(struct ofproto *p, struct ofconn *ofconn, return ofp_mkerr(OFPET_FLOW_MOD_FAILED, OFPFMFC_ALL_TABLES_FULL); } + /* Normalize ofp->match. If normalization actually changes anything, then + * log the differences. */ + ofm->match.pad1[0] = ofm->match.pad2[0] = 0; + orig_match = ofm->match; normalize_match(&ofm->match); + if (memcmp(&ofm->match, &orig_match, sizeof orig_match)) { + static struct vlog_rate_limit normal_rl = VLOG_RATE_LIMIT_INIT(1, 1); + if (!VLOG_DROP_INFO(&normal_rl)) { + char *old = ofp_match_to_literal_string(&orig_match); + char *new = ofp_match_to_literal_string(&ofm->match); + VLOG_INFO("%s: normalization changed ofp_match, details:", + rconn_get_name(ofconn->rconn)); + VLOG_INFO(" pre: %s", old); + VLOG_INFO("post: %s", new); + free(old); + free(new); + } + } + if (!ofm->match.wildcards) { ofm->priority = htons(UINT16_MAX); }