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

Commit 0fd9a65a authored by Neil Horman's avatar Neil Horman Committed by David S. Miller
Browse files

[SCTP] Support SO_BINDTODEVICE socket option on incoming packets.

parent 4243cac1
Loading
Loading
Loading
Loading
+34 −15
Original line number Original line Diff line number Diff line
@@ -178,6 +178,37 @@ int sctp_rcv(struct sk_buff *skb)


	asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);
	asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport);


	if (!asoc)
		ep = __sctp_rcv_lookup_endpoint(&dest);

	/* Retrieve the common input handling substructure. */
	rcvr = asoc ? &asoc->base : &ep->base;
	sk = rcvr->sk;

	/*
	 * If a frame arrives on an interface and the receiving socket is
	 * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB
	 */
	if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb)))
	{
		sock_put(sk);
		if (asoc) {
			sctp_association_put(asoc);
			asoc = NULL;
		} else {
			sctp_endpoint_put(ep);
			ep = NULL;
		}
		sk = sctp_get_ctl_sock();
		ep = sctp_sk(sk)->ep;
		sctp_endpoint_hold(ep);
		sock_hold(sk);
		rcvr = &ep->base;
	}

	if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
		goto discard_release;

	/*
	/*
	 * RFC 2960, 8.4 - Handle "Out of the blue" Packets.
	 * RFC 2960, 8.4 - Handle "Out of the blue" Packets.
	 * An SCTP packet is called an "out of the blue" (OOTB)
	 * An SCTP packet is called an "out of the blue" (OOTB)
@@ -187,22 +218,12 @@ int sctp_rcv(struct sk_buff *skb)
	 * packet belongs.
	 * packet belongs.
	 */
	 */
	if (!asoc) {
	if (!asoc) {
		ep = __sctp_rcv_lookup_endpoint(&dest);
		if (sctp_rcv_ootb(skb)) {
		if (sctp_rcv_ootb(skb)) {
			SCTP_INC_STATS_BH(SCTP_MIB_OUTOFBLUES);
			SCTP_INC_STATS_BH(SCTP_MIB_OUTOFBLUES);
			goto discard_release;
			goto discard_release;
		}
		}
	}
	}


	/* Retrieve the common input handling substructure. */
	rcvr = asoc ? &asoc->base : &ep->base;
	sk = rcvr->sk;

	if ((sk) && (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)) {
		goto discard_release;
	}


	/* SCTP seems to always need a timestamp right now (FIXME) */
	/* SCTP seems to always need a timestamp right now (FIXME) */
	if (skb->stamp.tv_sec == 0) {
	if (skb->stamp.tv_sec == 0) {
		do_gettimeofday(&skb->stamp);
		do_gettimeofday(&skb->stamp);
@@ -265,13 +286,11 @@ discard_it:


discard_release:
discard_release:
	/* Release any structures we may be holding. */
	/* Release any structures we may be holding. */
	if (asoc) {
	sock_put(sk);
		sock_put(asoc->base.sk);
	if (asoc)
		sctp_association_put(asoc);
		sctp_association_put(asoc);
	} else {
	else
		sock_put(ep->base.sk);
		sctp_endpoint_put(ep);
		sctp_endpoint_put(ep);
	}


	goto discard_it;
	goto discard_it;
}
}