X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=c2c48e12bccbb55df556fef8a7d65ba86330dc3b;hb=611d30ceb68c8542d11acee8248f66f9485505e9;hp=bf4a51fcafa6a98cb326c63c55f830fbe3115379;hpb=844dff325b1f6a6f520fce9242c85162275ab7ad;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index bf4a51fc..c2c48e12 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1515,7 +1515,10 @@ send_port_status(struct ofproto *p, const struct ofport *ofport, struct ofp_port_status *ops; struct ofpbuf *b; - if (!ofconn_receives_async_msgs(ofconn)) { + /* Primary controllers, even slaves, should always get port status + updates. Otherwise obey ofconn_receives_async_msgs(). */ + if (ofconn->type != OFCONN_PRIMARY + && !ofconn_receives_async_msgs(ofconn)) { continue; } @@ -1618,9 +1621,9 @@ update_port(struct ofproto *p, const char *devname) return; } else if (old_ofport && new_ofport) { /* Most of the 'config' bits are OpenFlow soft state, but - * OFPPC_PORT_DOWN is maintained the kernel. So transfer the OpenFlow - * bits from old_ofport. (make_ofport() only sets OFPPC_PORT_DOWN and - * leaves the other bits 0.) */ + * OFPPC_PORT_DOWN is maintained by the kernel. So transfer the + * OpenFlow bits from old_ofport. (make_ofport() only sets + * OFPPC_PORT_DOWN and leaves the other bits 0.) */ new_ofport->opp.config |= old_ofport->opp.config & ~OFPPC_PORT_DOWN; if (ofport_equal(old_ofport, new_ofport)) { @@ -2785,15 +2788,12 @@ xlate_set_queue_action(struct action_xlate_ctx *ctx, 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)) { + ovs_be16 tci = ctx->flow.vlan_tci; + if (!(tci & htons(VLAN_CFI))) { 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)); + oa->dl_tci.tci = tci & ~htons(VLAN_CFI); } } @@ -2801,12 +2801,11 @@ 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; + ovs_be16 old_tci = ctx->flow.vlan_tci; nxm_execute_reg_move(narm, &ctx->flow); - if (ctx->flow.dl_vlan != old_vlan || ctx->flow.dl_vlan_pcp != old_pcp) { + if (ctx->flow.vlan_tci != old_tci) { xlate_set_dl_tci(ctx); } } @@ -2896,18 +2895,20 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, break; case OFPAT_SET_VLAN_VID: - ctx->flow.dl_vlan = ia->vlan_vid.vlan_vid; + ctx->flow.vlan_tci &= ~htons(VLAN_VID_MASK); + ctx->flow.vlan_tci |= ia->vlan_vid.vlan_vid | htons(VLAN_CFI); xlate_set_dl_tci(ctx); break; case OFPAT_SET_VLAN_PCP: - ctx->flow.dl_vlan_pcp = ia->vlan_pcp.vlan_pcp; + ctx->flow.vlan_tci &= ~htons(VLAN_PCP_MASK); + ctx->flow.vlan_tci |= htons( + (ia->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT) | VLAN_CFI); xlate_set_dl_tci(ctx); break; case OFPAT_STRIP_VLAN: - ctx->flow.dl_vlan = htons(OFP_VLAN_NONE); - ctx->flow.dl_vlan_pcp = 0; + ctx->flow.vlan_tci = htons(0); xlate_set_dl_tci(ctx); break; @@ -3412,7 +3413,7 @@ put_ofp_flow_stats(struct ofconn *ofconn, struct rule *rule, ofs->length = htons(len); ofs->table_id = 0; ofs->pad = 0; - cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofs->match); + ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofs->match); calc_flow_duration(rule->created, &ofs->duration_sec, &ofs->duration_nsec); ofs->cookie = rule->flow_cookie; ofs->priority = htons(rule->cr.priority); @@ -3451,7 +3452,8 @@ handle_flow_stats_request(struct ofconn *ofconn, struct cls_rule target; struct rule *rule; - cls_rule_from_match(&fsr->match, 0, NXFF_OPENFLOW10, 0, &target); + ofputil_cls_rule_from_match(&fsr->match, 0, NXFF_OPENFLOW10, 0, + &target); cls_cursor_init(&cursor, &ofconn->ofproto->cls, &target); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { put_ofp_flow_stats(ofconn, rule, fsr->out_port, &reply); @@ -3543,7 +3545,7 @@ flow_stats_ds(struct ofproto *ofproto, struct rule *rule, struct ds *results) size_t act_len = sizeof *rule->actions * rule->n_actions; query_stats(ofproto, rule, &packet_count, &byte_count); - cls_rule_to_match(&rule->cr, NXFF_OPENFLOW10, &match); + ofputil_cls_rule_to_match(&rule->cr, NXFF_OPENFLOW10, &match); ds_put_format(results, "duration=%llds, ", (time_msec() - rule->created) / 1000); @@ -3624,7 +3626,8 @@ handle_aggregate_stats_request(struct ofconn *ofconn, } request = (struct ofp_aggregate_stats_request *) osr->body; - cls_rule_from_match(&request->match, 0, NXFF_OPENFLOW10, 0, &target); + ofputil_cls_rule_from_match(&request->match, 0, NXFF_OPENFLOW10, 0, + &target); msg = start_ofp_stats_reply(osr, sizeof *reply); reply = append_ofp_stats_reply(sizeof *reply, ofconn, &msg); @@ -4183,8 +4186,8 @@ handle_ofpt_flow_mod(struct ofconn *ofconn, struct ofp_header *oh) } /* Translate the message. */ - cls_rule_from_match(&ofm->match, ntohs(ofm->priority), ofconn->flow_format, - ofm->cookie, &fm.cr); + ofputil_cls_rule_from_match(&ofm->match, ntohs(ofm->priority), + ofconn->flow_format, ofm->cookie, &fm.cr); fm.cookie = ofm->cookie; fm.command = ntohs(ofm->command); fm.idle_timeout = ntohs(ofm->idle_timeout); @@ -4459,6 +4462,11 @@ handle_odp_miss_msg(struct ofproto *p, struct ofpbuf *packet) payload.size = msg->length - sizeof *msg; flow_extract(&payload, msg->arg, msg->port, &flow); + packet->l2 = payload.l2; + packet->l3 = payload.l3; + packet->l4 = payload.l4; + packet->l7 = payload.l7; + /* Check with in-band control to see if this packet should be sent * to the local port regardless of the flow table. */ if (in_band_msg_in_hook(p->in_band, &flow, &payload)) { @@ -4813,7 +4821,7 @@ compose_ofp_flow_removed(struct ofconn *ofconn, const struct rule *rule, struct ofpbuf *buf; ofr = make_openflow(sizeof *ofr, OFPT_FLOW_REMOVED, &buf); - cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match); + ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match); ofr->cookie = rule->flow_cookie; ofr->priority = htons(rule->cr.priority); ofr->reason = reason;