X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=4403a53448fd8f1708d5004312ef3b0f9f7d2451;hb=d6de72a12fad59941409ac3ff57f1660ac5a28bb;hp=cd87cd0d55c2040324afa7f78f40f1ab5d6a8526;hpb=f1defbf96df61a1fce8ec8ca63a56018bff4c940;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index cd87cd0d..4403a534 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -88,7 +88,7 @@ struct rule { uint16_t idle_timeout; /* In seconds from time of last use. */ uint16_t hard_timeout; /* In seconds from time of creation. */ bool send_flow_removed; /* Send a flow removed message? */ - long long int used; /* Last-used time (0 if never used). */ + long long int used; /* Time last used; time created if not used. */ long long int created; /* Creation time. */ uint64_t packet_count; /* Number of packets received. */ uint64_t byte_count; /* Number of bytes received. */ @@ -1298,15 +1298,21 @@ ofproto_send_packet(struct ofproto *p, const struct flow *flow, return 0; } +/* Adds a flow to the OpenFlow flow table in 'p' that matches 'cls_rule' and + * performs the 'n_actions' actions in 'actions'. The new flow will not + * timeout. + * + * If cls_rule->priority is in the range of priorities supported by OpenFlow + * (0...65535, inclusive) then the flow will be visible to OpenFlow + * controllers; otherwise, it will be hidden. + * + * The caller retains ownership of 'cls_rule' and 'actions'. */ void ofproto_add_flow(struct ofproto *p, const struct cls_rule *cls_rule, - const union ofp_action *actions, size_t n_actions, - int idle_timeout) + const union ofp_action *actions, size_t n_actions) { struct rule *rule; - rule = rule_create(p, NULL, actions, n_actions, - idle_timeout >= 0 ? idle_timeout : 5 /* XXX */, - 0, 0, false); + rule = rule_create(p, NULL, actions, n_actions, 0, 0, 0, false); rule->cr = *cls_rule; rule_insert(p, rule, NULL, 0); } @@ -1854,7 +1860,7 @@ rule_create(struct ofproto *ofproto, struct rule *super, rule->n_actions = n_actions; rule->actions = xmemdup(actions, n_actions * sizeof *actions); } - netflow_flow_clear(&rule->nf_flow); + netflow_flow_init(&rule->nf_flow); netflow_flow_update_time(ofproto->netflow, &rule->nf_flow, rule->created); return rule; @@ -2102,7 +2108,6 @@ rule_make_actions(struct ofproto *p, struct rule *rule, assert(!rule->cr.wc.wildcards); super = rule->super ? rule->super : rule; - rule->tags = 0; xlate_actions(super->actions, super->n_actions, &rule->cr.flow, p, packet, &a, &rule->tags, &rule->may_install, &rule->nf_flow.output_iface); @@ -2431,7 +2436,7 @@ struct action_xlate_ctx { /* Output. */ struct odp_actions *out; /* Datapath actions. */ - tag_type *tags; /* Tags associated with OFPP_NORMAL actions. */ + tag_type tags; /* Tags associated with OFPP_NORMAL actions. */ bool may_set_up_flow; /* True ordinarily; false if the actions must * be reassessed for every packet. */ uint16_t nf_output_iface; /* Output interface index for NetFlow. */ @@ -2551,7 +2556,7 @@ xlate_output_action__(struct action_xlate_ctx *ctx, break; case OFPP_NORMAL: if (!ctx->ofproto->ofhooks->normal_cb(&ctx->flow, ctx->packet, - ctx->out, ctx->tags, + ctx->out, &ctx->tags, &ctx->nf_output_iface, ctx->ofproto->aux)) { COVERAGE_INC(ofproto_uninstallable); @@ -2669,6 +2674,36 @@ xlate_set_queue_action(struct action_xlate_ctx *ctx, = priority; } +static void +xlate_set_dl_tci(struct action_xlate_ctx *ctx) +{ + ovs_be16 dl_vlan = ctx->flow.dl_vlan; + uint8_t dl_vlan_pcp = ctx->flow.dl_vlan_pcp; + + if (dl_vlan == htons(OFP_VLAN_NONE)) { + odp_actions_add(ctx->out, ODPAT_STRIP_VLAN); + } else { + union odp_action *oa = odp_actions_add(ctx->out, ODPAT_SET_DL_TCI); + oa->dl_tci.tci = htons(ntohs(dl_vlan & htons(VLAN_VID_MASK)) + | (dl_vlan_pcp << VLAN_PCP_SHIFT) + | VLAN_CFI); + } +} + +static void +xlate_reg_move_action(struct action_xlate_ctx *ctx, + const struct nx_action_reg_move *narm) +{ + ovs_be16 old_vlan = ctx->flow.dl_vlan; + uint8_t old_pcp = ctx->flow.dl_vlan_pcp; + + nxm_execute_reg_move(narm, &ctx->flow); + + if (ctx->flow.dl_vlan != old_vlan || ctx->flow.dl_vlan_pcp != old_pcp) { + xlate_set_dl_tci(ctx); + } +} + static void xlate_nicira_action(struct action_xlate_ctx *ctx, const struct nx_action_header *nah) @@ -2707,6 +2742,15 @@ xlate_nicira_action(struct action_xlate_ctx *ctx, odp_actions_add(ctx->out, ODPAT_POP_PRIORITY); break; + case NXAST_REG_MOVE: + xlate_reg_move_action(ctx, (const struct nx_action_reg_move *) nah); + break; + + case NXAST_REG_LOAD: + nxm_execute_reg_load((const struct nx_action_reg_load *) nah, + &ctx->flow); + break; + /* If you add a new action here that modifies flow data, don't forget to * update the flow key in ctx->flow at the same time. */ @@ -2742,23 +2786,19 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, break; case OFPAT_SET_VLAN_VID: - oa = odp_actions_add(ctx->out, ODPAT_SET_DL_TCI); - oa->dl_tci.tci = ia->vlan_vid.vlan_vid; - oa->dl_tci.tci |= htons(ctx->flow.dl_vlan_pcp << VLAN_PCP_SHIFT); ctx->flow.dl_vlan = ia->vlan_vid.vlan_vid; + xlate_set_dl_tci(ctx); break; case OFPAT_SET_VLAN_PCP: - oa = odp_actions_add(ctx->out, ODPAT_SET_DL_TCI); - oa->dl_tci.tci = htons(ia->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT); - oa->dl_tci.tci |= ctx->flow.dl_vlan; ctx->flow.dl_vlan_pcp = ia->vlan_pcp.vlan_pcp; + xlate_set_dl_tci(ctx); break; case OFPAT_STRIP_VLAN: - odp_actions_add(ctx->out, ODPAT_STRIP_VLAN); ctx->flow.dl_vlan = htons(OFP_VLAN_NONE); ctx->flow.dl_vlan_pcp = 0; + xlate_set_dl_tci(ctx); break; case OFPAT_SET_DL_SRC: @@ -2824,8 +2864,8 @@ xlate_actions(const union ofp_action *in, size_t n_in, struct odp_actions *out, tag_type *tags, bool *may_set_up_flow, uint16_t *nf_output_iface) { - tag_type no_tags = 0; struct action_xlate_ctx ctx; + COVERAGE_INC(ofproto_ofp2odp); odp_actions_init(out); ctx.flow = *flow; @@ -2833,7 +2873,7 @@ xlate_actions(const union ofp_action *in, size_t n_in, ctx.ofproto = ofproto; ctx.packet = packet; ctx.out = out; - ctx.tags = tags ? tags : &no_tags; + ctx.tags = 0; ctx.may_set_up_flow = true; ctx.nf_output_iface = NF_OUT_DROP; do_xlate_actions(in, n_in, &ctx); @@ -2845,6 +2885,9 @@ xlate_actions(const union ofp_action *in, size_t n_in, ctx.may_set_up_flow = false; } + if (tags) { + *tags = ctx.tags; + } if (may_set_up_flow) { *may_set_up_flow = ctx.may_set_up_flow; } @@ -3664,7 +3707,7 @@ handle_vendor_stats_request(struct ofconn *ofconn, return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_VENDOR); } - if (ntohs(nsm->header.length) < sizeof(struct nicira_stats_msg)) { + if (ntohs(osr->header.length) < sizeof(struct nicira_stats_msg)) { VLOG_WARN_RL(&rl, "truncated Nicira stats request"); return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); } @@ -4788,8 +4831,7 @@ revalidate_rule(struct ofproto *p, struct rule *rule) rule->super = super; rule->hard_timeout = super->hard_timeout; rule->idle_timeout = super->idle_timeout; - rule->created = super->created; - rule->used = 0; + rule->created = rule->used = super->created; } }