X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=727f39605198dc388bdb24ea720b0ed4af797a53;hb=48c3de13bee26106d8e708600904f2b20bd08818;hp=5e8a1d8306459f675b0ae8b67ed63062a491d5d9;hpb=f1588b1fa1be46231ee079358e428dae74ff09cc;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 5e8a1d83..727f3960 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -24,6 +24,7 @@ #include #include #include +#include "byte-order.h" #include "classifier.h" #include "coverage.h" #include "discovery.h" @@ -58,9 +59,8 @@ #include "unixctl.h" #include "vconn.h" #include "vlog.h" -#include "xtoxll.h" -VLOG_DEFINE_THIS_MODULE(ofproto) +VLOG_DEFINE_THIS_MODULE(ofproto); #include "sflow_api.h" @@ -81,7 +81,7 @@ static void ofport_free(struct ofport *); static void hton_ofp_phy_port(struct ofp_phy_port *); static int xlate_actions(const union ofp_action *in, size_t n_in, - const flow_t *flow, struct ofproto *ofproto, + const struct flow *, struct ofproto *, const struct ofpbuf *packet, struct odp_actions *out, tag_type *tags, bool *may_set_up_flow, uint16_t *nf_output_iface); @@ -89,8 +89,7 @@ static int xlate_actions(const union ofp_action *in, size_t n_in, struct rule { struct cls_rule cr; - uint64_t flow_cookie; /* Controller-issued identifier. - (Kept in network-byte order.) */ + ovs_be64 flow_cookie; /* Controller-issued identifier. */ 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? */ @@ -155,7 +154,7 @@ rule_is_hidden(const struct rule *rule) static struct rule *rule_create(struct ofproto *, struct rule *super, const union ofp_action *, size_t n_actions, uint16_t idle_timeout, uint16_t hard_timeout, - uint64_t flow_cookie, bool send_flow_removed); + ovs_be64 flow_cookie, bool send_flow_removed); static void rule_free(struct rule *); static void rule_destroy(struct ofproto *, struct rule *); static struct rule *rule_from_cls_rule(const struct cls_rule *); @@ -1277,8 +1276,17 @@ ofproto_port_del(struct ofproto *ofproto, uint16_t odp_port) return error; } +/* Checks if 'ofproto' thinks 'odp_port' should be included in floods. Returns + * true if 'odp_port' exists and should be included, false otherwise. */ +bool +ofproto_port_is_floodable(struct ofproto *ofproto, uint16_t odp_port) +{ + struct ofport *ofport = get_port(ofproto, odp_port); + return ofport && !(ofport->opp.config & OFPPC_NO_FLOOD); +} + int -ofproto_send_packet(struct ofproto *p, const flow_t *flow, +ofproto_send_packet(struct ofproto *p, const struct flow *flow, const union ofp_action *actions, size_t n_actions, const struct ofpbuf *packet) { @@ -1298,8 +1306,8 @@ ofproto_send_packet(struct ofproto *p, const flow_t *flow, } void -ofproto_add_flow(struct ofproto *p, - const flow_t *flow, uint32_t wildcards, unsigned int priority, +ofproto_add_flow(struct ofproto *p, const struct flow *flow, + uint32_t wildcards, unsigned int priority, const union ofp_action *actions, size_t n_actions, int idle_timeout) { @@ -1312,7 +1320,7 @@ ofproto_add_flow(struct ofproto *p, } void -ofproto_delete_flow(struct ofproto *ofproto, const flow_t *flow, +ofproto_delete_flow(struct ofproto *ofproto, const struct flow *flow, uint32_t wildcards, unsigned int priority) { struct rule *rule; @@ -1363,6 +1371,8 @@ reinit_ports(struct ofproto *p) size_t n_odp_ports; size_t i; + COVERAGE_INC(ofproto_reinit_ports); + svec_init(&devnames); HMAP_FOR_EACH (ofport, hmap_node, &p->ports) { svec_add (&devnames, (char *) ofport->opp.name); @@ -1387,7 +1397,6 @@ make_ofport(const struct odp_port *odp_port) enum netdev_flags flags; struct ofport *ofport; struct netdev *netdev; - bool carrier; int error; memset(&netdev_options, 0, sizeof netdev_options); @@ -1415,8 +1424,7 @@ make_ofport(const struct odp_port *odp_port) netdev_get_flags(netdev, &flags); ofport->opp.config = flags & NETDEV_UP ? 0 : OFPPC_PORT_DOWN; - netdev_get_carrier(netdev, &carrier); - ofport->opp.state = carrier ? 0 : OFPPS_LINK_DOWN; + ofport->opp.state = netdev_get_carrier(netdev) ? 0 : OFPPS_LINK_DOWN; netdev_get_features(netdev, &ofport->opp.curr, &ofport->opp.advertised, @@ -1836,7 +1844,7 @@ static struct rule * rule_create(struct ofproto *ofproto, struct rule *super, const union ofp_action *actions, size_t n_actions, uint16_t idle_timeout, uint16_t hard_timeout, - uint64_t flow_cookie, bool send_flow_removed) + ovs_be64 flow_cookie, bool send_flow_removed) { struct rule *rule = xzalloc(sizeof *rule); rule->idle_timeout = idle_timeout; @@ -1897,7 +1905,7 @@ rule_destroy(struct ofproto *ofproto, struct rule *rule) } static bool -rule_has_out_port(const struct rule *rule, uint16_t out_port) +rule_has_out_port(const struct rule *rule, ovs_be16 out_port) { const union ofp_action *oa; struct actions_iterator i; @@ -1967,7 +1975,7 @@ execute_odp_actions(struct ofproto *ofproto, uint16_t in_port, * Takes ownership of 'packet'. */ static void rule_execute(struct ofproto *ofproto, struct rule *rule, - struct ofpbuf *packet, const flow_t *flow) + struct ofpbuf *packet, const struct flow *flow) { const union odp_action *actions; struct odp_flow_stats stats; @@ -2026,7 +2034,7 @@ rule_insert(struct ofproto *p, struct rule *rule, struct ofpbuf *packet, /* Send the packet and credit it to the rule. */ if (packet) { - flow_t flow; + struct flow flow; flow_extract(packet, 0, in_port, &flow); rule_execute(p, rule, packet, &flow); } @@ -2048,7 +2056,7 @@ rule_insert(struct ofproto *p, struct rule *rule, struct ofpbuf *packet, static struct rule * rule_create_subrule(struct ofproto *ofproto, struct rule *rule, - const flow_t *flow) + const struct flow *flow) { struct rule *subrule = rule_create(ofproto, rule, NULL, 0, rule->idle_timeout, rule->hard_timeout, @@ -2056,7 +2064,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; } @@ -2120,7 +2132,7 @@ do_put_flow(struct ofproto *ofproto, struct rule *rule, int flags, struct odp_flow_put *put) { memset(&put->flow.stats, 0, sizeof put->flow.stats); - put->flow.key = rule->cr.flow; + odp_flow_key_from_flow(&put->flow.key, &rule->cr.flow); put->flow.actions = rule->odp_actions; put->flow.n_actions = rule->n_odp_actions; put->flow.flags = 0; @@ -2224,7 +2236,7 @@ rule_uninstall(struct ofproto *p, struct rule *rule) if (rule->installed) { struct odp_flow odp_flow; - odp_flow.key = rule->cr.flow; + odp_flow_key_from_flow(&odp_flow.key, &rule->cr.flow); odp_flow.actions = NULL; odp_flow.n_actions = 0; odp_flow.flags = 0; @@ -2439,7 +2451,7 @@ add_controller_action(struct odp_actions *actions, uint16_t max_len) struct action_xlate_ctx { /* Input. */ - flow_t flow; /* Flow to which these actions correspond. */ + struct flow flow; /* Flow to which these actions correspond. */ int recurse; /* Recursion level, via xlate_table_action. */ struct ofproto *ofproto; const struct ofpbuf *packet; /* The packet corresponding to 'flow', or a @@ -2484,10 +2496,11 @@ add_output_action(struct action_xlate_ctx *ctx, uint16_t port) } static struct rule * -lookup_valid_rule(struct ofproto *ofproto, const flow_t *flow) +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. */ @@ -2577,6 +2590,7 @@ xlate_output_action__(struct action_xlate_ctx *ctx, case OFPP_FLOOD: flood_packets(ctx->ofproto, ctx->flow.in_port, OFPPC_NO_FLOOD, &ctx->nf_output_iface, ctx->out); + break; case OFPP_ALL: flood_packets(ctx->ofproto, ctx->flow.in_port, 0, &ctx->nf_output_iface, ctx->out); @@ -2757,13 +2771,17 @@ 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_VLAN_VID); - ctx->flow.dl_vlan = oa->vlan_vid.vlan_vid = ia->vlan_vid.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; break; case OFPAT_SET_VLAN_PCP: - oa = odp_actions_add(ctx->out, ODPAT_SET_VLAN_PCP); - ctx->flow.dl_vlan_pcp = oa->vlan_pcp.vlan_pcp = ia->vlan_pcp.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; break; case OFPAT_STRIP_VLAN: @@ -2830,7 +2848,7 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, static int xlate_actions(const union ofp_action *in, size_t n_in, - const flow_t *flow, struct ofproto *ofproto, + const struct flow *flow, struct ofproto *ofproto, const struct ofpbuf *packet, struct odp_actions *out, tag_type *tags, bool *may_set_up_flow, uint16_t *nf_output_iface) @@ -2900,9 +2918,9 @@ handle_packet_out(struct ofproto *p, struct ofconn *ofconn, struct ofp_packet_out *opo; struct ofpbuf payload, *buffer; struct odp_actions actions; + struct flow flow; int n_actions; uint16_t in_port; - flow_t flow; int error; error = reject_slave_controller(ofconn, oh); @@ -2931,14 +2949,12 @@ handle_packet_out(struct ofproto *p, struct ofconn *ofconn, flow_extract(&payload, 0, ofp_port_to_odp_port(ntohs(opo->in_port)), &flow); error = xlate_actions((const union ofp_action *) opo->actions, n_actions, &flow, p, &payload, &actions, NULL, NULL, NULL); - if (error) { - return error; + if (!error) { + dpif_execute(p->dpif, actions.actions, actions.n_actions, &payload); } - - dpif_execute(p->dpif, actions.actions, actions.n_actions, &payload); ofpbuf_delete(buffer); - return 0; + return error; } static void @@ -2999,7 +3015,7 @@ handle_port_mod(struct ofproto *p, struct ofconn *ofconn, } static struct ofpbuf * -make_stats_reply(uint32_t xid, uint16_t type, size_t body_len) +make_stats_reply(ovs_be32 xid, ovs_be16 type, size_t body_len) { struct ofp_stats_reply *osr; struct ofpbuf *msg; @@ -3165,7 +3181,7 @@ handle_port_stats_request(struct ofproto *p, struct ofconn *ofconn, struct flow_stats_cbdata { struct ofproto *ofproto; struct ofconn *ofconn; - uint16_t out_port; + ovs_be16 out_port; struct ofpbuf *msg; }; @@ -3199,12 +3215,12 @@ query_stats(struct ofproto *p, struct rule *rule, if (rule->cr.wc.wildcards) { size_t i = 0; LIST_FOR_EACH (subrule, list, &rule->list) { - odp_flows[i++].key = subrule->cr.flow; + odp_flow_key_from_flow(&odp_flows[i++].key, &subrule->cr.flow); packet_count += subrule->packet_count; byte_count += subrule->byte_count; } } else { - odp_flows[0].key = rule->cr.flow; + odp_flow_key_from_flow(&odp_flows[0].key, &rule->cr.flow); } /* Fetch up-to-date statistics from the datapath and add them in. */ @@ -3332,6 +3348,8 @@ flow_stats_ds_cb(struct cls_rule *rule_, void *cbdata_) ofp_print_match(results, &match, true); if (act_len > 0) { ofp_print_actions(results, &rule->actions->header, act_len); + } else { + ds_put_cstr(results, "drop"); } ds_put_cstr(results, "\n"); } @@ -3358,7 +3376,7 @@ ofproto_get_all_flows(struct ofproto *p, struct ds *results) struct aggregate_stats_cbdata { struct ofproto *ofproto; - uint16_t out_port; + ovs_be16 out_port; uint64_t packet_count; uint64_t byte_count; uint32_t n_flows; @@ -3600,7 +3618,7 @@ add_flow(struct ofproto *p, struct ofconn *ofconn, int error; if (ofm->flags & htons(OFPFF_CHECK_OVERLAP)) { - flow_t flow; + struct flow flow; uint32_t wildcards; flow_from_match(&ofm->match, p->tun_id_from_cookie, ofm->cookie, @@ -3635,7 +3653,7 @@ static struct rule * find_flow_strict(struct ofproto *p, const struct ofp_flow_mod *ofm) { uint32_t wildcards; - flow_t flow; + struct flow flow; flow_from_match(&ofm->match, p->tun_id_from_cookie, ofm->cookie, &flow, &wildcards); @@ -3650,7 +3668,7 @@ send_buffered_packet(struct ofproto *ofproto, struct ofconn *ofconn, { struct ofpbuf *packet; uint16_t in_port; - flow_t flow; + struct flow flow; int error; if (ofm->buffer_id == htonl(UINT32_MAX)) { @@ -3785,11 +3803,11 @@ modify_flow(struct ofproto *p, const struct ofp_flow_mod *ofm, struct delete_flows_cbdata { struct ofproto *ofproto; - uint16_t out_port; + ovs_be16 out_port; }; static void delete_flows_cb(struct cls_rule *, void *cbdata_); -static void delete_flow(struct ofproto *, struct rule *, uint16_t out_port); +static void delete_flow(struct ofproto *, struct rule *, ovs_be16 out_port); /* Implements OFPFC_DELETE. */ static void @@ -3837,7 +3855,7 @@ delete_flows_cb(struct cls_rule *rule_, void *cbdata_) * 'out_port' is htons(OFPP_NONE) or if 'rule' actually outputs to the * specified 'out_port'. */ static void -delete_flow(struct ofproto *p, struct rule *rule, uint16_t out_port) +delete_flow(struct ofproto *p, struct rule *rule, ovs_be16 out_port) { if (rule_is_hidden(rule)) { return; @@ -4120,7 +4138,7 @@ handle_odp_miss_msg(struct ofproto *p, struct ofpbuf *packet) struct odp_msg *msg = packet->data; struct rule *rule; struct ofpbuf payload; - flow_t flow; + struct flow flow; payload.data = msg + 1; payload.size = msg->length - sizeof *msg; @@ -4282,9 +4300,12 @@ ofproto_update_used(struct ofproto *p) for (i = 0; i < n_flows; i++) { struct odp_flow *f = &flows[i]; struct rule *rule; + struct flow flow; + + odp_flow_key_to_flow(&f->key, &flow); rule = rule_from_cls_rule( - classifier_find_rule_exactly(&p->cls, &f->key, 0, UINT16_MAX)); + classifier_find_rule_exactly(&p->cls, &flow, 0, UINT16_MAX)); if (rule && rule->installed) { update_time(p, rule, &f->stats); @@ -4405,7 +4426,7 @@ rule_active_timeout(struct ofproto *ofproto, struct rule *rule) * ofproto_update_used() zeroed TCP flags. */ memset(&odp_flow, 0, sizeof odp_flow); if (rule->installed) { - odp_flow.key = rule->cr.flow; + odp_flow_key_from_flow(&odp_flow.key, &rule->cr.flow); odp_flow.flags = ODPFF_ZERO_TCP_FLAGS; dpif_flow_get(ofproto->dpif, &odp_flow); @@ -4515,12 +4536,13 @@ revalidate_cb(struct cls_rule *sub_, void *cbdata_) static bool revalidate_rule(struct ofproto *p, struct rule *rule) { - const flow_t *flow = &rule->cr.flow; + const struct flow *flow = &rule->cr.flow; 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; @@ -4775,7 +4797,7 @@ pick_fallback_dpid(void) } static bool -default_normal_ofhook_cb(const flow_t *flow, const struct ofpbuf *packet, +default_normal_ofhook_cb(const struct flow *flow, const struct ofpbuf *packet, struct odp_actions *actions, tag_type *tags, uint16_t *nf_output_iface, void *ofproto_) {