diff --git a/lib/learn.c b/lib/learn.c index 90991b165..911dd04f8 100644 --- a/lib/learn.c +++ b/lib/learn.c @@ -324,6 +324,7 @@ learn_execute(const struct ofpact_learn *learn, const struct flow *flow, fm->flags = learn->flags; fm->ofpacts = NULL; fm->ofpacts_len = 0; + fm->delete_reason = OFPRR_DELETE; if (learn->fin_idle_timeout || learn->fin_hard_timeout) { struct ofpact_fin_timeout *oft; diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index c759f036b..93bdbea12 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1289,6 +1289,7 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string, fm->out_port = OFPP_ANY; fm->flags = 0; fm->out_group = OFPG11_ANY; + fm->delete_reason = OFPRR_DELETE; if (fields & F_ACTIONS) { act_str = strstr(string, "action"); if (!act_str) { diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 09e44383e..03fc97861 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -1596,6 +1596,9 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm, struct ofpbuf b; enum ofpraw raw; + /* Ignored for non-delete actions */ + fm->delete_reason = OFPRR_DELETE; + ofpbuf_use_const(&b, oh, ntohs(oh->length)); raw = ofpraw_pull_assert(&b); if (raw == OFPRAW_OFPT11_FLOW_MOD) { diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 552b00634..878bcf84f 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -307,6 +307,9 @@ struct ofputil_flow_mod { enum ofputil_flow_mod_flags flags; struct ofpact *ofpacts; /* Series of "struct ofpact"s. */ size_t ofpacts_len; /* Length of ofpacts, in bytes. */ + + /* Reason for delete; ignored for non-delete commands */ + enum ofp_flow_removed_reason delete_reason; }; enum ofperr ofputil_decode_flow_mod(struct ofputil_flow_mod *, diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 4615f7ed8..a49685cb8 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1868,6 +1868,7 @@ flow_mod_init(struct ofputil_flow_mod *fm, fm->flags = 0; fm->ofpacts = CONST_CAST(struct ofpact *, ofpacts); fm->ofpacts_len = ofpacts_len; + fm->delete_reason = OFPRR_DELETE; } static int @@ -4338,7 +4339,8 @@ delete_flows_loose(struct ofproto *ofproto, struct ofconn *ofconn, rule_criteria_destroy(&criteria); if (!error && rules.n > 0) { - error = delete_flows__(ofproto, ofconn, request, &rules, OFPRR_DELETE); + error = delete_flows__(ofproto, ofconn, request, &rules, + fm->delete_reason); } rule_collection_destroy(&rules); @@ -4363,7 +4365,8 @@ delete_flow_strict(struct ofproto *ofproto, struct ofconn *ofconn, rule_criteria_destroy(&criteria); if (!error && rules.n > 0) { - error = delete_flows__(ofproto, ofconn, request, &rules, OFPRR_DELETE); + error = delete_flows__(ofproto, ofconn, request, &rules, + fm->delete_reason); } rule_collection_destroy(&rules); @@ -5705,6 +5708,7 @@ delete_group__(struct ofproto *ofproto, struct ofgroup *ofgroup) /* Delete all flow entries containing this group in a group action */ match_init_catchall(&match); flow_mod_init(&fm, &match, 0, NULL, 0, OFPFC_DELETE); + fm.delete_reason = OFPRR_GROUP_DELETE; fm.out_group = ofgroup->group_id; handle_flow_mod__(ofproto, NULL, &fm, NULL); diff --git a/tests/ofproto.at b/tests/ofproto.at index 6f6160e02..34cca3732 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -1818,6 +1818,15 @@ udp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=00:26:b9:8c:b0:f9,dl_dst=00:25:8 if test X"$1" = X"OFPRR_DELETE"; then shift; echo >>expout "OFPT_FLOW_REMOVED (OF1.3): reason=delete table_id=0" fi + + # OFPT_FLOW_REMOVED, OFPRR_GROUP_DELETE + ovs-ofctl -O OpenFlow13 add-group br0 group_id=1234,type=all,bucket=output:10 + ovs-ofctl -O OpenFlow13 add-flow br0 send_flow_rem,actions=group:1234 + ovs-ofctl -O OpenFlow13 --strict del-groups br0 group_id=1234 + if test X"$1" = X"OFPRR_DELETE"; then shift; + echo >>expout "OFPT_FLOW_REMOVED (OF1.3): reason=gropu_delete table_id=0" + fi + AT_FAIL_IF([test X"$1" != X]) ovs-appctl -t ovs-ofctl ofctl/barrier diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index ea72be0da..93f138211 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -2530,6 +2530,7 @@ fte_make_flow_mod(const struct fte *fte, int index, uint16_t command, fm.ofpacts = NULL; fm.ofpacts_len = 0; } + fm.delete_reason = OFPRR_DELETE; ofm = ofputil_encode_flow_mod(&fm, protocol); list_push_back(packets, &ofm->list_node);