static int handle_session_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr, struct request_session *request) { __u64 count; int error; if (nat64_is_stateless()) { log_err("SIIT doesn't have session tables."); return -EINVAL; } switch (nat64_hdr->operation) { case OP_DISPLAY: return handle_session_display(nl_hdr, request); case OP_COUNT: log_debug("Returning session count."); error = sessiondb_count(request->l4_proto, &count); if (error) return respond_error(nl_hdr, error); return respond_setcfg(nl_hdr, &count, sizeof(count)); default: log_err("Unknown operation: %d", nat64_hdr->operation); return respond_error(nl_hdr, -EINVAL); } }
static int handle_pool4_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr, union request_pool4 *request) { struct response_pool4_count counters; if (xlat_is_siit()) { log_err("SIIT doesn't have pool4."); return -EINVAL; } switch (jool_hdr->operation) { case OP_DISPLAY: return handle_pool4_display(nl_hdr, request); case OP_COUNT: log_debug("Returning IPv4 pool counters."); pool4db_count(&counters.tables, &counters.samples, &counters.taddrs); return respond_setcfg(nl_hdr, &counters, sizeof(counters)); case OP_ADD: return handle_pool4_add(nl_hdr, request); case OP_REMOVE: return handle_pool4_rm(nl_hdr, request); case OP_FLUSH: return handle_pool4_flush(nl_hdr, request); default: log_err("Unknown operation: %d", jool_hdr->operation); return respond_error(nl_hdr, -EINVAL); } }
static int handle_pool6_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr, union request_pool6 *request) { __u64 count; int error; switch (jool_hdr->operation) { case OP_DISPLAY: return handle_pool6_display(nl_hdr, request); case OP_COUNT: log_debug("Returning IPv6 prefix count."); error = pool6_count(&count); if (error) return respond_error(nl_hdr, error); return respond_setcfg(nl_hdr, &count, sizeof(count)); case OP_ADD: case OP_UPDATE: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Adding a prefix to the IPv6 pool."); return respond_error(nl_hdr, pool6_add(&request->add.prefix)); case OP_REMOVE: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Removing a prefix from the IPv6 pool."); error = pool6_remove(&request->remove.prefix); if (error) return respond_error(nl_hdr, error); if (nat64_is_stateful() && !request->flush.quick) error = sessiondb_delete_by_prefix6(&request->remove.prefix); return respond_error(nl_hdr, error); case OP_FLUSH: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Flushing the IPv6 pool..."); error = pool6_flush(); if (error) return respond_error(nl_hdr, error); if (nat64_is_stateful() && !request->flush.quick) error = sessiondb_flush(); return respond_error(nl_hdr, error); default: log_err("Unknown operation: %d", jool_hdr->operation); return respond_error(nl_hdr, -EINVAL); } }
static int handle_rfc6791_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr, union request_pool4 *request) { __u64 count; int error; if (nat64_is_stateful()) { log_err("RFC 6791 does not apply to Stateful NAT64."); return -EINVAL; } switch (nat64_hdr->operation) { case OP_DISPLAY: return handle_pool6791_display(nl_hdr, request); case OP_COUNT: log_debug("Returning IPv4 address count."); error = rfc6791_count(&count); if (error) return respond_error(nl_hdr, error); return respond_setcfg(nl_hdr, &count, sizeof(count)); case OP_ADD: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Adding an address to the IPv4 pool."); return respond_error(nl_hdr, rfc6791_add(&request->add.addrs)); case OP_REMOVE: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Removing an address from the IPv4 pool."); error = rfc6791_remove(&request->remove.addrs); if (error) return respond_error(nl_hdr, error); return respond_error(nl_hdr, error); case OP_FLUSH: if (verify_superpriv()) { return respond_error(nl_hdr, -EPERM); } log_debug("Flushing the IPv4 pool..."); error = rfc6791_flush(); if (error) return respond_error(nl_hdr, error); return respond_error(nl_hdr, error); default: log_err("Unknown operation: %d", nat64_hdr->operation); return respond_error(nl_hdr, -EINVAL); } }
static int handle_eamt_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr, union request_eamt *request) { __u64 count; int error; if (xlat_is_nat64()) { log_err("Stateful NAT64 doesn't have an EAMT."); return -EINVAL; } switch (jool_hdr->operation) { case OP_DISPLAY: return handle_eamt_display(nl_hdr, request); case OP_COUNT: log_debug("Returning EAMT count."); error = eamt_count(&count); if (error) return respond_error(nl_hdr, error); return respond_setcfg(nl_hdr, &count, sizeof(count)); case OP_TEST: return handle_eamt_test(nl_hdr, request); case OP_ADD: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Adding EAMT entry."); return respond_error(nl_hdr, eamt_add(&request->add.prefix6, &request->add.prefix4, request->add.force)); case OP_REMOVE: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Removing EAMT entry."); return respond_error(nl_hdr, eamt_rm( request->rm.prefix6_set ? &request->rm.prefix6 : NULL, request->rm.prefix4_set ? &request->rm.prefix4 : NULL)); case OP_FLUSH: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); eamt_flush(); return respond_error(nl_hdr, 0); default: log_err("Unknown operation: %d", jool_hdr->operation); return respond_error(nl_hdr, -EINVAL); } }
static int handle_eamt_test(struct nlmsghdr *nl_hdr, union request_eamt *request) { struct in6_addr addr6; struct in_addr addr4; int error; log_debug("Translating address for the user."); if (request->test.addr_is_ipv6) { error = eamt_xlat_6to4(&request->test.addr.addr6, &addr4); if (error) return respond_error(nl_hdr, error); return respond_setcfg(nl_hdr, &addr4, sizeof(addr4)); } else { error = eamt_xlat_4to6(&request->test.addr.addr4, &addr6); if (error) return respond_error(nl_hdr, error); return respond_setcfg(nl_hdr, &addr6, sizeof(addr6)); } }
static int handle_blacklist_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr, union request_pool *request) { __u64 count; int error; if (xlat_is_nat64()) { log_err("Blacklist does not apply to Stateful NAT64."); return -EINVAL; } switch (jool_hdr->operation) { case OP_DISPLAY: log_debug("Sending Blacklist pool to userspace."); return handle_blacklist_display(nl_hdr, request); case OP_COUNT: log_debug("Returning address count in the Blacklist pool."); error = blacklist_count(&count); if (error) return respond_error(nl_hdr, error); return respond_setcfg(nl_hdr, &count, sizeof(count)); case OP_ADD: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Adding an address to the Blacklist pool."); return respond_error(nl_hdr, blacklist_add(&request->add.addrs)); case OP_REMOVE: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Removing an address from the Blacklist pool."); return respond_error(nl_hdr, blacklist_rm(&request->rm.addrs)); case OP_FLUSH: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Flushing the Blacklist pool..."); return respond_error(nl_hdr, blacklist_flush()); default: log_err("Unknown operation: %d", jool_hdr->operation); return respond_error(nl_hdr, -EINVAL); } }
static int handle_global_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr, union request_global *request) { struct global_config response = { .mtu_plateaus = NULL }; unsigned char *buffer; size_t buffer_len; bool disabled; int error; switch (jool_hdr->operation) { case OP_DISPLAY: log_debug("Returning 'Global' options."); error = config_clone(&response); if (error) goto end; disabled = xlat_is_nat64() ? pool6_is_empty() : (pool6_is_empty() && eamt_is_empty()); error = serialize_global_config(&response, disabled, &buffer, &buffer_len); if (error) goto end; error = respond_setcfg(nl_hdr, buffer, buffer_len); kfree(buffer); break; case OP_UPDATE: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Updating 'Global' options."); buffer = (unsigned char *) (request + 1); buffer_len = jool_hdr->length - sizeof(*jool_hdr) - sizeof(*request); error = handle_global_update(request->update.type, buffer_len, buffer); break; default: log_err("Unknown operation: %d", jool_hdr->operation); error = -EINVAL; } end: return respond_error(nl_hdr, error); }
static int handle_bib_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr, struct request_bib *request) { __u64 count; int error; if (nat64_is_stateless()) { log_err("SIIT doesn't have BIBs."); return -EINVAL; } switch (nat64_hdr->operation) { case OP_DISPLAY: return handle_bib_display(nl_hdr, request); case OP_COUNT: log_debug("Returning BIB count."); error = bibdb_count(request->l4_proto, &count); if (error) return respond_error(nl_hdr, error); return respond_setcfg(nl_hdr, &count, sizeof(count)); case OP_ADD: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Adding BIB entry."); return respond_error(nl_hdr, add_static_route(request)); case OP_REMOVE: if (verify_superpriv()) return respond_error(nl_hdr, -EPERM); log_debug("Removing BIB entry."); return respond_error(nl_hdr, delete_static_route(request)); default: log_err("Unknown operation: %d", nat64_hdr->operation); return respond_error(nl_hdr, -EINVAL); } }