Example #1
0
void
parse_ofp_flow_mod_file(const char *file_name, uint16_t command,
                        struct ofputil_flow_mod **fms, size_t *n_fms)
{
    size_t allocated_fms;
    FILE *stream;
    struct ds s;

    stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
    if (stream == NULL) {
        ovs_fatal(errno, "%s: open", file_name);
    }

    allocated_fms = *n_fms;
    ds_init(&s);
    while (!ds_get_preprocessed_line(&s, stream)) {
        if (*n_fms >= allocated_fms) {
            *fms = x2nrealloc(*fms, &allocated_fms, sizeof **fms);
        }
        parse_ofp_flow_mod_str(&(*fms)[*n_fms], ds_cstr(&s), command, false);
        *n_fms += 1;
    }
    ds_destroy(&s);

    if (stream != stdin) {
        fclose(stream);
    }
}
Example #2
0
/* Similar to parse_ofp_flow_mod_str(), except that the string is read from
 * 'stream' and the command is always OFPFC_ADD.  Returns false if end-of-file
 * is reached before reading a flow, otherwise true. */
bool
parse_ofp_flow_mod_file(struct list *packets,
                        enum nx_flow_format *cur, bool *flow_mod_table_id,
                        FILE *stream, uint16_t command)
{
    struct ds s;
    bool ok;

    ds_init(&s);
    ok = ds_get_preprocessed_line(&s, stream) == 0;
    if (ok) {
        parse_ofp_flow_mod_str(packets, cur, flow_mod_table_id,
                               ds_cstr(&s), command, true);
    }
    ds_destroy(&s);

    return ok;
}
Example #3
0
/* Opens file 'file_name' and reads each line as a flow_mod or a group_mod,
 * depending on the first keyword on each line.  Stores each flow and group
 * mods in '*bms', an array allocated on the caller's behalf, and the number of
 * messages in '*n_bms'.
 *
 * Returns NULL if successful, otherwise a malloc()'d string describing the
 * error.  The caller is responsible for freeing the returned string. */
char * OVS_WARN_UNUSED_RESULT
parse_ofp_bundle_file(const char *file_name,
                      const struct ofputil_port_map *port_map,
                      const struct ofputil_table_map *table_map,
                      struct ofputil_bundle_msg **bms, size_t *n_bms,
                      enum ofputil_protocol *usable_protocols)
{
    size_t allocated_bms;
    char *error = NULL;
    int line_number;
    FILE *stream;
    struct ds ds;

    *usable_protocols = OFPUTIL_P_ANY;

    *bms = NULL;
    *n_bms = 0;

    stream = !strcmp(file_name, "-") ? stdin : fopen(file_name, "r");
    if (stream == NULL) {
        return xasprintf("%s: open failed (%s)",
                         file_name, ovs_strerror(errno));
    }

    allocated_bms = *n_bms;
    ds_init(&ds);
    line_number = 0;
    while (!ds_get_preprocessed_line(&ds, stream, &line_number)) {
        enum ofputil_protocol usable;
        char *s = ds_cstr(&ds);
        size_t len;

        if (*n_bms >= allocated_bms) {
            struct ofputil_bundle_msg *new_bms;

            new_bms = x2nrealloc(*bms, &allocated_bms, sizeof **bms);
            for (size_t i = 0; i < *n_bms; i++) {
                if (new_bms[i].type == OFPTYPE_GROUP_MOD) {
                    ovs_list_moved(&new_bms[i].gm.buckets,
                                   &(*bms)[i].gm.buckets);
                }
            }
            *bms = new_bms;
        }

        s += strspn(s, " \t\r\n");   /* Skip white space. */
        len = strcspn(s, ", \t\r\n"); /* Get length of the first token. */

        if (!strncmp(s, "flow", len)) {
            s += len;
            error = parse_ofp_flow_mod_str(&(*bms)[*n_bms].fm, s, port_map,
                                           table_map, -2, &usable);
            if (error) {
                break;
            }
            (*bms)[*n_bms].type = OFPTYPE_FLOW_MOD;
        } else if (!strncmp(s, "group", len)) {
            s += len;
            error = parse_ofp_group_mod_str(&(*bms)[*n_bms].gm, -2, s,
                                            port_map, table_map, &usable);
            if (error) {
                break;
            }
            (*bms)[*n_bms].type = OFPTYPE_GROUP_MOD;
        } else if (!strncmp(s, "packet-out", len)) {
            s += len;
            error = parse_ofp_packet_out_str(&(*bms)[*n_bms].po, s, port_map,
                                             table_map, &usable);
            if (error) {
                break;
            }
            (*bms)[*n_bms].type = OFPTYPE_PACKET_OUT;
        } else {
            error = xasprintf("Unsupported bundle message type: %.*s",
                              (int)len, s);
            break;
        }

        *usable_protocols &= usable; /* Each line can narrow the set. */
        *n_bms += 1;
    }

    ds_destroy(&ds);
    if (stream != stdin) {
        fclose(stream);
    }

    if (error) {
        char *err_msg = xasprintf("%s:%d: %s", file_name, line_number, error);
        free(error);

        ofputil_free_bundle_msgs(*bms, *n_bms);
        *bms = NULL;
        *n_bms = 0;
        return err_msg;
    }
    return NULL;
}