ofproto: Fix OVS crash when reverting old flows in bundle commit

During bundle commit flows which are added in bundle are applied
to ofproto in-order. In case if a flow cannot be added (e.g. flow
action is go-to group id which does not exist), OVS tries to
revert back all previous flows which were successfully applied
from the same bundle. This is possible since OVS maintains list
of old flows which were replaced by flows from the bundle.

While reinserting old flows ovs asserts due to check on rule
state != RULE_INITIALIZED.  This will work only for new flows, but
for old flow the rule state will be RULE_REMOVED. This is causing
an assert and OVS crash.

The ovs assert check should be modified to != RULE_INSERTED to prevent
any existing rule being re-inserted and allow new rules and old rules
(in case of revert) to get inserted.

Here is an example to trigger the assert:

$ ovs-vsctl add-br br-test -- set Bridge br-test datapath_type=netdev

$ cat flows.txt
flow add table=1,priority=0,in_port=2,actions=NORMAL
flow add table=1,priority=0,in_port=3,actions=NORMAL

$ ovs-ofctl dump-flows -OOpenflow13 br-test
 cookie=0x0, duration=2.465s, table=1, n_packets=0, n_bytes=0, priority=0,in_port=2 actions=NORMAL
 cookie=0x0, duration=2.465s, table=1, n_packets=0, n_bytes=0, priority=0,in_port=3 actions=NORMAL

$ cat flow-modify.txt
flow modify table=1,priority=0,in_port=2,actions=drop
flow modify table=1,priority=0,in_port=3,actions=group:10

$ ovs-ofctl bundle br-test flow-modify.txt -OOpenflow13

First flow rule will be modified since it is a valid rule. However second
rule is invalid since no group with id 10 exists. Bundle commit tries to
revert (insert) the first rule to old flow which results in ovs_assert at
ofproto_rule_insert__() since old rule->state = RULE_REMOVED.

Signed-off-by: Vishal Deep Ajmera <vishal.deep.ajmera@ericsson.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
handle_table_desc_request(struct ofconn *ofconn,
                          const struct ofp_header *request)
{
    struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
    struct ofputil_table_desc *table_desc;
    struct ovs_list replies;
    size_t i;

    query_tables_desc(ofproto, &table_desc);
    ofpmp_init(&replies, request);
    for (i = 0; i < ofproto->n_tables; i++) {
        if (!(ofproto->tables[i].flags & OFTABLE_HIDDEN)) {
            ofputil_append_table_desc_reply(&table_desc[i], &replies,
                                            request->version);
        }
    }
    ofconn_send_replies(ofconn, &replies);
    free(table_desc);
    return 0;
}

handle_table_desc_request(struct ofconn *ofconn,
                          const struct ofp_header *request)
{
    struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
    struct ofputil_table_desc *table_desc;
    struct ovs_list replies;
    size_t i;

    query_tables_desc(ofproto, &table_desc);
    ofpmp_init(&replies, request);
    for (i = 0; i < ofproto->n_tables; i++) {
        if (!(ofproto->tables[i].flags & OFTABLE_HIDDEN)) {
            ofputil_append_table_desc_reply(&table_desc[i], &replies,
                                            request->version);
        }
    }
    ofconn_send_replies(ofconn, &replies);
    free(table_desc);
    return 0;
}
