Exemple #1
0
static unsigned int nat64_core(struct sk_buff *skb_in,
		bool (*compute_out_tuple_fn)(struct tuple *, struct sk_buff *, struct tuple *),
		bool (*translate_packet_fn)(struct tuple *, struct sk_buff *, struct sk_buff **),
		bool (*send_packet_fn)(struct sk_buff *, struct sk_buff *))
{
	struct sk_buff *skb_out = NULL;
	struct tuple tuple_in, tuple_out;

	if (!determine_in_tuple(skb_in, &tuple_in))
		goto free_and_fail;
	if (filtering_and_updating(skb_in, &tuple_in) != NF_ACCEPT)
		goto free_and_fail;
	if (!compute_out_tuple_fn(&tuple_in, skb_in, &tuple_out))
		goto free_and_fail;
	if (!translate_packet_fn(&tuple_out, skb_in, &skb_out))
		goto free_and_fail;
	if (is_hairpin(&tuple_out)) {
		if (!handling_hairpinning(skb_out, &tuple_out))
			goto free_and_fail;
	} else {
		if (!send_packet_fn(skb_in, skb_out))
			goto fail;
	}

	log_debug("Success.");
	return NF_DROP; /* Lol, the irony. */

free_and_fail:
	kfree_skb(skb_out);
	/* Fall through. */

fail:
	log_debug("Failure.");
	return NF_DROP;
}
Exemple #2
0
static unsigned int core_common(struct packet *in)
{
	struct packet out;
	struct tuple tuple_in;
	struct tuple tuple_out;
	verdict result;

	result = determine_in_tuple(in, &tuple_in);
	if (result != VERDICT_CONTINUE)
		goto end;
	result = filtering_and_updating(in, &tuple_in);
	if (result != VERDICT_CONTINUE)
		goto end;
	result = compute_out_tuple(&tuple_in, &tuple_out, in);
	if (result != VERDICT_CONTINUE)
		goto end;
	result = translating_the_packet(&tuple_out, in, &out);
	if (result != VERDICT_CONTINUE)
		goto end;

	if (is_hairpin(&out)) {
		result = handling_hairpinning(&out, &tuple_out);
		kfree_skb(out.skb);
	} else {
		result = sendpkt_send(in, &out);
		/* send_pkt releases skb_out regardless of verdict. */
	}

	if (result != VERDICT_CONTINUE)
		goto end;

	log_debug("Success.");
	/*
	 * The new packet was sent, so the original one can die; drop it.
	 *
	 * NF_DROP translates into an error (see nf_hook_slow()).
	 * Sending a replacing & translated version of the packet should not count as an error,
	 * so we free the incoming packet ourselves and return NF_STOLEN on success.
	 */
	kfree_skb(in->skb);
	result = VERDICT_STOLEN;
	/* Fall through. */

end:
	if (result == VERDICT_ACCEPT)
		log_debug("Returning the packet to the kernel.");

	return (unsigned int) result;
}