X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=ofproto%2Fofproto-dpif.c;h=ff6df41ff0088dad3995fe3acef37622632b788a;hb=296e07ace0ff2d5819ce760d6018ba82d14aa2a8;hp=7d6a002d359a8f5f95afccd5f058b57489cf6674;hpb=c376f9a3e968570d2df2574336d86185fc18b8a2;p=openvswitch diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 7d6a002d..ff6df41f 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -118,8 +118,7 @@ static void rule_credit_stats(struct rule_dpif *, static void flow_push_stats(struct rule_dpif *, const struct flow *, const struct dpif_flow_stats *); static tag_type rule_calculate_tag(const struct flow *, - const struct flow_wildcards *, - uint32_t basis); + const struct minimask *, uint32_t basis); static void rule_invalidate(const struct rule_dpif *); #define MAX_MIRRORS 32 @@ -598,7 +597,6 @@ struct ofproto_dpif { struct hmap_node all_ofproto_dpifs_node; /* In 'all_ofproto_dpifs'. */ struct ofproto up; struct dpif *dpif; - int max_ports; /* Special OpenFlow rules. */ struct rule_dpif *miss_rule; /* Sends flow table misses to controller. */ @@ -744,6 +742,7 @@ construct(struct ofproto *ofproto_) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); const char *name = ofproto->up.name; + int max_ports; int error; int i; @@ -753,7 +752,9 @@ construct(struct ofproto *ofproto_) return error; } - ofproto->max_ports = dpif_get_max_ports(ofproto->dpif); + max_ports = dpif_get_max_ports(ofproto->dpif); + ofproto_init_max_ports(ofproto_, MIN(max_ports, OFPP_MAX)); + ofproto->n_matches = 0; dpif_flow_flush(ofproto->dpif); @@ -820,8 +821,9 @@ add_internal_flow(struct ofproto_dpif *ofproto, int id, struct ofputil_flow_mod fm; int error; - cls_rule_init_catchall(&fm.cr, 0); - cls_rule_set_reg(&fm.cr, 0, id); + match_init_catchall(&fm.match); + fm.priority = 0; + match_set_reg(&fm.match, 0, id); fm.new_cookie = htonll(0); fm.cookie = htonll(0); fm.cookie_mask = htonll(0); @@ -842,7 +844,7 @@ add_internal_flow(struct ofproto_dpif *ofproto, int id, return error; } - *rulep = rule_dpif_lookup__(ofproto, &fm.cr.flow, TBL_INTERNAL); + *rulep = rule_dpif_lookup__(ofproto, &fm.match.flow, TBL_INTERNAL); assert(*rulep != NULL); return 0; @@ -1156,7 +1158,7 @@ get_features(struct ofproto *ofproto_ OVS_UNUSED, } static void -get_tables(struct ofproto *ofproto_, struct ofp10_table_stats *ots) +get_tables(struct ofproto *ofproto_, struct ofp12_table_stats *ots) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); struct dpif_dp_stats s; @@ -1164,9 +1166,8 @@ get_tables(struct ofproto *ofproto_, struct ofp10_table_stats *ots) strcpy(ots->name, "classifier"); dpif_get_dp_stats(ofproto->dpif, &s); - put_32aligned_be64(&ots->lookup_count, htonll(s.n_hit + s.n_missed)); - put_32aligned_be64(&ots->matched_count, - htonll(s.n_hit + ofproto->n_matches)); + ots->lookup_count = htonll(s.n_hit + s.n_missed); + ots->matched_count = htonll(s.n_hit + ofproto->n_matches); } static struct ofport * @@ -3116,7 +3117,7 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, struct dpif_upcall *upcalls, continue; } flow_extract(upcall->packet, miss->flow.skb_priority, - miss->flow.tun_id, miss->flow.in_port, &miss->flow); + &miss->flow.tunnel, miss->flow.in_port, &miss->flow); /* Add other packets to a to-do list. */ hash = flow_hash(&miss->flow, 0); @@ -4636,13 +4637,6 @@ rule_construct(struct rule *rule_) struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto); struct rule_dpif *victim; uint8_t table_id; - enum ofperr error; - - error = ofpacts_check(rule->up.ofpacts, rule->up.ofpacts_len, - &rule->up.cr.flow, ofproto->max_ports); - if (error) { - return error; - } rule->packet_count = 0; rule->byte_count = 0; @@ -4669,10 +4663,17 @@ rule_construct(struct rule *rule_) } table_id = rule->up.table_id; - rule->tag = (victim ? victim->tag - : table_id == 0 ? 0 - : rule_calculate_tag(&rule->up.cr.flow, &rule->up.cr.wc, - ofproto->tables[table_id].basis)); + if (victim) { + rule->tag = victim->tag; + } else if (table_id == 0) { + rule->tag = 0; + } else { + struct flow flow; + + miniflow_expand(&rule->up.cr.match.flow, &flow); + rule->tag = rule_calculate_tag(&flow, &rule->up.cr.match.mask, + ofproto->tables[table_id].basis); + } complete_operation(rule); return 0; @@ -4745,15 +4746,6 @@ static void rule_modify_actions(struct rule *rule_) { struct rule_dpif *rule = rule_dpif_cast(rule_); - struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto); - enum ofperr error; - - error = ofpacts_check(rule->up.ofpacts, rule->up.ofpacts_len, - &rule->up.cr.flow, ofproto->max_ports); - if (error) { - ofoperation_complete(rule->up.pending, error); - return; - } complete_operation(rule); } @@ -4771,7 +4763,7 @@ send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet) struct flow flow; int error; - flow_extract(packet, 0, 0, 0, &flow); + flow_extract(packet, 0, NULL, 0, &flow); odp_port = vsp_realdev_to_vlandev(ofproto, ofport->odp_port, flow.vlan_tci); if (odp_port != ofport->odp_port) { @@ -4965,8 +4957,11 @@ compose_output_action__(struct action_xlate_ctx *ctx, uint16_t ofp_port, if (ofport) { struct priority_to_dscp *pdscp; - if (ofport->up.pp.config & OFPUTIL_PC_NO_FWD - || (check_stp && !stp_forward_in_state(ofport->stp_state))) { + if (ofport->up.pp.config & OFPUTIL_PC_NO_FWD) { + xlate_report(ctx, "OFPPC_NO_FWD set, skipping output"); + return; + } else if (check_stp && !stp_forward_in_state(ofport->stp_state)) { + xlate_report(ctx, "STP not in forwarding state, skipping output"); return; } @@ -5004,7 +4999,7 @@ compose_output_action(struct action_xlate_ctx *ctx, uint16_t ofp_port) static void xlate_table_action(struct action_xlate_ctx *ctx, - uint16_t in_port, uint8_t table_id) + uint16_t in_port, uint8_t table_id, bool may_packet_in) { if (ctx->recurse < MAX_RESUBMIT_RECURSION) { struct ofproto_dpif *ofproto = ctx->ofproto; @@ -5027,7 +5022,7 @@ xlate_table_action(struct action_xlate_ctx *ctx, ctx->tags |= (rule && rule->tag ? rule->tag : rule_calculate_tag(&ctx->flow, - &table->other_table->wc, + &table->other_table->mask, table->basis)); } } @@ -5040,6 +5035,17 @@ xlate_table_action(struct action_xlate_ctx *ctx, ctx->resubmit_hook(ctx, rule); } + if (rule == NULL && may_packet_in) { + /* TODO:XXX + * check if table configuration flags + * OFPTC_TABLE_MISS_CONTROLLER, default. + * OFPTC_TABLE_MISS_CONTINUE, + * OFPTC_TABLE_MISS_DROP + * When OF1.0, OFPTC_TABLE_MISS_CONTINUE is used. What to do? + */ + rule = rule_dpif_miss_rule(ofproto, &ctx->flow); + } + if (rule) { struct rule_dpif *old_rule = ctx->rule; @@ -5081,7 +5087,7 @@ xlate_ofpact_resubmit(struct action_xlate_ctx *ctx, table_id = ctx->table_id; } - xlate_table_action(ctx, in_port, table_id); + xlate_table_action(ctx, in_port, table_id, false); } static void @@ -5198,7 +5204,7 @@ compose_dec_ttl(struct action_xlate_ctx *ctx, struct ofpact_cnt_ids *ids) static void xlate_output_action(struct action_xlate_ctx *ctx, - uint16_t port, uint16_t max_len) + uint16_t port, uint16_t max_len, bool may_packet_in) { uint16_t prev_nf_output_iface = ctx->nf_output_iface; @@ -5209,7 +5215,7 @@ xlate_output_action(struct action_xlate_ctx *ctx, compose_output_action(ctx, ctx->flow.in_port); break; case OFPP_TABLE: - xlate_table_action(ctx, ctx->flow.in_port, 0); + xlate_table_action(ctx, ctx->flow.in_port, 0, may_packet_in); break; case OFPP_NORMAL: xlate_normal(ctx); @@ -5229,6 +5235,8 @@ xlate_output_action(struct action_xlate_ctx *ctx, default: if (port != ctx->flow.in_port) { compose_output_action(ctx, port); + } else { + xlate_report(ctx, "skipping output to input port"); } break; } @@ -5249,7 +5257,7 @@ xlate_output_reg_action(struct action_xlate_ctx *ctx, { uint64_t port = mf_get_subfield(&or->src, &ctx->flow); if (port <= UINT16_MAX) { - xlate_output_action(ctx, port, or->max_len); + xlate_output_action(ctx, port, or->max_len, false); } } @@ -5266,7 +5274,7 @@ xlate_enqueue_action(struct action_xlate_ctx *ctx, error = dpif_queue_to_priority(ctx->ofproto->dpif, queue_id, &priority); if (error) { /* Fall back to ordinary output action. */ - xlate_output_action(ctx, enqueue->port, 0); + xlate_output_action(ctx, enqueue->port, 0, false); return; } @@ -5361,7 +5369,7 @@ xlate_bundle_action(struct action_xlate_ctx *ctx, if (bundle->dst.field) { nxm_reg_load(&bundle->dst, port, &ctx->flow); } else { - xlate_output_action(ctx, port, 0); + xlate_output_action(ctx, port, 0, false); } } @@ -5459,7 +5467,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, switch (a->type) { case OFPACT_OUTPUT: xlate_output_action(ctx, ofpact_get_OUTPUT(a)->port, - ofpact_get_OUTPUT(a)->max_len); + ofpact_get_OUTPUT(a)->max_len, true); break; case OFPACT_CONTROLLER: @@ -5529,7 +5537,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_SET_TUNNEL: - ctx->flow.tun_id = htonll(ofpact_get_SET_TUNNEL(a)->tun_id); + ctx->flow.tunnel.tun_id = htonll(ofpact_get_SET_TUNNEL(a)->tun_id); break; case OFPACT_SET_QUEUE: @@ -5614,7 +5622,7 @@ action_xlate_ctx_init(struct action_xlate_ctx *ctx, ctx->ofproto = ofproto; ctx->flow = *flow; ctx->base_flow = ctx->flow; - ctx->base_flow.tun_id = 0; + memset(&ctx->base_flow.tunnel, 0, sizeof ctx->base_flow.tunnel); ctx->base_flow.vlan_tci = initial_tci; ctx->rule = rule; ctx->packet = packet; @@ -6004,7 +6012,7 @@ add_mirror_actions(struct action_xlate_ctx *ctx, const struct flow *orig_flow) m = ofproto->mirrors[mirror_mask_ffs(mirrors) - 1]; if (!vlan_is_mirrored(m, vlan)) { - mirrors &= mirrors - 1; + mirrors = zero_rightmost_1bit(mirrors); continue; } @@ -6034,7 +6042,7 @@ update_mirror_stats(struct ofproto_dpif *ofproto, mirror_mask_t mirrors, return; } - for (; mirrors; mirrors &= mirrors - 1) { + for (; mirrors; mirrors = zero_rightmost_1bit(mirrors)) { struct ofmirror *m; m = ofproto->mirrors[mirror_mask_ffs(mirrors) - 1]; @@ -6317,18 +6325,17 @@ xlate_normal(struct action_xlate_ctx *ctx) * a few more, but not all of the facets or even all of the facets that * resubmit to the table modified by MAC learning). */ -/* Calculates the tag to use for 'flow' and wildcards 'wc' when it is inserted +/* Calculates the tag to use for 'flow' and mask 'mask' when it is inserted * into an OpenFlow table with the given 'basis'. */ static tag_type -rule_calculate_tag(const struct flow *flow, const struct flow_wildcards *wc, +rule_calculate_tag(const struct flow *flow, const struct minimask *mask, uint32_t secret) { - if (flow_wildcards_is_catchall(wc)) { + if (minimask_is_catchall(mask)) { return 0; } else { - struct flow tag_flow = *flow; - flow_zero_wildcards(&tag_flow, wc); - return tag_create_deterministic(flow_hash(&tag_flow, secret)); + uint32_t hash = flow_hash_in_minimask(flow, mask, secret); + return tag_create_deterministic(hash); } } @@ -6430,40 +6437,32 @@ packet_out(struct ofproto *ofproto_, struct ofpbuf *packet, const struct ofpact *ofpacts, size_t ofpacts_len) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); - enum ofperr error; - - if (flow->in_port >= ofproto->max_ports && flow->in_port < OFPP_MAX) { - return OFPERR_NXBRC_BAD_IN_PORT; - } + struct odputil_keybuf keybuf; + struct dpif_flow_stats stats; - error = ofpacts_check(ofpacts, ofpacts_len, flow, ofproto->max_ports); - if (!error) { - struct odputil_keybuf keybuf; - struct dpif_flow_stats stats; + struct ofpbuf key; - struct ofpbuf key; + struct action_xlate_ctx ctx; + uint64_t odp_actions_stub[1024 / 8]; + struct ofpbuf odp_actions; - struct action_xlate_ctx ctx; - uint64_t odp_actions_stub[1024 / 8]; - struct ofpbuf odp_actions; + ofpbuf_use_stack(&key, &keybuf, sizeof keybuf); + odp_flow_key_from_flow(&key, flow); - ofpbuf_use_stack(&key, &keybuf, sizeof keybuf); - odp_flow_key_from_flow(&key, flow); + dpif_flow_stats_extract(flow, packet, time_msec(), &stats); - dpif_flow_stats_extract(flow, packet, time_msec(), &stats); + action_xlate_ctx_init(&ctx, ofproto, flow, flow->vlan_tci, NULL, + packet_get_tcp_flags(packet, flow), packet); + ctx.resubmit_stats = &stats; - action_xlate_ctx_init(&ctx, ofproto, flow, flow->vlan_tci, NULL, - packet_get_tcp_flags(packet, flow), packet); - ctx.resubmit_stats = &stats; + ofpbuf_use_stub(&odp_actions, + odp_actions_stub, sizeof odp_actions_stub); + xlate_actions(&ctx, ofpacts, ofpacts_len, &odp_actions); + dpif_execute(ofproto->dpif, key.data, key.size, + odp_actions.data, odp_actions.size, packet); + ofpbuf_uninit(&odp_actions); - ofpbuf_use_stub(&odp_actions, - odp_actions_stub, sizeof odp_actions_stub); - xlate_actions(&ctx, ofpacts, ofpacts_len, &odp_actions); - dpif_execute(ofproto->dpif, key.data, key.size, - odp_actions.data, odp_actions.size, packet); - ofpbuf_uninit(&odp_actions); - } - return error; + return 0; } /* NetFlow. */ @@ -6782,7 +6781,8 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[], ds_put_cstr(&result, s); free(s); - flow_extract(packet, priority, tun_id, in_port, &flow); + flow_extract(packet, priority, NULL, in_port, &flow); + flow.tunnel.tun_id = tun_id; initial_tci = flow.vlan_tci; } else { unixctl_command_reply_error(conn, "Bad command syntax");