/** * Inserts a single entry, validates it, removes it, validates again. * Does not touch the session tables. */ static bool simple_bib(void) { struct ipv4_transport_addr addr = addr4[0]; struct bib_entry *bib; bool success = true; if (is_error(pool4_get_any_port(L4PROTO_TCP, &addr.l3, &addr.l4))) return false; bib = bib_create(&addr, &addr6[0], false, L4PROTO_TCP); if (!assert_not_null(bib, "Allocation of test BIB entry")) return false; success &= assert_equals_int(0, bibdb_add(bib), "BIB insertion call"); success &= assert_bib("BIB insertion state", bib, false, true, false); if (!success) return false; success &= assert_equals_int(0, bibdb_remove(bib, false), "BIB removal call"); success &= assert_bib("BIB removal state", bib, false, false, false); if (!success) return false; bib_kfree(bib); return success; }
static bool add_bib(struct in_addr *ip4_addr, __u16 ip4_port, struct in6_addr *ip6_addr, __u16 ip6_port, l4_protocol l4_proto) { struct bib_entry *bib; struct ipv6_tuple_address addr6; struct ipv4_tuple_address addr4; /* Generate the BIB. */ addr4.address = *ip4_addr; addr4.l4_id = ip4_port; addr6.address = *ip6_addr; addr6.l4_id = ip6_port; bib = bib_create(&addr4, &addr6, false); if (!bib) { log_warning("Can't allocate a BIB entry!"); return false; } /* log_debug("BIB [%pI4#%u, %pI6c#%u]", &bib->ipv4.address, bib->ipv4.l4_id, &bib->ipv6.address, bib->ipv6.l4_id); */ /* Add it to the table. */ if (is_error(bib_add(bib, l4_proto))) { log_warning("Can't add the dummy BIB to the table."); bib_kfree(bib); return false; } return true; }
static bool init(void) { if (bib_init()) return false; db = bib_create(); if (!db) bib_destroy(); return db; }
bool inject_bib_entry( u_int8_t l4protocol ) { struct ipv4_tuple_address ta_ipv4; struct ipv6_tuple_address ta_ipv6; struct in_addr addr4; struct in6_addr addr6; struct bib_entry *bib_e; if (!str_to_addr4_verbose(IPV4_INJECT_BIB_ENTRY_DST_ADDR, &addr4)) return false; if (!str_to_addr6_verbose(IPV6_INJECT_BIB_ENTRY_SRC_ADDR, &addr6)) return false; if ( l4protocol == IPPROTO_ICMP || l4protocol == IPPROTO_ICMPV6 ) { transport_address_ipv4( addr4, INIT_TUPLE_ICMP_ID, &ta_ipv4 ); transport_address_ipv6( addr6, INIT_TUPLE_ICMP_ID, &ta_ipv6 ); } else { transport_address_ipv4( addr4, IPV4_INJECT_BIB_ENTRY_DST_PORT, &ta_ipv4 ); transport_address_ipv6( addr6, IPV6_INJECT_BIB_ENTRY_SRC_PORT, &ta_ipv6 ); } bib_e = bib_create( &ta_ipv4, &ta_ipv6, false); if (!bib_e) { log_warning("Could not allocate the BIB entry."); return false; } if (bib_add( bib_e, l4protocol ) != 0) { log_warning("Could not insert the BIB entry to the table."); return false; } return true; }
int add_static_route(struct request_bib *req) { struct bib_entry *bib = NULL; int error; error = pool4_get(req->l4_proto, &req->add.addr4); if (error) { log_err("The IPv4 address and port could not be reserved from the pool. " "Maybe the IPv4 address you provided does not belong to the pool. " "Or maybe they're being used by some other BIB entry?"); return error; } bib = bib_create(&req->add.addr4, &req->add.addr6, true, req->l4_proto); if (!bib) { log_err("Could not allocate the BIB entry."); error = -ENOMEM; goto bib_error; } error = bibdb_add(bib); if (error) { log_err("The BIB entry could not be added to the database. Maybe an entry with the " "same IPv4 and/or IPv6 transport address already exists?"); bib_kfree(bib); goto bib_error; } /* * We do not call bib_return(bib) here, because we want the entry to hold a fake user so the * timer doesn't delete it. */ return 0; bib_error: pool4_return(req->l4_proto, &req->add.addr4); return error; }
struct bib_entry *create_bib_entry(int ipv4_index, int ipv6_index) { return bib_create(&addr4[ipv4_index], &addr6[ipv6_index], false); }
int add_static_route(struct request_bib *req) { struct bib_entry *bib_by_ipv6, *bib_by_ipv4; struct bib_entry *bib = NULL; int error; if (!pool4_contains(&req->add.ipv4.address)) { log_err(ERR_POOL6_NOT_FOUND, "The address '%pI4' does not belong to the IPv4 pool.", &req->add.ipv4.address); return -EINVAL; } spin_lock_bh(&bib_session_lock); /* Check if the BIB entry exists. */ error = bib_get_by_ipv6(&req->add.ipv6, req->l4_proto, &bib_by_ipv6); if (!error) { bib = bib_by_ipv6; goto already_mapped; } if (error != -ENOENT) goto generic_error; error = bib_get_by_ipv4(&req->add.ipv4, req->l4_proto, &bib_by_ipv4); if (!error) { bib = bib_by_ipv4; goto already_mapped; } if (error != -ENOENT) goto generic_error; /* Borrow the address and port from the IPv4 pool. */ if (is_error(pool4_get(req->l4_proto, &req->add.ipv4))) { /* * This might happen if Filtering just reserved the address#port, but hasn't yet inserted * the BIB entry to the table. This is because bib_session_lock doesn't cover the IPv4 * pool. * Otherwise something's not returning borrowed address#ports to the pool, which is an * error. */ log_err(ERR_BIB_REINSERT, "Port number %u from address %pI4 is taken from the IPv4 pool, " "but it wasn't found in the BIB. Please try again; if the problem persists, " "please report.", req->add.ipv4.l4_id, &req->add.ipv4.address); error = -EEXIST; goto failure; } /* Create and insert the entry. */ bib = bib_create(&req->add.ipv4, &req->add.ipv6, true); if (!bib) { log_err(ERR_ALLOC_FAILED, "Could NOT allocate a BIB entry."); error = -ENOMEM; goto failure; } error = bib_add(bib, req->l4_proto); if (error) { log_err(ERR_UNKNOWN_ERROR, "Could NOT add the BIB entry to the table."); goto failure; } spin_unlock_bh(&bib_session_lock); return 0; already_mapped: log_err(ERR_BIB_REINSERT, "%pI6c#%u is already mapped to %pI4#%u.", &bib->ipv6.address, bib->ipv6.l4_id, &bib->ipv4.address, bib->ipv4.l4_id); error = -EEXIST; bib = NULL; goto failure; generic_error: log_err(ERR_UNKNOWN_ERROR, "Error code %u while trying to interact with the BIB.", error); /* Fall through. */ failure: if (bib) bib_kfree(bib); spin_unlock_bh(&bib_session_lock); return error; }
struct bib_entry *create_bib_entry(int ipv4_index, int ipv6_index) { struct ipv4_tuple_address address_4 = create_tuple_addr_4(ipv4_index); struct ipv6_tuple_address address_6 = create_tuple_addr_6(ipv4_index); return bib_create(&address_4, &address_6); }