char * process_escape_args(char **argv) { struct ds ds = DS_EMPTY_INITIALIZER; char **argp; for (argp = argv; *argp; argp++) { const char *arg = *argp; const char *p; if (argp != argv) { ds_put_char(&ds, ' '); } if (arg[strcspn(arg, " \t\r\n\v\\\'\"")]) { ds_put_char(&ds, '"'); for (p = arg; *p; p++) { if (*p == '\\' || *p == '\"') { ds_put_char(&ds, '\\'); } ds_put_char(&ds, *p); } ds_put_char(&ds, '"'); } else { ds_put_cstr(&ds, arg); } } return ds_cstr(&ds); }
action_syntax_error(struct action_context *ctx, const char *message, ...) { if (action_error_handle_common(ctx)) { return; } struct ds s; ds_init(&s); ds_put_cstr(&s, "Syntax error"); if (ctx->lexer->token.type == LEX_T_END) { ds_put_cstr(&s, " at end of input"); } else if (ctx->lexer->start) { ds_put_format(&s, " at `%.*s'", (int) (ctx->lexer->input - ctx->lexer->start), ctx->lexer->start); } if (message) { ds_put_char(&s, ' '); va_list args; va_start(args, message); ds_put_format_valist(&s, message, args); va_end(args); } ds_put_char(&s, '.'); ctx->error = ds_steal_cstr(&s); }
void flow_format(struct ds *ds, const struct flow *flow) { ds_put_format(ds, "priority:%"PRIu32 ",tunnel:%#"PRIx64 ",metadata:%#"PRIx64 ",in_port:%04"PRIx16, flow->skb_priority, ntohll(flow->tun_id), ntohll(flow->metadata), flow->in_port); ds_put_format(ds, ",tci("); if (flow->vlan_tci) { ds_put_format(ds, "vlan:%"PRIu16",pcp:%d", vlan_tci_to_vid(flow->vlan_tci), vlan_tci_to_pcp(flow->vlan_tci)); } else { ds_put_char(ds, '0'); } ds_put_format(ds, ") mac("ETH_ADDR_FMT"->"ETH_ADDR_FMT ") type:%04"PRIx16, ETH_ADDR_ARGS(flow->dl_src), ETH_ADDR_ARGS(flow->dl_dst), ntohs(flow->dl_type)); if (flow->dl_type == htons(ETH_TYPE_IPV6)) { ds_put_format(ds, " label:%#"PRIx32" proto:%"PRIu8" tos:%#"PRIx8 " ttl:%"PRIu8" ipv6(", ntohl(flow->ipv6_label), flow->nw_proto, flow->nw_tos, flow->nw_ttl); print_ipv6_addr(ds, &flow->ipv6_src); ds_put_cstr(ds, "->"); print_ipv6_addr(ds, &flow->ipv6_dst); ds_put_char(ds, ')'); } else { ds_put_format(ds, " proto:%"PRIu8" tos:%#"PRIx8" ttl:%"PRIu8 " ip("IP_FMT"->"IP_FMT")", flow->nw_proto, flow->nw_tos, flow->nw_ttl, IP_ARGS(&flow->nw_src), IP_ARGS(&flow->nw_dst)); } if (flow->nw_frag) { ds_put_format(ds, " frag(%s)", flow->nw_frag == FLOW_NW_FRAG_ANY ? "first" : flow->nw_frag == (FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER) ? "later" : "<error>"); } if (flow->tp_src || flow->tp_dst) { ds_put_format(ds, " port(%"PRIu16"->%"PRIu16")", ntohs(flow->tp_src), ntohs(flow->tp_dst)); } if (!eth_addr_is_zero(flow->arp_sha) || !eth_addr_is_zero(flow->arp_tha)) { ds_put_format(ds, " arp_ha("ETH_ADDR_FMT"->"ETH_ADDR_FMT")", ETH_ADDR_ARGS(flow->arp_sha), ETH_ADDR_ARGS(flow->arp_tha)); } }
/* Appends unicode code point 'uc' to 'ds' in UTF-8 encoding. */ void ds_put_utf8(struct ds *ds, int uc) { if (uc <= 0x7f) { ds_put_char(ds, uc); } else if (uc <= 0x7ff) { ds_put_char(ds, 0xc0 | (uc >> 6)); ds_put_char(ds, 0x80 | (uc & 0x3f)); } else if (uc <= 0xffff) {
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; }
/* Appends a description of 'mp' to 's', in the format that ovs-ofctl(8) * describes. */ void multipath_format(const struct ofpact_multipath *mp, struct ds *s) { const char *fields, *algorithm; fields = flow_hash_fields_to_str(mp->fields); switch (mp->algorithm) { case NX_MP_ALG_MODULO_N: algorithm = "modulo_n"; break; case NX_MP_ALG_HASH_THRESHOLD: algorithm = "hash_threshold"; break; case NX_MP_ALG_HRW: algorithm = "hrw"; break; case NX_MP_ALG_ITER_HASH: algorithm = "iter_hash"; break; default: algorithm = "<unknown>"; } ds_put_format(s, "multipath(%s,%"PRIu16",%s,%d,%"PRIu16",", fields, mp->basis, algorithm, mp->max_link + 1, mp->arg); mf_format_subfield(&mp->dst, s); ds_put_char(s, ')'); }
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); }
static void format_flow_tunnel(struct ds *s, const struct match *match) { const struct flow_wildcards *wc = &match->wc; const struct flow_tnl *tnl = &match->flow.tunnel; switch (wc->masks.tunnel.tun_id) { case 0: break; case CONSTANT_HTONLL(UINT64_MAX): ds_put_format(s, "tun_id=%#"PRIx64",", ntohll(tnl->tun_id)); break; default: ds_put_format(s, "tun_id=%#"PRIx64"/%#"PRIx64",", ntohll(tnl->tun_id), ntohll(wc->masks.tunnel.tun_id)); break; } format_ip_netmask(s, "tun_src", tnl->ip_src, wc->masks.tunnel.ip_src); format_ip_netmask(s, "tun_dst", tnl->ip_dst, wc->masks.tunnel.ip_dst); if (wc->masks.tunnel.ip_tos) { ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos); } if (wc->masks.tunnel.ip_ttl) { ds_put_format(s, "tun_ttl=%"PRIu8",", tnl->ip_ttl); } if (wc->masks.tunnel.flags) { format_flags(s, flow_tun_flag_to_string, tnl->flags, '|'); ds_put_char(s, ','); } }
void ofputil_format_bundle_add(struct ds *s, const struct ofputil_bundle_add_msg *badd, const struct ofputil_port_map *port_map, const struct ofputil_table_map *table_map, int verbosity) { ds_put_char(s, '\n'); ds_put_format(s, " bundle_id=%#"PRIx32, badd->bundle_id); ds_put_cstr(s, " flags="); ofp_print_bit_names(s, badd->flags, bundle_flags_to_name, ' '); ds_put_char(s, '\n'); char *msg = ofp_to_string(badd->msg, ntohs(badd->msg->length), port_map, table_map, verbosity); ds_put_and_free_cstr(s, msg); }
static void format_generic_odp_action(struct ds *ds, const struct nlattr *a) { size_t len = nl_attr_get_size(a); ds_put_format(ds, "action%"PRId16, nl_attr_type(a)); if (len) { const uint8_t *unspec; unsigned int i; unspec = nl_attr_get(a); for (i = 0; i < len; i++) { ds_put_char(ds, i ? ' ': '('); ds_put_format(ds, "%02x", unspec[i]); } ds_put_char(ds, ')'); } }
static void format_eth_masked(struct ds *s, const char *name, const uint8_t eth[6], const uint8_t mask[6]) { if (!eth_addr_is_zero(mask)) { ds_put_format(s, "%s=", name); eth_format_masked(eth, mask, s); ds_put_char(s, ','); } }
static void format_ip_netmask(struct ds *s, const char *name, ovs_be32 ip, ovs_be32 netmask) { if (netmask) { ds_put_format(s, "%s=", name); ip_format_masked(ip, netmask, s); ds_put_char(s, ','); } }
/* Breaks 'words' into words at white space, respecting shell-like quoting * conventions, and appends the words to 'svec'. */ void svec_parse_words(struct svec *svec, const char *words) { struct ds word = DS_EMPTY_INITIALIZER; const char *p, *q; for (p = words; *p != '\0'; p = q) { int quote = 0; while (isspace((unsigned char) *p)) { p++; } if (*p == '\0') { break; } ds_clear(&word); for (q = p; *q != '\0'; q++) { if (*q == quote) { quote = 0; } else if (*q == '\'' || *q == '"') { quote = *q; } else if (*q == '\\' && (!quote || quote == '"')) { q++; if (*q == '\0') { VLOG_WARN(LOG_MODULE, "%s: ends in trailing backslash", words); break; } ds_put_char(&word, *q); } else if (isspace((unsigned char) *q) && !quote) { q++; break; } else { ds_put_char(&word, *q); } } svec_add(svec, ds_cstr(&word)); if (quote) { VLOG_WARN(LOG_MODULE, "%s: word ends inside quoted string", words); } } ds_destroy(&word); }
static void format_ipv6_netmask(struct ds *s, const char *name, const struct in6_addr *addr, const struct in6_addr *netmask) { if (!ipv6_mask_is_any(netmask)) { ds_put_format(s, "%s=", name); print_ipv6_masked(s, addr, netmask); ds_put_char(s, ','); } }
enum ofperr ofputil_queue_stats_reply_format(struct ds *string, const struct ofp_header *oh, const struct ofputil_port_map *port_map, int verbosity) { ds_put_format(string, " %"PRIuSIZE" queues\n", ofputil_count_queue_stats(oh)); if (verbosity < 1) { return 0; } struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length)); for (;;) { struct ofputil_queue_stats qs; int retval; retval = ofputil_decode_queue_stats(&qs, &b); if (retval) { return retval != EOF ? retval : 0; } ds_put_cstr(string, " port "); ofputil_format_port(qs.port_no, port_map, string); ds_put_cstr(string, " queue "); ofp_print_queue_name(string, qs.queue_id); ds_put_cstr(string, ": "); print_queue_stat(string, "bytes=", qs.tx_bytes, 1); print_queue_stat(string, "pkts=", qs.tx_packets, 1); print_queue_stat(string, "errors=", qs.tx_errors, 1); ds_put_cstr(string, "duration="); if (qs.duration_sec != UINT32_MAX) { ofp_print_duration(string, qs.duration_sec, qs.duration_nsec); } else { ds_put_char(string, '?'); } ds_put_char(string, '\n'); } }
static void format_uint32_masked(struct ds *s, const char *name, uint32_t value, uint32_t mask) { if (mask) { ds_put_format(s, "%s=%#"PRIx32, name, value); if (mask != UINT32_MAX) { ds_put_format(s, "/%#"PRIx32, mask); } ds_put_char(s, ','); } }
static void format_be64_masked(struct ds *s, const char *name, ovs_be64 value, ovs_be64 mask) { if (mask != htonll(0)) { ds_put_format(s, "%s=%#"PRIx64, name, ntohll(value)); if (mask != OVS_BE64_MAX) { ds_put_format(s, "/%#"PRIx64, ntohll(mask)); } ds_put_char(s, ','); } }
/* Appends a human-readable representation of 'nab' to 's'. */ void bundle_format(const struct ofpact_bundle *bundle, struct ds *s) { const char *action, *fields, *algorithm; size_t i; fields = flow_hash_fields_to_str(bundle->fields); switch (bundle->algorithm) { case NX_BD_ALG_HRW: algorithm = "hrw"; break; case NX_BD_ALG_ACTIVE_BACKUP: algorithm = "active_backup"; break; default: algorithm = "<unknown>"; } action = bundle->dst.field ? "bundle_load" : "bundle"; ds_put_format(s, "%s%s(%s%s,%"PRIu16",%s,%s,", colors.paren, action, colors.end, fields, bundle->basis, algorithm, "ofport"); if (bundle->dst.field) { mf_format_subfield(&bundle->dst, s); ds_put_char(s, ','); } ds_put_format(s, "%sslaves:%s", colors.param, colors.end); for (i = 0; i < bundle->n_slaves; i++) { if (i) { ds_put_char(s, ','); } ofputil_format_port(bundle->slaves[i], s); } ds_put_format(s, "%s)%s", colors.paren, colors.end); }
/* Appends a string representation of the TCP flags value 'tcp_flags' * (e.g. obtained via packet_get_tcp_flags() or TCP_FLAGS) to 's', in the * format used by tcpdump. */ void packet_format_tcp_flags(struct ds *s, uint8_t tcp_flags) { if (!tcp_flags) { ds_put_cstr(s, "none"); return; } if (tcp_flags & TCP_SYN) { ds_put_char(s, 'S'); } if (tcp_flags & TCP_FIN) { ds_put_char(s, 'F'); } if (tcp_flags & TCP_PSH) { ds_put_char(s, 'P'); } if (tcp_flags & TCP_RST) { ds_put_char(s, 'R'); } if (tcp_flags & TCP_URG) { ds_put_char(s, 'U'); } if (tcp_flags & TCP_ACK) { ds_put_char(s, '.'); } if (tcp_flags & 0x40) { ds_put_cstr(s, "[40]"); } if (tcp_flags & 0x80) { ds_put_cstr(s, "[80]"); } }
void ds_put_printable(struct ds *ds, const char *s, size_t n) { ds_reserve(ds, ds->length + n); while (n-- > 0) { unsigned char c = *s++; if (c < 0x20 || c > 0x7e || c == '\\' || c == '"') { ds_put_format(ds, "\\%03o", (int) c); } else { ds_put_char(ds, c); } } }
void print_ipv6_masked(struct ds *s, const struct in6_addr *addr, const struct in6_addr *mask) { print_ipv6_addr(s, addr); if (mask && !ipv6_mask_is_exact(mask)) { if (ipv6_is_cidr(mask)) { int cidr_bits = ipv6_count_cidr_bits(mask); ds_put_format(s, "/%d", cidr_bits); } else { ds_put_char(s, '/'); print_ipv6_addr(s, mask); } } }
void format_odp_actions(struct ds *ds, const union odp_action *actions, size_t n_actions) { size_t i; for (i = 0; i < n_actions; i++) { if (i) { ds_put_char(ds, ','); } format_odp_action(ds, &actions[i]); } if (!n_actions) { ds_put_cstr(ds, "drop"); } }
static void format_be32_masked(struct ds *s, const char *name, ovs_be32 value, ovs_be32 mask) { if (mask != htonl(0)) { ds_put_format(s, "%s=", name); if (mask == OVS_BE32_MAX) { ds_put_format(s, "%"PRIu32, ntohl(value)); } else { ds_put_format(s, "0x%"PRIx32"/0x%"PRIx32, ntohl(value), ntohl(mask)); } ds_put_char(s, ','); } }
static void format_be16_masked(struct ds *s, const char *name, ovs_be16 value, ovs_be16 mask) { if (mask != htons(0)) { ds_put_format(s, "%s=", name); if (mask == htons(UINT16_MAX)) { ds_put_format(s, "%"PRIu16, ntohs(value)); } else { ds_put_format(s, "0x%"PRIx16"/0x%"PRIx16, ntohs(value), ntohs(mask)); } ds_put_char(s, ','); } }
void ofputil_switch_features_format(struct ds *s, const struct ofputil_switch_features *features) { ds_put_format(s, " dpid:%016"PRIx64"\n", features->datapath_id); ds_put_format(s, "n_tables:%"PRIu8", n_buffers:%"PRIu32, features->n_tables, features->n_buffers); if (features->auxiliary_id) { ds_put_format(s, ", auxiliary_id:%"PRIu8, features->auxiliary_id); } ds_put_char(s, '\n'); ds_put_cstr(s, "capabilities: "); ofp_print_bit_names(s, features->capabilities, ofputil_capabilities_to_name, ' '); ds_put_char(s, '\n'); if (features->ofpacts) { ds_put_cstr(s, "actions: "); ofpact_bitmap_format(features->ofpacts, s); ds_put_char(s, '\n'); } }
static void print_queue_stat(struct ds *string, const char *leader, uint64_t stat, int more) { ds_put_cstr(string, leader); if (stat != UINT64_MAX) { ds_put_format(string, "%"PRIu64, stat); } else { ds_put_char(string, '?'); } if (more) { ds_put_cstr(string, ", "); } else { ds_put_cstr(string, "\n"); } }
static void lex_token_format_masked_integer(const struct lex_token *token, struct ds *s) { enum lex_format format = lex_token_get_format(token); lex_token_format_value(&token->value, format, s); ds_put_char(s, '/'); const union mf_subvalue *mask = &token->mask; if (format == LEX_F_IPV4 && ip_is_cidr(mask->ipv4)) { ds_put_format(s, "%d", ip_count_cidr_bits(mask->ipv4)); } else if (token->format == LEX_F_IPV6 && ipv6_is_cidr(&mask->ipv6)) { ds_put_format(s, "%d", ipv6_count_cidr_bits(&mask->ipv6)); } else { lex_token_format_value(&token->mask, format, s); } }
/* Returns a string that represents 'protocols'. The return value might be a * comma-separated list if 'protocols' doesn't have a simple name. The return * value is "none" if 'protocols' is 0. * * The caller must free the returned string (with free()). */ char * ofputil_protocols_to_string(enum ofputil_protocol protocols) { struct ds s; ovs_assert(!(protocols & ~OFPUTIL_P_ANY)); if (protocols == 0) { return xstrdup("none"); } ds_init(&s); while (protocols) { const struct proto_abbrev *p; int i; if (s.length) { ds_put_char(&s, ','); } for (p = proto_abbrevs; p < &proto_abbrevs[N_PROTO_ABBREVS]; p++) { if ((protocols & p->protocol) == p->protocol) { ds_put_cstr(&s, p->name); protocols &= ~p->protocol; goto match; } } for (i = 0; i < CHAR_BIT * sizeof(enum ofputil_protocol); i++) { enum ofputil_protocol bit = 1u << i; if (protocols & bit) { ds_put_cstr(&s, ofputil_protocol_to_string(bit)); protocols &= ~bit; goto match; } } OVS_NOT_REACHED(); match: ; } return ds_steal_cstr(&s); }
log_wakeup(const struct backtrace *backtrace, const char *format, ...) { struct ds ds; va_list args; ds_init(&ds); va_start(args, format); ds_put_format_valist(&ds, format, args); va_end(args); if (backtrace) { int i; ds_put_char(&ds, ':'); for (i = 0; i < backtrace->n_frames; i++) { ds_put_format(&ds, " 0x%x", backtrace->frames[i]); } } VLOG_DBG("%s", ds_cstr(&ds)); ds_destroy(&ds); }
static void format_flow_tunnel(struct ds *s, const struct match *match) { const struct flow_wildcards *wc = &match->wc; const struct flow_tnl *tnl = &match->flow.tunnel; format_be64_masked(s, "tun_id", tnl->tun_id, wc->masks.tunnel.tun_id); format_ip_netmask(s, "tun_src", tnl->ip_src, wc->masks.tunnel.ip_src); format_ip_netmask(s, "tun_dst", tnl->ip_dst, wc->masks.tunnel.ip_dst); if (wc->masks.tunnel.ip_tos) { ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos); } if (wc->masks.tunnel.ip_ttl) { ds_put_format(s, "tun_ttl=%"PRIu8",", tnl->ip_ttl); } if (wc->masks.tunnel.flags) { format_flags(s, flow_tun_flag_to_string, tnl->flags, '|'); ds_put_char(s, ','); } }