diff --git a/net/tipc/link.c b/net/tipc/link.c index d1a764b9b2d8..a42f4a1d3cd1 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -327,8 +327,6 @@ static int link_schedule_port(struct tipc_link *l_ptr, u32 origport, u32 sz) spin_lock_bh(&tipc_port_list_lock); p_ptr = tipc_port_lock(origport); if (p_ptr) { - if (!p_ptr->wakeup) - goto exit; if (!list_empty(&p_ptr->wait_list)) goto exit; p_ptr->congested = 1; @@ -363,7 +361,7 @@ void tipc_link_wakeup_ports(struct tipc_link *l_ptr, int all) list_del_init(&p_ptr->wait_list); spin_lock_bh(p_ptr->lock); p_ptr->congested = 0; - p_ptr->wakeup(p_ptr); + tipc_port_wakeup(p_ptr); win -= p_ptr->waiting_pkts; spin_unlock_bh(p_ptr->lock); } diff --git a/net/tipc/port.c b/net/tipc/port.c index c7c2b549a39e..5c14c7801ee6 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -1,7 +1,7 @@ /* * net/tipc/port.c: TIPC port code * - * Copyright (c) 1992-2007, Ericsson AB + * Copyright (c) 1992-2007, 2014, Ericsson AB * Copyright (c) 2004-2008, 2010-2013, Wind River Systems * All rights reserved. * @@ -38,6 +38,7 @@ #include "config.h" #include "port.h" #include "name_table.h" +#include "socket.h" /* Connection management: */ #define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ @@ -54,17 +55,6 @@ static struct sk_buff *port_build_self_abort_msg(struct tipc_port *, u32 err); static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *, u32 err); static void port_timeout(unsigned long ref); - -static u32 port_peernode(struct tipc_port *p_ptr) -{ - return msg_destnode(&p_ptr->phdr); -} - -static u32 port_peerport(struct tipc_port *p_ptr) -{ - return msg_destport(&p_ptr->phdr); -} - /** * tipc_port_peer_msg - verify message was sent by connected port's peer * @@ -76,11 +66,11 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg) u32 peernode; u32 orignode; - if (msg_origport(msg) != port_peerport(p_ptr)) + if (msg_origport(msg) != tipc_port_peerport(p_ptr)) return 0; orignode = msg_orignode(msg); - peernode = port_peernode(p_ptr); + peernode = tipc_port_peernode(p_ptr); return (orignode == peernode) || (!orignode && (peernode == tipc_own_addr)) || (!peernode && (orignode == tipc_own_addr)); @@ -90,20 +80,18 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg) * tipc_port_mcast_xmit - send a multicast message to local and remote * destinations */ -int tipc_port_mcast_xmit(u32 ref, struct tipc_name_seq const *seq, - struct iovec const *msg_sect, unsigned int len) +int tipc_port_mcast_xmit(struct tipc_port *oport, + struct tipc_name_seq const *seq, + struct iovec const *msg_sect, + unsigned int len) { struct tipc_msg *hdr; struct sk_buff *buf; struct sk_buff *ibuf = NULL; struct tipc_port_list dports = {0, NULL, }; - struct tipc_port *oport = tipc_port_deref(ref); int ext_targets; int res; - if (unlikely(!oport)) - return -EINVAL; - /* Create multicast message */ hdr = &oport->phdr; msg_set_type(hdr, TIPC_MCAST_MSG); @@ -200,40 +188,32 @@ void tipc_port_mcast_rcv(struct sk_buff *buf, struct tipc_port_list *dp) tipc_port_list_free(dp); } -/** - * tipc_createport - create a generic TIPC port - * - * Returns pointer to (locked) TIPC port, or NULL if unable to create it - */ -struct tipc_port *tipc_createport(struct sock *sk, - u32 (*dispatcher)(struct tipc_port *, - struct sk_buff *), - void (*wakeup)(struct tipc_port *), - const u32 importance) + +void tipc_port_wakeup(struct tipc_port *port) +{ + tipc_sock_wakeup(tipc_port_to_sock(port)); +} + +/* tipc_port_init - intiate TIPC port and lock it + * + * Returns obtained reference if initialization is successful, zero otherwise + */ +u32 tipc_port_init(struct tipc_port *p_ptr, + const unsigned int importance) { - struct tipc_port *p_ptr; struct tipc_msg *msg; u32 ref; - p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); - if (!p_ptr) { - pr_warn("Port creation failed, no memory\n"); - return NULL; - } ref = tipc_ref_acquire(p_ptr, &p_ptr->lock); if (!ref) { - pr_warn("Port creation failed, ref. table exhausted\n"); - kfree(p_ptr); - return NULL; + pr_warn("Port registration failed, ref. table exhausted\n"); + return 0; } - p_ptr->sk = sk; p_ptr->max_pkt = MAX_PKT_DEFAULT; p_ptr->ref = ref; INIT_LIST_HEAD(&p_ptr->wait_list); INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); - p_ptr->dispatcher = dispatcher; - p_ptr->wakeup = wakeup; k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref); INIT_LIST_HEAD(&p_ptr->publications); INIT_LIST_HEAD(&p_ptr->port_list); @@ -249,10 +229,10 @@ struct tipc_port *tipc_createport(struct sock *sk, msg_set_origport(msg, ref); list_add_tail(&p_ptr->port_list, &ports); spin_unlock_bh(&tipc_port_list_lock); - return p_ptr; + return ref; } -int tipc_deleteport(struct tipc_port *p_ptr) +void tipc_port_destroy(struct tipc_port *p_ptr) { struct sk_buff *buf = NULL; @@ -273,67 +253,7 @@ int tipc_deleteport(struct tipc_port *p_ptr) list_del(&p_ptr->wait_list); spin_unlock_bh(&tipc_port_list_lock); k_term_timer(&p_ptr->timer); - kfree(p_ptr); tipc_net_route_msg(buf); - return 0; -} - -static int port_unreliable(struct tipc_port *p_ptr) -{ - return msg_src_droppable(&p_ptr->phdr); -} - -int tipc_portunreliable(u32 ref, unsigned int *isunreliable) -{ - struct tipc_port *p_ptr; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - *isunreliable = port_unreliable(p_ptr); - tipc_port_unlock(p_ptr); - return 0; -} - -int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) -{ - struct tipc_port *p_ptr; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - msg_set_src_droppable(&p_ptr->phdr, (isunreliable != 0)); - tipc_port_unlock(p_ptr); - return 0; -} - -static int port_unreturnable(struct tipc_port *p_ptr) -{ - return msg_dest_droppable(&p_ptr->phdr); -} - -int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) -{ - struct tipc_port *p_ptr; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - *isunrejectable = port_unreturnable(p_ptr); - tipc_port_unlock(p_ptr); - return 0; -} - -int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) -{ - struct tipc_port *p_ptr; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - msg_set_dest_droppable(&p_ptr->phdr, (isunrejectable != 0)); - tipc_port_unlock(p_ptr); - return 0; } /* @@ -351,8 +271,8 @@ static struct sk_buff *port_build_proto_msg(struct tipc_port *p_ptr, if (buf) { msg = buf_msg(buf); tipc_msg_init(msg, CONN_MANAGER, type, INT_H_SIZE, - port_peernode(p_ptr)); - msg_set_destport(msg, port_peerport(p_ptr)); + tipc_port_peernode(p_ptr)); + msg_set_destport(msg, tipc_port_peerport(p_ptr)); msg_set_origport(msg, p_ptr->ref); msg_set_msgcnt(msg, ack); } @@ -548,13 +468,12 @@ void tipc_port_proto_rcv(struct sk_buff *buf) /* Process protocol message sent by peer */ switch (msg_type(msg)) { case CONN_ACK: - wakeable = tipc_port_congested(p_ptr) && p_ptr->congested && - p_ptr->wakeup; + wakeable = tipc_port_congested(p_ptr) && p_ptr->congested; p_ptr->acked += msg_msgcnt(msg); if (!tipc_port_congested(p_ptr)) { p_ptr->congested = 0; if (wakeable) - p_ptr->wakeup(p_ptr); + tipc_port_wakeup(p_ptr); } break; case CONN_PROBE: @@ -585,8 +504,8 @@ static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id) ret = tipc_snprintf(buf, len, "%-10u:", p_ptr->ref); if (p_ptr->connected) { - u32 dport = port_peerport(p_ptr); - u32 destnode = port_peernode(p_ptr); + u32 dport = tipc_port_peerport(p_ptr); + u32 destnode = tipc_port_peernode(p_ptr); ret += tipc_snprintf(buf + ret, len - ret, " connected to <%u.%u.%u:%u>", @@ -674,34 +593,6 @@ void tipc_acknowledge(u32 ref, u32 ack) tipc_net_route_msg(buf); } -int tipc_portimportance(u32 ref, unsigned int *importance) -{ - struct tipc_port *p_ptr; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - *importance = (unsigned int)msg_importance(&p_ptr->phdr); - tipc_port_unlock(p_ptr); - return 0; -} - -int tipc_set_portimportance(u32 ref, unsigned int imp) -{ - struct tipc_port *p_ptr; - - if (imp > TIPC_CRITICAL_IMPORTANCE) - return -EINVAL; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - msg_set_importance(&p_ptr->phdr, (u32)imp); - tipc_port_unlock(p_ptr); - return 0; -} - - int tipc_publish(struct tipc_port *p_ptr, unsigned int scope, struct tipc_name_seq const *seq) { @@ -883,7 +774,7 @@ int tipc_port_rcv(struct sk_buff *buf) /* validate destination & pass to port, otherwise reject message */ p_ptr = tipc_port_lock(destport); if (likely(p_ptr)) { - err = p_ptr->dispatcher(p_ptr, buf); + err = tipc_sk_rcv(&tipc_port_to_sock(p_ptr)->sk, buf); tipc_port_unlock(p_ptr); if (likely(!err)) return dsz; @@ -914,19 +805,19 @@ static int tipc_port_iovec_rcv(struct tipc_port *sender, /** * tipc_send - send message sections on connection */ -int tipc_send(u32 ref, struct iovec const *msg_sect, unsigned int len) +int tipc_send(struct tipc_port *p_ptr, + struct iovec const *msg_sect, + unsigned int len) { - struct tipc_port *p_ptr; u32 destnode; int res; - p_ptr = tipc_port_deref(ref); - if (!p_ptr || !p_ptr->connected) + if (!p_ptr->connected) return -EINVAL; p_ptr->congested = 1; if (!tipc_port_congested(p_ptr)) { - destnode = port_peernode(p_ptr); + destnode = tipc_port_peernode(p_ptr); if (likely(!in_own_node(destnode))) res = tipc_link_iovec_xmit_fast(p_ptr, msg_sect, len, destnode); @@ -940,7 +831,7 @@ int tipc_send(u32 ref, struct iovec const *msg_sect, unsigned int len) return res; } } - if (port_unreliable(p_ptr)) { + if (tipc_port_unreliable(p_ptr)) { p_ptr->congested = 0; return len; } @@ -950,17 +841,18 @@ int tipc_send(u32 ref, struct iovec const *msg_sect, unsigned int len) /** * tipc_send2name - send message sections to port name */ -int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, - struct iovec const *msg_sect, unsigned int len) +int tipc_send2name(struct tipc_port *p_ptr, + struct tipc_name const *name, + unsigned int domain, + struct iovec const *msg_sect, + unsigned int len) { - struct tipc_port *p_ptr; struct tipc_msg *msg; u32 destnode = domain; u32 destport; int res; - p_ptr = tipc_port_deref(ref); - if (!p_ptr || p_ptr->connected) + if (p_ptr->connected) return -EINVAL; msg = &p_ptr->phdr; @@ -987,9 +879,9 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, p_ptr->sent++; return res; } - if (port_unreliable(p_ptr)) { + if (tipc_port_unreliable(p_ptr)) return len; - } + return -ELINKCONG; } return tipc_port_iovec_reject(p_ptr, msg, msg_sect, len, @@ -999,15 +891,15 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, /** * tipc_send2port - send message sections to port identity */ -int tipc_send2port(u32 ref, struct tipc_portid const *dest, - struct iovec const *msg_sect, unsigned int len) +int tipc_send2port(struct tipc_port *p_ptr, + struct tipc_portid const *dest, + struct iovec const *msg_sect, + unsigned int len) { - struct tipc_port *p_ptr; struct tipc_msg *msg; int res; - p_ptr = tipc_port_deref(ref); - if (!p_ptr || p_ptr->connected) + if (p_ptr->connected) return -EINVAL; msg = &p_ptr->phdr; @@ -1030,8 +922,8 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest, p_ptr->sent++; return res; } - if (port_unreliable(p_ptr)) { + if (tipc_port_unreliable(p_ptr)) return len; - } + return -ELINKCONG; } diff --git a/net/tipc/port.h b/net/tipc/port.h index 3ec3e94e4334..a00397393bd1 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -1,7 +1,7 @@ /* * net/tipc/port.h: Include file for TIPC port code * - * Copyright (c) 1994-2007, Ericsson AB + * Copyright (c) 1994-2007, 2014, Ericsson AB * Copyright (c) 2004-2007, 2010-2013, Wind River Systems * All rights reserved. * @@ -48,7 +48,6 @@ /** * struct tipc_port - TIPC port structure - * @sk: pointer to socket handle * @lock: pointer to spinlock for controlling access to port * @connected: non-zero if port is currently connected to a peer port * @conn_type: TIPC type used when connection was established @@ -60,8 +59,6 @@ * @ref: unique reference to port in TIPC object registry * @phdr: preformatted message header used when sending messages * @port_list: adjacent ports in TIPC's global list of ports - * @dispatcher: ptr to routine which handles received messages - * @wakeup: ptr to routine to call when port is no longer congested * @wait_list: adjacent ports in list of ports waiting on link congestion * @waiting_pkts: * @sent: # of non-empty messages sent by port @@ -74,7 +71,6 @@ * @subscription: "node down" subscription used to terminate failed connections */ struct tipc_port { - struct sock *sk; spinlock_t *lock; int connected; u32 conn_type; @@ -86,8 +82,6 @@ struct tipc_port { u32 ref; struct tipc_msg phdr; struct list_head port_list; - u32 (*dispatcher)(struct tipc_port *, struct sk_buff *); - void (*wakeup)(struct tipc_port *); struct list_head wait_list; u32 waiting_pkts; u32 sent; @@ -106,29 +100,18 @@ struct tipc_port_list; /* * TIPC port manipulation routines */ -struct tipc_port *tipc_createport(struct sock *sk, - u32 (*dispatcher)(struct tipc_port *, - struct sk_buff *), - void (*wakeup)(struct tipc_port *), - const u32 importance); +u32 tipc_port_init(struct tipc_port *p_ptr, + const unsigned int importance); int tipc_reject_msg(struct sk_buff *buf, u32 err); void tipc_acknowledge(u32 port_ref, u32 ack); -int tipc_deleteport(struct tipc_port *p_ptr); - -int tipc_portimportance(u32 portref, unsigned int *importance); -int tipc_set_portimportance(u32 portref, unsigned int importance); - -int tipc_portunreliable(u32 portref, unsigned int *isunreliable); -int tipc_set_portunreliable(u32 portref, unsigned int isunreliable); - -int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); -int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); +void tipc_port_destroy(struct tipc_port *p_ptr); int tipc_publish(struct tipc_port *p_ptr, unsigned int scope, struct tipc_name_seq const *name_seq); + int tipc_withdraw(struct tipc_port *p_ptr, unsigned int scope, struct tipc_name_seq const *name_seq); @@ -138,6 +121,7 @@ int tipc_port_disconnect(u32 portref); int tipc_port_shutdown(u32 ref); +void tipc_port_wakeup(struct tipc_port *port); /* * The following routines require that the port be locked on entry @@ -151,20 +135,33 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg); * TIPC messaging routines */ int tipc_port_rcv(struct sk_buff *buf); -int tipc_send(u32 portref, struct iovec const *msg_sect, unsigned int len); -int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, - struct iovec const *msg_sect, unsigned int len); +int tipc_send(struct tipc_port *port, + struct iovec const *msg_sect, + unsigned int len); -int tipc_send2port(u32 portref, struct tipc_portid const *dest, - struct iovec const *msg_sect, unsigned int len); +int tipc_send2name(struct tipc_port *port, + struct tipc_name const *name, + u32 domain, + struct iovec const *msg_sect, + unsigned int len); -int tipc_port_mcast_xmit(u32 portref, struct tipc_name_seq const *seq, - struct iovec const *msg, unsigned int len); +int tipc_send2port(struct tipc_port *port, + struct tipc_portid const *dest, + struct iovec const *msg_sect, + unsigned int len); -int tipc_port_iovec_reject(struct tipc_port *p_ptr, struct tipc_msg *hdr, - struct iovec const *msg_sect, unsigned int len, +int tipc_port_mcast_xmit(struct tipc_port *port, + struct tipc_name_seq const *seq, + struct iovec const *msg, + unsigned int len); + +int tipc_port_iovec_reject(struct tipc_port *p_ptr, + struct tipc_msg *hdr, + struct iovec const *msg_sect, + unsigned int len, int err); + struct sk_buff *tipc_port_get_ports(void); void tipc_port_proto_rcv(struct sk_buff *buf); void tipc_port_mcast_rcv(struct sk_buff *buf, struct tipc_port_list *dp); @@ -188,14 +185,53 @@ static inline void tipc_port_unlock(struct tipc_port *p_ptr) spin_unlock_bh(p_ptr->lock); } -static inline struct tipc_port *tipc_port_deref(u32 ref) -{ - return (struct tipc_port *)tipc_ref_deref(ref); -} - static inline int tipc_port_congested(struct tipc_port *p_ptr) { return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); } + +static inline u32 tipc_port_peernode(struct tipc_port *p_ptr) +{ + return msg_destnode(&p_ptr->phdr); +} + +static inline u32 tipc_port_peerport(struct tipc_port *p_ptr) +{ + return msg_destport(&p_ptr->phdr); +} + +static inline bool tipc_port_unreliable(struct tipc_port *port) +{ + return msg_src_droppable(&port->phdr) != 0; +} + +static inline void tipc_port_set_unreliable(struct tipc_port *port, + bool unreliable) +{ + msg_set_src_droppable(&port->phdr, unreliable ? 1 : 0); +} + +static inline bool tipc_port_unreturnable(struct tipc_port *port) +{ + return msg_dest_droppable(&port->phdr) != 0; +} + +static inline void tipc_port_set_unreturnable(struct tipc_port *port, + bool unreturnable) +{ + msg_set_dest_droppable(&port->phdr, unreturnable ? 1 : 0); +} + + +static inline int tipc_port_importance(struct tipc_port *port) +{ + return msg_importance(&port->phdr); +} + +static inline void tipc_port_set_importance(struct tipc_port *port, int imp) +{ + msg_set_importance(&port->phdr, (u32)imp); +} + #endif diff --git a/net/tipc/ref.c b/net/tipc/ref.c index de3d593e2fee..3d4ecd754eee 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -89,7 +89,7 @@ struct ref_table { static struct ref_table tipc_ref_table; -static DEFINE_RWLOCK(ref_table_lock); +static DEFINE_SPINLOCK(ref_table_lock); /** * tipc_ref_table_init - create reference table for objects @@ -159,7 +159,7 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) } /* take a free entry, if available; otherwise initialize a new entry */ - write_lock_bh(&ref_table_lock); + spin_lock_bh(&ref_table_lock); if (tipc_ref_table.first_free) { index = tipc_ref_table.first_free; entry = &(tipc_ref_table.entries[index]); @@ -175,7 +175,7 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) } else { ref = 0; } - write_unlock_bh(&ref_table_lock); + spin_unlock_bh(&ref_table_lock); /* * Grab the lock so no one else can modify this entry @@ -216,7 +216,7 @@ void tipc_ref_discard(u32 ref) index = ref & index_mask; entry = &(tipc_ref_table.entries[index]); - write_lock_bh(&ref_table_lock); + spin_lock_bh(&ref_table_lock); if (!entry->object) { pr_err("Attempt to discard ref. to non-existent obj\n"); @@ -242,7 +242,7 @@ void tipc_ref_discard(u32 ref) tipc_ref_table.last_free = index; exit: - write_unlock_bh(&ref_table_lock); + spin_unlock_bh(&ref_table_lock); } /** @@ -264,20 +264,3 @@ void *tipc_ref_lock(u32 ref) } return NULL; } - - -/** - * tipc_ref_deref - return pointer referenced object (without locking it) - */ -void *tipc_ref_deref(u32 ref) -{ - if (likely(tipc_ref_table.entries)) { - struct reference *entry; - - entry = &tipc_ref_table.entries[ref & - tipc_ref_table.index_mask]; - if (likely(entry->ref == ref)) - return entry->object; - } - return NULL; -} diff --git a/net/tipc/ref.h b/net/tipc/ref.h index 5bc8e7ab84de..d01aa1df63b8 100644 --- a/net/tipc/ref.h +++ b/net/tipc/ref.h @@ -44,6 +44,5 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock); void tipc_ref_discard(u32 ref); void *tipc_ref_lock(u32 ref); -void *tipc_ref_deref(u32 ref); #endif diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 336e18d6cf46..2a89bdb331b5 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1,7 +1,7 @@ /* * net/tipc/socket.c: TIPC socket API * - * Copyright (c) 2001-2007, 2012 Ericsson AB + * Copyright (c) 2001-2007, 2012-2014, Ericsson AB * Copyright (c) 2004-2008, 2010-2013, Wind River Systems * All rights reserved. * @@ -38,26 +38,13 @@ #include "port.h" #include -#include #define SS_LISTENING -1 /* socket is listening */ #define SS_READY -2 /* socket is connectionless */ #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ -struct tipc_sock { - struct sock sk; - struct tipc_port *p; - struct tipc_portid peer_name; - unsigned int conn_timeout; -}; - -#define tipc_sk(sk) ((struct tipc_sock *)(sk)) -#define tipc_sk_port(sk) (tipc_sk(sk)->p) - static int backlog_rcv(struct sock *sk, struct sk_buff *skb); -static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); -static void wakeupdispatch(struct tipc_port *tport); static void tipc_data_ready(struct sock *sk, int len); static void tipc_write_space(struct sock *sk); static int tipc_release(struct socket *sock); @@ -115,6 +102,8 @@ static struct proto tipc_proto_kern; * - port reference */ +#include "socket.h" + /** * advance_rx_queue - discard first buffer in socket receive queue * @@ -150,13 +139,15 @@ static void reject_rx_queue(struct sock *sk) * * Returns 0 on success, errno otherwise */ -static int tipc_sk_create(struct net *net, struct socket *sock, int protocol, - int kern) +static int tipc_sk_create(struct net *net, struct socket *sock, + int protocol, int kern) { const struct proto_ops *ops; socket_state state; struct sock *sk; - struct tipc_port *tp_ptr; + struct tipc_sock *tsk; + struct tipc_port *port; + u32 ref; /* Validate arguments */ if (unlikely(protocol != 0)) @@ -189,10 +180,12 @@ static int tipc_sk_create(struct net *net, struct socket *sock, int protocol, if (sk == NULL) return -ENOMEM; - /* Allocate TIPC port for socket to use */ - tp_ptr = tipc_createport(sk, &dispatch, &wakeupdispatch, - TIPC_LOW_IMPORTANCE); - if (unlikely(!tp_ptr)) { + tsk = tipc_sk(sk); + port = &tsk->port; + + ref = tipc_port_init(port, TIPC_LOW_IMPORTANCE); + if (!ref) { + pr_warn("Socket registration failed, ref. table exhausted\n"); sk_free(sk); return -ENOMEM; } @@ -206,17 +199,14 @@ static int tipc_sk_create(struct net *net, struct socket *sock, int protocol, sk->sk_rcvbuf = sysctl_tipc_rmem[1]; sk->sk_data_ready = tipc_data_ready; sk->sk_write_space = tipc_write_space; - tipc_sk(sk)->p = tp_ptr; tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT; - - spin_unlock_bh(tp_ptr->lock); + tipc_port_unlock(port); if (sock->state == SS_READY) { - tipc_set_portunreturnable(tp_ptr->ref, 1); + tipc_port_set_unreturnable(port, true); if (sock->type == SOCK_DGRAM) - tipc_set_portunreliable(tp_ptr->ref, 1); + tipc_port_set_unreliable(port, true); } - return 0; } @@ -308,7 +298,8 @@ int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, static int tipc_release(struct socket *sock) { struct sock *sk = sock->sk; - struct tipc_port *tport; + struct tipc_sock *tsk; + struct tipc_port *port; struct sk_buff *buf; int res; @@ -319,7 +310,8 @@ static int tipc_release(struct socket *sock) if (sk == NULL) return 0; - tport = tipc_sk_port(sk); + tsk = tipc_sk(sk); + port = &tsk->port; lock_sock(sk); /* @@ -336,17 +328,16 @@ static int tipc_release(struct socket *sock) if ((sock->state == SS_CONNECTING) || (sock->state == SS_CONNECTED)) { sock->state = SS_DISCONNECTING; - tipc_port_disconnect(tport->ref); + tipc_port_disconnect(port->ref); } tipc_reject_msg(buf, TIPC_ERR_NO_PORT); } } - /* - * Delete TIPC port; this ensures no more messages are queued - * (also disconnects an active connection & sends a 'FIN-' to peer) + /* Destroy TIPC port; also disconnects an active connection and + * sends a 'FIN-' to peer. */ - res = tipc_deleteport(tport); + tipc_port_destroy(port); /* Discard any remaining (connection-based) messages in receive queue */ __skb_queue_purge(&sk->sk_receive_queue); @@ -381,12 +372,12 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr, { struct sock *sk = sock->sk; struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; - struct tipc_port *tport = tipc_sk_port(sock->sk); + struct tipc_sock *tsk = tipc_sk(sk); int res = -EINVAL; lock_sock(sk); if (unlikely(!uaddr_len)) { - res = tipc_withdraw(tport, 0, NULL); + res = tipc_withdraw(&tsk->port, 0, NULL); goto exit; } @@ -414,8 +405,8 @@ static int tipc_bind(struct socket *sock, struct sockaddr *uaddr, } res = (addr->scope > 0) ? - tipc_publish(tport, addr->scope, &addr->addr.nameseq) : - tipc_withdraw(tport, -addr->scope, &addr->addr.nameseq); + tipc_publish(&tsk->port, addr->scope, &addr->addr.nameseq) : + tipc_withdraw(&tsk->port, -addr->scope, &addr->addr.nameseq); exit: release_sock(sk); return res; @@ -438,17 +429,17 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; - struct tipc_sock *tsock = tipc_sk(sock->sk); + struct tipc_sock *tsk = tipc_sk(sock->sk); memset(addr, 0, sizeof(*addr)); if (peer) { if ((sock->state != SS_CONNECTED) && ((peer != 2) || (sock->state != SS_DISCONNECTING))) return -ENOTCONN; - addr->addr.id.ref = tsock->peer_name.ref; - addr->addr.id.node = tsock->peer_name.node; + addr->addr.id.ref = tipc_port_peerport(&tsk->port); + addr->addr.id.node = tipc_port_peernode(&tsk->port); } else { - addr->addr.id.ref = tsock->p->ref; + addr->addr.id.ref = tsk->port.ref; addr->addr.id.node = tipc_own_addr; } @@ -505,18 +496,19 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, poll_table *wait) { struct sock *sk = sock->sk; + struct tipc_sock *tsk = tipc_sk(sk); u32 mask = 0; sock_poll_wait(file, sk_sleep(sk), wait); switch ((int)sock->state) { case SS_UNCONNECTED: - if (!tipc_sk_port(sk)->congested) + if (!tsk->port.congested) mask |= POLLOUT; break; case SS_READY: case SS_CONNECTED: - if (!tipc_sk_port(sk)->congested) + if (!tsk->port.congested) mask |= POLLOUT; /* fall thru' */ case SS_CONNECTING: @@ -566,7 +558,7 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m) static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); DEFINE_WAIT(wait); int done; @@ -582,12 +574,13 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) return sock_intr_errno(*timeo_p); prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); - done = sk_wait_event(sk, timeo_p, !tport->congested); + done = sk_wait_event(sk, timeo_p, !tsk->port.congested); finish_wait(sk_sleep(sk), &wait); } while (!done); return 0; } + /** * tipc_sendmsg - send message in connectionless manner * @iocb: if NULL, indicates that socket lock is already held @@ -606,7 +599,8 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); + struct tipc_port *port = &tsk->port; DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); int needs_conn; long timeo; @@ -633,13 +627,13 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, res = -EISCONN; goto exit; } - if (tport->published) { + if (tsk->port.published) { res = -EOPNOTSUPP; goto exit; } if (dest->addrtype == TIPC_ADDR_NAME) { - tport->conn_type = dest->addr.name.name.type; - tport->conn_instance = dest->addr.name.name.instance; + tsk->port.conn_type = dest->addr.name.name.type; + tsk->port.conn_instance = dest->addr.name.name.instance; } /* Abort any pending connection attempts (very unlikely) */ @@ -652,13 +646,13 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, res = dest_name_check(dest, m); if (res) break; - res = tipc_send2name(tport->ref, + res = tipc_send2name(port, &dest->addr.name.name, dest->addr.name.domain, m->msg_iov, total_len); } else if (dest->addrtype == TIPC_ADDR_ID) { - res = tipc_send2port(tport->ref, + res = tipc_send2port(port, &dest->addr.id, m->msg_iov, total_len); @@ -670,7 +664,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, res = dest_name_check(dest, m); if (res) break; - res = tipc_port_mcast_xmit(tport->ref, + res = tipc_port_mcast_xmit(port, &dest->addr.nameseq, m->msg_iov, total_len); @@ -694,7 +688,8 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); + struct tipc_port *port = &tsk->port; DEFINE_WAIT(wait); int done; @@ -713,7 +708,7 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p) prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); done = sk_wait_event(sk, timeo_p, - (!tport->congested || !tport->connected)); + (!port->congested || !port->connected)); finish_wait(sk_sleep(sk), &wait); } while (!done); return 0; @@ -734,7 +729,7 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); int res = -EINVAL; long timeo; @@ -759,7 +754,7 @@ static int tipc_send_packet(struct kiocb *iocb, struct socket *sock, timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); do { - res = tipc_send(tport->ref, m->msg_iov, total_len); + res = tipc_send(&tsk->port, m->msg_iov, total_len); if (likely(res != -ELINKCONG)) break; res = tipc_wait_for_sndpkt(sock, &timeo); @@ -788,7 +783,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); struct msghdr my_msg; struct iovec my_iov; struct iovec *curr_iov; @@ -836,14 +831,14 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, my_msg.msg_name = NULL; bytes_sent = 0; - hdr_size = msg_hdr_sz(&tport->phdr); + hdr_size = msg_hdr_sz(&tsk->port.phdr); while (curr_iovlen--) { curr_start = curr_iov->iov_base; curr_left = curr_iov->iov_len; while (curr_left) { - bytes_to_send = tport->max_pkt - hdr_size; + bytes_to_send = tsk->port.max_pkt - hdr_size; if (bytes_to_send > TIPC_MAX_USER_MSG_SIZE) bytes_to_send = TIPC_MAX_USER_MSG_SIZE; if (curr_left < bytes_to_send) @@ -872,27 +867,25 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, /** * auto_connect - complete connection setup to a remote port - * @sock: socket structure + * @tsk: tipc socket structure * @msg: peer's response message * * Returns 0 on success, errno otherwise */ -static int auto_connect(struct socket *sock, struct tipc_msg *msg) +static int auto_connect(struct tipc_sock *tsk, struct tipc_msg *msg) { - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct tipc_port *p_ptr; + struct tipc_port *port = &tsk->port; + struct socket *sock = tsk->sk.sk_socket; + struct tipc_portid peer; - tsock->peer_name.ref = msg_origport(msg); - tsock->peer_name.node = msg_orignode(msg); - p_ptr = tipc_port_deref(tsock->p->ref); - if (!p_ptr) - return -EINVAL; + peer.ref = msg_origport(msg); + peer.node = msg_orignode(msg); - __tipc_port_connect(tsock->p->ref, p_ptr, &tsock->peer_name); + __tipc_port_connect(port->ref, port, &peer); if (msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE) return -EINVAL; - msg_set_importance(&p_ptr->phdr, (u32)msg_importance(msg)); + msg_set_importance(&port->phdr, (u32)msg_importance(msg)); sock->state = SS_CONNECTED; return 0; } @@ -1038,7 +1031,8 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t buf_len, int flags) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); + struct tipc_port *port = &tsk->port; struct sk_buff *buf; struct tipc_msg *msg; long timeo; @@ -1081,7 +1075,7 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock, set_orig_addr(m, msg); /* Capture ancillary data (optional) */ - res = anc_data_recv(m, msg, tport); + res = anc_data_recv(m, msg, port); if (res) goto exit; @@ -1107,8 +1101,8 @@ static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock, /* Consume received message (optional) */ if (likely(!(flags & MSG_PEEK))) { if ((sock->state != SS_READY) && - (++tport->conn_unacked >= TIPC_FLOW_CONTROL_WIN)) - tipc_acknowledge(tport->ref, tport->conn_unacked); + (++port->conn_unacked >= TIPC_FLOW_CONTROL_WIN)) + tipc_acknowledge(port->ref, port->conn_unacked); advance_rx_queue(sk); } exit: @@ -1132,7 +1126,8 @@ static int tipc_recv_stream(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t buf_len, int flags) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); + struct tipc_port *port = &tsk->port; struct sk_buff *buf; struct tipc_msg *msg; long timeo; @@ -1177,7 +1172,7 @@ static int tipc_recv_stream(struct kiocb *iocb, struct socket *sock, /* Optionally capture sender's address & ancillary data of first msg */ if (sz_copied == 0) { set_orig_addr(m, msg); - res = anc_data_recv(m, msg, tport); + res = anc_data_recv(m, msg, port); if (res) goto exit; } @@ -1215,8 +1210,8 @@ static int tipc_recv_stream(struct kiocb *iocb, struct socket *sock, /* Consume received message (optional) */ if (likely(!(flags & MSG_PEEK))) { - if (unlikely(++tport->conn_unacked >= TIPC_FLOW_CONTROL_WIN)) - tipc_acknowledge(tport->ref, tport->conn_unacked); + if (unlikely(++port->conn_unacked >= TIPC_FLOW_CONTROL_WIN)) + tipc_acknowledge(port->ref, port->conn_unacked); advance_rx_queue(sk); } @@ -1268,17 +1263,19 @@ static void tipc_data_ready(struct sock *sk, int len) /** * filter_connect - Handle all incoming messages for a connection-based socket - * @tsock: TIPC socket + * @tsk: TIPC socket * @msg: message * * Returns TIPC error status code and socket error status code * once it encounters some errors */ -static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf) +static u32 filter_connect(struct tipc_sock *tsk, struct sk_buff **buf) { - struct socket *sock = tsock->sk.sk_socket; + struct sock *sk = &tsk->sk; + struct tipc_port *port = &tsk->port; + struct socket *sock = sk->sk_socket; struct tipc_msg *msg = buf_msg(*buf); - struct sock *sk = &tsock->sk; + u32 retval = TIPC_ERR_NO_PORT; int res; @@ -1288,10 +1285,10 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf) switch ((int)sock->state) { case SS_CONNECTED: /* Accept only connection-based messages sent by peer */ - if (msg_connected(msg) && tipc_port_peer_msg(tsock->p, msg)) { + if (msg_connected(msg) && tipc_port_peer_msg(port, msg)) { if (unlikely(msg_errcode(msg))) { sock->state = SS_DISCONNECTING; - __tipc_port_disconnect(tsock->p); + __tipc_port_disconnect(port); } retval = TIPC_OK; } @@ -1308,7 +1305,7 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf) if (unlikely(!msg_connected(msg))) break; - res = auto_connect(sock, msg); + res = auto_connect(tsk, msg); if (res) { sock->state = SS_DISCONNECTING; sk->sk_err = -res; @@ -1387,6 +1384,7 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf) static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) { struct socket *sock = sk->sk_socket; + struct tipc_sock *tsk = tipc_sk(sk); struct tipc_msg *msg = buf_msg(buf); unsigned int limit = rcvbuf_limit(sk, buf); u32 res = TIPC_OK; @@ -1399,7 +1397,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) if (msg_connected(msg)) return TIPC_ERR_NO_PORT; } else { - res = filter_connect(tipc_sk(sk), &buf); + res = filter_connect(tsk, &buf); if (res != TIPC_OK || buf == NULL) return res; } @@ -1437,17 +1435,16 @@ static int backlog_rcv(struct sock *sk, struct sk_buff *buf) } /** - * dispatch - handle incoming message - * @tport: TIPC port that received message + * tipc_sk_rcv - handle incoming message + * @sk: socket receiving message * @buf: message * * Called with port lock already taken. * * Returns TIPC error status code (TIPC_OK if message is not to be rejected) */ -static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) +u32 tipc_sk_rcv(struct sock *sk, struct sk_buff *buf) { - struct sock *sk = tport->sk; u32 res; /* @@ -1470,19 +1467,6 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) return res; } -/** - * wakeupdispatch - wake up port after congestion - * @tport: port to wakeup - * - * Called with port lock already taken. - */ -static void wakeupdispatch(struct tipc_port *tport) -{ - struct sock *sk = tport->sk; - - sk->sk_write_space(sk); -} - static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) { struct sock *sk = sock->sk; @@ -1659,9 +1643,9 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) { struct sock *new_sk, *sk = sock->sk; struct sk_buff *buf; - struct tipc_sock *new_tsock; - struct tipc_port *new_tport; + struct tipc_port *new_port; struct tipc_msg *msg; + struct tipc_portid peer; u32 new_ref; long timeo; int res; @@ -1672,7 +1656,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) res = -EINVAL; goto exit; } - timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); res = tipc_wait_for_accept(sock, timeo); if (res) @@ -1685,9 +1668,8 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) goto exit; new_sk = new_sock->sk; - new_tsock = tipc_sk(new_sk); - new_tport = new_tsock->p; - new_ref = new_tport->ref; + new_port = &tipc_sk(new_sk)->port; + new_ref = new_port->ref; msg = buf_msg(buf); /* we lock on new_sk; but lockdep sees the lock on sk */ @@ -1700,15 +1682,15 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) reject_rx_queue(new_sk); /* Connect new socket to it's peer */ - new_tsock->peer_name.ref = msg_origport(msg); - new_tsock->peer_name.node = msg_orignode(msg); - tipc_port_connect(new_ref, &new_tsock->peer_name); + peer.ref = msg_origport(msg); + peer.node = msg_orignode(msg); + tipc_port_connect(new_ref, &peer); new_sock->state = SS_CONNECTED; - tipc_set_portimportance(new_ref, msg_importance(msg)); + tipc_port_set_importance(new_port, msg_importance(msg)); if (msg_named(msg)) { - new_tport->conn_type = msg_nametype(msg); - new_tport->conn_instance = msg_nameinst(msg); + new_port->conn_type = msg_nametype(msg); + new_port->conn_instance = msg_nameinst(msg); } /* @@ -1726,7 +1708,6 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) skb_set_owner_r(buf, new_sk); } release_sock(new_sk); - exit: release_sock(sk); return res; @@ -1744,7 +1725,8 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) static int tipc_shutdown(struct socket *sock, int how) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); + struct tipc_port *port = &tsk->port; struct sk_buff *buf; int res; @@ -1765,10 +1747,10 @@ static int tipc_shutdown(struct socket *sock, int how) kfree_skb(buf); goto restart; } - tipc_port_disconnect(tport->ref); + tipc_port_disconnect(port->ref); tipc_reject_msg(buf, TIPC_CONN_SHUTDOWN); } else { - tipc_port_shutdown(tport->ref); + tipc_port_shutdown(port->ref); } sock->state = SS_DISCONNECTING; @@ -1810,7 +1792,8 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt, char __user *ov, unsigned int ol) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); + struct tipc_port *port = &tsk->port; u32 value; int res; @@ -1828,16 +1811,16 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt, switch (opt) { case TIPC_IMPORTANCE: - res = tipc_set_portimportance(tport->ref, value); + tipc_port_set_importance(port, value); break; case TIPC_SRC_DROPPABLE: if (sock->type != SOCK_STREAM) - res = tipc_set_portunreliable(tport->ref, value); + tipc_port_set_unreliable(port, value); else res = -ENOPROTOOPT; break; case TIPC_DEST_DROPPABLE: - res = tipc_set_portunreturnable(tport->ref, value); + tipc_port_set_unreturnable(port, value); break; case TIPC_CONN_TIMEOUT: tipc_sk(sk)->conn_timeout = value; @@ -1869,7 +1852,8 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt, char __user *ov, int __user *ol) { struct sock *sk = sock->sk; - struct tipc_port *tport = tipc_sk_port(sk); + struct tipc_sock *tsk = tipc_sk(sk); + struct tipc_port *port = &tsk->port; int len; u32 value; int res; @@ -1886,13 +1870,13 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt, switch (opt) { case TIPC_IMPORTANCE: - res = tipc_portimportance(tport->ref, &value); + value = tipc_port_importance(port); break; case TIPC_SRC_DROPPABLE: - res = tipc_portunreliable(tport->ref, &value); + value = tipc_port_unreliable(port); break; case TIPC_DEST_DROPPABLE: - res = tipc_portunreturnable(tport->ref, &value); + value = tipc_port_unreturnable(port); break; case TIPC_CONN_TIMEOUT: value = tipc_sk(sk)->conn_timeout; diff --git a/net/tipc/socket.h b/net/tipc/socket.h new file mode 100644 index 000000000000..74e5c7f195a6 --- /dev/null +++ b/net/tipc/socket.h @@ -0,0 +1,72 @@ +/* net/tipc/socket.h: Include file for TIPC socket code + * + * Copyright (c) 2014, Ericsson AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the names of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _TIPC_SOCK_H +#define _TIPC_SOCK_H + +#include "port.h" +#include + +/** + * struct tipc_sock - TIPC socket structure + * @sk: socket - interacts with 'port' and with user via the socket API + * @port: port - interacts with 'sk' and with the rest of the TIPC stack + * @peer_name: the peer of the connection, if any + * @conn_timeout: the time we can wait for an unresponded setup request + */ + +struct tipc_sock { + struct sock sk; + struct tipc_port port; + unsigned int conn_timeout; +}; + +static inline struct tipc_sock *tipc_sk(const struct sock *sk) +{ + return container_of(sk, struct tipc_sock, sk); +} + +static inline struct tipc_sock *tipc_port_to_sock(const struct tipc_port *port) +{ + return container_of(port, struct tipc_sock, port); +} + +static inline void tipc_sock_wakeup(struct tipc_sock *tsk) +{ + tsk->sk.sk_write_space(&tsk->sk); +} + +u32 tipc_sk_rcv(struct sock *sk, struct sk_buff *buf); + +#endif