Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ece639ca authored by David S. Miller's avatar David S. Miller
Browse files
parents 0cc9d525 0af320fb
Loading
Loading
Loading
Loading
+1 −11
Original line number Diff line number Diff line
@@ -201,18 +201,8 @@ nf_tproxy_get_sock_v6(struct net *net, const u8 protocol,
}
#endif

static inline void
nf_tproxy_put_sock(struct sock *sk)
{
	/* TIME_WAIT inet sockets have to be handled differently */
	if ((sk->sk_protocol == IPPROTO_TCP) && (sk->sk_state == TCP_TIME_WAIT))
		inet_twsk_put(inet_twsk(sk));
	else
		sock_put(sk);
}

/* assign a socket to the skb -- consumes sk */
int
void
nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk);

#endif
+1 −1
Original line number Diff line number Diff line
@@ -410,7 +410,7 @@ fallback:
		if (p != NULL) {
			sb_add(m, "%02x", *p++);
			for (i = 1; i < len; i++)
				sb_add(m, ":%02x", p[i]);
				sb_add(m, ":%02x", *p++);
		}
		sb_add(m, " ");

+12 −15
Original line number Diff line number Diff line
@@ -28,26 +28,23 @@ nf_tproxy_destructor(struct sk_buff *skb)
	skb->destructor = NULL;

	if (sk)
		nf_tproxy_put_sock(sk);
		sock_put(sk);
}

/* consumes sk */
int
void
nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
{
	bool transparent = (sk->sk_state == TCP_TIME_WAIT) ?
				inet_twsk(sk)->tw_transparent :
				inet_sk(sk)->transparent;
	/* assigning tw sockets complicates things; most
	 * skb->sk->X checks would have to test sk->sk_state first */
	if (sk->sk_state == TCP_TIME_WAIT) {
		inet_twsk_put(inet_twsk(sk));
		return;
	}

	if (transparent) {
	skb_orphan(skb);
	skb->sk = sk;
	skb->destructor = nf_tproxy_destructor;
		return 1;
	} else
		nf_tproxy_put_sock(sk);

	return 0;
}
EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock);

+20 −2
Original line number Diff line number Diff line
@@ -33,6 +33,20 @@
#include <net/netfilter/nf_tproxy_core.h>
#include <linux/netfilter/xt_TPROXY.h>

static bool tproxy_sk_is_transparent(struct sock *sk)
{
	if (sk->sk_state != TCP_TIME_WAIT) {
		if (inet_sk(sk)->transparent)
			return true;
		sock_put(sk);
	} else {
		if (inet_twsk(sk)->tw_transparent)
			return true;
		inet_twsk_put(inet_twsk(sk));
	}
	return false;
}

static inline __be32
tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr)
{
@@ -141,7 +155,7 @@ tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport,
					   skb->dev, NFT_LOOKUP_LISTENER);

	/* NOTE: assign_sock consumes our sk reference */
	if (sk && nf_tproxy_assign_sock(skb, sk)) {
	if (sk && tproxy_sk_is_transparent(sk)) {
		/* This should be in a separate target, but we don't do multiple
		   targets on the same rule yet */
		skb->mark = (skb->mark & ~mark_mask) ^ mark_value;
@@ -149,6 +163,8 @@ tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport,
		pr_debug("redirecting: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n",
			 iph->protocol, &iph->daddr, ntohs(hp->dest),
			 &laddr, ntohs(lport), skb->mark);

		nf_tproxy_assign_sock(skb, sk);
		return NF_ACCEPT;
	}

@@ -306,7 +322,7 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par)
					   par->in, NFT_LOOKUP_LISTENER);

	/* NOTE: assign_sock consumes our sk reference */
	if (sk && nf_tproxy_assign_sock(skb, sk)) {
	if (sk && tproxy_sk_is_transparent(sk)) {
		/* This should be in a separate target, but we don't do multiple
		   targets on the same rule yet */
		skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value;
@@ -314,6 +330,8 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par)
		pr_debug("redirecting: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n",
			 tproto, &iph->saddr, ntohs(hp->source),
			 laddr, ntohs(lport), skb->mark);

		nf_tproxy_assign_sock(skb, sk);
		return NF_ACCEPT;
	}

+11 −2
Original line number Diff line number Diff line
@@ -35,6 +35,15 @@
#include <net/netfilter/nf_conntrack.h>
#endif

static void
xt_socket_put_sk(struct sock *sk)
{
	if (sk->sk_state == TCP_TIME_WAIT)
		inet_twsk_put(inet_twsk(sk));
	else
		sock_put(sk);
}

static int
extract_icmp4_fields(const struct sk_buff *skb,
		    u8 *protocol,
@@ -164,7 +173,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
				       (sk->sk_state == TCP_TIME_WAIT &&
					inet_twsk(sk)->tw_transparent));

		nf_tproxy_put_sock(sk);
		xt_socket_put_sk(sk);

		if (wildcard || !transparent)
			sk = NULL;
@@ -298,7 +307,7 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
				       (sk->sk_state == TCP_TIME_WAIT &&
					inet_twsk(sk)->tw_transparent));

		nf_tproxy_put_sock(sk);
		xt_socket_put_sk(sk);

		if (wildcard || !transparent)
			sk = NULL;