summaryrefslogtreecommitdiff
path: root/net/sctp/endpointola.c
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2022-11-16 15:01:20 -0500
committerDavid S. Miller <davem@davemloft.net>2022-11-18 11:42:54 +0000
commit0af03170637f47fb5cc6501d4b2dcbf1c14772a9 (patch)
tree5307ec19ec98002dc14ac83b5b0a8699f841edaa /net/sctp/endpointola.c
parent33e93ed2209d5971043bed41dd194bc583b57ef3 (diff)
sctp: add dif and sdif check in asoc and ep lookup
This patch at first adds a pernet global l3mdev_accept to decide if it accepts the packets from a l3mdev when a SCTP socket doesn't bind to any interface. It's set to 1 to avoid any possible incompatible issue, and in next patch, a sysctl will be introduced to allow to change it. Then similar to inet/udp_sk_bound_dev_eq(), sctp_sk_bound_dev_eq() is added to check either dif or sdif is equal to sk_bound_dev_if, and to check sid is 0 or l3mdev_accept is 1 if sk_bound_dev_if is not set. This function is used to match a association or a endpoint, namely called by sctp_addrs_lookup_transport() and sctp_endpoint_is_match(). All functions that needs updating are: sctp_rcv(): asoc: __sctp_rcv_lookup() __sctp_lookup_association() -> sctp_addrs_lookup_transport() __sctp_rcv_lookup_harder() __sctp_rcv_init_lookup() __sctp_lookup_association() -> sctp_addrs_lookup_transport() __sctp_rcv_walk_lookup() __sctp_rcv_asconf_lookup() __sctp_lookup_association() -> sctp_addrs_lookup_transport() ep: __sctp_rcv_lookup_endpoint() -> sctp_endpoint_is_match() sctp_connect(): sctp_endpoint_is_peeled_off() __sctp_lookup_association() sctp_has_association() sctp_lookup_association() __sctp_lookup_association() -> sctp_addrs_lookup_transport() sctp_diag_dump_one(): sctp_transport_lookup_process() -> sctp_addrs_lookup_transport() Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/endpointola.c')
-rw-r--r--net/sctp/endpointola.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index efffde7f2328..7e77b450697c 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -246,12 +246,15 @@ void sctp_endpoint_put(struct sctp_endpoint *ep)
/* Is this the endpoint we are looking for? */
struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep,
struct net *net,
- const union sctp_addr *laddr)
+ const union sctp_addr *laddr,
+ int dif, int sdif)
{
+ int bound_dev_if = READ_ONCE(ep->base.sk->sk_bound_dev_if);
struct sctp_endpoint *retval = NULL;
- if ((htons(ep->base.bind_addr.port) == laddr->v4.sin_port) &&
- net_eq(ep->base.net, net)) {
+ if (net_eq(ep->base.net, net) &&
+ sctp_sk_bound_dev_eq(net, bound_dev_if, dif, sdif) &&
+ (htons(ep->base.bind_addr.port) == laddr->v4.sin_port)) {
if (sctp_bind_addr_match(&ep->base.bind_addr, laddr,
sctp_sk(ep->base.sk)))
retval = ep;
@@ -298,6 +301,7 @@ out:
bool sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
const union sctp_addr *paddr)
{
+ int bound_dev_if = READ_ONCE(ep->base.sk->sk_bound_dev_if);
struct sctp_sockaddr_entry *addr;
struct net *net = ep->base.net;
struct sctp_bind_addr *bp;
@@ -307,7 +311,8 @@ bool sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
* so the address_list can not change.
*/
list_for_each_entry(addr, &bp->address_list, list) {
- if (sctp_has_association(net, &addr->a, paddr))
+ if (sctp_has_association(net, &addr->a, paddr,
+ bound_dev_if, bound_dev_if))
return true;
}