ofproto: Fix memory leak in rule_actions_unref().
[sliver-openvswitch.git] / ofproto / ofproto.c
index 0ceb85f..f305710 100644 (file)
@@ -2487,6 +2487,7 @@ rule_actions_unref(struct rule_actions *actions)
 
         atomic_sub(&actions->ref_count, 1, &orig);
         if (orig == 1) {
+            free(actions->ofpacts);
             free(actions);
         } else {
             ovs_assert(orig != 0);
@@ -2930,8 +2931,8 @@ handle_table_stats_request(struct ofconn *ofconn,
         ots[i].apply_actions = htonl(OFPAT11_OUTPUT);
         ots[i].write_setfields = htonll(OFPXMT13_MASK);
         ots[i].apply_setfields = htonll(OFPXMT13_MASK);
-        ots[i].metadata_match = htonll(UINT64_MAX);
-        ots[i].metadata_write = htonll(UINT64_MAX);
+        ots[i].metadata_match = OVS_BE64_MAX;
+        ots[i].metadata_write = OVS_BE64_MAX;
         ots[i].instructions = htonl(OFPIT11_ALL);
         ots[i].config = htonl(OFPTC11_TABLE_MISS_MASK);
         ots[i].max_entries = htonl(1000000); /* An arbitrary big number. */
@@ -3239,7 +3240,13 @@ collect_rule(struct rule *rule, const struct rule_criteria *c,
              struct rule_collection *rules)
     OVS_REQUIRES(ofproto_mutex)
 {
-    if (ofproto_rule_is_hidden(rule)) {
+    /* We ordinarily want to skip hidden rules, but there has to be a way for
+     * code internal to OVS to modify and delete them, so if the criteria
+     * specify a priority that can only be for a hidden flow, then allow hidden
+     * rules to be selected.  (This doesn't allow OpenFlow clients to meddle
+     * with hidden flows because OpenFlow uses only a 16-bit field to specify
+     * priority.) */
+    if (ofproto_rule_is_hidden(rule) && c->cr.priority <= UINT16_MAX) {
         return 0;
     } else if (rule->pending) {
         return OFPROTO_POSTPONE;
@@ -3278,7 +3285,7 @@ collect_rules_loose(struct ofproto *ofproto,
         goto exit;
     }
 
-    if (criteria->cookie_mask == htonll(UINT64_MAX)) {
+    if (criteria->cookie_mask == OVS_BE64_MAX) {
         struct rule *rule;
 
         HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node,
@@ -3339,7 +3346,7 @@ collect_rules_strict(struct ofproto *ofproto,
         goto exit;
     }
 
-    if (criteria->cookie_mask == htonll(UINT64_MAX)) {
+    if (criteria->cookie_mask == OVS_BE64_MAX) {
         struct rule *rule;
 
         HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node,
@@ -3982,7 +3989,7 @@ modify_flows__(struct ofproto *ofproto, struct ofconn *ofconn,
 
         op = ofoperation_create(group, rule, type, 0);
 
-        if (fm->modify_cookie && fm->new_cookie != htonll(UINT64_MAX)) {
+        if (fm->modify_cookie && fm->new_cookie != OVS_BE64_MAX) {
             ofproto_rule_change_cookie(ofproto, rule, fm->new_cookie);
         }
         if (type == OFOPERATION_REPLACE) {
@@ -4029,7 +4036,7 @@ modify_flows_add(struct ofproto *ofproto, struct ofconn *ofconn,
                  struct ofputil_flow_mod *fm, const struct ofp_header *request)
     OVS_REQUIRES(ofproto_mutex)
 {
-    if (fm->cookie_mask != htonll(0) || fm->new_cookie == htonll(UINT64_MAX)) {
+    if (fm->cookie_mask != htonll(0) || fm->new_cookie == OVS_BE64_MAX) {
         return 0;
     }
     return add_flow(ofproto, ofconn, fm, request);