void rpc_ip_set_print(rpc_t* rpc, void* ctx) { struct ip_set_list_item *p; struct ip_set *ip_set, ip_set2; void *c; str name; int pending; if (rpc->scan(ctx, "Sd", &name, &pending) < 1) { return; } p = ip_set_list_find_by_name(name); if (!p) { rpc->fault(ctx, 400, "Ip set not found"); return; } if (pending) { lock_get(&p->write_lock); ip_set = &p->ip_set_pending; } else { lock_get(&p->read_lock); if (!p->ip_set) { ip_set_init(&ip_set2, 1); /* dummy to return empty ip set */ ip_set = &ip_set2; } else ip_set = &p->ip_set->ip_set; } /* nested array/struct not supported */ rpc->add(ctx, "{", &c); if (rpc->struct_add(c, "s", "IPv", "4") < 0) goto err; if (rpc_ip_tree_print(rpc, c, "", ip_set->ipv4_tree, 0) < 0) goto err; rpc->add(ctx, "{", &c); if (rpc->struct_add(c, "s", "IPv", "6") < 0) goto err; #ifdef USE_IPV6 if (rpc_ip_tree_print(rpc, c, "", ip_set->ipv6_tree, 0) < 0) goto err; #endif err: if (pending) lock_release(&p->write_lock); else lock_release(&p->read_lock); }
static int rpc_ip_tree_print(rpc_t* rpc, void *ctx, char *prefix, struct ip_tree_leaf *tree, unsigned int indent) { int j; if (!tree) { if (rpc->struct_printf(ctx, "", "%*snil", indent, prefix) < 0) return -1; } else { str s; s = ip_tree_mask_to_str(tree->prefix_match, tree->prefix_match_len); if (rpc->struct_printf(ctx, "", "%*smatch %d bits {%.*s}", indent, prefix, tree->prefix_match_len, s.len, s.s) < 0) return -1; for (j=0; j<=1; j++) { if (rpc_ip_tree_print(rpc, ctx, j==0?"0:":"1:", tree->next[j], indent+2) < 0) return -1; } } return 0; }