bool test_address_filtering(void) { struct bib_entry *bib; struct session_entry *session; // Init. bib = create_bib_entry(0, 0); if (!bib) { log_warning("Could not allocate a BIB entry."); return false; } session = create_session_entry(0, 0, 0, 0, bib, IPPROTO_UDP, 12345); if (!session) { log_warning("Could not allocate a Session entry."); return false; } if (!bib_add(bib, IPPROTO_UDP)) { log_warning("Could not add the BIB entry."); return false; } if (!session_add(session)) { log_warning("Could not add the session entry."); return false; } // Test the packet is allowed when the tuple and session match perfectly. if (!test_address_filtering_aux(0, 0, 0, 0, true)) return false; // Test a tuple that completely mismatches the session. if (!test_address_filtering_aux(1, 1, 1, 1, false)) return false; // Now test tuples that nearly match the session. if (!test_address_filtering_aux(0, 0, 0, 1, false)) return false; if (!test_address_filtering_aux(0, 0, 1, 0, false)) return false; if (!test_address_filtering_aux(0, 1, 0, 0, true)) return false; // The remote port is the only one that doesn't matter. if (!test_address_filtering_aux(1, 0, 0, 0, false)) return false; return true; }
static struct session_entry *create_and_insert_session(int remote4_id, int local4_id, int local6_id, int remote6_id, struct bib_entry* bib, u_int8_t l4protocol, unsigned int dying_time) { struct session_entry *result; int error; result = create_session_entry(remote4_id, local4_id, local6_id, remote6_id, bib, l4protocol, dying_time); if (!result) { log_warning("Could not allocate a session entry."); return NULL; } error = session_add(result); if (error) { log_warning("Could not insert the session entry to the table; call returned %d.", error); return NULL; } return result; }
bool simple_session(void) { struct session_entry *session; bool success = true; session = create_session_entry(1, 0, 1, 0, NULL, IPPROTO_TCP, 12345); if (!assert_not_null(session, "Allocation of test session entry")) return false; success &= assert_equals_int(0, session_add(session), "Session insertion call"); success &= assert_session("Session insertion state", session, false, true, false); if (!success) return false; /* See simple_bib(). */ success &= assert_true(session_remove(session), "Session removal call"); success &= assert_session("Session removal state", session, false, false, false); if (!success) return false; kfree(session); return true; }
/* * The main function. */ int main(int argc, char **argv) { struct arguments args; int error; error = parse_args(argc, argv, &args); if (error) return error; switch (args.mode) { case MODE_POOL6: switch (args.operation) { case OP_DISPLAY: return pool6_display(); case OP_ADD: if (!args.pool6_prefix_set) { log_err(ERR_MISSING_PARAM, "Please enter the prefix to be added (--prefix)."); return -EINVAL; } return pool6_add(&args.pool6_prefix); case OP_REMOVE: if (!args.pool6_prefix_set) { log_err(ERR_MISSING_PARAM, "Please enter the prefix to be removed (--prefix)."); return -EINVAL; } return pool6_remove(&args.pool6_prefix); default: log_err(ERR_UNKNOWN_OP, "Unknown operation for IPv6 pool mode: %u.", args.operation); return -EINVAL; } break; case MODE_POOL4: switch (args.operation) { case OP_DISPLAY: return pool4_display(); case OP_ADD: if (!args.pool4_addr_set) { log_err(ERR_MISSING_PARAM, "Please enter the address to be added (--address)."); return -EINVAL; } return pool4_add(&args.pool4_addr); case OP_REMOVE: if (!args.pool4_addr_set) { log_err(ERR_MISSING_PARAM, "Please enter the address to be removed (--address)."); return -EINVAL; } return pool4_remove(&args.pool4_addr); default: log_err(ERR_UNKNOWN_OP, "Unknown operation for IPv4 pool mode: %u.", args.operation); return -EINVAL; } case MODE_BIB: switch (args.operation) { case OP_DISPLAY: return bib_display(args.tcp, args.udp, args.icmp); default: log_err(ERR_UNKNOWN_OP, "Unknown operation for BIB mode: %u.", args.operation); return -EINVAL; } break; case MODE_SESSION: switch (args.operation) { case OP_DISPLAY: return session_display(args.tcp, args.udp, args.icmp); case OP_ADD: error = 0; if (!args.session_pair6_remote_set) { log_err(ERR_MISSING_PARAM, "Missing remote IPv6 address#port (--remote6)."); error = -EINVAL; } if (!args.session_pair6_local_set) { log_err(ERR_MISSING_PARAM, "Missing local IPv6 address#port (--local6)."); error = -EINVAL; } if (!args.session_pair4_local_set) { log_err(ERR_MISSING_PARAM, "Missing local IPv4 address#port (--local4)."); error = -EINVAL; } if (!args.session_pair4_remote_set) { log_err(ERR_MISSING_PARAM, "Missing remote IPv4 address#port (--remote4)."); error = -EINVAL; } if (error) return error; return session_add(args.tcp, args.udp, args.icmp, &args.session_pair6, &args.session_pair4); case OP_REMOVE: if (args.session_pair6_remote_set && args.session_pair6_local_set) return session_remove_ipv6(args.tcp, args.udp, args.icmp, &args.session_pair6); if (args.session_pair4_remote_set && args.session_pair4_local_set) return session_remove_ipv4(args.tcp, args.udp, args.icmp, &args.session_pair4); log_err(ERR_MISSING_PARAM, "You need to provide both the local and remote nodes' " "address#port, either from the IPv6 or the IPv4 side."); return -EINVAL; default: log_err(ERR_UNKNOWN_OP, "Unknown operation for session mode: %u.", args.operation); return -EINVAL; } break; case MODE_FILTERING: return filtering_request(args.operation, &args.filtering); case MODE_TRANSLATE: error = translate_request(args.operation, &args.translate); if (args.translate.mtu_plateaus) free(args.translate.mtu_plateaus); return error; default: log_err(ERR_EMPTY_COMMAND, "Command seems empty; --help or --usage for info."); return -EINVAL; } }
bool test_clean_old_sessions(void) { struct bib_entry *bibs[BIB_COUNT]; struct session_entry *sessions[BIB_COUNT][SESSIONS_PER_BIB]; int cbib, cses; // "BIB counter, session counter". Sorry; I use them too much. const unsigned int time_before = jiffies_to_msecs(jiffies) - 1000; const unsigned int time_after = jiffies_to_msecs(jiffies) + 1000; // Allocate. for (cbib = 0; cbib < BIB_COUNT; cbib++) { bibs[cbib] = create_bib_entry(cbib, cbib); if (!bibs[cbib]) { log_warning("Could not allocate a BIB entry %d.", cbib); return false; } } for (cbib = 0; cbib < BIB_COUNT; cbib++) { for (cses = 0; cses < SESSIONS_PER_BIB; cses++) { sessions[cbib][cses] = create_session_entry(cbib, cses + 5, cbib, cses + 5, bibs[cbib], IPPROTO_UDP, time_after); if (!sessions[cbib][cses]) { log_warning("Could not allocate a Session entry %d-%d.", cbib, cses); return false; } } } sessions[3][1]->is_static = true; // Insert to the tables. for (cbib = 0; cbib < BIB_COUNT; cbib++) { if (!bib_add(bibs[cbib], IPPROTO_UDP)) { log_warning("Could not add BIB entry %d.", cbib); return false; } } for (cbib = 0; cbib < BIB_COUNT; cbib++) { for (cses = 0; cses < SESSIONS_PER_BIB; cses++) { if (!session_add(sessions[cbib][cses])) { log_warning("Could not add session entry %d-%d.", cbib, cses); return false; } } } // 1. Nothing has expired: // Test nothing gets deleted. clean_expired_sessions(); ASSERT_SINGLE_BIB("Clean deletes nothing", 0, true, true, true, true); ASSERT_SINGLE_BIB("Clean deletes nothing", 1, true, true, true, true); ASSERT_SINGLE_BIB("Clean deletes nothing", 2, true, true, true, true); ASSERT_SINGLE_BIB("Clean deletes nothing", 3, true, true, true, true); // 2. All of a single BIB's sessions expire: // Test both BIBs and Sessions die. sessions[1][0]->dying_time = time_before; sessions[1][1]->dying_time = time_before; sessions[1][2]->dying_time = time_before; clean_expired_sessions(); ASSERT_SINGLE_BIB("Whole BIB dies", 0, true, true, true, true); ASSERT_SINGLE_BIB("Whole BIB dies", 1, false, false, false, false); ASSERT_SINGLE_BIB("Whole BIB dies", 2, true, true, true, true); ASSERT_SINGLE_BIB("Whole BIB dies", 3, true, true, true, true); // 3. Some sessions of a BIB expire: // Test only they get deleted. sessions[2][0]->dying_time = time_before; sessions[2][1]->dying_time = time_before; clean_expired_sessions(); ASSERT_SINGLE_BIB("Some sessions die", 0, true, true, true, true); ASSERT_SINGLE_BIB("Some sessions die", 1, false, false, false, false); ASSERT_SINGLE_BIB("Some sessions die", 2, true, false, false, true); ASSERT_SINGLE_BIB("Some sessions die", 3, true, true, true, true); // 4. The rest of them expire: // Test the BIB keeps keeps behaving as expected. Perhaps unnecesary. sessions[2][2]->dying_time = time_before; clean_expired_sessions(); ASSERT_SINGLE_BIB("Last session dies", 0, true, true, true, true); ASSERT_SINGLE_BIB("Last session dies", 1, false, false, false, false); ASSERT_SINGLE_BIB("Last session dies", 2, false, false, false, false); ASSERT_SINGLE_BIB("Last session dies", 3, true, true, true, true); // 5. The sessions of a static BIB expire, but one of them is static. // Test only the dynamic ones die. sessions[3][0]->dying_time = time_before; sessions[3][1]->dying_time = time_before; sessions[3][2]->dying_time = time_before; clean_expired_sessions(); ASSERT_SINGLE_BIB("Static session doesn't die", 0, true, true, true, true); ASSERT_SINGLE_BIB("Static session doesn't die", 1, false, false, false, false); ASSERT_SINGLE_BIB("Static session doesn't die", 2, false, false, false, false); ASSERT_SINGLE_BIB("Static session doesn't die", 3, true, false, true, false); // Quit. return true; }