Пример #1
0
void
format_flags(struct ds *ds, const char *(*bit_to_string)(uint32_t),
             uint32_t flags, char del)
{
    uint32_t bad = 0;

    if (!flags) {
        return;
    }
    while (flags) {
        uint32_t bit = rightmost_1bit(flags);
        const char *s;

        s = bit_to_string(bit);
        if (s) {
            ds_put_format(ds, "%s%c", s, del);
        } else {
            bad |= bit;
        }

        flags &= ~bit;
    }

    if (bad) {
        ds_put_format(ds, "0x%"PRIx32"%c", bad, del);
    }
    ds_chomp(ds, del);
}
Пример #2
0
static void
test_lex(const char *input)
{
    struct ds output;

    ds_init(&output);
    struct lexer lexer;

    lexer_init(&lexer, input);
    ds_clear(&output);
    while (lexer_get(&lexer) != LEX_T_END) {
        size_t len = output.length;
        lex_token_format(&lexer.token, &output);

        /* Check that the formatted version can really be parsed back
         * losslessly. */
        if (lexer.token.type != LEX_T_ERROR) {
            const char *s = ds_cstr(&output) + len;
            struct lexer l2;

            lexer_init(&l2, s);
            lexer_get(&l2);
            compare_token(&lexer.token, &l2.token);
            lexer_destroy(&l2);
        }
        ds_put_char(&output, ' ');
    }
    lexer_destroy(&lexer);

    ds_chomp(&output, ' ');
    puts(ds_cstr(&output));
    ds_destroy(&output);
}
Пример #3
0
static void
output_line (struct line_reader *r, struct string *s, size_t n)
{
  int unit = r->encoding_info.unit;

  output_bytes (r, s, n);

  r->head += unit;
  r->length -= unit;

  ds_chomp (s, ss_buffer (r->encoding_info.cr, unit));
}
Пример #4
0
enum ofperr
ofputil_queue_get_config_reply_format(struct ds *string,
                                      const struct ofp_header *oh,
                                      const struct ofputil_port_map *port_map)
{
    struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));

    struct ofputil_queue_config *queues = NULL;
    size_t allocated_queues = 0;
    size_t n = 0;

    int retval = 0;
    for (;;) {
        if (n >= allocated_queues) {
            queues = x2nrealloc(queues, &allocated_queues, sizeof *queues);
        }
        retval = ofputil_pull_queue_get_config_reply(&b, &queues[n]);
        if (retval) {
            break;
        }
        n++;
    }

    qsort(queues, n, sizeof *queues, compare_queues);

    ds_put_char(string, ' ');

    ofp_port_t port = 0;
    for (const struct ofputil_queue_config *q = queues; q < &queues[n]; q++) {
        if (q->port != port) {
            port = q->port;

            ds_put_cstr(string, "port=");
            ofputil_format_port(port, port_map, string);
            ds_put_char(string, '\n');
        }

        ds_put_format(string, "queue %"PRIu32":", q->queue);
        print_queue_rate(string, "min_rate", q->min_rate);
        print_queue_rate(string, "max_rate", q->max_rate);
        ds_put_char(string, '\n');
    }

    ds_chomp(string, ' ');
    free(queues);

    return retval != EOF ? retval : 0;
}
Пример #5
0
/* Returns this chassis's Chassis record, if it is available and is currently
 * amenable to a transaction. */
const struct sbrec_chassis *
chassis_run(struct controller_ctx *ctx, const char *chassis_id,
            const struct ovsrec_bridge *br_int)
{
    if (!ctx->ovnsb_idl_txn) {
        return NULL;
    }

    const struct ovsrec_open_vswitch *cfg;
    const char *encap_type, *encap_ip;
    static bool inited = false;

    cfg = ovsrec_open_vswitch_first(ctx->ovs_idl);
    if (!cfg) {
        VLOG_INFO("No Open_vSwitch row defined.");
        return NULL;
    }

    encap_type = smap_get(&cfg->external_ids, "ovn-encap-type");
    encap_ip = smap_get(&cfg->external_ids, "ovn-encap-ip");
    if (!encap_type || !encap_ip) {
        VLOG_INFO("Need to specify an encap type and ip");
        return NULL;
    }

    char *tokstr = xstrdup(encap_type);
    char *save_ptr = NULL;
    char *token;
    uint32_t req_tunnels = 0;
    for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL;
         token = strtok_r(NULL, ",", &save_ptr)) {
        uint32_t type = get_tunnel_type(token);
        if (!type) {
            VLOG_INFO("Unknown tunnel type: %s", token);
        }
        req_tunnels |= type;
    }
    free(tokstr);

    const char *hostname = smap_get_def(&cfg->external_ids, "hostname", "");
    char hostname_[HOST_NAME_MAX + 1];
    if (!hostname[0]) {
        if (gethostname(hostname_, sizeof hostname_)) {
            hostname_[0] = '\0';
        }
        hostname = hostname_;
    }

    const char *bridge_mappings = get_bridge_mappings(&cfg->external_ids);
    const char *datapath_type =
        br_int && br_int->datapath_type ? br_int->datapath_type : "";

    struct ds iface_types = DS_EMPTY_INITIALIZER;
    ds_put_cstr(&iface_types, "");
    for (int j = 0; j < cfg->n_iface_types; j++) {
        ds_put_format(&iface_types, "%s,", cfg->iface_types[j]);
    }
    ds_chomp(&iface_types, ',');
    const char *iface_types_str = ds_cstr(&iface_types);

    const struct sbrec_chassis *chassis_rec
        = get_chassis(ctx->ovnsb_idl, chassis_id);

    if (chassis_rec) {
        if (strcmp(hostname, chassis_rec->hostname)) {
            sbrec_chassis_set_hostname(chassis_rec, hostname);
        }

        /* Determine new values for Chassis external-ids. */
        const char *chassis_bridge_mappings
            = get_bridge_mappings(&chassis_rec->external_ids);
        const char *chassis_datapath_type
            = smap_get_def(&chassis_rec->external_ids, "datapath-type", "");
        const char *chassis_iface_types
            = smap_get_def(&chassis_rec->external_ids, "iface-types", "");

        /* If any of the external-ids should change, update them. */
        if (strcmp(bridge_mappings, chassis_bridge_mappings) ||
            strcmp(datapath_type, chassis_datapath_type) ||
            strcmp(iface_types_str, chassis_iface_types)) {
            struct smap new_ids;
            smap_clone(&new_ids, &chassis_rec->external_ids);
            smap_replace(&new_ids, "ovn-bridge-mappings", bridge_mappings);
            smap_replace(&new_ids, "datapath-type", datapath_type);
            smap_replace(&new_ids, "iface-types", iface_types_str);
            sbrec_chassis_verify_external_ids(chassis_rec);
            sbrec_chassis_set_external_ids(chassis_rec, &new_ids);
            smap_destroy(&new_ids);
        }

        /* Compare desired tunnels against those currently in the database. */
        uint32_t cur_tunnels = 0;
        bool same = true;
        for (int i = 0; i < chassis_rec->n_encaps; i++) {
            cur_tunnels |= get_tunnel_type(chassis_rec->encaps[i]->type);
            same = same && !strcmp(chassis_rec->encaps[i]->ip, encap_ip);

            same = same && smap_get_bool(&chassis_rec->encaps[i]->options,
                                         "csum", false);
        }
        same = same && req_tunnels == cur_tunnels;

        if (same) {
            /* Nothing changed. */
            inited = true;
            ds_destroy(&iface_types);
            return chassis_rec;
        } else if (!inited) {
            struct ds cur_encaps = DS_EMPTY_INITIALIZER;
            for (int i = 0; i < chassis_rec->n_encaps; i++) {
                ds_put_format(&cur_encaps, "%s,",
                              chassis_rec->encaps[i]->type);
            }
            ds_chomp(&cur_encaps, ',');

            VLOG_WARN("Chassis config changing on startup, make sure "
                      "multiple chassis are not configured : %s/%s->%s/%s",
                      ds_cstr(&cur_encaps),
                      chassis_rec->encaps[0]->ip,
                      encap_type, encap_ip);
            ds_destroy(&cur_encaps);
        }
    }

    ovsdb_idl_txn_add_comment(ctx->ovnsb_idl_txn,
                              "ovn-controller: registering chassis '%s'",
                              chassis_id);

    if (!chassis_rec) {
        struct smap ext_ids = SMAP_INITIALIZER(&ext_ids);
        smap_add(&ext_ids, "ovn-bridge-mappings", bridge_mappings);
        smap_add(&ext_ids, "datapath-type", datapath_type);
        smap_add(&ext_ids, "iface-types", iface_types_str);
        chassis_rec = sbrec_chassis_insert(ctx->ovnsb_idl_txn);
        sbrec_chassis_set_name(chassis_rec, chassis_id);
        sbrec_chassis_set_hostname(chassis_rec, hostname);
        sbrec_chassis_set_external_ids(chassis_rec, &ext_ids);
        smap_destroy(&ext_ids);
    }

    ds_destroy(&iface_types);
    int n_encaps = count_1bits(req_tunnels);
    struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps);
    const struct smap options = SMAP_CONST1(&options, "csum", "true");

    for (int i = 0; i < n_encaps; i++) {
        const char *type = pop_tunnel_name(&req_tunnels);

        encaps[i] = sbrec_encap_insert(ctx->ovnsb_idl_txn);

        sbrec_encap_set_type(encaps[i], type);
        sbrec_encap_set_ip(encaps[i], encap_ip);
        sbrec_encap_set_options(encaps[i], &options);
    }

    sbrec_chassis_set_encaps(chassis_rec, encaps, n_encaps);
    free(encaps);

    inited = true;
    return chassis_rec;
}
Пример #6
0
void
chassis_run(struct controller_ctx *ctx, const char *chassis_id)
{
    if (!ctx->ovnsb_idl_txn) {
        return;
    }

    const struct ovsrec_open_vswitch *cfg;
    const char *encap_type, *encap_ip;
    static bool inited = false;

    cfg = ovsrec_open_vswitch_first(ctx->ovs_idl);
    if (!cfg) {
        VLOG_INFO("No Open_vSwitch row defined.");
        return;
    }

    encap_type = smap_get(&cfg->external_ids, "ovn-encap-type");
    encap_ip = smap_get(&cfg->external_ids, "ovn-encap-ip");
    if (!encap_type || !encap_ip) {
        VLOG_INFO("Need to specify an encap type and ip");
        return;
    }

    char *tokstr = xstrdup(encap_type);
    char *save_ptr = NULL;
    char *token;
    uint32_t req_tunnels = 0;
    for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL;
         token = strtok_r(NULL, ",", &save_ptr)) {
        uint32_t type = get_tunnel_type(token);
        if (!type) {
            VLOG_INFO("Unknown tunnel type: %s", token);
        }
        req_tunnels |= type;
    }
    free(tokstr);

    const char *hostname = smap_get(&cfg->external_ids, "hostname");
    char hostname_[HOST_NAME_MAX + 1];
    if (!hostname || !hostname[0]) {
        if (gethostname(hostname_, sizeof hostname_)) {
            hostname_[0] = '\0';
        }
        hostname = hostname_;
    }

    const struct sbrec_chassis *chassis_rec
        = get_chassis(ctx->ovnsb_idl, chassis_id);

    if (chassis_rec) {
        if (strcmp(hostname, chassis_rec->hostname)) {
            sbrec_chassis_set_hostname(chassis_rec, hostname);
        }

        /* Compare desired tunnels against those currently in the database. */
        uint32_t cur_tunnels = 0;
        bool same = true;
        for (int i = 0; i < chassis_rec->n_encaps; i++) {
            cur_tunnels |= get_tunnel_type(chassis_rec->encaps[i]->type);
            same = same && !strcmp(chassis_rec->encaps[i]->ip, encap_ip);
        }
        same = same && req_tunnels == cur_tunnels;

        if (same) {
            /* Nothing changed. */
            inited = true;
            return;
        } else if (!inited) {
            struct ds cur_encaps = DS_EMPTY_INITIALIZER;
            for (int i = 0; i < chassis_rec->n_encaps; i++) {
                ds_put_format(&cur_encaps, "%s,",
                              chassis_rec->encaps[i]->type);
            }
            ds_chomp(&cur_encaps, ',');

            VLOG_WARN("Chassis config changing on startup, make sure "
                      "multiple chassis are not configured : %s/%s->%s/%s",
                      ds_cstr(&cur_encaps),
                      chassis_rec->encaps[0]->ip,
                      encap_type, encap_ip);
            ds_destroy(&cur_encaps);
        }
    }

    ovsdb_idl_txn_add_comment(ctx->ovnsb_idl_txn,
                              "ovn-controller: registering chassis '%s'",
                              chassis_id);

    if (!chassis_rec) {
        chassis_rec = sbrec_chassis_insert(ctx->ovnsb_idl_txn);
        sbrec_chassis_set_name(chassis_rec, chassis_id);
        sbrec_chassis_set_hostname(chassis_rec, hostname);
    }

    int n_encaps = count_1bits(req_tunnels);
    struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps);
    for (int i = 0; i < n_encaps; i++) {
        const char *type = pop_tunnel_name(&req_tunnels);

        encaps[i] = sbrec_encap_insert(ctx->ovnsb_idl_txn);

        sbrec_encap_set_type(encaps[i], type);
        sbrec_encap_set_ip(encaps[i], encap_ip);
    }

    sbrec_chassis_set_encaps(chassis_rec, encaps, n_encaps);
    free(encaps);

    inited = true;
}