X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=3da2a7444d0af08ac07e58a764a95b5bd6e17df4;hb=a23aab1fc2f66b63ba9b7e4b9c9a8f6d58c367d0;hp=cd1bc8a2bf1e590ac47fc5249616080b3717f686;hpb=8054fc48f9a620aa07714a70f6ec301e0d8ec4ee;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index cd1bc8a2..3da2a744 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -64,12 +64,6 @@ VLOG_DEFINE_THIS_MODULE(ofproto); #include "sflow_api.h" -enum { - TABLEID_HASH = 0, - TABLEID_CLASSIFIER = 1 -}; - - struct ofport { struct hmap_node hmap_node; /* In struct ofproto's "ports" hmap. */ struct netdev *netdev; @@ -1323,11 +1317,12 @@ void ofproto_delete_flow(struct ofproto *ofproto, const struct flow *flow, uint32_t wildcards, unsigned int priority) { + struct cls_rule target; struct rule *rule; + cls_rule_from_flow(flow, wildcards, priority, &target); rule = rule_from_cls_rule(classifier_find_rule_exactly(&ofproto->cls, - flow, wildcards, - priority)); + &target)); if (rule) { rule_remove(ofproto, rule); } @@ -2064,7 +2059,11 @@ rule_create_subrule(struct ofproto *ofproto, struct rule *rule, COVERAGE_INC(ofproto_subrule_create); cls_rule_from_flow(flow, 0, (rule->cr.priority <= UINT16_MAX ? UINT16_MAX : rule->cr.priority), &subrule->cr); - classifier_insert_exact(&ofproto->cls, &subrule->cr); + + if (classifier_insert(&ofproto->cls, &subrule->cr)) { + /* Can't happen, */ + NOT_REACHED(); + } return subrule; } @@ -2298,34 +2297,15 @@ queue_tx(struct ofpbuf *msg, const struct ofconn *ofconn, } } -static void -send_error(const struct ofconn *ofconn, const struct ofp_header *oh, - int error, const void *data, size_t len) -{ - struct ofpbuf *buf; - struct ofp_error_msg *oem; - - if (!(error >> 16)) { - VLOG_WARN_RL(&rl, "not sending bad error code %d to controller", - error); - return; - } - - COVERAGE_INC(ofproto_error); - oem = make_openflow_xid(len + sizeof *oem, OFPT_ERROR, - oh ? oh->xid : 0, &buf); - oem->type = htons((unsigned int) error >> 16); - oem->code = htons(error & 0xffff); - memcpy(oem->data, data, len); - queue_tx(buf, ofconn, ofconn->reply_counter); -} - static void send_error_oh(const struct ofconn *ofconn, const struct ofp_header *oh, int error) { - size_t oh_length = ntohs(oh->length); - send_error(ofconn, oh, error, oh, MIN(oh_length, 64)); + struct ofpbuf *buf = make_ofp_error_msg(error, oh); + if (buf) { + COVERAGE_INC(ofproto_error); + queue_tx(buf, ofconn, ofconn->reply_counter); + } } static void @@ -2495,7 +2475,8 @@ static struct rule * lookup_valid_rule(struct ofproto *ofproto, const struct flow *flow) { struct rule *rule; - rule = rule_from_cls_rule(classifier_lookup(&ofproto->cls, flow)); + rule = rule_from_cls_rule(classifier_lookup(&ofproto->cls, flow, + CLS_INC_ALL)); /* The rule we found might not be valid, since we could be in need of * revalidation. If it is not valid, don't return it. */ @@ -3068,44 +3049,27 @@ handle_table_stats_request(struct ofproto *p, struct ofconn *ofconn, { struct ofp_table_stats *ots; struct ofpbuf *msg; - struct odp_stats dpstats; - int n_exact, n_subrules, n_wild; struct rule *rule; + int n_rules; msg = start_stats_reply(request, sizeof *ots * 2); - /* Count rules of various kinds. */ - n_subrules = 0; + /* Count rules other than subrules. */ + n_rules = classifier_count(&p->cls); CLASSIFIER_FOR_EACH_EXACT_RULE (rule, cr, &p->cls) { if (rule->super) { - n_subrules++; + n_rules--; } } - n_exact = classifier_count_exact(&p->cls) - n_subrules; - n_wild = classifier_count(&p->cls) - classifier_count_exact(&p->cls); - - /* Hash table. */ - dpif_get_dp_stats(p->dpif, &dpstats); - ots = append_stats_reply(sizeof *ots, ofconn, &msg); - memset(ots, 0, sizeof *ots); - ots->table_id = TABLEID_HASH; - strcpy(ots->name, "hash"); - ots->wildcards = htonl(0); - ots->max_entries = htonl(dpstats.max_capacity); - ots->active_count = htonl(n_exact); - ots->lookup_count = htonll(dpstats.n_frags + dpstats.n_hit + - dpstats.n_missed); - ots->matched_count = htonll(dpstats.n_hit); /* XXX */ /* Classifier table. */ ots = append_stats_reply(sizeof *ots, ofconn, &msg); memset(ots, 0, sizeof *ots); - ots->table_id = TABLEID_CLASSIFIER; strcpy(ots->name, "classifier"); ots->wildcards = p->tun_id_from_cookie ? htonl(OVSFW_ALL) : htonl(OFPFW_ALL); - ots->max_entries = htonl(65536); - ots->active_count = htonl(n_wild); + ots->max_entries = htonl(1024 * 1024); /* An arbitrary big number. */ + ots->active_count = htonl(n_rules); ots->lookup_count = htonll(0); /* XXX */ ots->matched_count = htonll(0); /* XXX */ @@ -3257,7 +3221,7 @@ flow_stats_cb(struct cls_rule *rule_, void *cbdata_) ofs = append_stats_reply(len, cbdata->ofconn, &cbdata->msg); ofs->length = htons(len); - ofs->table_id = rule->cr.wc.wildcards ? TABLEID_CLASSIFIER : TABLEID_HASH; + ofs->table_id = 0; ofs->pad = 0; flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, cbdata->ofproto->tun_id_from_cookie, &ofs->match); @@ -3278,10 +3242,7 @@ flow_stats_cb(struct cls_rule *rule_, void *cbdata_) static int table_id_to_include(uint8_t table_id) { - return (table_id == TABLEID_HASH ? CLS_INC_EXACT - : table_id == TABLEID_CLASSIFIER ? CLS_INC_WILD - : table_id == 0xff ? CLS_INC_ALL - : 0); + return table_id == 0 || table_id == 0xff ? CLS_INC_ALL : 0; } static int @@ -3613,13 +3574,11 @@ add_flow(struct ofproto *p, struct ofconn *ofconn, int error; if (ofm->flags & htons(OFPFF_CHECK_OVERLAP)) { - struct flow flow; - uint32_t wildcards; + struct cls_rule cr; - flow_from_match(&ofm->match, p->tun_id_from_cookie, ofm->cookie, - &flow, &wildcards); - if (classifier_rule_overlaps(&p->cls, &flow, wildcards, - ntohs(ofm->priority))) { + cls_rule_from_match(&ofm->match, ntohs(ofm->priority), + p->tun_id_from_cookie, ofm->cookie, &cr); + if (classifier_rule_overlaps(&p->cls, &cr)) { return ofp_mkerr(OFPET_FLOW_MOD_FAILED, OFPFMFC_OVERLAP); } } @@ -3647,14 +3606,11 @@ add_flow(struct ofproto *p, struct ofconn *ofconn, static struct rule * find_flow_strict(struct ofproto *p, const struct ofp_flow_mod *ofm) { - uint32_t wildcards; - struct flow flow; + struct cls_rule target; - flow_from_match(&ofm->match, p->tun_id_from_cookie, ofm->cookie, - &flow, &wildcards); - return rule_from_cls_rule(classifier_find_rule_exactly( - &p->cls, &flow, wildcards, - ntohs(ofm->priority))); + cls_rule_from_match(&ofm->match, ntohs(ofm->priority), + p->tun_id_from_cookie, ofm->cookie, &target); + return rule_from_cls_rule(classifier_find_rule_exactly(&p->cls, &target)); } static int @@ -4294,13 +4250,15 @@ ofproto_update_used(struct ofproto *p) for (i = 0; i < n_flows; i++) { struct odp_flow *f = &flows[i]; + struct cls_rule target; struct rule *rule; struct flow flow; odp_flow_key_to_flow(&f->key, &flow); + cls_rule_from_flow(&flow, 0, UINT16_MAX, &target); - rule = rule_from_cls_rule( - classifier_find_rule_exactly(&p->cls, &flow, 0, UINT16_MAX)); + rule = rule_from_cls_rule(classifier_find_rule_exactly(&p->cls, + &target)); if (rule && rule->installed) { update_time(p, rule, &f->stats); @@ -4536,7 +4494,8 @@ revalidate_rule(struct ofproto *p, struct rule *rule) COVERAGE_INC(ofproto_revalidate_rule); if (rule->super) { struct rule *super; - super = rule_from_cls_rule(classifier_lookup_wild(&p->cls, flow)); + super = rule_from_cls_rule(classifier_lookup(&p->cls, flow, + CLS_INC_WILD)); if (!super) { rule_remove(p, rule); return false;