Commit 2ce95503 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by David S. Miller

sctp: Make the ctl_sock per network namespace

- Kill sctp_get_ctl_sock, it is useless now.
- Pass struct net where needed so net->sctp.ctl_sock is accessible.
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Acked-by: default avatarVlad Yasevich <vyasevich@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4db67e80
#ifndef __NETNS_SCTP_H__ #ifndef __NETNS_SCTP_H__
#define __NETNS_SCTP_H__ #define __NETNS_SCTP_H__
struct sock;
struct netns_sctp { struct netns_sctp {
/* This is the global socket data structure used for responding to
* the Out-of-the-blue (OOTB) packets. A control sock will be created
* for this socket at the initialization time.
*/
struct sock *ctl_sock;
/* This is the global local address list. /* This is the global local address list.
* We actively maintain this complete list of addresses on * We actively maintain this complete list of addresses on
* the system by catching address add/delete events. * the system by catching address add/delete events.
......
...@@ -114,7 +114,6 @@ ...@@ -114,7 +114,6 @@
/* /*
* sctp/protocol.c * sctp/protocol.c
*/ */
extern struct sock *sctp_get_ctl_sock(void);
extern int sctp_copy_local_addr_list(struct net *, struct sctp_bind_addr *, extern int sctp_copy_local_addr_list(struct net *, struct sctp_bind_addr *,
sctp_scope_t, gfp_t gfp, sctp_scope_t, gfp_t gfp,
int flags); int flags);
......
...@@ -204,7 +204,7 @@ int sctp_rcv(struct sk_buff *skb) ...@@ -204,7 +204,7 @@ int sctp_rcv(struct sk_buff *skb)
sctp_endpoint_put(ep); sctp_endpoint_put(ep);
ep = NULL; ep = NULL;
} }
sk = sctp_get_ctl_sock(); sk = net->sctp.ctl_sock;
ep = sctp_sk(sk)->ep; ep = sctp_sk(sk)->ep;
sctp_endpoint_hold(ep); sctp_endpoint_hold(ep);
rcvr = &ep->base; rcvr = &ep->base;
...@@ -795,7 +795,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net, ...@@ -795,7 +795,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
goto hit; goto hit;
} }
ep = sctp_sk((sctp_get_ctl_sock()))->ep; ep = sctp_sk(net->sctp.ctl_sock)->ep;
hit: hit:
sctp_endpoint_hold(ep); sctp_endpoint_hold(ep);
......
...@@ -78,12 +78,6 @@ struct proc_dir_entry *proc_net_sctp; ...@@ -78,12 +78,6 @@ struct proc_dir_entry *proc_net_sctp;
struct idr sctp_assocs_id; struct idr sctp_assocs_id;
DEFINE_SPINLOCK(sctp_assocs_id_lock); DEFINE_SPINLOCK(sctp_assocs_id_lock);
/* This is the global socket data structure used for responding to
* the Out-of-the-blue (OOTB) packets. A control sock will be created
* for this socket at the initialization time.
*/
static struct sock *sctp_ctl_sock;
static struct sctp_pf *sctp_pf_inet6_specific; static struct sctp_pf *sctp_pf_inet6_specific;
static struct sctp_pf *sctp_pf_inet_specific; static struct sctp_pf *sctp_pf_inet_specific;
static struct sctp_af *sctp_af_v4_specific; static struct sctp_af *sctp_af_v4_specific;
...@@ -96,12 +90,6 @@ long sysctl_sctp_mem[3]; ...@@ -96,12 +90,6 @@ long sysctl_sctp_mem[3];
int sysctl_sctp_rmem[3]; int sysctl_sctp_rmem[3];
int sysctl_sctp_wmem[3]; int sysctl_sctp_wmem[3];
/* Return the address of the control sock. */
struct sock *sctp_get_ctl_sock(void)
{
return sctp_ctl_sock;
}
/* Set up the proc fs entry for the SCTP protocol. */ /* Set up the proc fs entry for the SCTP protocol. */
static __init int sctp_proc_init(void) static __init int sctp_proc_init(void)
{ {
...@@ -822,7 +810,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, ...@@ -822,7 +810,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
* Initialize the control inode/socket with a control endpoint data * Initialize the control inode/socket with a control endpoint data
* structure. This endpoint is reserved exclusively for the OOTB processing. * structure. This endpoint is reserved exclusively for the OOTB processing.
*/ */
static int sctp_ctl_sock_init(void) static int sctp_ctl_sock_init(struct net *net)
{ {
int err; int err;
sa_family_t family = PF_INET; sa_family_t family = PF_INET;
...@@ -830,14 +818,14 @@ static int sctp_ctl_sock_init(void) ...@@ -830,14 +818,14 @@ static int sctp_ctl_sock_init(void)
if (sctp_get_pf_specific(PF_INET6)) if (sctp_get_pf_specific(PF_INET6))
family = PF_INET6; family = PF_INET6;
err = inet_ctl_sock_create(&sctp_ctl_sock, family, err = inet_ctl_sock_create(&net->sctp.ctl_sock, family,
SOCK_SEQPACKET, IPPROTO_SCTP, &init_net); SOCK_SEQPACKET, IPPROTO_SCTP, net);
/* If IPv6 socket could not be created, try the IPv4 socket */ /* If IPv6 socket could not be created, try the IPv4 socket */
if (err < 0 && family == PF_INET6) if (err < 0 && family == PF_INET6)
err = inet_ctl_sock_create(&sctp_ctl_sock, AF_INET, err = inet_ctl_sock_create(&net->sctp.ctl_sock, AF_INET,
SOCK_SEQPACKET, IPPROTO_SCTP, SOCK_SEQPACKET, IPPROTO_SCTP,
&init_net); net);
if (err < 0) { if (err < 0) {
pr_err("Failed to create the SCTP control socket\n"); pr_err("Failed to create the SCTP control socket\n");
...@@ -1196,6 +1184,14 @@ static void sctp_v4_del_protocol(void) ...@@ -1196,6 +1184,14 @@ static void sctp_v4_del_protocol(void)
static int sctp_net_init(struct net *net) static int sctp_net_init(struct net *net)
{ {
int status;
/* Initialize the control inode/socket for handling OOTB packets. */
if ((status = sctp_ctl_sock_init(net))) {
pr_err("Failed to initialize the SCTP control sock\n");
goto err_ctl_sock_init;
}
/* Initialize the local address list. */ /* Initialize the local address list. */
INIT_LIST_HEAD(&net->sctp.local_addr_list); INIT_LIST_HEAD(&net->sctp.local_addr_list);
spin_lock_init(&net->sctp.local_addr_lock); spin_lock_init(&net->sctp.local_addr_lock);
...@@ -1210,6 +1206,9 @@ static int sctp_net_init(struct net *net) ...@@ -1210,6 +1206,9 @@ static int sctp_net_init(struct net *net)
(unsigned long)net); (unsigned long)net);
return 0; return 0;
err_ctl_sock_init:
return status;
} }
static void sctp_net_exit(struct net *net) static void sctp_net_exit(struct net *net)
...@@ -1217,6 +1216,9 @@ static void sctp_net_exit(struct net *net) ...@@ -1217,6 +1216,9 @@ static void sctp_net_exit(struct net *net)
/* Free the local address list */ /* Free the local address list */
sctp_free_addr_wq(net); sctp_free_addr_wq(net);
sctp_free_local_addr_list(net); sctp_free_local_addr_list(net);
/* Free the control endpoint. */
inet_ctl_sock_destroy(net->sctp.ctl_sock);
} }
static struct pernet_operations sctp_net_ops = { static struct pernet_operations sctp_net_ops = {
...@@ -1438,12 +1440,6 @@ SCTP_STATIC __init int sctp_init(void) ...@@ -1438,12 +1440,6 @@ SCTP_STATIC __init int sctp_init(void)
if (status) if (status)
goto err_v6_protosw_init; goto err_v6_protosw_init;
/* Initialize the control inode/socket for handling OOTB packets. */
if ((status = sctp_ctl_sock_init())) {
pr_err("Failed to initialize the SCTP control sock\n");
goto err_ctl_sock_init;
}
status = register_pernet_subsys(&sctp_net_ops); status = register_pernet_subsys(&sctp_net_ops);
if (status) if (status)
goto err_register_pernet_subsys; goto err_register_pernet_subsys;
...@@ -1465,8 +1461,6 @@ SCTP_STATIC __init int sctp_init(void) ...@@ -1465,8 +1461,6 @@ SCTP_STATIC __init int sctp_init(void)
err_add_protocol: err_add_protocol:
unregister_pernet_subsys(&sctp_net_ops); unregister_pernet_subsys(&sctp_net_ops);
err_register_pernet_subsys: err_register_pernet_subsys:
inet_ctl_sock_destroy(sctp_ctl_sock);
err_ctl_sock_init:
sctp_v6_protosw_exit(); sctp_v6_protosw_exit();
err_v6_protosw_init: err_v6_protosw_init:
sctp_v4_protosw_exit(); sctp_v4_protosw_exit();
...@@ -1506,9 +1500,6 @@ SCTP_STATIC __exit void sctp_exit(void) ...@@ -1506,9 +1500,6 @@ SCTP_STATIC __exit void sctp_exit(void)
sctp_v6_del_protocol(); sctp_v6_del_protocol();
sctp_v4_del_protocol(); sctp_v4_del_protocol();
/* Free the control endpoint. */
inet_ctl_sock_destroy(sctp_ctl_sock);
unregister_pernet_subsys(&sctp_net_ops); unregister_pernet_subsys(&sctp_net_ops);
/* Free protosw registrations */ /* Free protosw registrations */
......
...@@ -74,7 +74,8 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep, ...@@ -74,7 +74,8 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
static int sctp_eat_data(const struct sctp_association *asoc, static int sctp_eat_data(const struct sctp_association *asoc,
struct sctp_chunk *chunk, struct sctp_chunk *chunk,
sctp_cmd_seq_t *commands); sctp_cmd_seq_t *commands);
static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc, static struct sctp_packet *sctp_ootb_pkt_new(struct net *net,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk); const struct sctp_chunk *chunk);
static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep, static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
const struct sctp_association *asoc, const struct sctp_association *asoc,
...@@ -301,6 +302,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, ...@@ -301,6 +302,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
struct sctp_chunk *err_chunk; struct sctp_chunk *err_chunk;
struct sctp_packet *packet; struct sctp_packet *packet;
sctp_unrecognized_param_t *unk_param; sctp_unrecognized_param_t *unk_param;
struct net *net;
int len; int len;
/* 6.10 Bundling /* 6.10 Bundling
...@@ -318,7 +320,8 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, ...@@ -318,7 +320,8 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
/* If the packet is an OOTB packet which is temporarily on the /* If the packet is an OOTB packet which is temporarily on the
* control endpoint, respond with an ABORT. * control endpoint, respond with an ABORT.
*/ */
if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) { net = sock_net(ep->base.sk);
if (ep == sctp_sk(net->sctp.ctl_sock)->ep) {
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
} }
...@@ -646,11 +649,13 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, ...@@ -646,11 +649,13 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
int error = 0; int error = 0;
struct sctp_chunk *err_chk_p; struct sctp_chunk *err_chk_p;
struct sock *sk; struct sock *sk;
struct net *net;
/* If the packet is an OOTB packet which is temporarily on the /* If the packet is an OOTB packet which is temporarily on the
* control endpoint, respond with an ABORT. * control endpoint, respond with an ABORT.
*/ */
if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) { net = sock_net(ep->base.sk);
if (ep == sctp_sk(net->sctp.ctl_sock)->ep) {
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
} }
...@@ -1171,7 +1176,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, ...@@ -1171,7 +1176,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
/* Helper function to send out an abort for the restart /* Helper function to send out an abort for the restart
* condition. * condition.
*/ */
static int sctp_sf_send_restart_abort(union sctp_addr *ssa, static int sctp_sf_send_restart_abort(struct net *net, union sctp_addr *ssa,
struct sctp_chunk *init, struct sctp_chunk *init,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
...@@ -1197,7 +1202,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa, ...@@ -1197,7 +1202,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
errhdr->length = htons(len); errhdr->length = htons(len);
/* Assign to the control socket. */ /* Assign to the control socket. */
ep = sctp_sk((sctp_get_ctl_sock()))->ep; ep = sctp_sk(net->sctp.ctl_sock)->ep;
/* Association is NULL since this may be a restart attack and we /* Association is NULL since this may be a restart attack and we
* want to send back the attacker's vtag. * want to send back the attacker's vtag.
...@@ -1240,6 +1245,7 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, ...@@ -1240,6 +1245,7 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
struct sctp_chunk *init, struct sctp_chunk *init,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
struct net *net = sock_net(new_asoc->base.sk);
struct sctp_transport *new_addr; struct sctp_transport *new_addr;
int ret = 1; int ret = 1;
...@@ -1258,7 +1264,7 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, ...@@ -1258,7 +1264,7 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
transports) { transports) {
if (!list_has_sctp_addr(&asoc->peer.transport_addr_list, if (!list_has_sctp_addr(&asoc->peer.transport_addr_list,
&new_addr->ipaddr)) { &new_addr->ipaddr)) {
sctp_sf_send_restart_abort(&new_addr->ipaddr, init, sctp_sf_send_restart_abort(net, &new_addr->ipaddr, init,
commands); commands);
ret = 0; ret = 0;
break; break;
...@@ -1650,10 +1656,11 @@ sctp_disposition_t sctp_sf_do_5_2_3_initack(const struct sctp_endpoint *ep, ...@@ -1650,10 +1656,11 @@ sctp_disposition_t sctp_sf_do_5_2_3_initack(const struct sctp_endpoint *ep,
const sctp_subtype_t type, const sctp_subtype_t type,
void *arg, sctp_cmd_seq_t *commands) void *arg, sctp_cmd_seq_t *commands)
{ {
struct net *net = sock_net(ep->base.sk);
/* Per the above section, we'll discard the chunk if we have an /* Per the above section, we'll discard the chunk if we have an
* endpoint. If this is an OOTB INIT-ACK, treat it as such. * endpoint. If this is an OOTB INIT-ACK, treat it as such.
*/ */
if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) if (ep == sctp_sk(net->sctp.ctl_sock)->ep)
return sctp_sf_ootb(ep, asoc, type, arg, commands); return sctp_sf_ootb(ep, asoc, type, arg, commands);
else else
return sctp_sf_discard_chunk(ep, asoc, type, arg, commands); return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
...@@ -3163,8 +3170,10 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, ...@@ -3163,8 +3170,10 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
struct sctp_packet *packet = NULL; struct sctp_packet *packet = NULL;
struct sctp_chunk *chunk = arg; struct sctp_chunk *chunk = arg;
struct sctp_chunk *abort; struct sctp_chunk *abort;
struct net *net;
packet = sctp_ootb_pkt_new(asoc, chunk); net = sock_net(ep->base.sk);
packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (packet) { if (packet) {
/* Make an ABORT. The T bit will be set if the asoc /* Make an ABORT. The T bit will be set if the asoc
...@@ -3425,8 +3434,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, ...@@ -3425,8 +3434,10 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
struct sctp_packet *packet = NULL; struct sctp_packet *packet = NULL;
struct sctp_chunk *chunk = arg; struct sctp_chunk *chunk = arg;
struct sctp_chunk *shut; struct sctp_chunk *shut;
struct net *net;
packet = sctp_ootb_pkt_new(asoc, chunk); net = sock_net(ep->base.sk);
packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (packet) { if (packet) {
/* Make an SHUTDOWN_COMPLETE. /* Make an SHUTDOWN_COMPLETE.
...@@ -4262,6 +4273,7 @@ static sctp_disposition_t sctp_sf_abort_violation( ...@@ -4262,6 +4273,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
struct sctp_packet *packet = NULL; struct sctp_packet *packet = NULL;
struct sctp_chunk *chunk = arg; struct sctp_chunk *chunk = arg;
struct sctp_chunk *abort = NULL; struct sctp_chunk *abort = NULL;
struct net *net;
/* SCTP-AUTH, Section 6.3: /* SCTP-AUTH, Section 6.3:
* It should be noted that if the receiver wants to tear * It should be noted that if the receiver wants to tear
...@@ -4282,6 +4294,7 @@ static sctp_disposition_t sctp_sf_abort_violation( ...@@ -4282,6 +4294,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
if (!abort) if (!abort)
goto nomem; goto nomem;
net = sock_net(ep->base.sk);
if (asoc) { if (asoc) {
/* Treat INIT-ACK as a special case during COOKIE-WAIT. */ /* Treat INIT-ACK as a special case during COOKIE-WAIT. */
if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK && if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK &&
...@@ -4319,7 +4332,7 @@ static sctp_disposition_t sctp_sf_abort_violation( ...@@ -4319,7 +4332,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
} }
} else { } else {
packet = sctp_ootb_pkt_new(asoc, chunk); packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (!packet) if (!packet)
goto nomem_pkt; goto nomem_pkt;
...@@ -5825,8 +5838,10 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep, ...@@ -5825,8 +5838,10 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
{ {
struct sctp_packet *packet; struct sctp_packet *packet;
struct sctp_chunk *abort; struct sctp_chunk *abort;
struct net *net;
packet = sctp_ootb_pkt_new(asoc, chunk); net = sock_net(ep->base.sk);
packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (packet) { if (packet) {
/* Make an ABORT. /* Make an ABORT.
...@@ -5858,7 +5873,8 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep, ...@@ -5858,7 +5873,8 @@ static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
} }
/* Allocate a packet for responding in the OOTB conditions. */ /* Allocate a packet for responding in the OOTB conditions. */
static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc, static struct sctp_packet *sctp_ootb_pkt_new(struct net *net,
const struct sctp_association *asoc,
const struct sctp_chunk *chunk) const struct sctp_chunk *chunk)
{ {
struct sctp_packet *packet; struct sctp_packet *packet;
...@@ -5919,7 +5935,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc ...@@ -5919,7 +5935,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc
* the source address. * the source address.
*/ */
sctp_transport_route(transport, (union sctp_addr *)&chunk->dest, sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
sctp_sk(sctp_get_ctl_sock())); sctp_sk(net->sctp.ctl_sock));
packet = sctp_packet_init(&transport->packet, transport, sport, dport); packet = sctp_packet_init(&transport->packet, transport, sport, dport);
packet = sctp_packet_config(packet, vtag, 0); packet = sctp_packet_config(packet, vtag, 0);
...@@ -5946,7 +5962,8 @@ static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep, ...@@ -5946,7 +5962,8 @@ static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
struct sctp_packet *packet; struct sctp_packet *packet;
if (err_chunk) { if (err_chunk) {
packet = sctp_ootb_pkt_new(asoc, chunk); struct net *net = sock_net(ep->base.sk);
packet = sctp_ootb_pkt_new(net, asoc, chunk);
if (packet) { if (packet) {
struct sctp_signed_cookie *cookie; struct sctp_signed_cookie *cookie;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment