X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=cbd8928158a96392b3292f57d7a5335525a6740b;hb=0ff2282245a87f253843bf357988d7230139888f;hp=cb349aed95e4abc7d82432f3af5eb18f9bf1acdc;hpb=a9a2da38941ea4d312559543a3fb813d8fe7fd4e;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index cb349aed..cbd89281 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -430,7 +430,7 @@ ofproto_set_flow_eviction_threshold(struct ofproto *ofproto, unsigned threshold) } } -/* If forward_bpdu is true, the NORMAL action will forward frames with +/* If forward_bpdu is true, the NORMAL action will forward frames with * reserved (e.g. STP) destination Ethernet addresses. if forward_bpdu is false, * the NORMAL action will drop these frames. */ void @@ -442,7 +442,7 @@ ofproto_set_forward_bpdu(struct ofproto *ofproto, bool forward_bpdu) if (ofproto->ofproto_class->forward_bpdu_changed) { ofproto->ofproto_class->forward_bpdu_changed(ofproto); } - } + } } void @@ -1899,7 +1899,7 @@ handle_flow_stats_request(struct ofconn *ofconn, const struct ofp_stats_msg *osm) { struct ofproto *ofproto = ofconn_get_ofproto(ofconn); - struct flow_stats_request fsr; + struct ofputil_flow_stats_request fsr; struct list replies; struct list rules; struct rule *rule; @@ -2003,12 +2003,31 @@ ofproto_port_get_cfm_fault(const struct ofproto *ofproto, uint16_t ofp_port) : -1); } +/* Gets the MPIDs of the remote maintenance points broadcasting to 'ofp_port' + * within 'ofproto'. Populates 'rmps' with an array of MPIDs owned by + * 'ofproto', and 'n_rmps' with the number of MPIDs in 'rmps'. Returns a + * number less than 0 if CFM is not enabled on 'ofp_port'. */ +int +ofproto_port_get_cfm_remote_mpids(const struct ofproto *ofproto, + uint16_t ofp_port, const uint64_t **rmps, + size_t *n_rmps) +{ + struct ofport *ofport = ofproto_get_port(ofproto, ofp_port); + + *rmps = NULL; + *n_rmps = 0; + return (ofport && ofproto->ofproto_class->get_cfm_remote_mpids + ? ofproto->ofproto_class->get_cfm_remote_mpids(ofport, rmps, + n_rmps) + : -1); +} + static int handle_aggregate_stats_request(struct ofconn *ofconn, const struct ofp_stats_msg *osm) { struct ofproto *ofproto = ofconn_get_ofproto(ofconn); - struct flow_stats_request request; + struct ofputil_flow_stats_request request; struct ofputil_aggregate_stats stats; bool unknown_packets, unknown_bytes; struct ofpbuf *reply; @@ -2828,8 +2847,29 @@ ofoperation_destroy(struct ofoperation *op) * indicate success or an OpenFlow error code (constructed with * e.g. ofp_mkerr()). * - * If 'op' is a "delete flow" operation, 'error' must be 0. That is, flow - * deletions are not allowed to fail. + * If 'error' is 0, indicating success, the operation will be committed + * permanently to the flow table. There is one interesting subcase: + * + * - If 'op' is an "add flow" operation that is replacing an existing rule in + * the flow table (the "victim" rule) by a new one, then the caller must + * have uninitialized any derived state in the victim rule, as in step 5 in + * the "Life Cycle" in ofproto/ofproto-provider.h. ofoperation_complete() + * performs steps 6 and 7 for the victim rule, most notably by calling its + * ->rule_dealloc() function. + * + * If 'error' is nonzero, then generally the operation will be rolled back: + * + * - If 'op' is an "add flow" operation, ofproto removes the new rule or + * restores the original rule. The caller must have uninitialized any + * derived state in the new rule, as in step 5 of in the "Life Cycle" in + * ofproto/ofproto-provider.h. ofoperation_complete() performs steps 6 and + * and 7 for the new rule, calling its ->rule_dealloc() function. + * + * - If 'op' is a "modify flow" operation, ofproto restores the original + * actions. + * + * - 'op' must not be a "delete flow" operation. Removing a rule is not + * allowed to fail. It must always succeed. * * Please see the large comment in ofproto/ofproto-provider.h titled * "Asynchronous Operation Support" for more information. */