/** * "ars" means add, remove, send */ static bool test_pkt_queue_ars(void) { struct session_entry *session; struct sk_buff *skb; struct tuple tuple4; struct tcphdr *hdr_tcp; bool success = true; /* Prepare */ if (is_error(init_ipv4_tuple(&tuple4, "5.6.7.8", 5678, "192.168.2.1", 8765, L4PROTO_TCP))) return false; session = session_create_str_tcp("1::2", 1212, "3::4", 3434, "192.168.2.1", 8765, "5.6.7.8", 5678, V4_INIT); /* The session entry that is supposed to be created in "tcp_close_state_handle". */ if (!session) return false; if (is_error(create_skb4_tcp(&tuple4, &skb, 100, 32))) { session_return(session); return false; } hdr_tcp = tcp_hdr(skb); hdr_tcp->syn = true; hdr_tcp->rst = false; hdr_tcp->fin = false; success &= assert_equals_int(0, pktqueue_add(session, skb), "pktqueue_add 1"); success &= assert_equals_int(0, pktqueue_remove(session), "pktqueue_remove 1"); success &= assert_equals_int(-ENOENT, pktqueue_send(session), "pktqueue_send 1"); success &= assert_equals_int(0, icmp64_pop(), "pktqueue not sent an icmp error"); session_return(session); /* kfree_skb(skb); "skb" kfreed when pktqueue_remove is executed */ return success; }
/** * Second half of the filtering and updating done during the CLOSED state of the TCP state machine. * Processes IPv4 SYN packets when there's no state. * Part of RFC 6146 section 3.5.2.2. */ static verdict tcp_closed_v4_syn(struct packet *pkt, struct tuple *tuple4) { struct bib_entry *bib; struct session_entry *session; int error; verdict result = VERDICT_DROP; if (config_get_drop_external_connections()) { log_debug("Applying policy: Dropping externally initiated TCP connections."); return VERDICT_DROP; } error = bibdb_get(tuple4, &bib); if (error) { if (error != -ESRCH) return VERDICT_DROP; bib = NULL; } log_bib(bib); error = create_session_ipv4(tuple4, bib, &session); if (error) goto end_bib; log_session(session); session->state = V4_INIT; if (!bib || config_get_addr_dependent_filtering()) { error = pktqueue_add(session, pkt); if (error) { if (error == -E2BIG) { /* Fall back to assume there's no Simultaneous Open. */ icmp64_send(pkt, ICMPERR_PORT_UNREACHABLE, 0); } goto end_session; } /* At this point, skb's original skb completely belongs to pktqueue. */ result = VERDICT_STOLEN; error = sessiondb_add(session, SESSIONTIMER_SYN); if (error) { log_debug("Error code %d while adding the session to the DB.", error); pktqueue_remove(session); goto end_session; } } else { error = sessiondb_add(session, SESSIONTIMER_TRANS); if (error) { log_debug("Error code %d while adding the session to the DB.", error); goto end_session; } result = VERDICT_CONTINUE; } /* Fall through. */ end_session: session_return(session); /* Fall through. */ end_bib: if (bib) bib_return(bib); return result; }