forked from mirrors/linux
		
	[SCTP] Support SO_BINDTODEVICE socket option on incoming packets.
Signed-off-by: Neil Horman <nhorman@redhat.com> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									4243cac1e7
								
							
						
					
					
						commit
						0fd9a65a76
					
				
					 1 changed files with 34 additions and 15 deletions
				
			
		| 
						 | 
					@ -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 @@ int sctp_rcv(struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue