From b0d8626b6b0146782706bdb38fa770d7829f6024 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 07:18:25 -0300 Subject: LLC: small cleanups, leave debug on for a while . dprintk already puts the log level . fix some comments to match new behaviour --- include/net/llc_c_st.h | 12 ++++++------ include/net/llc_conn.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/net/llc_c_st.h b/include/net/llc_c_st.h index f0b40ed22754..0e79cfba4b3b 100644 --- a/include/net/llc_c_st.h +++ b/include/net/llc_c_st.h @@ -33,15 +33,15 @@ /* Connection state table structure */ struct llc_conn_state_trans { - llc_conn_ev_t ev; - u8 next_state; - llc_conn_ev_qfyr_t *ev_qualifiers; - llc_conn_action_t *ev_actions; + llc_conn_ev_t ev; + u8 next_state; + llc_conn_ev_qfyr_t *ev_qualifiers; + llc_conn_action_t *ev_actions; }; struct llc_conn_state { - u8 current_state; - struct llc_conn_state_trans **transitions; + u8 current_state; + struct llc_conn_state_trans **transitions; }; extern struct llc_conn_state llc_conn_state_table[]; diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index db42c7f6fc78..bf70b0688938 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h @@ -14,7 +14,7 @@ #include #include -#undef DEBUG_LLC_CONN_ALLOC +#define DEBUG_LLC_CONN_ALLOC struct llc_timer { struct timer_list timer; -- cgit v1.2.3 From a7f3da32c79236b61b0adde846b145286aa1b767 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 07:34:44 -0300 Subject: LLC: tcpfying the beast . s/mac_indicate/llc_rcv/g . s/llc_sap_send_ev/llc_sap_state_process/g . s/llc_station_send_ev/llc_station_state_process/g . s/llc_conn_send_ev/llc_conn_state_process/g . fix some comments wrt current behaviour . s/llc_find_sock/llc_lookup_established/g . llc_sock_alloc now receives the protocol family as a parameter, will be used by llc_lookup_listener to properly handle multiple upper layer protocols . s/inline/__inline__/g --- include/net/llc_conn.h | 15 ++++++++------- include/net/llc_mac.h | 4 ++-- include/net/llc_main.h | 4 ++-- include/net/llc_sap.h | 2 +- net/llc/llc_actn.c | 2 +- net/llc/llc_c_ac.c | 6 +++--- net/llc/llc_conn.c | 17 ++++++++++------- net/llc/llc_if.c | 50 +++++++++++++++++++++++++++----------------------- net/llc/llc_mac.c | 40 ++++++++++++++++------------------------ net/llc/llc_main.c | 17 +++++++++-------- net/llc/llc_sap.c | 4 ++-- net/llc/llc_sock.c | 19 ++++++++++--------- 12 files changed, 91 insertions(+), 89 deletions(-) (limited to 'include') diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index bf70b0688938..ea7725fa705f 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h @@ -80,7 +80,7 @@ struct llc_opt { struct llc_conn_state_ev; -extern struct sock *__llc_sock_alloc(void); +extern struct sock *__llc_sock_alloc(int family); extern void __llc_sock_free(struct sock *sk, u8 free); #ifdef DEBUG_LLC_CONN_ALLOC @@ -88,8 +88,8 @@ extern void __llc_sock_free(struct sock *sk, u8 free); __builtin_return_address(0), \ __builtin_return_address(1), \ __builtin_return_address(2)); -#define llc_sock_alloc() ({ \ - struct sock *__sk = __llc_sock_alloc(); \ +#define llc_sock_alloc(family) ({ \ + struct sock *__sk = __llc_sock_alloc(family); \ if (__sk) { \ llc_sk(__sk)->f_alloc = __FUNCTION__; \ llc_sk(__sk)->l_alloc = __LINE__; \ @@ -126,7 +126,7 @@ extern void __llc_sock_free(struct sock *sk, u8 free); return __ret; } \ } #else /* DEBUG_LLC_CONN_ALLOC */ -#define llc_sock_alloc() __llc_sock_alloc() +#define llc_sock_alloc(family) __llc_sock_alloc(family) #define llc_sock_free(__sk) __llc_sock_free(__sk, 1) #define llc_sock_assert(__sk) #define llc_sock_assert_ret(__sk) @@ -136,7 +136,7 @@ extern void llc_sock_reset(struct sock *sk); extern int llc_sock_init(struct sock *sk); /* Access to a connection */ -extern int llc_conn_send_ev(struct sock *sk, struct sk_buff *skb); +extern int llc_conn_state_process(struct sock *sk, struct sk_buff *skb); extern void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb); extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb); extern void llc_conn_free_ev(struct sk_buff *skb); @@ -146,8 +146,9 @@ extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit); extern int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, u16 *how_many_unacked); -extern struct sock *llc_find_sock(struct llc_sap *sap, struct llc_addr *daddr, - struct llc_addr *laddr); +extern struct sock *llc_lookup_established(struct llc_sap *sap, + struct llc_addr *daddr, + struct llc_addr *laddr); extern u8 llc_data_accept_state(u8 state); extern void llc_build_offset_table(void); #endif /* LLC_CONN_H */ diff --git a/include/net/llc_mac.h b/include/net/llc_mac.h index 9f2fb80ba98e..3fd75e4fe8bf 100644 --- a/include/net/llc_mac.h +++ b/include/net/llc_mac.h @@ -13,8 +13,8 @@ */ /* Defines MAC-layer interface to LLC layer */ extern int mac_send_pdu(struct sk_buff *skb); -extern int mac_indicate(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt); +extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt); extern struct net_device *mac_dev_peer(struct net_device *current_dev, int type, u8 *mac); extern int llc_pdu_router(struct llc_sap *sap, struct sock *sk, diff --git a/include/net/llc_main.h b/include/net/llc_main.h index e3aa4d2c7632..31810831fceb 100644 --- a/include/net/llc_main.h +++ b/include/net/llc_main.h @@ -61,8 +61,8 @@ extern void llc_sap_save(struct llc_sap *sap); extern void llc_free_sap(struct llc_sap *sap); extern struct llc_sap *llc_sap_find(u8 lsap); extern struct llc_station *llc_station_get(void); -extern void llc_station_send_ev(struct llc_station *station, - struct sk_buff *skb); +extern void llc_station_state_process(struct llc_station *station, + struct sk_buff *skb); extern void llc_station_send_pdu(struct llc_station *station, struct sk_buff *skb); extern struct sk_buff *llc_alloc_frame(void); diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h index 3fd694a166e6..cabd5a8ed9f2 100644 --- a/include/net/llc_sap.h +++ b/include/net/llc_sap.h @@ -49,7 +49,7 @@ struct llc_sap_state_ev; extern void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk); extern void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk); -extern void llc_sap_send_ev(struct llc_sap *sap, struct sk_buff *skb); +extern void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb); extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb); extern void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb); #endif /* LLC_SAP_H */ diff --git a/net/llc/llc_actn.c b/net/llc/llc_actn.c index 4b63a130b0c9..cb8704409d8e 100644 --- a/net/llc/llc_actn.c +++ b/net/llc/llc_actn.c @@ -142,6 +142,6 @@ static void llc_station_ack_tmr_callback(unsigned long timeout_data) ev->type = LLC_STATION_EV_TYPE_ACK_TMR; ev->data.tmr.timer_specific = NULL; - llc_station_send_ev(station, skb); + llc_station_state_process(station, skb); } } diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index 96e61732c317..93f3f7e448c0 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -1589,8 +1589,8 @@ u8 llc_circular_between(u8 a, u8 b, u8 c) * This function is called from timer callback functions. When connection * is busy (during sending a data frame) timer expiration event must be * queued. Otherwise this event can be sent to connection state machine. - * Queued events will process by process_rxframes_events function after - * sending data frame. Returns 0 for success, 1 otherwise. + * Queued events will process by llc_backlog_rcv function after sending + * data frame. */ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb) { @@ -1602,7 +1602,7 @@ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb) goto out; } if (!sk->lock.users) - llc_conn_send_ev(sk, skb); + llc_conn_state_process(sk, skb); else { llc_set_backlog_type(skb, LLC_EVENT); sk_add_backlog(sk, skb); diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 98072a6c552d..cfb144b9c413 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -39,7 +39,7 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk, static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; /** - * llc_conn_send_event - sends event to connection state machine + * llc_conn_state_process - sends event to connection state machine * @sk: connection * @skb: occurred event * @@ -48,7 +48,7 @@ static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; * indicated or confirmed, if needed. Returns 0 for success, 1 for * failure. The socket lock has to be held before calling this function. */ -int llc_conn_send_ev(struct sock *sk, struct sk_buff *skb) +int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) { /* sending event to state machine */ int rc = llc_conn_service(sk, skb); @@ -109,7 +109,7 @@ void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb) * * Sends received data pdu to upper layer (by using indicate function). * Prepares service parameters (prim and prim_data). calling indication - * function will be done in llc_conn_send_ev. + * function will be done in llc_conn_state_process. */ void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb) { @@ -127,7 +127,10 @@ void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb) prim->prim = LLC_DATA_PRIM; prim->sap = sap; ev->flag = 1; - /* saving prepd prim in event for future use in llc_conn_send_ev */ + /* + * Saving prepd prim in event for future use in + * llc_conn_state_process + */ ev->ind_prim = prim; } @@ -396,7 +399,7 @@ static int llc_exec_conn_trans_actions(struct sock *sk, } /** - * llc_find_sock - Finds connection in sap for the remote/local sap/mac + * llc_lookup_established - Finds connection for the remote/local sap/mac * @sap: SAP * @daddr: address of remote LLC (MAC + SAP) * @laddr: address of local LLC (MAC + SAP) @@ -405,8 +408,8 @@ static int llc_exec_conn_trans_actions(struct sock *sk, * mac, remote sap, local mac, and local sap. Returns pointer for * connection found, %NULL otherwise. */ -struct sock *llc_find_sock(struct llc_sap *sap, struct llc_addr *daddr, - struct llc_addr *laddr) +struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, + struct llc_addr *laddr) { struct sock *rc = NULL; struct list_head *entry; diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index a53cc174adf0..6ddb10c64254 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -70,7 +70,7 @@ static llc_prim_call_t llc_resp_prim[LLC_NBR_PRIMITIVES] = { * @lsap: SAP number. * @sap: pointer to allocated SAP (output argument). * - * Interface function to upper layer. each one who wants to get a SAP + * Interface function to upper layer. Each one who wants to get a SAP * (for example NetBEUI) should call this function. Returns the opened * SAP for success, NULL for failure. */ @@ -110,7 +110,7 @@ err: * llc_sap_close - close interface for upper layers. * @sap: SAP to be closed. * - * Close interface function to upper layer. each one who wants to + * Close interface function to upper layer. Each one who wants to * close an open SAP (for example NetBEUI) should call this function. */ void llc_sap_close(struct llc_sap *sap) @@ -123,9 +123,9 @@ void llc_sap_close(struct llc_sap *sap) * llc_sap_req - Request interface for upper layers * @prim: pointer to structure that contains service parameters. * - * Request interface function to upper layer. each one who wants to - * request a service from LLC, must call this function. details of - * requested service is defined in input argument(prim). Returns 0 for + * Request interface function to upper layer. Each one who wants to + * request a service from LLC, must call this function. Details of + * requested service is defined in input argument(prim). Returns 0 for * success, 1 otherwise. */ static int llc_sap_req(struct llc_prim_if_block *prim) @@ -174,7 +174,7 @@ static int llc_unitdata_req_handler(struct llc_prim_if_block *prim) ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.data = prim; rc = 0; - llc_sap_send_ev(sap, prim->data->udata.skb); + llc_sap_state_process(sap, prim->data->udata.skb); out: return rc; } @@ -200,7 +200,7 @@ static int llc_test_req_handler(struct llc_prim_if_block *prim) ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.data = prim; rc = 0; - llc_sap_send_ev(sap, prim->data->udata.skb); + llc_sap_state_process(sap, prim->data->udata.skb); out: return rc; } @@ -227,7 +227,7 @@ static int llc_xid_req_handler(struct llc_prim_if_block *prim) ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.data = prim; rc = 0; - llc_sap_send_ev(sap, prim->data->udata.skb); + llc_sap_state_process(sap, prim->data->udata.skb); out: return rc; } @@ -237,10 +237,10 @@ out: * @prim: pointer to structure that contains service parameters * * This function is called when upper layer wants to send data using - * connection oriented communication mode. during sending data, connection + * connection oriented communication mode. During sending data, connection * will be locked and received frames and expired timers will be queued. * Returns 0 for success, -ECONNABORTED when the connection already - * closed. and -EBUSY when sending data is not permitted in this state or + * closed and -EBUSY when sending data is not permitted in this state or * LLC has send an I pdu with p bit set to 1 and is waiting for it's * response. */ @@ -273,7 +273,7 @@ static int llc_data_req_handler(struct llc_prim_if_block *prim) ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.data = prim; prim->data->data.skb->dev = llc->dev; - rc = llc_conn_send_ev(sk, prim->data->data.skb); + rc = llc_conn_state_process(sk, prim->data->data.skb); out: release_sock(sk); return rc; @@ -297,8 +297,8 @@ static void llc_confirm_impossible(struct llc_prim_if_block *prim) * @prim: pointer to structure that contains service parameters. * * Upper layer calls this to establish an LLC connection with a remote - * machine. this function packages a proper event and sends it connection - * component state machine. Success or failure of connection + * machine. This function packages a proper event and sends it connection + * component state machine. Success or failure of connection * establishment will inform to upper layer via calling it's confirm * function and passing proper information. */ @@ -323,18 +323,22 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim) laddr.lsap = prim->data->conn.saddr.lsap; memcpy(daddr.mac, prim->data->conn.daddr.mac, sizeof(daddr.mac)); daddr.lsap = prim->data->conn.daddr.lsap; - sk = llc_find_sock(sap, &daddr, &laddr); + sk = llc_lookup_established(sap, &daddr, &laddr); if (sk) { llc_confirm_impossible(prim); goto out_put; } - rc = -ENOMEM; + rc = -ENOMEM; if (prim->data->conn.sk) { sk = prim->data->conn.sk; if (llc_sock_init(sk)) goto out; } else { - sk = llc_sock_alloc(); + /* + * FIXME: this one will die as soon as core and + * llc_sock starts sharing a struct sock. + */ + sk = llc_sock_alloc(PF_LLC); if (!sk) { llc_confirm_impossible(prim); goto out; @@ -359,7 +363,7 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim) ev->data.prim.prim = LLC_CONN_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.data = prim; - rc = llc_conn_send_ev(sk, skb); + rc = llc_conn_state_process(sk, skb); } if (rc) { llc_sap_unassign_sock(sap, sk); @@ -378,7 +382,7 @@ out: * @prim: pointer to structure that contains service parameters. * * Upper layer calls this when it wants to close an established LLC - * connection with a remote machine. this function packages a proper event + * connection with a remote machine. This function packages a proper event * and sends it to connection component state machine. Returns 0 for * success, 1 otherwise. */ @@ -406,7 +410,7 @@ static int llc_disc_req_handler(struct llc_prim_if_block *prim) ev->data.prim.prim = LLC_DISC_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.data = prim; - rc = llc_conn_send_ev(sk, skb); + rc = llc_conn_state_process(sk, skb); out: release_sock(sk); sock_put(sk); @@ -418,7 +422,7 @@ out: * @prim: pointer to structure that contains service parameters. * * Called when upper layer wants to reset an established LLC connection - * with a remote machine. this function packages a proper event and sends + * with a remote machine. This function packages a proper event and sends * it to connection component state machine. Returns 0 for success, 1 * otherwise. */ @@ -437,7 +441,7 @@ static int llc_rst_req_handler(struct llc_prim_if_block *prim) ev->data.prim.prim = LLC_RESET_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.data = prim; - rc = llc_conn_send_ev(sk, skb); + rc = llc_conn_state_process(sk, skb); } release_sock(sk); return rc; @@ -455,7 +459,7 @@ static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim) * llc_sap_resp - Sends response to peer * @prim: pointer to structure that contains service parameters * - * This function is a interface function to upper layer. each one who + * This function is a interface function to upper layer. Each one who * wants to response to an indicate can call this function via calling * sap_resp with proper service parameters. Returns 0 for success, 1 * otherwise. @@ -509,7 +513,7 @@ static int llc_rst_rsp_handler(struct llc_prim_if_block *prim) ev->data.prim.prim = LLC_RESET_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_RESP; ev->data.prim.data = prim; - rc = llc_conn_send_ev(sk, skb); + rc = llc_conn_state_process(sk, skb); } return rc; } diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c index 7e7e3e2986f7..3fd329feb0cb 100644 --- a/net/llc/llc_mac.c +++ b/net/llc/llc_mac.c @@ -67,7 +67,7 @@ out: } /** - * mac_indicate - 802.2 entry point from net lower layers + * llc_rcv - 802.2 entry point from net lower layers * @skb: received pdu * @dev: device that receive pdu * @pt: packet type @@ -78,7 +78,7 @@ out: * related to a busy connection (a connection is sending data now), * function queues this frame in connection's backlog. */ -int mac_indicate(struct sk_buff *skb, struct net_device *dev, +int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) { struct llc_sap *sap; @@ -119,11 +119,14 @@ int mac_indicate(struct sk_buff *skb, struct net_device *dev, llc_pdu_decode_da(skb, daddr.mac); llc_pdu_decode_dsap(skb, &daddr.lsap); - sk = llc_find_sock(sap, &saddr, &daddr); - if (!sk) { /* didn't find an active connection; allocate a - * connection to use; associate it with this SAP - */ - sk = llc_sock_alloc(); + sk = llc_lookup_established(sap, &saddr, &daddr); + if (!sk) { + /* + * FIXME: here we'll pass the sk->family of the + * listening socket, if found, when + * llc_lookup_listener is added in the next patches. + */ + sk = llc_sock_alloc(PF_LLC); if (!sk) goto drop; memcpy(&llc_sk(sk)->daddr, &saddr, sizeof(saddr)); @@ -131,21 +134,10 @@ int mac_indicate(struct sk_buff *skb, struct net_device *dev, sock_hold(sk); } bh_lock_sock(sk); - if (!sk->lock.users) { - /* FIXME: Check this on SMP as it is now calling - * llc_pdu_router _with_ the lock held. - * Old comment: - * With the current code one can't call - * llc_pdu_router with the socket lock held, cause - * it'll route the pdu to the upper layers and it can - * reenter llc and in llc_req_prim will try to grab - * the same lock, maybe we should use spin_trylock_bh - * in the llc_req_prim (llc_data_req_handler, etc) and - * add the request to the backlog, well see... - */ + if (!sk->lock.users) rc = llc_pdu_router(llc_sk(sk)->sap, sk, skb, LLC_TYPE_2); - } else { + else { dprintk("%s: add to backlog\n", __FUNCTION__); llc_set_backlog_type(skb, LLC_PACKET); sk_add_backlog(sk, skb); @@ -203,7 +195,7 @@ static void fix_up_incoming_skb(struct sk_buff *skb) * is NULL then data unit destined for station else frame destined for SAP * or connection; finds a matching open SAP, if one, forwards the packet * to it; if no matching SAP, drops the packet. Returns 0 or the return of - * llc_conn_send_ev (that may well result in the connection being + * llc_conn_state_process (that may well result in the connection being * destroyed) */ int llc_pdu_router(struct llc_sap *sap, struct sock* sk, @@ -218,13 +210,13 @@ int llc_pdu_router(struct llc_sap *sap, struct sock* sk, ev->type = LLC_STATION_EV_TYPE_PDU; ev->data.pdu.reason = 0; - llc_station_send_ev(station, skb); + llc_station_state_process(station, skb); } else if (type == LLC_TYPE_1) { struct llc_sap_state_ev *ev = llc_sap_ev(skb); ev->type = LLC_SAP_EV_TYPE_PDU; ev->data.pdu.reason = 0; - llc_sap_send_ev(sap, skb); + llc_sap_state_process(sap, skb); } else if (type == LLC_TYPE_2) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); struct llc_opt *llc = llc_sk(sk); @@ -234,7 +226,7 @@ int llc_pdu_router(struct llc_sap *sap, struct sock* sk, ev->type = LLC_CONN_EV_TYPE_PDU; ev->data.pdu.reason = 0; - rc = llc_conn_send_ev(sk, skb); + rc = llc_conn_state_process(sk, skb); } else rc = -EINVAL; return rc; diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c index 4b024b4ab586..ee6d8dc0caef 100644 --- a/net/llc/llc_main.c +++ b/net/llc/llc_main.c @@ -136,7 +136,7 @@ struct llc_sap *llc_sap_find(u8 sap_value) * * This function processes frames that has received and timers that has * expired during sending an I pdu (refer to data_req_handler). frames - * queue by mac_indicate function (llc_mac.c) and timers queue by timer + * queue by llc_rcv function (llc_mac.c) and timers queue by timer * callback functions(llc_c_ac.c). */ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb) @@ -152,7 +152,7 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb) } else if (llc_backlog_type(skb) == LLC_EVENT) { /* timer expiration event */ if (llc->state > 1) /* not closed */ - rc = llc_conn_send_ev(sk, skb); + rc = llc_conn_state_process(sk, skb); else llc_conn_free_ev(skb); kfree_skb(skb); @@ -199,13 +199,14 @@ out: /** * __llc_sock_alloc - Allocates LLC sock + * @family: upper layer protocol family * * Allocates a LLC sock and initializes it. Returns the new LLC sock * or %NULL if there's no memory available for one */ -struct sock *__llc_sock_alloc(void) +struct sock *__llc_sock_alloc(int family) { - struct sock *sk = sk_alloc(PF_LLC, GFP_ATOMIC, 1, NULL); + struct sock *sk = sk_alloc(family, GFP_ATOMIC, 1, NULL); if (!sk) goto out; @@ -319,14 +320,14 @@ struct llc_station *llc_station_get(void) } /** - * llc_station_send_ev: queue event and try to process queue. + * llc_station_state_process: queue event and try to process queue. * @station: Address of the station * @skb: Address of the event * * Queues an event (on the station event queue) for handling by the * station state machine and attempts to process any queued-up events. */ -void llc_station_send_ev(struct llc_station *station, struct sk_buff *skb) +void llc_station_state_process(struct llc_station *station, struct sk_buff *skb) { spin_lock_bh(&station->ev_q.lock); skb_queue_tail(&station->ev_q.list, skb); @@ -556,13 +557,13 @@ unlock: static struct packet_type llc_packet_type = { .type = __constant_htons(ETH_P_802_2), - .func = mac_indicate, + .func = llc_rcv, .data = (void *)1, }; static struct packet_type llc_tr_packet_type = { .type = __constant_htons(ETH_P_TR_802_2), - .func = mac_indicate, + .func = llc_rcv, .data = (void *)1, }; diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 0d2d204fb421..a597a2269b2e 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -63,14 +63,14 @@ void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk) } /** - * llc_sap_send_ev - sends event to SAP state machine + * llc_sap_state_process - sends event to SAP state machine * @sap: pointer to SAP * @skb: pointer to occurred event * * After executing actions of the event, upper layer will be indicated * if needed(on receiving an UI frame). */ -void llc_sap_send_ev(struct llc_sap *sap, struct sk_buff *skb) +void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) { struct llc_sap_state_ev *ev = llc_sap_ev(skb); diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index 4acbbd335228..2d0b9a5e19c2 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -63,7 +63,7 @@ static int llc_ui_wait_for_disc(struct sock *sk, int seconds); * * Return the next unused link number for a given sap. */ -static inline u16 llc_ui_next_link_no(int sap) +static __inline__ u16 llc_ui_next_link_no(int sap) { return llc_ui_sap_link_no_max[sap]++; } @@ -77,7 +77,7 @@ static inline u16 llc_ui_next_link_no(int sap) * is not a complete match up to len, 1 if a complete match up to len is * found. */ -static inline u8 llc_ui_mac_match(u8 *mac1, u8 *mac2) +static __inline__ u8 llc_ui_mac_match(u8 *mac1, u8 *mac2) { return !memcmp(mac1, mac2, IFHWADDRLEN); } @@ -89,7 +89,7 @@ static inline u8 llc_ui_mac_match(u8 *mac1, u8 *mac2) * Determines if a given address is a null mac address. Returns 0 if the * address is not a null mac, 1 if the address is a null mac. */ -static inline u8 llc_ui_mac_null(u8 *mac) +static __inline__ u8 llc_ui_mac_null(u8 *mac) { return !memcmp(mac, llc_ui_addrany, IFHWADDRLEN); } @@ -98,7 +98,7 @@ static inline u8 llc_ui_mac_null(u8 *mac) * llc_ui_addr_null - determines if a address structure is null * @addr: Address to test if null. */ -static inline u8 llc_ui_addr_null(struct sockaddr_llc *addr) +static __inline__ u8 llc_ui_addr_null(struct sockaddr_llc *addr) { return !memcmp(addr, &llc_ui_addrnull, sizeof(*addr)); } @@ -111,7 +111,7 @@ static inline u8 llc_ui_addr_null(struct sockaddr_llc *addr) * Returns 0 if ARP header type not supported or the corresponding * ethernet protocol type. */ -static inline u16 llc_ui_protocol_type(u16 arphrd) +static __inline__ u16 llc_ui_protocol_type(u16 arphrd) { u16 rc = htons(ETH_P_802_2); @@ -129,7 +129,8 @@ static inline u16 llc_ui_protocol_type(u16 arphrd) * operation the user would like to perform and the type of socket. * Returns the correct llc header length. */ -static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr) +static __inline__ u8 llc_ui_header_len(struct sock *sk, + struct sockaddr_llc *addr) { u8 rc = LLC_PDU_LEN_U; @@ -280,7 +281,7 @@ static int llc_ui_send_llc1(struct llc_sap *sap, struct sk_buff *skb, * structure which matches the sap number the user specified. * Returns llc_sap upon match, %NULL otherwise. */ -static inline struct llc_sap *llc_ui_find_sap(u8 sap) +static __inline__ struct llc_sap *llc_ui_find_sap(u8 sap) { struct sock *sk; struct llc_sap *s = NULL; @@ -399,7 +400,7 @@ static struct sock *llc_ui_bh_find_sk_by_addr(struct llc_addr *addr, * * Insert a socket into the local llc socket list. */ -static inline void llc_ui_insert_socket(struct sock *sk) +static __inline__ void llc_ui_insert_socket(struct sock *sk) { write_lock_bh(&llc_ui_sockets_lock); sk->next = llc_ui_sockets; @@ -417,7 +418,7 @@ static inline void llc_ui_insert_socket(struct sock *sk) * * Remove a socket from the local llc socket list. */ -static inline void llc_ui_remove_socket(struct sock *sk) +static __inline__ void llc_ui_remove_socket(struct sock *sk) { write_lock_bh(&llc_ui_sockets_lock); if (sk->pprev) { -- cgit v1.2.3 From c34311f78b8bf3b79380c6e2f8d9b3c143357d5e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 07:36:53 -0300 Subject: LLC: llc_build_and_send_pkt Rename llc_data_req_handler with llc_build_and_send_pkt, following my plan to have LLC look more like TCP/IP and to slowly remove all the ugly prim types and sap->{req,ind,conf}. No problems with Appletalk up to now as it only uses UI and I'm up to now only concentrating on connection mode, so that we can remove all the duplicated work in core and PF_LLC. --- include/net/llc_if.h | 2 ++ net/llc/llc_if.c | 26 ++++++++++---------------- net/llc/llc_sock.c | 12 ++---------- 3 files changed, 14 insertions(+), 26 deletions(-) (limited to 'include') diff --git a/include/net/llc_if.h b/include/net/llc_if.h index cc2348004161..d4a53e05e6e9 100644 --- a/include/net/llc_if.h +++ b/include/net/llc_if.h @@ -152,4 +152,6 @@ typedef int (*llc_prim_call_t)(struct llc_prim_if_block *prim_if); extern struct llc_sap *llc_sap_open(llc_prim_call_t network_indicate, llc_prim_call_t network_confirm, u8 lsap); extern void llc_sap_close(struct llc_sap *sap); + +extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb); #endif /* LLC_IF_H */ diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index 6ddb10c64254..cab3de5fb797 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -31,7 +31,6 @@ static int llc_sap_req(struct llc_prim_if_block *prim); static int llc_unitdata_req_handler(struct llc_prim_if_block *prim); static int llc_test_req_handler(struct llc_prim_if_block *prim); static int llc_xid_req_handler(struct llc_prim_if_block *prim); -static int llc_data_req_handler(struct llc_prim_if_block *prim); static int llc_conn_req_handler(struct llc_prim_if_block *prim); static int llc_disc_req_handler(struct llc_prim_if_block *prim); static int llc_rst_req_handler(struct llc_prim_if_block *prim); @@ -45,7 +44,7 @@ static int llc_no_rsp_handler(struct llc_prim_if_block *prim); static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = { [LLC_DATAUNIT_PRIM] = llc_unitdata_req_handler, [LLC_CONN_PRIM] = llc_conn_req_handler, - [LLC_DATA_PRIM] = llc_data_req_handler, + [LLC_DATA_PRIM] = NULL, /* replaced by llc_build_and_send_pkt */ [LLC_DISC_PRIM] = llc_disc_req_handler, [LLC_RESET_PRIM] = llc_rst_req_handler, [LLC_FLOWCONTROL_PRIM] = llc_flowcontrol_req_handler, @@ -233,7 +232,7 @@ out: } /** - * llc_data_req_handler - Connection data sending for upper layers. + * llc_build_and_send_pkt - Connection data sending for upper layers. * @prim: pointer to structure that contains service parameters * * This function is called when upper layer wants to send data using @@ -244,15 +243,10 @@ out: * LLC has send an I pdu with p bit set to 1 and is waiting for it's * response. */ -static int llc_data_req_handler(struct llc_prim_if_block *prim) +int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb) { struct llc_conn_state_ev *ev; int rc = -ECONNABORTED; - /* accept data frame from network layer to be sent using connection - * mode communication; timeout/retries handled by this layer; - * package primitive as an event and send to connection event handler - */ - struct sock *sk = prim->data->data.sk; struct llc_opt *llc = llc_sk(sk); lock_sock(sk); @@ -267,13 +261,13 @@ static int llc_data_req_handler(struct llc_prim_if_block *prim) llc->failed_data_req = 1; goto out; } - ev = llc_conn_ev(prim->data->data.skb); - ev->type = LLC_CONN_EV_TYPE_PRIM; - ev->data.prim.prim = LLC_DATA_PRIM; - ev->data.prim.type = LLC_PRIM_TYPE_REQ; - ev->data.prim.data = prim; - prim->data->data.skb->dev = llc->dev; - rc = llc_conn_state_process(sk, prim->data->data.skb); + ev = llc_conn_ev(skb); + ev->type = LLC_CONN_EV_TYPE_PRIM; + ev->data.prim.prim = LLC_DATA_PRIM; + ev->data.prim.type = LLC_PRIM_TYPE_REQ; + ev->data.prim.data = NULL; + skb->dev = llc->dev; + rc = llc_conn_state_process(sk, skb); out: release_sock(sk); return rc; diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index d6ed9d110813..ef6e600806bd 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -215,22 +215,14 @@ out: static int llc_ui_send_data(struct llc_sap *sap, struct sock* sk, struct sk_buff *skb, struct sockaddr_llc *addr) { - union llc_u_prim_data prim_data; - struct llc_prim_if_block prim; struct llc_ui_opt* llc_ui = llc_ui_sk(sk); struct llc_opt* llc_core = llc_sk(llc_ui->core_sk); int rc; - prim.data = &prim_data; - prim.sap = sap; - prim.prim = LLC_DATA_PRIM; - prim_data.data.skb = skb; - prim_data.data.pri = 0; - prim_data.data.sk = llc_ui->core_sk; - skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd); + skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd); sock_hold(sk); try: - rc = sap->req(&prim); + rc = llc_build_and_send_pkt(llc_ui->core_sk, skb); if (rc != -EBUSY) goto out; rc = wait_event_interruptible(sk->socket->wait, !llc_ui->core_sk || -- cgit v1.2.3 From c3be6700f35fdcf9f81a0d46f6472e9952f15229 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 07:38:34 -0300 Subject: LLC: kill llc_prim_data and LLC_PRIM_DATA for sap->ind() and sap->conf() On the road to kill all prims, llc_prim_data bits the dust, now the core queues the data directly and takes care of the conf semantics, i.e. waking up the upper layer when the confirmation arrives. Maybe I'll have to put more info on skb->cb for conf and ind, but for PF_LLC this is enough for now. Have to check NetBEUI tho. But we can always add back removed features, better than having features that nobody uses :-) --- include/net/llc_if.h | 9 ------- net/llc/llc_c_ac.c | 20 +++++----------- net/llc/llc_conn.c | 66 +++++++++++++++++++++++++++++----------------------- net/llc/llc_mac.c | 1 + net/llc/llc_sock.c | 61 +++++------------------------------------------- 5 files changed, 50 insertions(+), 107 deletions(-) (limited to 'include') diff --git a/include/net/llc_if.h b/include/net/llc_if.h index d4a53e05e6e9..975485fc42c0 100644 --- a/include/net/llc_if.h +++ b/include/net/llc_if.h @@ -97,14 +97,6 @@ struct llc_prim_flow_ctrl { u32 amount; }; -struct llc_prim_data { - struct sock *sk; - u16 link; - u8 pri; - struct sk_buff *skb; /* pointer to frame */ - u8 status; /* reason */ -}; - /* Sending data in conection-less mode */ struct llc_prim_unit_data { struct llc_addr saddr; @@ -133,7 +125,6 @@ union llc_u_prim_data { struct llc_prim_disc disc; struct llc_prim_reset res; struct llc_prim_flow_ctrl fc; - struct llc_prim_data data; /* data */ struct llc_prim_unit_data udata; /* unit data */ struct llc_prim_xid xid; struct llc_prim_test test; diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index 93f3f7e448c0..7c3140481908 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -112,21 +112,13 @@ int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb) static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); - struct llc_opt *llc = llc_sk(sk); - struct llc_sap *sap = llc->sap; - struct llc_prim_if_block *prim = &sap->llc_cfm_prim; - union llc_u_prim_data *prim_data = prim->data; - prim_data->data.sk = sk; - prim_data->data.pri = 0; - prim_data->data.link = llc->link; - prim_data->data.status = LLC_STATUS_RECEIVED; - prim_data->data.skb = NULL; - prim->data = prim_data; - prim->prim = LLC_DATA_PRIM; - prim->sap = sap; - ev->flag = 1; - ev->cfm_prim = prim; + /* + * FIXME: find better way to tell upper layer that the packet was + * confirmed by the other endpoint + */ + ev->flag = LLC_DATA_PRIM + 1; + ev->cfm_prim = (void *)1; return 0; } diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index cfb144b9c413..2b95ea22be73 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -58,7 +58,13 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) struct llc_prim_if_block *ind_prim = ev->ind_prim; struct llc_prim_if_block *cfm_prim = ev->cfm_prim; - llc_conn_free_ev(skb); + /* + * FIXME: this will vanish as soon I get rid of the double sock crap + */ + if (flag != LLC_DATA_PRIM + 1) + llc_conn_free_ev(skb); + else if (ind_prim && cfm_prim) + skb_get(skb); #ifdef THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY /* check if the connection was freed by the state machine by * means of llc_conn_disc */ @@ -71,25 +77,41 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) if (!flag) /* indicate or confirm not required */ goto out; rc = 0; - if (ind_prim) /* indication required */ - llc->sap->ind(ind_prim); + if (ind_prim) { /* indication required */ + /* + * FIXME: this will be saner as soon I get rid of the double + * sock crap + */ + if (flag == LLC_DATA_PRIM + 1) { + struct sock *upper = llc_sk(skb->sk)->handler; + + skb->sk = upper; + if (sock_queue_rcv_skb(upper, skb)) { + printk(KERN_ERR + "%s: sock_queue_rcv_skb failed!\n", + __FUNCTION__); + kfree_skb(skb); + } + } else + llc->sap->ind(ind_prim); + } if (!cfm_prim) /* confirmation not required */ goto out; /* data confirm has preconditions */ - if (cfm_prim->prim != LLC_DATA_PRIM) { + /* FIXME: see FIXMEs above */ + if (flag != LLC_DATA_PRIM + 1) { llc->sap->conf(cfm_prim); goto out; } if (!llc_data_accept_state(llc->state)) { /* In this state, we can send I pdu */ - /* FIXME: check if we don't need to see if sk->lock.users != 0 - * is needed here - */ - rc = llc->sap->conf(cfm_prim); - if (rc) /* confirmation didn't accept by upper layer */ - llc->failed_data_req = 1; + struct sock* upper = llc_sk(skb->sk)->handler; + + if (upper) + wake_up(upper->sleep); } else - llc->failed_data_req = 1; + rc = llc->failed_data_req = 1; + kfree_skb(skb); out: return rc; } @@ -114,24 +136,10 @@ void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb) void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); - struct llc_opt *llc = llc_sk(sk); - struct llc_sap *sap = llc->sap; - struct llc_prim_if_block *prim = &sap->llc_ind_prim; - union llc_u_prim_data *prim_data = prim->data; - - prim_data->data.sk = sk; - prim_data->data.pri = 0; - prim_data->data.skb = skb; - prim_data->data.link = llc->link; - prim->data = prim_data; - prim->prim = LLC_DATA_PRIM; - prim->sap = sap; - ev->flag = 1; - /* - * Saving prepd prim in event for future use in - * llc_conn_state_process - */ - ev->ind_prim = prim; + + /* FIXME: indicate that we should send this to the upper layer */ + ev->flag = LLC_DATA_PRIM + 1; + ev->ind_prim = (void *)1; } /** diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c index 3fd329feb0cb..50a3934df9dc 100644 --- a/net/llc/llc_mac.c +++ b/net/llc/llc_mac.c @@ -133,6 +133,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, llc_sap_assign_sock(sap, sk); sock_hold(sk); } + skb->sk = sk; bh_lock_sock(sk); if (!sk->lock.users) rc = llc_pdu_router(llc_sk(sk)->sap, sk, skb, diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index ef6e600806bd..f2c36b0d120d 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -1423,44 +1423,6 @@ out_put: out:; } -/** - * llc_ui_ind_data - handle DATA indication - * @prim: Primitive block provided by the llc layer. - * - * handle CONNECT indication. - */ -static void llc_ui_ind_data(struct llc_prim_if_block *prim) -{ - struct llc_prim_data *prim_data = &prim->data->data; - struct sk_buff *skb = prim_data->skb; - struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb); - struct sock* sk = llc_sk(prim_data->sk)->handler; - - if (!sk) - goto out; - sock_hold(sk); - if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) - goto out_put; - /* save primitive for use by the user. */ - llc_ui->sllc_family = AF_LLC; - llc_ui->sllc_arphrd = skb->dev->type; - llc_ui->sllc_test = 0; - llc_ui->sllc_xid = 0; - llc_ui->sllc_ua = 0; - llc_ui->sllc_dsap = llc_ui_sk(sk)->sap->laddr.lsap; - memcpy(llc_ui->sllc_dmac, llc_sk(prim_data->sk)->laddr.mac, - IFHWADDRLEN); - llc_ui->sllc_ssap = llc_sk(prim_data->sk)->daddr.lsap; - memcpy(llc_ui->sllc_smac, llc_sk(prim_data->sk)->daddr.mac, - IFHWADDRLEN); - /* queue skb to the user. */ - if (sock_queue_rcv_skb(sk, skb)) - kfree_skb(skb); -out_put: - sock_put(sk); -out:; -} - /** * llc_ui_ind_disc - handle DISC indication * @prim: Primitive block provided by the llc layer. @@ -1510,7 +1472,9 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) case LLC_CONN_PRIM: llc_ui_ind_conn(prim); break; case LLC_DATA_PRIM: - llc_ui_ind_data(prim); break; + printk(KERN_ERR "%s: shouldn't happen, LLC_DATA_PRIM " + "is gone for ->ind()...\n", __FUNCTION__); + break; case LLC_DISC_PRIM: llc_ui_ind_disc(prim); break; case LLC_RESET_PRIM: @@ -1553,21 +1517,6 @@ out_put: out:; } -/** - * llc_ui_conf_data - handle DATA confirm. - * @prim: Primitive block provided by the llc layer. - * - * handle DATA confirm. - */ -static void llc_ui_conf_data(struct llc_prim_if_block *prim) -{ - struct llc_prim_data *prim_data = &prim->data->data; - struct sock* sk = llc_sk(prim_data->sk)->handler; - - if (sk) - wake_up(sk->sleep); -} - /** * llc_ui_conf_disc - handle DISC confirm. * @prim: Primitive block provided by the llc layer. @@ -1607,7 +1556,9 @@ static int llc_ui_confirm(struct llc_prim_if_block *prim) case LLC_CONN_PRIM: llc_ui_conf_conn(prim); break; case LLC_DATA_PRIM: - llc_ui_conf_data(prim); break; + printk(KERN_ERR "%s: shouldn't happen, LLC_DATA_PRIM " + "is gone for ->conf()...\n", __FUNCTION__); + break; case LLC_DISC_PRIM: llc_ui_conf_disc(prim); break; case LLC_RESET_PRIM: break; -- cgit v1.2.3 From 45bbe785d733f211efc4b59a537e2a04b82bb84c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 07:43:40 -0300 Subject: [LLC] split llc_pdu_router into llc_{station,sap,conn}_rcv --- include/net/llc_mac.h | 5 +-- net/llc/llc_mac.c | 107 +++++++++++++++++++++++++------------------------- net/llc/llc_main.c | 2 +- 3 files changed, 57 insertions(+), 57 deletions(-) (limited to 'include') diff --git a/include/net/llc_mac.h b/include/net/llc_mac.h index 3fd75e4fe8bf..0164d51c1037 100644 --- a/include/net/llc_mac.h +++ b/include/net/llc_mac.h @@ -2,7 +2,7 @@ #define LLC_MAC_H /* * Copyright (c) 1997 by Procom Technology, Inc. - * 2001 by Arnaldo Carvalho de Melo + * 2001, 2002 by Arnaldo Carvalho de Melo * * This program can be redistributed or modified under the terms of the * GNU General Public License as published by the Free Software Foundation. @@ -17,9 +17,8 @@ extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt); extern struct net_device *mac_dev_peer(struct net_device *current_dev, int type, u8 *mac); -extern int llc_pdu_router(struct llc_sap *sap, struct sock *sk, - struct sk_buff *skb, u8 type); extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da); +extern int llc_conn_rcv(struct sock *sk, struct sk_buff *skb); static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type) { diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c index 50a3934df9dc..57e918e4cc25 100644 --- a/net/llc/llc_mac.c +++ b/net/llc/llc_mac.c @@ -33,8 +33,9 @@ #define dprintk(args...) #endif -/* function prototypes */ static void fix_up_incoming_skb(struct sk_buff *skb); +static void llc_station_rcv(struct sk_buff *skb); +static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb); /** * mac_send_pdu - Sends PDU to specific device. @@ -74,9 +75,9 @@ out: * * When the system receives a 802.2 frame this function is called. It * checks SAP and connection of received pdu and passes frame to - * llc_pdu_router for sending to proper state machine. If frame is - * related to a busy connection (a connection is sending data now), - * function queues this frame in connection's backlog. + * llc_{station,sap,conn}_rcv for sending to proper state machine. If + * the frame is related to a busy connection (a connection is sending + * data now), it queues this frame in the connection's backlog. */ int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) @@ -85,7 +86,8 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct llc_pdu_sn *pdu; u8 dest; - /* When the interface is in promisc. mode, drop all the crap that it + /* + * When the interface is in promisc. mode, drop all the crap that it * receives, do not try to analyse it. */ if (skb->pkt_type == PACKET_OTHERHOST) { @@ -98,18 +100,16 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, fix_up_incoming_skb(skb); pdu = llc_pdu_sn_hdr(skb); if (!pdu->dsap) { /* NULL DSAP, refer to station */ - if (llc_pdu_router(NULL, NULL, skb, 0)) - goto drop; + llc_station_rcv(skb); goto out; } sap = llc_sap_find(pdu->dsap); if (!sap) /* unknown SAP */ goto drop; llc_decode_pdu_type(skb, &dest); - if (dest == LLC_DEST_SAP) { /* type 1 services */ - if (llc_pdu_router(sap, NULL, skb, LLC_TYPE_1)) - goto drop; - } else if (dest == LLC_DEST_CONN) { + if (dest == LLC_DEST_SAP) /* type 1 services */ + llc_sap_rcv(sap, skb); + else if (dest == LLC_DEST_CONN) { struct llc_addr saddr, daddr; struct sock *sk; int rc; @@ -136,10 +136,8 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, skb->sk = sk; bh_lock_sock(sk); if (!sk->lock.users) - rc = llc_pdu_router(llc_sk(sk)->sap, sk, skb, - LLC_TYPE_2); + rc = llc_conn_rcv(sk, skb); else { - dprintk("%s: add to backlog\n", __FUNCTION__); llc_set_backlog_type(skb, LLC_PACKET); sk_add_backlog(sk, skb); rc = 0; @@ -184,53 +182,56 @@ static void fix_up_incoming_skb(struct sk_buff *skb) } } -/** - * llc_pdu_router - routes received pdus to the upper layers - * @sap: current sap component structure. - * @sk: current connection structure. - * @frame: received frame. - * @type: type of received frame, that is LLC_TYPE_1 or LLC_TYPE_2 +/* + * llc_station_rcv - send received pdu to the station state machine + * @skb: received frame. * - * Queues received PDUs from LLC_MAC PDU receive queue until queue is - * empty; examines LLC header to determine the destination of PDU, if DSAP - * is NULL then data unit destined for station else frame destined for SAP - * or connection; finds a matching open SAP, if one, forwards the packet - * to it; if no matching SAP, drops the packet. Returns 0 or the return of - * llc_conn_state_process (that may well result in the connection being - * destroyed) + * Sends data unit to station state machine. */ -int llc_pdu_router(struct llc_sap *sap, struct sock* sk, - struct sk_buff *skb, u8 type) +static void llc_station_rcv(struct sk_buff *skb) { - struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - int rc = 0; + struct llc_station *station = llc_station_get(); + struct llc_station_state_ev *ev = llc_station_ev(skb); + + ev->type = LLC_STATION_EV_TYPE_PDU; + ev->data.pdu.reason = 0; + llc_station_state_process(station, skb); +} - if (!pdu->dsap) { - struct llc_station *station = llc_station_get(); - struct llc_station_state_ev *ev = llc_station_ev(skb); - ev->type = LLC_STATION_EV_TYPE_PDU; - ev->data.pdu.reason = 0; - llc_station_state_process(station, skb); - } else if (type == LLC_TYPE_1) { - struct llc_sap_state_ev *ev = llc_sap_ev(skb); +/** + * llc_conn_rcv - sends received pdus to the connection state machine + * @sk: current connection structure. + * @skb: received frame. + * + * Sends received pdus to the connection state machine. + */ +int llc_conn_rcv(struct sock* sk, struct sk_buff *skb) +{ + struct llc_conn_state_ev *ev = llc_conn_ev(skb); + struct llc_opt *llc = llc_sk(sk); - ev->type = LLC_SAP_EV_TYPE_PDU; - ev->data.pdu.reason = 0; - llc_sap_state_process(sap, skb); - } else if (type == LLC_TYPE_2) { - struct llc_conn_state_ev *ev = llc_conn_ev(skb); - struct llc_opt *llc = llc_sk(sk); + if (!llc->dev) + llc->dev = skb->dev; + ev->type = LLC_CONN_EV_TYPE_PDU; + ev->data.pdu.reason = 0; + return llc_conn_state_process(sk, skb); +} - if (!llc->dev) - llc->dev = skb->dev; +/** + * llc_sap_rcv - sends received pdus to the sap state machine + * @sap: current sap component structure. + * @skb: received frame. + * + * Sends received pdus to the sap state machine. + */ +static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb) +{ + struct llc_sap_state_ev *ev = llc_sap_ev(skb); - ev->type = LLC_CONN_EV_TYPE_PDU; - ev->data.pdu.reason = 0; - rc = llc_conn_state_process(sk, skb); - } else - rc = -EINVAL; - return rc; + ev->type = LLC_SAP_EV_TYPE_PDU; + ev->data.pdu.reason = 0; + llc_sap_state_process(sap, skb); } /** diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c index ee6d8dc0caef..fe24722bd45a 100644 --- a/net/llc/llc_main.c +++ b/net/llc/llc_main.c @@ -146,7 +146,7 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb) if (llc_backlog_type(skb) == LLC_PACKET) { if (llc->state > 1) /* not closed */ - rc = llc_pdu_router(llc->sap, sk, skb, LLC_TYPE_2); + rc = llc_conn_rcv(sk, skb); else kfree_skb(skb); } else if (llc_backlog_type(skb) == LLC_EVENT) { -- cgit v1.2.3 From 3c611730bac6a2c9d17493c7e70dc608fcb30f0d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 07:45:39 -0300 Subject: [LLC] use llc_mac_{match,null} in more places --- include/net/llc_mac.h | 32 ++++++++++++++++++++++++++ net/llc/llc_conn.c | 4 ++-- net/llc/llc_mac.c | 2 ++ net/llc/llc_sock.c | 62 +++++++++++++++------------------------------------ 4 files changed, 54 insertions(+), 46 deletions(-) (limited to 'include') diff --git a/include/net/llc_mac.h b/include/net/llc_mac.h index 0164d51c1037..3ab584987448 100644 --- a/include/net/llc_mac.h +++ b/include/net/llc_mac.h @@ -30,4 +30,36 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb) return skb->cb[sizeof(skb->cb) - 1]; } +extern u8 llc_mac_null_var[IFHWADDRLEN]; + +/** + * llc_mac_null - determines if a address is a null mac address + * @mac: Mac address to test if null. + * + * Determines if a given address is a null mac address. Returns 0 if the + * address is not a null mac, 1 if the address is a null mac. + */ +static __inline__ int llc_mac_null(u8 *mac) +{ + return !memcmp(mac, llc_mac_null_var, IFHWADDRLEN); +} + +static __inline__ int llc_addrany(struct llc_addr *addr) +{ + return llc_mac_null(addr->mac) && !addr->lsap; +} + +/** + * llc_mac_match - determines if two mac addresses are the same + * @mac1: First mac address to compare. + * @mac2: Second mac address to compare. + * + * Determines if two given mac address are the same. Returns 0 if there + * is not a complete match up to len, 1 if a complete match up to len is + * found. + */ +static __inline__ int llc_mac_match(u8 *mac1, u8 *mac2) +{ + return !memcmp(mac1, mac2, IFHWADDRLEN); +} #endif /* LLC_MAC_H */ diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 2b95ea22be73..bfe193412b71 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -430,8 +430,8 @@ struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, if (llc->laddr.lsap == laddr->lsap && llc->daddr.lsap == daddr->lsap && - !memcmp(llc->laddr.mac, laddr->mac, ETH_ALEN) && - !memcmp(llc->daddr.mac, daddr->mac, ETH_ALEN)) { + llc_mac_match(llc->laddr.mac, laddr->mac) && + llc_mac_match(llc->daddr.mac, daddr->mac)) { rc = llc->sk; break; } diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c index 57e918e4cc25..0020b3801d6a 100644 --- a/net/llc/llc_mac.c +++ b/net/llc/llc_mac.c @@ -33,6 +33,8 @@ #define dprintk(args...) #endif +u8 llc_mac_null_var[IFHWADDRLEN]; + static void fix_up_incoming_skb(struct sk_buff *skb); static void llc_station_rcv(struct sk_buff *skb); static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb); diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index b3dd84d6e763..0b2c3a9966d4 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,6 @@ /* remember: uninitialized global data is zeroed because its in .bss */ static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START; static u16 llc_ui_sap_link_no_max[256]; -static u8 llc_ui_addrany[IFHWADDRLEN]; static struct sockaddr_llc llc_ui_addrnull; static struct proto_ops llc_ui_ops; static struct sock *llc_ui_sockets; @@ -69,32 +69,6 @@ static __inline__ u16 llc_ui_next_link_no(int sap) return llc_ui_sap_link_no_max[sap]++; } -/** - * llc_ui_mac_match - determines if two mac addresses are the same - * @mac1: First mac address to compare. - * @mac2: Second mac address to compare. - * - * Determines if two given mac address are the same. Returns 0 if there - * is not a complete match up to len, 1 if a complete match up to len is - * found. - */ -static __inline__ u8 llc_ui_mac_match(u8 *mac1, u8 *mac2) -{ - return !memcmp(mac1, mac2, IFHWADDRLEN); -} - -/** - * llc_ui_mac_null - determines if a address is a null mac address - * @mac: Mac address to test if null. - * - * Determines if a given address is a null mac address. Returns 0 if the - * address is not a null mac, 1 if the address is a null mac. - */ -static __inline__ u8 llc_ui_mac_null(u8 *mac) -{ - return !memcmp(mac, llc_ui_addrany, IFHWADDRLEN); -} - /** * llc_ui_addr_null - determines if a address structure is null * @addr: Address to test if null. @@ -304,9 +278,9 @@ static struct sock *__llc_ui_find_sk_by_exact(struct llc_addr *laddr, if (llc_ui->addr.sllc_ssap == laddr->lsap && llc_ui->addr.sllc_dsap == daddr->lsap && - llc_ui_mac_null(llc_ui->addr.sllc_mmac) && - llc_ui_mac_match(llc_ui->addr.sllc_smac, laddr->mac) && - llc_ui_mac_match(llc_ui->addr.sllc_dmac, daddr->mac)) + llc_mac_null(llc_ui->addr.sllc_mmac) && + llc_mac_match(llc_ui->addr.sllc_smac, laddr->mac) && + llc_mac_match(llc_ui->addr.sllc_dmac, daddr->mac)) break; } return sk; @@ -333,27 +307,27 @@ static struct sock *__llc_ui_find_sk_by_addr(struct llc_addr *laddr, if (llc_ui->addr.sllc_ssap != laddr->lsap) continue; - if (llc_ui_mac_null(llc_ui->addr.sllc_smac)) { - if (!llc_ui_mac_null(llc_ui->addr.sllc_mmac) && - !llc_ui_mac_match(llc_ui->addr.sllc_mmac, + if (llc_mac_null(llc_ui->addr.sllc_smac)) { + if (!llc_mac_null(llc_ui->addr.sllc_mmac) && + !llc_mac_match(llc_ui->addr.sllc_mmac, laddr->mac)) continue; break; } - if (dev && !llc_ui_mac_null(llc_ui->addr.sllc_mmac) && - llc_ui_mac_match(llc_ui->addr.sllc_mmac, laddr->mac) && - llc_ui_mac_match(llc_ui->addr.sllc_smac, dev->dev_addr)) + if (dev && !llc_mac_null(llc_ui->addr.sllc_mmac) && + llc_mac_match(llc_ui->addr.sllc_mmac, laddr->mac) && + llc_mac_match(llc_ui->addr.sllc_smac, dev->dev_addr)) break; if (dev->flags & IFF_LOOPBACK) break; - if (!llc_ui_mac_match(llc_ui->addr.sllc_smac, laddr->mac)) + if (!llc_mac_match(llc_ui->addr.sllc_smac, laddr->mac)) continue; tmp_sk = __llc_ui_find_sk_by_exact(laddr, daddr); if (tmp_sk) { sk = tmp_sk; break; } - if (llc_ui_mac_null(llc_ui->addr.sllc_dmac)) + if (llc_mac_null(llc_ui->addr.sllc_dmac)) break; } return sk; @@ -597,7 +571,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) if (!sk->zapped) goto out; /* bind to a specific mac, optional. */ - if (!llc_ui_mac_null(addr->sllc_smac)) { + if (!llc_mac_null(addr->sllc_smac)) { rtnl_lock(); dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac); rtnl_unlock(); @@ -625,11 +599,11 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) struct sock *ask; rc = -EUSERS; /* can't get exclusive use of sap */ - if (!dev && llc_ui_mac_null(addr->sllc_mmac)) + if (!dev && llc_mac_null(addr->sllc_mmac)) goto out; memset(&laddr, 0, sizeof(laddr)); memset(&daddr, 0, sizeof(daddr)); - if (!llc_ui_mac_null(addr->sllc_mmac)) { + if (!llc_mac_null(addr->sllc_mmac)) { if (sk->type != SOCK_DGRAM) { rc = -EOPNOTSUPP; goto out; @@ -1630,14 +1604,14 @@ static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length) for (s = llc_ui_sockets; s; s = s->next) { struct llc_ui_opt *llc_ui = llc_ui_sk(s); len += sprintf(buffer + len, "%p %02X %02X ", s, s->type, - !llc_ui_mac_null(llc_ui->addr.sllc_mmac)); + !llc_mac_null(llc_ui->addr.sllc_mmac)); if (llc_ui->sap) { if (llc_ui->dev && - llc_ui_mac_null(llc_ui->addr.sllc_mmac)) + llc_mac_null(llc_ui->addr.sllc_mmac)) llc_ui_format_mac(buffer + len, llc_ui->dev->dev_addr); else { - if (!llc_ui_mac_null(llc_ui->addr.sllc_mmac)) + if (!llc_mac_null(llc_ui->addr.sllc_mmac)) llc_ui_format_mac(buffer + len, llc_ui->addr.sllc_mmac); else -- cgit v1.2.3 From ebf9bc772851196b2a5e8daf4eadd609c734501f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 07:46:44 -0300 Subject: [LLC] turn tons of simple pdu functions into returning void All of those functions cannot possibly fail, so there is no point in always returning 0. I'll probably turn all of them into inlines in the future too. --- include/net/llc_pdu.h | 56 +++++++++++----------- net/llc/llc_c_ac.c | 13 +++-- net/llc/llc_conn.c | 6 +-- net/llc/llc_pdu.c | 130 +++++++++++++++++++------------------------------- net/llc/llc_s_ac.c | 23 ++------- 5 files changed, 92 insertions(+), 136 deletions(-) (limited to 'include') diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h index 6236c0cab669..02145e59174c 100644 --- a/include/net/llc_pdu.h +++ b/include/net/llc_pdu.h @@ -237,35 +237,35 @@ struct llc_frmr_info { extern void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type); extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value); -extern int llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit); -extern int llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit); -extern int llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa); -extern int llc_pdu_decode_da(struct sk_buff *skb, u8 *ds); -extern int llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap); -extern int llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap); -extern int llc_decode_pdu_type(struct sk_buff *skb, u8 *destination); +extern void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit); +extern void llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit); +extern void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa); +extern void llc_pdu_decode_da(struct sk_buff *skb, u8 *ds); +extern void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap); +extern void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap); +extern void llc_decode_pdu_type(struct sk_buff *skb, u8 *destination); extern void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap, u8 dsap, u8 cr); -extern int llc_pdu_init_as_ui_cmd(struct sk_buff *skb); -extern int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported, +extern void llc_pdu_init_as_ui_cmd(struct sk_buff *skb); +extern void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported, u8 rx_window); -extern int llc_pdu_init_as_test_cmd(struct sk_buff *skb); -extern int llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit); -extern int llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr); -extern int llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); -extern int llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); -extern int llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); -extern int llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit); -extern int llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit); -extern int llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported, - u8 rx_window); -extern int llc_pdu_init_as_test_rsp(struct sk_buff *skb, - struct sk_buff *ev_skb); -extern int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, - struct llc_pdu_sn *prev_pdu, - u8 f_bit, u8 vs, u8 vr, u8 vzyxw); -extern int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); -extern int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); -extern int llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); -extern int llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit); +extern void llc_pdu_init_as_test_cmd(struct sk_buff *skb); +extern void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit); +extern void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr); +extern void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); +extern void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); +extern void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr); +extern void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit); +extern void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit); +extern void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported, + u8 rx_window); +extern void llc_pdu_init_as_test_rsp(struct sk_buff *skb, + struct sk_buff *ev_skb); +extern void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, + struct llc_pdu_sn *prev_pdu, + u8 f_bit, u8 vs, u8 vr, u8 vzyxw); +extern void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); +extern void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); +extern void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr); +extern void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit); #endif /* LLC_PDU_H */ diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index 7c3140481908..bc296905424d 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -1334,12 +1334,15 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb) int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); - u8 f_bit; - if (!LLC_PDU_IS_RSP(pdu) && - !llc_pdu_decode_pf_bit(skb, &f_bit) && f_bit) { - llc_sk(sk)->p_flag = 0; - llc_conn_ac_stop_p_timer(sk, skb); + if (!LLC_PDU_IS_RSP(pdu)) { + u8 f_bit; + + llc_pdu_decode_pf_bit(skb, &f_bit); + if (f_bit) { + llc_sk(sk)->p_flag = 0; + llc_conn_ac_stop_p_timer(sk, skb); + } } return 0; } diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index bfe193412b71..ef6093acb1c3 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -451,10 +451,8 @@ out: */ u8 llc_data_accept_state(u8 state) { - if (state != LLC_CONN_STATE_NORMAL && state != LLC_CONN_STATE_BUSY && - state != LLC_CONN_STATE_REJ) - return 1; /* data_conn_refuse */ - return 0; + return state != LLC_CONN_STATE_NORMAL && state != LLC_CONN_STATE_BUSY && + state != LLC_CONN_STATE_REJ; } /** diff --git a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c index f62dec772a0a..069ec96c9312 100644 --- a/net/llc/llc_pdu.c +++ b/net/llc/llc_pdu.c @@ -18,7 +18,7 @@ #include #include -static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type); +static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type); static __inline__ int llc_get_hdr_len(u8 pdu_type); static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu); @@ -60,9 +60,7 @@ void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value) u8 pdu_type; struct llc_pdu_sn *pdu; - if (llc_pdu_decode_pdu_type(skb, &pdu_type)) - goto out; - + llc_pdu_decode_pdu_type(skb, &pdu_type); pdu = llc_pdu_sn_hdr(skb); switch (pdu_type) { @@ -74,7 +72,6 @@ void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value) pdu->ctrl_1 |= (pdu->ctrl_1 & 0xEF) | (bit_value << 4); break; } -out:; } /** @@ -86,15 +83,12 @@ out:; * PDU). In I or S pdus, p/f bit is right bit of fourth byte in header. In * U pdus p/f bit is fifth bit of third byte. */ -int llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit) +void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit) { u8 pdu_type; struct llc_pdu_sn *pdu; - int rc = llc_pdu_decode_pdu_type(skb, &pdu_type); - - if (rc) - goto out; + llc_pdu_decode_pdu_type(skb, &pdu_type); pdu = llc_pdu_sn_hdr(skb); switch (pdu_type) { @@ -106,22 +100,19 @@ int llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit) *pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4; break; } -out: - return 0; } /** - * llc_pdu_decode_cr_bit - extracs command response bit from LLC header + * llc_pdu_decode_cr_bit - extracts command response bit from LLC header * @skb: input skb that c/r bit must be extracted from it. * @cr_bit: command/response bit (0 or 1). * * This function extracts command/response bit from LLC header. this bit * is right bit of source SAP. */ -int llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit) +void llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit) { *cr_bit = llc_pdu_un_hdr(skb)->ssap & LLC_PDU_CMD_RSP_MASK; - return 0; } /** @@ -131,13 +122,12 @@ int llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit) * * This function extracts source address(MAC) of input frame. */ -int llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) +void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) { if (skb->protocol == ntohs(ETH_P_802_2)) memcpy(sa, ((struct ethhdr *)skb->mac.raw)->h_source, ETH_ALEN); else if (skb->protocol == ntohs(ETH_P_TR_802_2)) memcpy(sa, ((struct trh_hdr *)skb->mac.raw)->saddr, ETH_ALEN); - return 0; } /** @@ -147,13 +137,12 @@ int llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) * * This function extracts destination address(MAC) of input frame. */ -int llc_pdu_decode_da(struct sk_buff *skb, u8 *da) +void llc_pdu_decode_da(struct sk_buff *skb, u8 *da) { if (skb->protocol == ntohs(ETH_P_802_2)) memcpy(da, ((struct ethhdr *)skb->mac.raw)->h_dest, ETH_ALEN); else if (skb->protocol == ntohs(ETH_P_TR_802_2)) memcpy(da, ((struct trh_hdr *)skb->mac.raw)->daddr, ETH_ALEN); - return 0; } /** @@ -164,10 +153,9 @@ int llc_pdu_decode_da(struct sk_buff *skb, u8 *da) * This function extracts destination SAP of input frame. right bit of * DSAP designates individual/group SAP. */ -int llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap) +void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap) { *dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE; - return 0; } /** @@ -175,13 +163,12 @@ int llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap) * @skb: input skb that source SAP must be extracted from it. * @ssap: source SAP (output argument). * - * This function extracts source SAP of input frame. right bit of SSAP is + * This function extracts source SAP of input frame. Right bit of SSAP is * command/response bit. */ -int llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap) +void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap) { *ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE; - return 0; } /** @@ -190,13 +177,12 @@ int llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap) * * This function sets third byte of LLC header as a UI PDU. */ -int llc_pdu_init_as_ui_cmd(struct sk_buff *skb) +void llc_pdu_init_as_ui_cmd(struct sk_buff *skb) { struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); pdu->ctrl_1 = LLC_PDU_TYPE_U; pdu->ctrl_1 |= LLC_1_PDU_CMD_UI; - return 0; } /** @@ -206,8 +192,8 @@ int llc_pdu_init_as_ui_cmd(struct sk_buff *skb) * This function sets third,fourth,fifth and sixth bytes of LLC header as * a XID PDU. */ -int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported, - u8 rx_window) +void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported, + u8 rx_window) { struct llc_xid_info *xid_info; struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); @@ -220,7 +206,6 @@ int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported, xid_info->type = svcs_supported; xid_info->rw = rx_window << 1; /* size of recieve window */ skb_put(skb, 3); - return 0; } /** @@ -229,14 +214,13 @@ int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported, * * Sets a PDU as TEST */ -int llc_pdu_init_as_test_cmd(struct sk_buff *skb) +void llc_pdu_init_as_test_cmd(struct sk_buff *skb) { struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); pdu->ctrl_1 = LLC_PDU_TYPE_U; pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST; pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; - return 0; } /** @@ -246,18 +230,17 @@ int llc_pdu_init_as_test_cmd(struct sk_buff *skb) * * Builds a pdu frame as a DISC command. */ -int llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit) +void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit) { struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); pdu->ctrl_1 = LLC_PDU_TYPE_U; pdu->ctrl_1 |= LLC_2_PDU_CMD_DISC; pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK; - return 0; } /** - * pdu_init_as_i_cmd - builds I pdu + * llc_pdu_init_as_i_cmd - builds I pdu * @skb: Address of the skb to build * @p_bit: The P bit to set in the PDU * @ns: The sequence number of the data PDU @@ -265,7 +248,7 @@ int llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit) * * Builds a pdu frame as an I command. */ -int llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr) +void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -274,18 +257,17 @@ int llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr) pdu->ctrl_2 |= (p_bit & LLC_I_PF_BIT_MASK); /* p/f bit */ pdu->ctrl_1 |= (ns << 1) & 0xFE; /* set N(S) in bits 2..8 */ pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ - return 0; } /** - * pdu_init_as_rej_cmd - builds REJ PDU + * llc_pdu_init_as_rej_cmd - builds REJ PDU * @skb: Address of the skb to build * @p_bit: The P bit to set in the PDU * @nr: The seq. number of the expected I PDU from the remote * * Builds a pdu frame as a REJ command. */ -int llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) +void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -295,18 +277,17 @@ int llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK; pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ - return 0; } /** - * pdu_init_as_rnr_cmd - builds RNR pdu + * llc_pdu_init_as_rnr_cmd - builds RNR pdu * @skb: Address of the skb to build * @p_bit: The P bit to set in the PDU * @nr: The seq. number of the expected I PDU from the remote * * Builds a pdu frame as an RNR command. */ -int llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) +void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -316,18 +297,17 @@ int llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) pdu->ctrl_2 |= p_bit & LLC_S_PF_BIT_MASK; pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ - return 0; } /** - * pdu_init_as_rr_cmd - Builds RR pdu + * llc_pdu_init_as_rr_cmd - Builds RR pdu * @skb: Address of the skb to build * @p_bit: The P bit to set in the PDU * @nr: The seq. number of the expected I PDU from the remote * * Builds a pdu frame as an RR command. */ -int llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) +void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -336,53 +316,50 @@ int llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr) pdu->ctrl_2 = p_bit & LLC_S_PF_BIT_MASK; pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ - return 0; } /** - * pdu_init_as_sabme_cmd - builds SABME pdu + * llc_pdu_init_as_sabme_cmd - builds SABME pdu * @skb: Address of the skb to build * @p_bit: The P bit to set in the PDU * * Builds a pdu frame as an SABME command. */ -int llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit) +void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit) { struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); pdu->ctrl_1 = LLC_PDU_TYPE_U; pdu->ctrl_1 |= LLC_2_PDU_CMD_SABME; pdu->ctrl_1 |= ((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK; - return 0; } /** - * pdu_init_as_dm_rsp - builds DM response pdu + * llc_pdu_init_as_dm_rsp - builds DM response pdu * @skb: Address of the skb to build * @f_bit: The F bit to set in the PDU * * Builds a pdu frame as a DM response. */ -int llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit) +void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit) { struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); pdu->ctrl_1 = LLC_PDU_TYPE_U; pdu->ctrl_1 |= LLC_2_PDU_RSP_DM; pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK; - return 0; } /** - * pdu_init_as_xid_rsp - builds XID response PDU + * llc_pdu_init_as_xid_rsp - builds XID response PDU * @skb: Address of the skb to build * @svcs_supported: The class of the LLC (I or II) * @rx_window: The size of the receive window of the LLC * * Builds a pdu frame as an XID response. */ -int llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported, - u8 rx_window) +void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported, + u8 rx_window) { struct llc_xid_info *xid_info; struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); @@ -396,17 +373,16 @@ int llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported, xid_info->type = svcs_supported; xid_info->rw = rx_window << 1; skb_put(skb, 3); - return 0; } /** - * pdu_init_as_test_rsp - build TEST response PDU + * llc_pdu_init_as_test_rsp - build TEST response PDU * @skb: Address of the skb to build * @ev_skb: The received TEST command PDU frame * * Builds a pdu frame as a TEST response. */ -int llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb) +void llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb) { int dsize; struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); @@ -421,12 +397,11 @@ int llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb) memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize); skb_put(skb, dsize); } - return 0; } /** - * pdu_init_as_frmr_rsp - builds FRMR response PDU - * @pdu_frame: Address of the frame to build + * llc_pdu_init_as_frmr_rsp - builds FRMR response PDU + * @skb: Address of the frame to build * @prev_pdu: The rejected PDU frame * @f_bit: The F bit to set in the PDU * @vs: tx state vari value for the data link conn at the rejecting LLC @@ -435,8 +410,8 @@ int llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb) * * Builds a pdu frame as a FRMR response. */ -int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu, - u8 f_bit, u8 vs, u8 vr, u8 vzyxw) +void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu, + u8 f_bit, u8 vs, u8 vr, u8 vzyxw) { struct llc_frmr_info *frmr_info; u8 prev_pf = 0; @@ -460,18 +435,17 @@ int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu, FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw); FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw); skb_put(skb, 5); - return 0; } /** - * pdu_init_as_rr_rsp - builds RR response pdu + * llc_pdu_init_as_rr_rsp - builds RR response pdu * @skb: Address of the skb to build * @f_bit: The F bit to set in the PDU * @nr: The seq. number of the expected data PDU from the remote * * Builds a pdu frame as an RR response. */ -int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) +void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -481,18 +455,17 @@ int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK; pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ - return 0; } /** - * pdu_init_as_rej_rsp - builds REJ response pdu + * llc_pdu_init_as_rej_rsp - builds REJ response pdu * @skb: Address of the skb to build * @f_bit: The F bit to set in the PDU * @nr: The seq. number of the expected data PDU from the remote * * Builds a pdu frame as a REJ response. */ -int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) +void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -502,18 +475,17 @@ int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK; pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ - return 0; } /** - * pdu_init_as_rnr_rsp - builds RNR response pdu - * @pdu_frame: Address of the frame to build + * llc_pdu_init_as_rnr_rsp - builds RNR response pdu + * @skb: Address of the frame to build * @f_bit: The F bit to set in the PDU * @nr: The seq. number of the expected data PDU from the remote * * Builds a pdu frame as an RNR response. */ -int llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) +void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -523,24 +495,22 @@ int llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr) pdu->ctrl_2 |= f_bit & LLC_S_PF_BIT_MASK; pdu->ctrl_1 &= 0x0F; /* setting bits 5..8 to zero(reserved) */ pdu->ctrl_2 |= (nr << 1) & 0xFE; /* set N(R) in bits 10..16 */ - return 0; } /** - * pdu_init_as_ua_rsp - builds UA response pdu + * llc_pdu_init_as_ua_rsp - builds UA response pdu * @skb: Address of the frame to build * @f_bit: The F bit to set in the PDU * * Builds a pdu frame as a UA response. */ -int llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit) +void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit) { struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); pdu->ctrl_1 = LLC_PDU_TYPE_U; pdu->ctrl_1 |= LLC_2_PDU_RSP_UA; pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK; - return 0; } /** @@ -548,9 +518,9 @@ int llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit) * @skb: input skb that type of it must be designated. * @type: type of PDU (output argument). * - * This function designates type of PDU (I,S or U). + * This function designates type of PDU (I, S or U). */ -static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type) +static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type) { struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); @@ -561,7 +531,6 @@ static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type) *type = LLC_PDU_TYPE_S; } else *type = LLC_PDU_TYPE_I; - return 0; } /** @@ -571,7 +540,7 @@ static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type) * * This function designates which component of LLC must handle this PDU. */ -int llc_decode_pdu_type(struct sk_buff *skb, u8 *dest) +void llc_decode_pdu_type(struct sk_buff *skb, u8 *dest) { u8 type = LLC_DEST_CONN; /* I-PDU or S-PDU type */ struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -596,7 +565,6 @@ int llc_decode_pdu_type(struct sk_buff *skb, u8 *dest) } out: *dest = type; - return 0; } /** diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c index f2be18568aec..e3f8ff640a82 100644 --- a/net/llc/llc_s_ac.c +++ b/net/llc/llc_s_ac.c @@ -57,13 +57,10 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap, prim_data->daddr.lsap, LLC_PDU_CMD); - rc = llc_pdu_init_as_ui_cmd(skb); - if (rc) - goto out; + llc_pdu_init_as_ui_cmd(skb); rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac); if (!rc) llc_sap_send_pdu(sap, skb); -out: return rc; } @@ -85,13 +82,10 @@ int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap, prim_data->daddr.lsap, LLC_PDU_CMD); - rc = llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); - if (rc) - goto out; + llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac); if (!rc) llc_sap_send_pdu(sap, skb); -out: return rc; } @@ -118,9 +112,7 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb) nskb->dev = skb->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, LLC_PDU_RSP); - rc = llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0); - if (rc) - goto out; + llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0); rc = lan_hdrs_init(nskb, mac_sa, mac_da); if (!rc) llc_sap_send_pdu(sap, nskb); @@ -146,13 +138,10 @@ int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap, prim_data->daddr.lsap, LLC_PDU_CMD); - rc = llc_pdu_init_as_test_cmd(skb); - if (rc) - goto out; + llc_pdu_init_as_test_cmd(skb); rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac); if (!rc) llc_sap_send_pdu(sap, skb); -out: return rc; } @@ -171,9 +160,7 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb) nskb->dev = skb->dev; llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, LLC_PDU_RSP); - rc = llc_pdu_init_as_test_rsp(nskb, skb); - if (rc) - goto out; + llc_pdu_init_as_test_rsp(nskb, skb); rc = lan_hdrs_init(nskb, mac_sa, mac_da); if (!rc) llc_sap_send_pdu(sap, nskb); -- cgit v1.2.3 From 269f04b762fa11f693d3c3167afcdd4ca505fca6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 07:48:48 -0300 Subject: [LLC] use just one struct sock per connection With this PF_LLC is tightly integrated with the core and that is a good thing 8) . kill llc_ui_opt, the only non-duplicated bit is struct sockaddr_llc and this now lives in llc_opt . remove debug code from llc_sk_alloc/free (previously llc_sock_alloc/free) . the skbs allocated for event processing don't need to have any payload at all, just the skb->cb is enough, so remove the bogus 1 from alloc_skb calls . llc_conn_disc put on death row . llc_process_tmr_ev callers have to hold the socket lock . the request functions in llc_if.c doesn't hold the socket lock anymore its up to its callers on the socket layer (llc_sock.c) . llc_sk_alloc now receives a priority for sk_alloc call and is the only way to alloc a new sock (from llc_mac and llc_sock, bottom and top) . added the traditional struct sock REFCNT_DEBUG support for llc . llc_sock was simplified and is on the zen route to cleanliness, wait for the next patches, it'll shrink a lot when I zap all the crap (as in not needed) list handling, using the existing list maintained in struct llc_sap for that, probably splitting it in two, one for listening sockets and other for (being) established ones. Ah, and the sap->ind and sap->req and friends will die. --- include/linux/llc.h | 11 - include/net/llc_conn.h | 64 +---- include/net/llc_if.h | 2 - net/llc/llc_actn.c | 2 +- net/llc/llc_c_ac.c | 42 ++-- net/llc/llc_conn.c | 34 +-- net/llc/llc_if.c | 56 +---- net/llc/llc_mac.c | 19 +- net/llc/llc_main.c | 59 +++-- net/llc/llc_sock.c | 619 ++++++++++++++++++++++++------------------------- 10 files changed, 409 insertions(+), 499 deletions(-) (limited to 'include') diff --git a/include/linux/llc.h b/include/linux/llc.h index 824a149e9e6b..77ac5d9df544 100644 --- a/include/linux/llc.h +++ b/include/linux/llc.h @@ -78,17 +78,6 @@ enum llc_sockopts { #define LLC_SAP_DYN_STOP 0xDE #define LLC_SAP_DYN_TRIES 4 -struct sock; - -struct llc_ui_opt { - u16 link; /* network layer link number */ - struct llc_sap *sap; /* pointer to parent SAP */ - struct sock *core_sk; - struct net_device *dev; /* device to send to remote */ - struct sockaddr_llc addr; /* address sock is bound to */ -}; - -#define llc_ui_sk(__sk) ((struct llc_ui_opt *)(__sk)->protinfo) #define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0])) #ifdef CONFIG_LLC_UI diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index ea7725fa705f..3b2d68e45075 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h @@ -2,7 +2,7 @@ #define LLC_CONN_H /* * Copyright (c) 1997 by Procom Technology, Inc. - * 2001 by Arnaldo Carvalho de Melo + * 2001, 2002 by Arnaldo Carvalho de Melo * * This program can be redistributed or modified under the terms of the * GNU General Public License as published by the Free Software Foundation. @@ -13,8 +13,7 @@ */ #include #include - -#define DEBUG_LLC_CONN_ALLOC +#include struct llc_timer { struct timer_list timer; @@ -25,7 +24,7 @@ struct llc_timer { struct llc_opt { struct list_head node; /* entry in sap->sk_list.list */ struct sock *sk; /* sock that has this llc_opt */ - void *handler; /* for upper layers usage */ + struct sockaddr_llc addr; /* address sock is bound to */ u8 state; /* state of connection */ struct llc_sap *sap; /* pointer to parent SAP */ struct llc_addr laddr; /* lsap/mac pair */ @@ -80,60 +79,11 @@ struct llc_opt { struct llc_conn_state_ev; -extern struct sock *__llc_sock_alloc(int family); -extern void __llc_sock_free(struct sock *sk, u8 free); - -#ifdef DEBUG_LLC_CONN_ALLOC -#define dump_stack() printk(KERN_INFO "call trace: %p, %p, %p\n", \ - __builtin_return_address(0), \ - __builtin_return_address(1), \ - __builtin_return_address(2)); -#define llc_sock_alloc(family) ({ \ - struct sock *__sk = __llc_sock_alloc(family); \ - if (__sk) { \ - llc_sk(__sk)->f_alloc = __FUNCTION__; \ - llc_sk(__sk)->l_alloc = __LINE__; \ - } \ - __sk;}) -#define __llc_sock_assert(__sk) \ - if (llc_sk(__sk)->f_free) { \ - printk(KERN_ERR \ - "%p conn (alloc'd @ %s(%d)) " \ - "already freed @ %s(%d) " \ - "being used again @ %s(%d)\n", \ - llc_sk(__sk), \ - llc_sk(__sk)->f_alloc, llc_sk(__sk)->l_alloc, \ - llc_sk(__sk)->f_free, llc_sk(__sk)->l_free, \ - __FUNCTION__, __LINE__); \ - dump_stack(); -#define llc_sock_free(__sk) \ -{ \ - __llc_sock_assert(__sk) \ - } else { \ - __llc_sock_free(__sk, 0); \ - llc_sk(__sk)->f_free = __FUNCTION__; \ - llc_sk(__sk)->l_free = __LINE__; \ - } \ -} -#define llc_sock_assert(__sk) \ -{ \ - __llc_sock_assert(__sk); \ - return; } \ -} -#define llc_sock_assert_ret(__sk, __ret) \ -{ \ - __llc_sock_assert(__sk); \ - return __ret; } \ -} -#else /* DEBUG_LLC_CONN_ALLOC */ -#define llc_sock_alloc(family) __llc_sock_alloc(family) -#define llc_sock_free(__sk) __llc_sock_free(__sk, 1) -#define llc_sock_assert(__sk) -#define llc_sock_assert_ret(__sk) -#endif /* DEBUG_LLC_CONN_ALLOC */ +extern struct sock *llc_sk_alloc(int family, int priority); +extern void llc_sk_free(struct sock *sk); -extern void llc_sock_reset(struct sock *sk); -extern int llc_sock_init(struct sock *sk); +extern void llc_sk_reset(struct sock *sk); +extern int llc_sk_init(struct sock *sk); /* Access to a connection */ extern int llc_conn_state_process(struct sock *sk, struct sk_buff *skb); diff --git a/include/net/llc_if.h b/include/net/llc_if.h index 975485fc42c0..e294c1d976b1 100644 --- a/include/net/llc_if.h +++ b/include/net/llc_if.h @@ -73,8 +73,6 @@ struct llc_prim_conn { u8 pri; /* service_class */ struct net_device *dev; struct sock *sk; /* returned from REQUEST */ - void *handler; /* upper layer use, - stored in llc_opt->handler */ u16 link; struct sk_buff *skb; /* received SABME */ }; diff --git a/net/llc/llc_actn.c b/net/llc/llc_actn.c index cb8704409d8e..dadb22054749 100644 --- a/net/llc/llc_actn.c +++ b/net/llc/llc_actn.c @@ -134,7 +134,7 @@ int llc_station_ac_report_status(struct llc_station *station, static void llc_station_ack_tmr_callback(unsigned long timeout_data) { struct llc_station *station = (struct llc_station *)timeout_data; - struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC); + struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); station->ack_tmr_running = 0; if (skb) { diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index bc296905424d..ecb6d6f1658d 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -1454,8 +1454,9 @@ int llc_conn_ac_set_f_flag_p(struct sock *sk, struct sk_buff *skb) void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) { struct sock *sk = (struct sock *)timeout_data; - struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC); + struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); + bh_lock_sock(sk); llc_sk(sk)->pf_cycle_timer.running = 0; if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); @@ -1464,13 +1465,15 @@ void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) ev->data.tmr.timer_specific = NULL; llc_process_tmr_ev(sk, skb); } + bh_unlock_sock(sk); } static void llc_conn_busy_tmr_cb(unsigned long timeout_data) { struct sock *sk = (struct sock *)timeout_data; - struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC); + struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); + bh_lock_sock(sk); llc_sk(sk)->busy_state_timer.running = 0; if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); @@ -1479,13 +1482,15 @@ static void llc_conn_busy_tmr_cb(unsigned long timeout_data) ev->data.tmr.timer_specific = NULL; llc_process_tmr_ev(sk, skb); } + bh_unlock_sock(sk); } void llc_conn_ack_tmr_cb(unsigned long timeout_data) { struct sock* sk = (struct sock *)timeout_data; - struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC); + struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); + bh_lock_sock(sk); llc_sk(sk)->ack_timer.running = 0; if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); @@ -1494,13 +1499,15 @@ void llc_conn_ack_tmr_cb(unsigned long timeout_data) ev->data.tmr.timer_specific = NULL; llc_process_tmr_ev(sk, skb); } + bh_unlock_sock(sk); } static void llc_conn_rej_tmr_cb(unsigned long timeout_data) { struct sock *sk = (struct sock *)timeout_data; - struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC); + struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); + bh_lock_sock(sk); llc_sk(sk)->rej_sent_timer.running = 0; if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); @@ -1509,6 +1516,7 @@ static void llc_conn_rej_tmr_cb(unsigned long timeout_data) ev->data.tmr.timer_specific = NULL; llc_process_tmr_ev(sk, skb); } + bh_unlock_sock(sk); } int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb) @@ -1536,14 +1544,11 @@ int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb) * llc_conn_disc - removes connection from SAP list and frees it * @sk: closed connection * @skb: occurred event - * - * Returns 2, to indicate the state machine that the connection was freed. */ int llc_conn_disc(struct sock *sk, struct sk_buff *skb) { - llc_sap_unassign_sock(llc_sk(sk)->sap, sk); - llc_sock_free(sk); - return 2; + /* FIXME: this thing seems to want to die */ + return 0; } /** @@ -1555,7 +1560,7 @@ int llc_conn_disc(struct sock *sk, struct sk_buff *skb) */ int llc_conn_reset(struct sock *sk, struct sk_buff *skb) { - llc_sock_reset(sk); + llc_sk_reset(sk); return 0; } @@ -1589,19 +1594,16 @@ u8 llc_circular_between(u8 a, u8 b, u8 c) */ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb) { - bh_lock_sock(sk); if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) { printk(KERN_WARNING "%s: timer called on closed connection\n", __FUNCTION__); llc_conn_free_ev(skb); - goto out; - } - if (!sk->lock.users) - llc_conn_state_process(sk, skb); - else { - llc_set_backlog_type(skb, LLC_EVENT); - sk_add_backlog(sk, skb); + } else { + if (!sk->lock.users) + llc_conn_state_process(sk, skb); + else { + llc_set_backlog_type(skb, LLC_EVENT); + sk_add_backlog(sk, skb); + } } -out: - bh_unlock_sock(sk); } diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index ef6093acb1c3..46e54e9621ba 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -43,7 +43,7 @@ static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; * @sk: connection * @skb: occurred event * - * Sends an event to connection state machine. after processing event + * Sends an event to connection state machine. After processing event * (executing it's actions and changing state), upper layer will be * indicated or confirmed, if needed. Returns 0 for success, 1 for * failure. The socket lock has to be held before calling this function. @@ -65,15 +65,6 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) llc_conn_free_ev(skb); else if (ind_prim && cfm_prim) skb_get(skb); -#ifdef THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY - /* check if the connection was freed by the state machine by - * means of llc_conn_disc */ - if (rc == 2) { - printk(KERN_INFO "%s: rc == 2\n", __FUNCTION__); - rc = -ECONNABORTED; - goto out; - } -#endif /* THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY */ if (!flag) /* indicate or confirm not required */ goto out; rc = 0; @@ -83,10 +74,13 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) * sock crap */ if (flag == LLC_DATA_PRIM + 1) { - struct sock *upper = llc_sk(skb->sk)->handler; - - skb->sk = upper; - if (sock_queue_rcv_skb(upper, skb)) { + if (sock_queue_rcv_skb(skb->sk, skb)) { + /* + * FIXME: have to sync the LLC state + * machine wrt mem usage with + * sk->{r,w}mem_alloc, will do + * this soon 8) + */ printk(KERN_ERR "%s: sock_queue_rcv_skb failed!\n", __FUNCTION__); @@ -105,10 +99,8 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) } if (!llc_data_accept_state(llc->state)) { /* In this state, we can send I pdu */ - struct sock* upper = llc_sk(skb->sk)->handler; - - if (upper) - wake_up(upper->sleep); + if (skb->sk) + skb->sk->write_space(skb->sk); } else rc = llc->failed_data_req = 1; kfree_skb(skb); @@ -118,7 +110,6 @@ out: void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb) { - llc_sock_assert(sk); /* queue PDU to send to MAC layer */ skb_queue_tail(&sk->write_queue, skb); llc_conn_send_pdus(sk); @@ -380,11 +371,10 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk, * llc_exec_conn_trans_actions - executes related actions * @sk: connection * @trans: transition that it's actions must be performed - * @skb: happened event + * @skb: event * * Executes actions that is related to happened event. Returns 0 for - * success, 1 to indicate failure of at least one action or 2 if the - * connection was freed (llc_conn_disc was called) + * success, 1 to indicate failure of at least one action. */ static int llc_exec_conn_trans_actions(struct sock *sk, struct llc_conn_state_trans *trans, diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index cab3de5fb797..8af1ec3a1417 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -249,7 +250,6 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb) int rc = -ECONNABORTED; struct llc_opt *llc = llc_sk(sk); - lock_sock(sk); if (llc->state == LLC_CONN_STATE_ADM) goto out; rc = -EBUSY; @@ -269,7 +269,6 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb) skb->dev = llc->dev; rc = llc_conn_state_process(sk, skb); out: - release_sock(sk); return rc; } @@ -299,7 +298,6 @@ static void llc_confirm_impossible(struct llc_prim_if_block *prim) static int llc_conn_req_handler(struct llc_prim_if_block *prim) { int rc = -EBUSY; - struct llc_opt *llc; struct llc_sap *sap = prim->sap; struct sk_buff *skb; struct net_device *ddev = mac_dev_peer(prim->data->conn.dev, @@ -319,37 +317,16 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim) daddr.lsap = prim->data->conn.daddr.lsap; sk = llc_lookup_established(sap, &daddr, &laddr); if (sk) { - llc_confirm_impossible(prim); - goto out_put; - } - rc = -ENOMEM; - if (prim->data->conn.sk) { - sk = prim->data->conn.sk; - if (llc_sock_init(sk)) - goto out; - } else { - /* - * FIXME: this one will die as soon as core and - * llc_sock starts sharing a struct sock. - */ - sk = llc_sock_alloc(PF_LLC); - if (!sk) { + if (sk->state == TCP_ESTABLISHED) { llc_confirm_impossible(prim); - goto out; - } - prim->data->conn.sk = sk; + goto out_put; + } else + sock_put(sk); } + rc = -ENOMEM; + sk = prim->data->conn.sk; sock_hold(sk); - lock_sock(sk); - /* assign new connection to it's SAP */ - llc_sap_assign_sock(sap, sk); - llc = llc_sk(sk); - memcpy(&llc->daddr, &daddr, sizeof(llc->daddr)); - memcpy(&llc->laddr, &laddr, sizeof(llc->laddr)); - llc->dev = ddev; - llc->link = prim->data->conn.link; - llc->handler = prim->data->conn.handler; - skb = alloc_skb(1, GFP_ATOMIC); + skb = alloc_skb(0, GFP_ATOMIC); if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); @@ -359,15 +336,10 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim) ev->data.prim.data = prim; rc = llc_conn_state_process(sk, skb); } - if (rc) { - llc_sap_unassign_sock(sap, sk); - llc_sock_free(sk); + if (rc) llc_confirm_impossible(prim); - } - release_sock(sk); out_put: sock_put(sk); -out: return rc; } @@ -388,7 +360,6 @@ static int llc_disc_req_handler(struct llc_prim_if_block *prim) struct sock* sk = prim->data->disc.sk; sock_hold(sk); - lock_sock(sk); if (llc_sk(sk)->state == LLC_CONN_STATE_ADM || llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) goto out; @@ -396,7 +367,7 @@ static int llc_disc_req_handler(struct llc_prim_if_block *prim) * Postpone unassigning the connection from its SAP and returning the * connection until all ACTIONs have been completely executed */ - skb = alloc_skb(1, GFP_ATOMIC); + skb = alloc_skb(0, GFP_ATOMIC); if (!skb) goto out; ev = llc_conn_ev(skb); @@ -406,7 +377,6 @@ static int llc_disc_req_handler(struct llc_prim_if_block *prim) ev->data.prim.data = prim; rc = llc_conn_state_process(sk, skb); out: - release_sock(sk); sock_put(sk); return rc; } @@ -426,8 +396,7 @@ static int llc_rst_req_handler(struct llc_prim_if_block *prim) int rc = 1; struct sock *sk = prim->data->res.sk; - lock_sock(sk); - skb = alloc_skb(1, GFP_ATOMIC); + skb = alloc_skb(0, GFP_ATOMIC); if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); @@ -437,7 +406,6 @@ static int llc_rst_req_handler(struct llc_prim_if_block *prim) ev->data.prim.data = prim; rc = llc_conn_state_process(sk, skb); } - release_sock(sk); return rc; } @@ -498,7 +466,7 @@ static int llc_rst_rsp_handler(struct llc_prim_if_block *prim) * package as event and send it to connection event handler */ struct sock *sk = prim->data->res.sk; - struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC); + struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c index 0020b3801d6a..b8b031510043 100644 --- a/net/llc/llc_mac.c +++ b/net/llc/llc_mac.c @@ -27,7 +27,7 @@ #include #include -#if 1 +#if 0 #define dprintk(args...) printk(KERN_DEBUG args) #else #define dprintk(args...) @@ -123,23 +123,30 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, sk = llc_lookup_established(sap, &saddr, &daddr); if (!sk) { + struct llc_opt *llc; + + dprintk("%s: llc_lookup_established failed\n", __FUNCTION__); /* * FIXME: here we'll pass the sk->family of the * listening socket, if found, when * llc_lookup_listener is added in the next patches. */ - sk = llc_sock_alloc(PF_LLC); + sk = llc_sk_alloc(PF_LLC, GFP_ATOMIC); if (!sk) goto drop; - memcpy(&llc_sk(sk)->daddr, &saddr, sizeof(saddr)); + llc = llc_sk(sk); + memcpy(&llc->laddr, &daddr, sizeof(llc->laddr)); + memcpy(&llc->daddr, &saddr, sizeof(llc->daddr)); llc_sap_assign_sock(sap, sk); sock_hold(sk); } skb->sk = sk; bh_lock_sock(sk); - if (!sk->lock.users) - rc = llc_conn_rcv(sk, skb); - else { + if (!sk->lock.users) { + /* rc = */ llc_conn_rcv(sk, skb); + rc = 0; + } else { + dprintk("%s: adding to backlog...\n", __FUNCTION__); llc_set_backlog_type(skb, LLC_PACKET); sk_add_backlog(sk, skb); rc = 0; diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c index fe24722bd45a..a1768084605b 100644 --- a/net/llc/llc_main.c +++ b/net/llc/llc_main.c @@ -52,6 +52,11 @@ static int llc_rtn_all_conns(struct llc_sap *sap); static struct llc_station llc_main_station; /* only one of its kind */ +#undef LLC_REFCNT_DEBUG +#ifdef LLC_REFCNT_DEBUG +static atomic_t llc_sock_nr; +#endif + /** * llc_sap_alloc - allocates and initializes sap. * @@ -165,10 +170,12 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb) } /** - * llc_sock_init - Initialize a socket with default llc values. + * llc_sk_init - Initializes a socket with default llc values. * @sk: socket to intiailize. + * + * Initializes a socket with default llc values. */ -int llc_sock_init(struct sock* sk) +int llc_sk_init(struct sock* sk) { struct llc_opt *llc = kmalloc(sizeof(*llc), GFP_ATOMIC); int rc = -ENOMEM; @@ -198,61 +205,83 @@ out: } /** - * __llc_sock_alloc - Allocates LLC sock + * llc_sk_alloc - Allocates LLC sock * @family: upper layer protocol family + * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) * * Allocates a LLC sock and initializes it. Returns the new LLC sock * or %NULL if there's no memory available for one */ -struct sock *__llc_sock_alloc(int family) +struct sock *llc_sk_alloc(int family, int priority) { - struct sock *sk = sk_alloc(family, GFP_ATOMIC, 1, NULL); + struct sock *sk = sk_alloc(family, priority, 1, NULL); + MOD_INC_USE_COUNT; if (!sk) - goto out; - if (llc_sock_init(sk)) + goto decmod; + if (llc_sk_init(sk)) goto outsk; sock_init_data(NULL, sk); +#ifdef LLC_REFCNT_DEBUG + atomic_inc(&llc_sock_nr); + printk(KERN_DEBUG "LLC socket %p created in %s, now we have %d alive\n", sk, + __FUNCTION__, atomic_read(&llc_sock_nr)); +#endif out: return sk; outsk: sk_free(sk); sk = NULL; +decmod: + MOD_DEC_USE_COUNT; goto out; } /** - * __llc_sock_free - Frees a LLC socket + * llc_sk_free - Frees a LLC socket * @sk - socket to free * * Frees a LLC socket */ -void __llc_sock_free(struct sock *sk, u8 free) +void llc_sk_free(struct sock *sk) { struct llc_opt *llc = llc_sk(sk); llc->state = LLC_CONN_OUT_OF_SVC; - /* stop all (possibly) running timers */ + /* Stop all (possibly) running timers */ llc_conn_ac_stop_all_timers(sk, NULL); #ifdef DEBUG_LLC_CONN_ALLOC printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __FUNCTION__, skb_queue_len(&llc->pdu_unack_q), skb_queue_len(&sk->write_queue)); #endif + skb_queue_purge(&sk->receive_queue); skb_queue_purge(&sk->write_queue); skb_queue_purge(&llc->pdu_unack_q); - if (free) - sock_put(sk); +#ifdef LLC_REFCNT_DEBUG + if (atomic_read(&sk->refcnt) != 1) { + printk(KERN_DEBUG "Destruction of LLC sock %p delayed in %s, cnt=%d\n", + sk, __FUNCTION__, atomic_read(&sk->refcnt)); + printk(KERN_DEBUG "%d LLC sockets are still alive\n", + atomic_read(&llc_sock_nr)); + } else { + atomic_dec(&llc_sock_nr); + printk(KERN_DEBUG "LLC socket %p released in %s, %d are still alive\n", sk, + __FUNCTION__, atomic_read(&llc_sock_nr)); + } +#endif + sock_put(sk); + MOD_DEC_USE_COUNT; } /** - * llc_sock_reset - resets a connection + * llc_sk_reset - resets a connection * @sk: LLC socket to reset * * Resets a connection to the out of service state. Stops its timers * and frees any frames in the queues of the connection. */ -void llc_sock_reset(struct sock *sk) +void llc_sk_reset(struct sock *sk) { struct llc_opt *llc = llc_sk(sk); @@ -585,7 +614,7 @@ static int __init llc_init(void) skb_queue_head_init(&llc_main_station.mac_pdu_q); skb_queue_head_init(&llc_main_station.ev_q.list); spin_lock_init(&llc_main_station.ev_q.lock); - skb = alloc_skb(1, GFP_ATOMIC); + skb = alloc_skb(0, GFP_ATOMIC); if (!skb) goto err; llc_build_offset_table(); diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index 0b2c3a9966d4..5753d316feaf 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -11,6 +11,7 @@ * connections. * * Copyright (c) 2001 by Jay Schulist + * 2002 by Arnaldo Carvalho de Melo * * This program can be redistributed or modified under the terms of the * GNU General Public License as published by the Free Software Foundation. @@ -57,6 +58,13 @@ static int llc_ui_confirm(struct llc_prim_if_block *prim); static int llc_ui_wait_for_conn(struct sock *sk, int timeout); static int llc_ui_wait_for_disc(struct sock *sk, int timeout); static int llc_ui_wait_for_data(struct sock *sk, int timeout); +static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout); + +#if 0 +#define dprintk(args...) printk(KERN_DEBUG args) +#else +#define dprintk(args...) +#endif /** * llc_ui_next_link_no - return the next unused link number for a sap @@ -130,7 +138,7 @@ static int llc_ui_send_conn(struct sock *sk, struct llc_sap *sap, struct sockaddr_llc *addr, struct net_device *dev, int link) { - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); union llc_u_prim_data prim_data; struct llc_prim_if_block prim; @@ -139,10 +147,9 @@ static int llc_ui_send_conn(struct sock *sk, struct llc_sap *sap, prim.prim = LLC_CONN_PRIM; prim_data.conn.dev = dev; prim_data.conn.link = link; - prim_data.conn.sk = NULL; - prim_data.conn.handler = sk; + prim_data.conn.sk = sk; prim_data.conn.pri = 0; - prim_data.conn.saddr.lsap = llc_ui->addr.sllc_ssap; + prim_data.conn.saddr.lsap = llc->addr.sllc_ssap; prim_data.conn.daddr.lsap = addr->sllc_dsap; memcpy(prim_data.conn.saddr.mac, dev->dev_addr, IFHWADDRLEN); memcpy(prim_data.conn.daddr.mac, addr->sllc_dmac, IFHWADDRLEN); @@ -159,55 +166,50 @@ static int llc_ui_send_conn(struct sock *sk, struct llc_sap *sap, */ static int llc_ui_send_disc(struct sock *sk) { - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); union llc_u_prim_data prim_data; struct llc_prim_if_block prim; int rc = 0; - if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) + if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) { + rc = 1; goto out; + } sk->state = TCP_CLOSING; prim.data = &prim_data; - prim.sap = llc_ui->sap; + prim.sap = llc->sap; prim.prim = LLC_DISC_PRIM; - prim_data.disc.sk = llc_ui->core_sk; - prim_data.disc.link = llc_ui->link; - rc = llc_ui->sap->req(&prim); + prim_data.disc.sk = sk; + prim_data.disc.link = llc->link; + rc = llc->sap->req(&prim); out: return rc; } /** * llc_ui_send_data - send data via reliable llc2 connection - * @sap: Sap the socket is bound to. * @sk: Connection the socket is using. * @skb: Data the user wishes to send. * @addr: Source and destination fields provided by the user. + * @noblock: can we block waiting for data? * * Send data via reliable llc2 connection. - * Returns 0 upon success, non-zero if action did not succeed. + * Returns 0 upon success, non-zero if action did not succeed. */ -static int llc_ui_send_data(struct llc_sap *sap, struct sock* sk, - struct sk_buff *skb, struct sockaddr_llc *addr) +static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, + struct sockaddr_llc *addr, int noblock) { - struct llc_ui_opt* llc_ui = llc_ui_sk(sk); - struct llc_opt* llc_core = llc_sk(llc_ui->core_sk); - int rc; + struct llc_opt* llc = llc_sk(sk); + int rc = 0; skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd); - sock_hold(sk); -try: - rc = llc_build_and_send_pkt(llc_ui->core_sk, skb); - if (rc != -EBUSY) - goto out; - rc = wait_event_interruptible(sk->socket->wait, !llc_ui->core_sk || - !llc_core->failed_data_req); + if (llc_data_accept_state(llc->state) || llc->p_flag) { + int timeout = sock_sndtimeo(sk, noblock); + + rc = llc_ui_wait_for_busy_core(sk, timeout); + } if (!rc) - goto try; - if (!llc_ui->core_sk) - rc = -ENOTCONN; -out: - sock_put(sk); + rc = llc_build_and_send_pkt(sk, skb); return rc; } @@ -255,12 +257,12 @@ static __inline__ struct llc_sap *llc_ui_find_sap(u8 sap) read_lock_bh(&llc_ui_sockets_lock); for (sk = llc_ui_sockets; sk; sk = sk->next) { - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); - if (!llc_ui->sap) + if (!llc->sap) continue; - if (llc_ui->sap->laddr.lsap == sap) { - s = llc_ui->sap; + if (llc->sap->laddr.lsap == sap) { + s = llc->sap; break; } } @@ -274,13 +276,13 @@ static struct sock *__llc_ui_find_sk_by_exact(struct llc_addr *laddr, struct sock *sk; for (sk = llc_ui_sockets; sk; sk = sk->next) { - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); - if (llc_ui->addr.sllc_ssap == laddr->lsap && - llc_ui->addr.sllc_dsap == daddr->lsap && - llc_mac_null(llc_ui->addr.sllc_mmac) && - llc_mac_match(llc_ui->addr.sllc_smac, laddr->mac) && - llc_mac_match(llc_ui->addr.sllc_dmac, daddr->mac)) + if (llc->addr.sllc_ssap == laddr->lsap && + llc->addr.sllc_dsap == daddr->lsap && + llc_mac_null(llc->addr.sllc_mmac) && + llc_mac_match(llc->addr.sllc_smac, laddr->mac) && + llc_mac_match(llc->addr.sllc_dmac, daddr->mac)) break; } return sk; @@ -303,31 +305,31 @@ static struct sock *__llc_ui_find_sk_by_addr(struct llc_addr *laddr, struct sock *sk, *tmp_sk; for (sk = llc_ui_sockets; sk; sk = sk->next) { - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); - if (llc_ui->addr.sllc_ssap != laddr->lsap) + if (llc->addr.sllc_ssap != laddr->lsap) continue; - if (llc_mac_null(llc_ui->addr.sllc_smac)) { - if (!llc_mac_null(llc_ui->addr.sllc_mmac) && - !llc_mac_match(llc_ui->addr.sllc_mmac, - laddr->mac)) + if (llc_mac_null(llc->addr.sllc_smac)) { + if (!llc_mac_null(llc->addr.sllc_mmac) && + !llc_mac_match(llc->addr.sllc_mmac, + laddr->mac)) continue; break; } - if (dev && !llc_mac_null(llc_ui->addr.sllc_mmac) && - llc_mac_match(llc_ui->addr.sllc_mmac, laddr->mac) && - llc_mac_match(llc_ui->addr.sllc_smac, dev->dev_addr)) + if (dev && !llc_mac_null(llc->addr.sllc_mmac) && + llc_mac_match(llc->addr.sllc_mmac, laddr->mac) && + llc_mac_match(llc->addr.sllc_smac, dev->dev_addr)) break; if (dev->flags & IFF_LOOPBACK) break; - if (!llc_mac_match(llc_ui->addr.sllc_smac, laddr->mac)) + if (!llc_mac_match(llc->addr.sllc_smac, laddr->mac)) continue; tmp_sk = __llc_ui_find_sk_by_exact(laddr, daddr); if (tmp_sk) { sk = tmp_sk; break; } - if (llc_mac_null(llc_ui->addr.sllc_dmac)) + if (llc_mac_null(llc->addr.sllc_dmac)) break; } return sk; @@ -393,7 +395,8 @@ static __inline__ void llc_ui_remove_socket(struct sock *sk) sk->next->pprev = sk->pprev; *sk->pprev = sk->next; sk->pprev = NULL; - /* this only makes sense if the socket was inserted on the + /* + * This only makes sense if the socket was inserted on the * list, if sk->pprev is NULL it wasn't */ sock_put(sk); @@ -401,38 +404,13 @@ static __inline__ void llc_ui_remove_socket(struct sock *sk) write_unlock_bh(&llc_ui_sockets_lock); } -/** - * llc_ui_destroy_sk - destroy socket - * @data: Socket which is to be destroyed. - * - * Really destroy the socket. - */ -static void llc_ui_destroy_sk(struct sock *sk) -{ - skb_queue_purge(&sk->receive_queue); - skb_queue_purge(&sk->write_queue); - sock_put(sk); - MOD_DEC_USE_COUNT; -} - -/** - * llc_ui_destroy_timer - try to destroy socket again - * @data: Socket which is to be destroyed. - * - * Attempt to destroy a socket which was previously destroyed but - * was still in use at the time. - */ -static void llc_ui_destroy_timer(unsigned long data) +static void llc_ui_sk_init(struct socket *sock, struct sock *sk) { - struct sock *sk = (struct sock *)data; - - if (!atomic_read(&sk->wmem_alloc) && - !atomic_read(&sk->rmem_alloc) && sk->dead) - llc_ui_destroy_sk(sk); - else { - sk->timer.expires = jiffies + SOCK_DESTROY_TIME; - add_timer(&sk->timer); - } + sk->type = sock->type; + sk->sleep = &sock->wait; + sk->socket = sock; + sock->sk = sk; + sock->ops = &llc_ui_ops; } /** @@ -447,31 +425,17 @@ static void llc_ui_destroy_timer(unsigned long data) static int llc_ui_create(struct socket *sock, int protocol) { struct sock *sk; - struct llc_ui_opt *llc_ui; int rc = -ESOCKTNOSUPPORT; - MOD_INC_USE_COUNT; - if (sock->type != SOCK_DGRAM && sock->type != SOCK_STREAM) - goto decmod; - rc = -ENOMEM; - sk = sk_alloc(PF_LLC, GFP_KERNEL, 1, NULL); - if (!sk) - goto decmod; - llc_ui = kmalloc(sizeof(*llc_ui), GFP_KERNEL); - if (!llc_ui) - goto outsk; - memset(llc_ui, 0, sizeof(*llc_ui)); - rc = 0; - sock_init_data(sock, sk); - llc_ui_sk(sk) = llc_ui; - sock->ops = &llc_ui_ops; -out: + if (sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM) { + rc = -ENOMEM; + sk = llc_sk_alloc(PF_LLC, GFP_KERNEL); + if (sk) { + rc = 0; + llc_ui_sk_init(sock, sk); + } + } return rc; -outsk: - sk_free(sk); -decmod: - MOD_DEC_USE_COUNT; - goto out; } /** @@ -483,33 +447,25 @@ decmod: static int llc_ui_release(struct socket *sock) { struct sock *sk = sock->sk; - struct llc_ui_opt *llc_ui; + struct llc_opt *llc; if (!sk) goto out; sock_hold(sk); lock_sock(sk); - llc_ui = llc_ui_sk(sk); - if (llc_ui->core_sk && !llc_ui_send_disc(sk)) + llc = llc_sk(sk); + dprintk("%s: closing local(%02X) remote(%02X)\n", __FUNCTION__, + llc->laddr.lsap, llc->daddr.lsap); + if (!llc_ui_send_disc(sk)) llc_ui_wait_for_disc(sk, sk->rcvtimeo); - llc_ui_remove_socket(sk); + llc_sap_unassign_sock(llc->sap, sk); release_sock(sk); + llc_ui_remove_socket(sk); - if (llc_ui->sap && !llc_ui_find_sap(llc_ui->sap->laddr.lsap)) - llc_sap_close(llc_ui->sap); - sock_orphan(sk); - sock->sk = NULL; - if (!atomic_read(&sk->wmem_alloc) && - !atomic_read(&sk->rmem_alloc) && sk->dead) - llc_ui_destroy_sk(sk); - else { - init_timer(&sk->timer); - sk->timer.expires = jiffies + SOCK_DESTROY_TIME; - sk->timer.function = llc_ui_destroy_timer; - sk->timer.data = (unsigned long)sk; - add_timer(&sk->timer); - } + if (llc->sap && list_empty(&llc->sap->sk_list.list)) + llc_sap_close(llc->sap); sock_put(sk); + llc_sk_free(sk); out: return 0; } @@ -563,7 +519,7 @@ out: static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) { struct sock *sk = sock->sk; - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); struct llc_sap *sap; struct net_device *dev = NULL; int rc = -EINVAL; @@ -578,7 +534,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) rc = -ENETUNREACH; if (!dev) goto out; - llc_ui->dev = dev; + llc->dev = dev; } /* bind to a specific sap, optional. */ if (!addr->sllc_ssap) { @@ -619,10 +575,15 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) goto out; } } - memcpy(&llc_ui->addr, addr, sizeof(*addr)); - llc_ui->sap = sap; + llc->laddr.lsap = addr->sllc_ssap; + memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN); + llc->daddr.lsap = addr->sllc_dsap; + memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN); + memcpy(&llc->addr, addr, sizeof(llc->addr)); rc = sk->zapped = 0; llc_ui_insert_socket(sk); + /* assign new connection to it's SAP */ + llc_sap_assign_sock(sap, sk); out: return rc; } @@ -651,6 +612,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) struct sock *sk = sock->sk; int rc = -EINVAL; + dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_ssap); if (!sk->zapped || addrlen != sizeof(*addr)) goto out; rc = -EAFNOSUPPORT; @@ -686,7 +648,7 @@ static int llc_ui_shutdown(struct socket *sock, int how) goto out; rc = llc_ui_send_disc(sk); if (!rc) - llc_ui_wait_for_disc(sk, sk->rcvtimeo); + rc = llc_ui_wait_for_disc(sk, sk->rcvtimeo); /* Wake up anyone sleeping in poll */ sk->state_change(sk); out: @@ -712,7 +674,7 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, int addrlen, int flags) { struct sock *sk = sock->sk; - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr; struct net_device *dev; int rc = -EINVAL; @@ -730,14 +692,15 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, if (rc) goto out; } - if (!llc_ui->dev) { + if (!llc->dev) { rtnl_lock(); dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac); rtnl_unlock(); if (!dev) goto out; + llc->dev = dev; } else - dev = llc_ui->dev; + dev = llc->dev; if (sk->type != SOCK_STREAM) goto out; rc = -EALREADY; @@ -745,14 +708,17 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, goto out; sock->state = SS_CONNECTING; sk->state = TCP_SYN_SENT; - llc_ui->link = llc_ui_next_link_no(llc_ui->sap->laddr.lsap); - rc = llc_ui_send_conn(sk, llc_ui->sap, addr, dev, llc_ui->link); + llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap); + rc = llc_ui_send_conn(sk, llc->sap, addr, dev, llc->link); if (rc) { + dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__); sock->state = SS_UNCONNECTED; sk->state = TCP_CLOSE; goto out; } rc = llc_ui_wait_for_conn(sk, sk->rcvtimeo); + if (rc) + dprintk("%s: llc_ui_wait_for_conn failed=%d\n", __FUNCTION__, rc); out: release_sock(sk); return rc; @@ -802,6 +768,12 @@ static int llc_ui_wait_for_disc(struct sock *sk, int timeout) add_wait_queue_exclusive(sk->sleep, &wait); for (;;) { __set_current_state(TASK_INTERRUPTIBLE); + rc = -ERESTARTSYS; + if (signal_pending(current)) + break; + rc = -EAGAIN; + if (!timeout) + break; rc = 0; if (sk->state != TCP_CLOSE) { release_sock(sk); @@ -809,12 +781,6 @@ static int llc_ui_wait_for_disc(struct sock *sk, int timeout) lock_sock(sk); } else break; - rc = -ERESTARTSYS; - if (signal_pending(current)) - break; - rc = -EAGAIN; - if (!timeout) - break; } __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); @@ -823,23 +789,12 @@ static int llc_ui_wait_for_disc(struct sock *sk, int timeout) static int llc_ui_wait_for_conn(struct sock *sk, int timeout) { - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); DECLARE_WAITQUEUE(wait, current); int rc; add_wait_queue_exclusive(sk->sleep, &wait); for (;;) { __set_current_state(TASK_INTERRUPTIBLE); - rc = 0; - if (sk->state != TCP_ESTABLISHED) { - release_sock(sk); - timeout = schedule_timeout(timeout); - lock_sock(sk); - } else { - if (!llc_ui->core_sk) - rc = -EAGAIN; - break; - } rc = -EAGAIN; if (sk->state == TCP_CLOSE) break; @@ -849,6 +804,13 @@ static int llc_ui_wait_for_conn(struct sock *sk, int timeout) rc = -EAGAIN; if (!timeout) break; + rc = 0; + if (sk->state != TCP_ESTABLISHED) { + release_sock(sk); + timeout = schedule_timeout(timeout); + lock_sock(sk); + } else + break; } __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); @@ -858,11 +820,19 @@ static int llc_ui_wait_for_conn(struct sock *sk, int timeout) static int llc_ui_wait_for_data(struct sock *sk, int timeout) { DECLARE_WAITQUEUE(wait, current); - int rc; + int rc = 0; add_wait_queue_exclusive(sk->sleep, &wait); for (;;) { __set_current_state(TASK_INTERRUPTIBLE); + if (sk->shutdown & RCV_SHUTDOWN) + break; + rc = -ERESTARTSYS; + if (signal_pending(current)) + break; + rc = -EAGAIN; + if (!timeout) + break; rc = 0; if (skb_queue_empty(&sk->receive_queue)) { release_sock(sk); @@ -870,12 +840,38 @@ static int llc_ui_wait_for_data(struct sock *sk, int timeout) lock_sock(sk); } else break; + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(sk->sleep, &wait); + return rc; +} + +static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout) +{ + DECLARE_WAITQUEUE(wait, current); + struct llc_opt *llc = llc_sk(sk); + int rc; + + add_wait_queue_exclusive(sk->sleep, &wait); + for (;;) { + dprintk("%s: looping...\n", __FUNCTION__); + __set_current_state(TASK_INTERRUPTIBLE); + rc = -ENOTCONN; + if (sk->shutdown & RCV_SHUTDOWN) + break; rc = -ERESTARTSYS; if (signal_pending(current)) break; rc = -EAGAIN; if (!timeout) break; + rc = 0; + if (llc_data_accept_state(llc->state) || llc->p_flag) { + release_sock(sk); + timeout = schedule_timeout(timeout); + lock_sock(sk); + } else + break; } __set_current_state(TASK_RUNNING); remove_wait_queue(sk->sleep, &wait); @@ -894,11 +890,11 @@ static int llc_ui_wait_for_data(struct sock *sk, int timeout) static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) { struct sock *sk = sock->sk, *newsk; - struct llc_ui_opt *llc_ui, *newllc_ui; - struct llc_opt *newllc_core; + struct llc_opt *llc, *newllc; struct sk_buff *skb; int rc = -EOPNOTSUPP; + dprintk("%s: accepting on %02X\n", __FUNCTION__, llc_sk(sk)->addr.sllc_ssap); lock_sock(sk); if (sk->type != SOCK_STREAM) goto out; @@ -909,40 +905,32 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) rc = llc_ui_wait_for_data(sk, sk->rcvtimeo); if (rc) goto out; + dprintk("%s: got a new connection on %02X\n", __FUNCTION__, llc_sk(sk)->addr.sllc_ssap); skb = skb_dequeue(&sk->receive_queue); - rc = -EINVAL; if (!skb->sk) goto frees; - /* attach connection to a new socket. */ - rc = llc_ui_create(newsock, sk->protocol); - if (rc) - goto frees; rc = 0; - newsk = newsock->sk; + newsk = skb->sk; + /* attach connection to a new socket. */ + llc_ui_sk_init(newsock, newsk); newsk->pair = NULL; - newsk->socket = newsock; - newsk->sleep = &newsock->wait; newsk->zapped = 0; newsk->state = TCP_ESTABLISHED; newsock->state = SS_CONNECTED; - llc_ui = llc_ui_sk(sk); - newllc_ui = llc_ui_sk(newsk); - newllc_ui->sap = llc_ui->sap; - newllc_ui->dev = llc_ui->dev; - newllc_ui->core_sk = skb->sk; - newllc_core = llc_sk(newllc_ui->core_sk); - newllc_ui->link = newllc_core->link; - newllc_core->handler = newsk; - memcpy(&newllc_ui->addr, &llc_ui->addr, sizeof(newllc_ui->addr)); - memcpy(newllc_ui->addr.sllc_dmac, newllc_core->daddr.mac, IFHWADDRLEN); - newllc_ui->addr.sllc_dsap = newllc_core->daddr.lsap; + llc = llc_sk(sk); + newllc = llc_sk(newsk); + memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr)); + memcpy(newllc->addr.sllc_dmac, newllc->daddr.mac, IFHWADDRLEN); + newllc->addr.sllc_dsap = newllc->daddr.lsap; /* put original socket back into a clean listen state. */ sk->state = TCP_LISTEN; sk->ack_backlog--; llc_ui_insert_socket(newsk); skb->sk = NULL; + dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__, + llc_sk(sk)->addr.sllc_ssap, newllc->addr.sllc_dsap); frees: kfree_skb(skb); out: @@ -967,12 +955,21 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, int size, struct sock *sk = sock->sk; struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name; struct sk_buff *skb; - int rc = -ENOMEM, copied = 0; + int rc = -ENOMEM, copied = 0, timeout; int noblock = flags & MSG_DONTWAIT; + dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__, + llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap); lock_sock(sk); - skb = skb_recv_datagram(sk, flags, noblock, &rc); - if (!skb) + timeout = sock_rcvtimeo(sk, noblock); + rc = llc_ui_wait_for_data(sk, timeout); + if (rc) { + dprintk("%s: llc_ui_wait_for_data failed recv in %02X from %02X\n", + __FUNCTION__, llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap); + goto out; + } + skb = skb_dequeue(&sk->receive_queue); + if (!skb) /* shutdown */ goto out; copied = skb->len; if (copied > size) { @@ -986,7 +983,7 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, int size, memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); msg->msg_namelen = sizeof(*uaddr); dgram_free: - skb_free_datagram(sk, skb); /* Free the datagram. */ + kfree_skb(skb); out: release_sock(sk); return rc ? : copied; @@ -1006,24 +1003,23 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) { struct sock *sk = sock->sk; - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name; int flags = msg->msg_flags; + int noblock = flags & MSG_DONTWAIT; struct net_device *dev; struct sk_buff *skb; - int rc = -EOPNOTSUPP, size = 0; + int rc = -EINVAL, size = 0; + dprintk("%s: sending from %02X to %02X\n", __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap); lock_sock(sk); - if (flags & ~MSG_DONTWAIT) - goto release; - rc = -EINVAL; if (addr) { if (msg->msg_namelen < sizeof(*addr)) goto release; } else { - if (llc_ui_addr_null(&llc_ui->addr)) + if (llc_ui_addr_null(&llc->addr)) goto release; - addr = &llc_ui->addr; + addr = &llc->addr; } /* must bind connection to sap if user hasn't done it. */ if (sk->zapped) { @@ -1032,7 +1028,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, if (rc) goto release; } - if (!llc_ui->dev) { + if (!llc->dev) { rtnl_lock(); dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac); rtnl_unlock(); @@ -1040,12 +1036,12 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, if (!dev) goto release; } else - dev = llc_ui->dev; + dev = llc->dev; size = dev->hard_header_len + len + llc_ui_header_len(sk, addr); rc = -EMSGSIZE; if (size > dev->mtu) goto release; - skb = sock_alloc_send_skb(sk, size, flags & MSG_DONTWAIT, &rc); + skb = sock_alloc_send_skb(sk, size, noblock, &rc); if (!skb) goto release; skb->sk = sk; @@ -1053,30 +1049,32 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, skb_reserve(skb, dev->hard_header_len + llc_ui_header_len(sk, addr)); rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); if (rc) - goto release; + goto out; if (addr->sllc_test) { - rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_TEST_PRIM); + rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_TEST_PRIM); goto out; } if (addr->sllc_xid) { - rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_XID_PRIM); + rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_XID_PRIM); goto out; } if (sk->type == SOCK_DGRAM || addr->sllc_ua) { - rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_DATAUNIT_PRIM); + rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_DATAUNIT_PRIM); goto out; } rc = -ENOPROTOOPT; if (!(sk->type == SOCK_STREAM && !addr->sllc_ua)) goto out; - rc = -ENOTCONN; - if (!llc_ui->core_sk) - goto out; - rc = llc_ui_send_data(llc_ui->sap, sk, skb, addr); + rc = llc_ui_send_data(sk, skb, addr, noblock); + if (rc) + dprintk("%s: llc_ui_send_data failed: %d\n", __FUNCTION__, rc); out: if (rc) - skb_free_datagram(sk, skb); + kfree_skb(skb); release: + if (rc) + dprintk("%s: failed sending from %02X to %02X: %d\n", + __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc); release_sock(sk); return rc ? : len; } @@ -1095,7 +1093,7 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr, { struct sockaddr_llc sllc; struct sock *sk = sock->sk; - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct llc_opt *llc = llc_sk(sk); int rc = 0; lock_sock(sk); @@ -1107,20 +1105,19 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr, rc = -ENOTCONN; if (sk->state != TCP_ESTABLISHED) goto out; - if(llc_ui->dev) - sllc.sllc_arphrd = llc_ui->dev->type; - sllc.sllc_dsap = llc_sk(llc_ui->core_sk)->daddr.lsap; - memcpy(&sllc.sllc_dmac, &llc_sk(llc_ui->core_sk)->daddr.mac, - IFHWADDRLEN); + if(llc->dev) + sllc.sllc_arphrd = llc->dev->type; + sllc.sllc_dsap = llc->daddr.lsap; + memcpy(&sllc.sllc_dmac, &llc->daddr.mac, IFHWADDRLEN); } else { rc = -EINVAL; - if (!llc_ui->sap) + if (!llc->sap) goto out; - sllc.sllc_ssap = llc_ui->sap->laddr.lsap; + sllc.sllc_ssap = llc->sap->laddr.lsap; - if (llc_ui->dev) { - sllc.sllc_arphrd = llc_ui->dev->type; - memcpy(&sllc.sllc_smac, &llc_ui->dev->dev_addr, + if (llc->dev) { + sllc.sllc_arphrd = llc->dev->type; + memcpy(&sllc.sllc_smac, &llc->dev->dev_addr, IFHWADDRLEN); } } @@ -1160,61 +1157,56 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) { struct sock *sk = sock->sk; - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); - struct llc_opt *llc_core; + struct llc_opt *llc = llc_sk(sk); int rc = -EINVAL, opt; lock_sock(sk); if (level != SOL_LLC || optlen != sizeof(int)) goto out; - rc = -ENOTCONN; - if (!llc_ui->core_sk) - goto out; rc = get_user(opt, (int *)optval); if (rc) goto out; rc = -EINVAL; - llc_core = llc_sk(llc_ui->core_sk); switch (optname) { case LLC_OPT_RETRY: if (opt > LLC_OPT_MAX_RETRY) goto out; - llc_core->n2 = opt; + llc->n2 = opt; break; case LLC_OPT_SIZE: if (opt > LLC_OPT_MAX_SIZE) goto out; - llc_core->n1 = opt; + llc->n1 = opt; break; case LLC_OPT_ACK_TMR_EXP: if (opt > LLC_OPT_MAX_ACK_TMR_EXP) goto out; - llc_core->ack_timer.expire = opt; + llc->ack_timer.expire = opt; break; case LLC_OPT_P_TMR_EXP: if (opt > LLC_OPT_MAX_P_TMR_EXP) goto out; - llc_core->pf_cycle_timer.expire = opt; + llc->pf_cycle_timer.expire = opt; break; case LLC_OPT_REJ_TMR_EXP: if (opt > LLC_OPT_MAX_REJ_TMR_EXP) goto out; - llc_core->rej_sent_timer.expire = opt; + llc->rej_sent_timer.expire = opt; break; case LLC_OPT_BUSY_TMR_EXP: if (opt > LLC_OPT_MAX_BUSY_TMR_EXP) goto out; - llc_core->busy_state_timer.expire = opt; + llc->busy_state_timer.expire = opt; break; case LLC_OPT_TX_WIN: if (opt > LLC_OPT_MAX_WIN) goto out; - llc_core->k = opt; + llc->k = opt; break; case LLC_OPT_RX_WIN: if (opt > LLC_OPT_MAX_WIN) goto out; - llc_core->rw = opt; + llc->rw = opt; break; default: rc = -ENOPROTOOPT; @@ -1240,40 +1232,35 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) { struct sock *sk = sock->sk; - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); - struct llc_opt *llc_core; + struct llc_opt *llc = llc_sk(sk); int val = 0, len = 0, rc = -EINVAL; lock_sock(sk); if (level != SOL_LLC) goto out; - rc = -ENOTCONN; - if (!llc_ui->core_sk) - goto out; rc = get_user(len, optlen); if (rc) goto out; rc = -EINVAL; if (len != sizeof(int)) goto out; - llc_core = llc_sk(llc_ui->core_sk); switch (optname) { case LLC_OPT_RETRY: - val = llc_core->n2; break; + val = llc->n2; break; case LLC_OPT_SIZE: - val = llc_core->n1; break; + val = llc->n1; break; case LLC_OPT_ACK_TMR_EXP: - val = llc_core->ack_timer.expire; break; + val = llc->ack_timer.expire; break; case LLC_OPT_P_TMR_EXP: - val = llc_core->pf_cycle_timer.expire; break; + val = llc->pf_cycle_timer.expire; break; case LLC_OPT_REJ_TMR_EXP: - val = llc_core->rej_sent_timer.expire; break; + val = llc->rej_sent_timer.expire; break; case LLC_OPT_BUSY_TMR_EXP: - val = llc_core->busy_state_timer.expire; break; + val = llc->busy_state_timer.expire; break; case LLC_OPT_TX_WIN: - val = llc_core->k; break; + val = llc->k; break; case LLC_OPT_RX_WIN: - val = llc_core->rw; break; + val = llc->rw; break; default: rc = -ENOPROTOOPT; goto out; @@ -1296,7 +1283,7 @@ static void llc_ui_ind_test(struct llc_prim_if_block *prim) { struct llc_prim_test *prim_data = &prim->data->test; struct sk_buff *skb = prim_data->skb; - struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb); + struct sockaddr_llc *addr = llc_ui_skb_cb(skb); struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr, &prim_data->saddr, skb->dev); if (!sk) @@ -1304,15 +1291,15 @@ static void llc_ui_ind_test(struct llc_prim_if_block *prim) if (sk->state == TCP_LISTEN) goto out_put; /* save primitive for use by the user. */ - llc_ui->sllc_family = AF_LLC; - llc_ui->sllc_arphrd = skb->dev->type; - llc_ui->sllc_test = 1; - llc_ui->sllc_xid = 0; - llc_ui->sllc_ua = 0; - llc_ui->sllc_dsap = prim_data->daddr.lsap; - memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); - llc_ui->sllc_ssap = prim_data->saddr.lsap; - memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); + addr->sllc_family = AF_LLC; + addr->sllc_arphrd = skb->dev->type; + addr->sllc_test = 1; + addr->sllc_xid = 0; + addr->sllc_ua = 0; + addr->sllc_dsap = prim_data->daddr.lsap; + memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); + addr->sllc_ssap = prim_data->saddr.lsap; + memcpy(addr->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); /* queue skb to the user. */ if (sock_queue_rcv_skb(sk, skb)) kfree_skb(skb); @@ -1331,7 +1318,7 @@ static void llc_ui_ind_xid(struct llc_prim_if_block *prim) { struct llc_prim_xid *prim_data = &prim->data->xid; struct sk_buff *skb = prim_data->skb; - struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb); + struct sockaddr_llc *addr = llc_ui_skb_cb(skb); struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr, &prim_data->saddr, skb->dev); if (!sk) @@ -1339,15 +1326,15 @@ static void llc_ui_ind_xid(struct llc_prim_if_block *prim) if (sk->state == TCP_LISTEN) goto out_put; /* save primitive for use by the user. */ - llc_ui->sllc_family = AF_LLC; - llc_ui->sllc_arphrd = 0; - llc_ui->sllc_test = 0; - llc_ui->sllc_xid = 1; - llc_ui->sllc_ua = 0; - llc_ui->sllc_dsap = prim_data->daddr.lsap; - memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); - llc_ui->sllc_ssap = prim_data->saddr.lsap; - memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); + addr->sllc_family = AF_LLC; + addr->sllc_arphrd = 0; + addr->sllc_test = 0; + addr->sllc_xid = 1; + addr->sllc_ua = 0; + addr->sllc_dsap = prim_data->daddr.lsap; + memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); + addr->sllc_ssap = prim_data->saddr.lsap; + memcpy(addr->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); /* queue skb to the user. */ if (sock_queue_rcv_skb(sk, skb)) kfree_skb(skb); @@ -1366,7 +1353,7 @@ static void llc_ui_ind_dataunit(struct llc_prim_if_block *prim) { struct llc_prim_unit_data *prim_data = &prim->data->udata; struct sk_buff *skb = prim_data->skb; - struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb); + struct sockaddr_llc *addr = llc_ui_skb_cb(skb); struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr, &prim_data->saddr, skb->dev); if (!sk) @@ -1374,15 +1361,15 @@ static void llc_ui_ind_dataunit(struct llc_prim_if_block *prim) if (sk->state == TCP_LISTEN) goto out_put; /* save primitive for use by the user. */ - llc_ui->sllc_family = AF_LLC; - llc_ui->sllc_arphrd = skb->dev->type; - llc_ui->sllc_test = 0; - llc_ui->sllc_xid = 0; - llc_ui->sllc_ua = 1; - llc_ui->sllc_dsap = prim_data->daddr.lsap; - memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); - llc_ui->sllc_ssap = prim_data->saddr.lsap; - memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); + addr->sllc_family = AF_LLC; + addr->sllc_arphrd = skb->dev->type; + addr->sllc_test = 0; + addr->sllc_xid = 0; + addr->sllc_ua = 1; + addr->sllc_dsap = prim_data->daddr.lsap; + memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN); + addr->sllc_ssap = prim_data->saddr.lsap; + memcpy(addr->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN); /* queue skb to the user. */ if (sock_queue_rcv_skb(sk, skb)) kfree_skb(skb); @@ -1400,29 +1387,36 @@ out:; static void llc_ui_ind_conn(struct llc_prim_if_block *prim) { struct llc_prim_conn *prim_data = &prim->data->conn; - struct sock* sk; + struct sock* newsk = prim_data->sk, *parent; + struct llc_opt *newllc = llc_sk(newsk); struct sk_buff *skb2; - llc_sk(prim_data->sk)->laddr.lsap = prim->sap->laddr.lsap; - sk = llc_ui_find_sk_by_addr(&llc_sk(prim_data->sk)->laddr, - &prim_data->saddr, prim_data->dev); - if (!sk) + parent = llc_ui_find_sk_by_addr(&newllc->laddr, &prim_data->saddr, + prim_data->dev); + if (!parent) { + dprintk("%s: can't find a parent :-(\n", __FUNCTION__); goto out; - if (sk->type != SOCK_STREAM || sk->state != TCP_LISTEN) + } + dprintk("%s: found parent of remote %02X, its local %02X\n", __FUNCTION__, + newllc->daddr.lsap, llc_sk(parent)->laddr.lsap); + if (parent->type != SOCK_STREAM || parent->state != TCP_LISTEN) { + dprintk("%s: bad parent :-(\n", __FUNCTION__); goto out_put; - if (prim->data->conn.status) + } + if (prim->data->conn.status) { + dprintk("%s: bad status :-(\n", __FUNCTION__); goto out_put; /* bad status. */ + } /* give this connection a link number. */ - llc_sk(prim_data->sk)->link = - llc_ui_next_link_no(llc_sk(prim_data->sk)->laddr.lsap); + newllc->link = llc_ui_next_link_no(newllc->laddr.lsap); skb2 = alloc_skb(0, GFP_ATOMIC); if (!skb2) goto out_put; - skb2->sk = prim_data->sk; - skb_queue_tail(&sk->receive_queue, skb2); - sk->state_change(sk); + skb2->sk = newsk; + skb_queue_tail(&parent->receive_queue, skb2); + parent->state_change(parent); out_put: - sock_put(sk); + sock_put(parent); out:; } @@ -1435,14 +1429,13 @@ out:; static void llc_ui_ind_disc(struct llc_prim_if_block *prim) { struct llc_prim_disc *prim_data = &prim->data->disc; - struct sock* sk = llc_sk(prim_data->sk)->handler; + struct sock* sk = prim_data->sk; - if (!sk) - goto out; sock_hold(sk); - if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) + if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) { + dprintk("%s: bad socket...\n", __FUNCTION__); goto out_put; - llc_ui_sk(sk)->core_sk = NULL; + } sk->shutdown = SHUTDOWN_MASK; sk->socket->state = SS_UNCONNECTED; sk->state = TCP_CLOSE; @@ -1452,7 +1445,6 @@ static void llc_ui_ind_disc(struct llc_prim_if_block *prim) } out_put: sock_put(sk); -out:; } /** @@ -1475,8 +1467,8 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) case LLC_CONN_PRIM: llc_ui_ind_conn(prim); break; case LLC_DATA_PRIM: - printk(KERN_ERR "%s: shouldn't happen, LLC_DATA_PRIM " - "is gone for ->ind()...\n", __FUNCTION__); + dprintk("%s: shouldn't happen, LLC_DATA_PRIM " + "is gone for ->ind()...\n", __FUNCTION__); break; case LLC_DISC_PRIM: llc_ui_ind_disc(prim); break; @@ -1496,28 +1488,21 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) static void llc_ui_conf_conn(struct llc_prim_if_block *prim) { struct llc_prim_conn *prim_data = &prim->data->conn; - struct llc_opt *llc_core = llc_sk(prim_data->sk); - struct sock* sk = llc_core->handler; - struct llc_ui_opt *llc_ui = llc_ui_sk(sk); + struct sock* sk = prim_data->sk; - if (!sk) - goto out; sock_hold(sk); if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT) goto out_put; if (!prim->data->conn.status) { sk->socket->state = SS_CONNECTED; sk->state = TCP_ESTABLISHED; - llc_ui->core_sk = prim_data->sk; } else { sk->socket->state = SS_UNCONNECTED; sk->state = TCP_CLOSE; - llc_ui->core_sk = NULL; } sk->state_change(sk); out_put: sock_put(sk); -out:; } /** @@ -1529,20 +1514,16 @@ out:; static void llc_ui_conf_disc(struct llc_prim_if_block *prim) { struct llc_prim_disc *prim_data = &prim->data->disc; - struct sock* sk = llc_sk(prim_data->sk)->handler; + struct sock* sk = prim_data->sk; - if (!sk) - goto out; sock_hold(sk); if (sk->type != SOCK_STREAM || sk->state != TCP_CLOSING) goto out_put; - llc_ui_sk(sk)->core_sk = NULL; sk->socket->state = SS_UNCONNECTED; sk->state = TCP_CLOSE; sk->state_change(sk); out_put: sock_put(sk); -out:; } /** @@ -1559,8 +1540,8 @@ static int llc_ui_confirm(struct llc_prim_if_block *prim) case LLC_CONN_PRIM: llc_ui_conf_conn(prim); break; case LLC_DATA_PRIM: - printk(KERN_ERR "%s: shouldn't happen, LLC_DATA_PRIM " - "is gone for ->conf()...\n", __FUNCTION__); + dprintk("%s: shouldn't happen, LLC_DATA_PRIM " + "is gone for ->conf()...\n", __FUNCTION__); break; case LLC_DISC_PRIM: llc_ui_conf_disc(prim); break; @@ -1596,46 +1577,42 @@ static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length) off_t pos = 0; off_t begin = 0; struct sock *s; - int len = sprintf(buffer, "SocketID SKt Mc local_mac_sap\t " - "remote_mac_sap\t tx_queue rx_queue st uid " - "link_no\n"); + int len = sprintf(buffer, "SKt Mc local_mac_sap " + "remote_mac_sap tx_queue rx_queue st uid " + "link\n"); /* Output the LLC socket data for the /proc filesystem */ read_lock_bh(&llc_ui_sockets_lock); for (s = llc_ui_sockets; s; s = s->next) { - struct llc_ui_opt *llc_ui = llc_ui_sk(s); - len += sprintf(buffer + len, "%p %02X %02X ", s, s->type, - !llc_mac_null(llc_ui->addr.sllc_mmac)); - if (llc_ui->sap) { - if (llc_ui->dev && - llc_mac_null(llc_ui->addr.sllc_mmac)) + struct llc_opt *llc = llc_sk(s); + + len += sprintf(buffer + len, "%2X %2X ", s->type, + !llc_mac_null(llc->addr.sllc_mmac)); + if (llc->sap) { + if (llc->dev && llc_mac_null(llc->addr.sllc_mmac)) llc_ui_format_mac(buffer + len, - llc_ui->dev->dev_addr); + llc->dev->dev_addr); else { - if (!llc_mac_null(llc_ui->addr.sllc_mmac)) + if (!llc_mac_null(llc->addr.sllc_mmac)) llc_ui_format_mac(buffer + len, - llc_ui->addr.sllc_mmac); + llc->addr.sllc_mmac); else sprintf(buffer + len, "00:00:00:00:00:00"); } len += MAC_FORMATTED_SIZE; len += sprintf(buffer + len, "@%02X ", - llc_ui->sap->laddr.lsap); + llc->sap->laddr.lsap); } else len += sprintf(buffer + len, "00:00:00:00:00:00@00 "); - llc_ui_format_mac(buffer + len, llc_ui->addr.sllc_dmac); + llc_ui_format_mac(buffer + len, llc->addr.sllc_dmac); len += MAC_FORMATTED_SIZE; len += sprintf(buffer + len, - "@%02X %08d:%08d %02d %-3d ", - llc_ui->addr.sllc_dsap, + "@%02X %8d %8d %2d %-3d ", + llc->addr.sllc_dsap, atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc), s->state, SOCK_INODE(s->socket)->i_uid); - if (llc_ui->core_sk) - len += sprintf(buffer + len, "%-7d\n", - llc_sk(llc_ui->core_sk)->link); - else - len += sprintf(buffer + len, "no_link\n"); + len += sprintf(buffer + len, "%-4d\n", llc->link); /* Are we still dumping unwanted data then discard the record */ pos = begin + len; @@ -1686,7 +1663,7 @@ static struct proto_ops SOCKOPS_WRAPPED(llc_ui_ops) = { SOCKOPS_WRAP(llc_ui, PF_LLC); static char llc_ui_banner[] __initdata = - KERN_INFO "NET4.0 IEEE 802.2 User Interface SAPs, Jay Schulist, 2001\n"; + KERN_INFO "NET4.0 IEEE 802.2 BSD sockets, Jay Schulist, 2001, Arnaldo C. Melo, 2002\n"; int __init llc_ui_init(void) { -- cgit v1.2.3 From 209fb681d4d4715885b0a9c01418d78a30c1cba4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 17:51:15 -0300 Subject: LLC: llc_lookup_listener With this LLC_CONN_PRIM and friends went to the death row, next patch will introduce llc_establish_connection, turning on the electric chair switch for LLC_CONN_PRIM et al. --- include/net/llc_conn.h | 2 ++ net/llc/llc_c_ac.c | 16 +++------------- net/llc/llc_conn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++--- net/llc/llc_mac.c | 30 +++++++++++++++++++---------- net/llc/llc_sock.c | 47 ++++------------------------------------------ 5 files changed, 77 insertions(+), 69 deletions(-) (limited to 'include') diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index 3b2d68e45075..5846a5b91841 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h @@ -99,6 +99,8 @@ extern int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, extern struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, struct llc_addr *laddr); +extern struct sock *llc_lookup_listener(struct llc_sap *sap, + struct llc_addr *laddr); extern u8 llc_data_accept_state(u8 state); extern void llc_build_offset_table(void); #endif /* LLC_CONN_H */ diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index ecb6d6f1658d..0f68bd457a74 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -65,24 +65,14 @@ int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb) sap = llc_sap_find(dsap); if (sap) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); - struct llc_prim_if_block *prim = &sap->llc_ind_prim; - union llc_u_prim_data *prim_data = prim->data; struct llc_opt *llc = llc_sk(sk); - prim_data->conn.daddr.lsap = dsap; llc_pdu_decode_sa(skb, llc->daddr.mac); llc_pdu_decode_da(skb, llc->laddr.mac); llc->dev = skb->dev; - prim_data->conn.pri = 0; - prim_data->conn.sk = sk; - prim_data->conn.dev = skb->dev; - memcpy(&prim_data->conn.daddr, &llc->laddr, sizeof(llc->laddr)); - memcpy(&prim_data->conn.saddr, &llc->daddr, sizeof(llc->daddr)); - prim->data = prim_data; - prim->prim = LLC_CONN_PRIM; - prim->sap = llc->sap; - ev->flag = 1; - ev->ind_prim = prim; + /* FIXME: find better way to notify upper layer */ + ev->flag = LLC_CONN_PRIM + 1; + ev->ind_prim = (void *)1; rc = 0; } return rc; diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 46e54e9621ba..02d277dab2e4 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +62,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) /* * FIXME: this will vanish as soon I get rid of the double sock crap */ - if (flag != LLC_DATA_PRIM + 1) + if (flag != LLC_DATA_PRIM + 1 && flag != LLC_CONN_PRIM + 1) llc_conn_free_ev(skb); else if (ind_prim && cfm_prim) skb_get(skb); @@ -73,7 +74,8 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) * FIXME: this will be saner as soon I get rid of the double * sock crap */ - if (flag == LLC_DATA_PRIM + 1) { + switch (flag) { + case LLC_DATA_PRIM + 1: if (sock_queue_rcv_skb(skb->sk, skb)) { /* * FIXME: have to sync the LLC state @@ -86,8 +88,18 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) __FUNCTION__); kfree_skb(skb); } - } else + break; + case LLC_CONN_PRIM + 1: { + struct sock *parent = skb->sk; + + skb->sk = sk; + skb_queue_tail(&parent->receive_queue, skb); + sk->state_change(parent); + } + break; + default: llc->sap->ind(ind_prim); + } } if (!cfm_prim) /* confirmation not required */ goto out; @@ -433,6 +445,39 @@ out: return rc; } +/** + * llc_lookup_listener - Finds listener for local MAC + SAP + * @sap: SAP + * @laddr: address of local LLC (MAC + SAP) + * + * Search connection list of the SAP and finds connection listening on + * local mac, and local sap. Returns pointer for parent socket found, + * %NULL otherwise. + */ +struct sock *llc_lookup_listener(struct llc_sap *sap, struct llc_addr *laddr) +{ + struct sock *rc = NULL; + struct list_head *entry; + + spin_lock_bh(&sap->sk_list.lock); + if (list_empty(&sap->sk_list.list)) + goto out; + list_for_each(entry, &sap->sk_list.list) { + struct llc_opt *llc = list_entry(entry, struct llc_opt, node); + + if (llc->sk->type != SOCK_STREAM || llc->sk->state != TCP_LISTEN || + llc->laddr.lsap != laddr->lsap || + !llc_mac_match(llc->laddr.mac, laddr->mac)) + continue; + rc = llc->sk; + } + if (rc) + sock_hold(rc); +out: + spin_unlock_bh(&sap->sk_list.lock); + return rc; +} + /** * llc_data_accept_state - designates if in this state data can be sent. * @state: state of connection. diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c index b8b031510043..6f9250fb78f0 100644 --- a/net/llc/llc_mac.c +++ b/net/llc/llc_mac.c @@ -123,24 +123,34 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, sk = llc_lookup_established(sap, &saddr, &daddr); if (!sk) { - struct llc_opt *llc; - - dprintk("%s: llc_lookup_established failed\n", __FUNCTION__); /* - * FIXME: here we'll pass the sk->family of the - * listening socket, if found, when - * llc_lookup_listener is added in the next patches. + * Didn't find an active connection; verify if there + * is a listening socket for this llc addr */ - sk = llc_sk_alloc(PF_LLC, GFP_ATOMIC); - if (!sk) + struct llc_opt *llc; + struct sock *parent; + + parent = llc_lookup_listener(sap, &daddr); + + if (!parent) { + dprintk("llc_lookup_listener failed!\n"); goto drop; + } + + sk = llc_sk_alloc(parent->family, GFP_ATOMIC); + if (!sk) { + sock_put(parent); + goto drop; + } llc = llc_sk(sk); memcpy(&llc->laddr, &daddr, sizeof(llc->laddr)); memcpy(&llc->daddr, &saddr, sizeof(llc->daddr)); llc_sap_assign_sock(sap, sk); sock_hold(sk); - } - skb->sk = sk; + sock_put(parent); + skb->sk = parent; + } else + skb->sk = sk; bh_lock_sock(sk); if (!sk->lock.users) { /* rc = */ llc_conn_rcv(sk, skb); diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index 5753d316feaf..27e1c5d72429 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -923,6 +923,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr)); memcpy(newllc->addr.sllc_dmac, newllc->daddr.mac, IFHWADDRLEN); newllc->addr.sllc_dsap = newllc->daddr.lsap; + newllc->link = llc_ui_next_link_no(newllc->laddr.lsap); /* put original socket back into a clean listen state. */ sk->state = TCP_LISTEN; @@ -1378,48 +1379,6 @@ out_put: out:; } -/** - * llc_ui_ind_conn - handle CONNECT indication - * @prim: Primitive block provided by the llc layer. - * - * handle CONNECT indication. - */ -static void llc_ui_ind_conn(struct llc_prim_if_block *prim) -{ - struct llc_prim_conn *prim_data = &prim->data->conn; - struct sock* newsk = prim_data->sk, *parent; - struct llc_opt *newllc = llc_sk(newsk); - struct sk_buff *skb2; - - parent = llc_ui_find_sk_by_addr(&newllc->laddr, &prim_data->saddr, - prim_data->dev); - if (!parent) { - dprintk("%s: can't find a parent :-(\n", __FUNCTION__); - goto out; - } - dprintk("%s: found parent of remote %02X, its local %02X\n", __FUNCTION__, - newllc->daddr.lsap, llc_sk(parent)->laddr.lsap); - if (parent->type != SOCK_STREAM || parent->state != TCP_LISTEN) { - dprintk("%s: bad parent :-(\n", __FUNCTION__); - goto out_put; - } - if (prim->data->conn.status) { - dprintk("%s: bad status :-(\n", __FUNCTION__); - goto out_put; /* bad status. */ - } - /* give this connection a link number. */ - newllc->link = llc_ui_next_link_no(newllc->laddr.lsap); - skb2 = alloc_skb(0, GFP_ATOMIC); - if (!skb2) - goto out_put; - skb2->sk = newsk; - skb_queue_tail(&parent->receive_queue, skb2); - parent->state_change(parent); -out_put: - sock_put(parent); -out:; -} - /** * llc_ui_ind_disc - handle DISC indication * @prim: Primitive block provided by the llc layer. @@ -1465,7 +1424,9 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) case LLC_DATAUNIT_PRIM: llc_ui_ind_dataunit(prim); break; case LLC_CONN_PRIM: - llc_ui_ind_conn(prim); break; + dprintk("%s: shouldn't happen, LLC_CONN_PRIM " + "is gone for ->ind()...\n", __FUNCTION__); + break; case LLC_DATA_PRIM: dprintk("%s: shouldn't happen, LLC_DATA_PRIM " "is gone for ->ind()...\n", __FUNCTION__); -- cgit v1.2.3 From 7282621067bc47d470b87e17c1ecf92a4d26b19e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 11 Sep 2002 19:11:07 -0300 Subject: [LLC] llc_establish_connection & LLC_CONN_PRIM bits the bucket . Bzzzt, rest in peace LLC_DATA_PRIM. We won't miss you. . In the process I also killed sap->resp and all of the functions it was calling, the Procom guys left this in the codebase but _nobody_ was actually using it. --- include/net/llc_if.h | 14 +---- include/net/llc_sap.h | 2 - net/llc/llc_c_ac.c | 20 ++----- net/llc/llc_conn.c | 19 ++++++- net/llc/llc_if.c | 151 ++++++++------------------------------------------ net/llc/llc_sock.c | 65 ++-------------------- 6 files changed, 53 insertions(+), 218 deletions(-) (limited to 'include') diff --git a/include/net/llc_if.h b/include/net/llc_if.h index e294c1d976b1..86cf648b7872 100644 --- a/include/net/llc_if.h +++ b/include/net/llc_if.h @@ -66,17 +66,6 @@ struct llc_addr { }; /* Primitive-specific data */ -struct llc_prim_conn { - struct llc_addr saddr; /* used by request only */ - struct llc_addr daddr; /* used by request only */ - u8 status; /* reason for failure */ - u8 pri; /* service_class */ - struct net_device *dev; - struct sock *sk; /* returned from REQUEST */ - u16 link; - struct sk_buff *skb; /* received SABME */ -}; - struct llc_prim_disc { struct sock *sk; u16 link; @@ -119,7 +108,6 @@ struct llc_prim_test { }; union llc_u_prim_data { - struct llc_prim_conn conn; struct llc_prim_disc disc; struct llc_prim_reset res; struct llc_prim_flow_ctrl fc; @@ -142,5 +130,7 @@ extern struct llc_sap *llc_sap_open(llc_prim_call_t network_indicate, llc_prim_call_t network_confirm, u8 lsap); extern void llc_sap_close(struct llc_sap *sap); +extern int llc_establish_connection(struct sock *sk, u8 *lmac, + u8 *dmac, u8 dsap); extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb); #endif /* LLC_IF_H */ diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h index cabd5a8ed9f2..3132bebd1422 100644 --- a/include/net/llc_sap.h +++ b/include/net/llc_sap.h @@ -18,7 +18,6 @@ * @p_bit - only lowest-order bit used * @f_bit - only lowest-order bit used * @req - provided by LLC layer - * @resp - provided by LLC layer * @ind - provided by network layer * @conf - provided by network layer * @laddr - SAP value in this 'lsap' @@ -32,7 +31,6 @@ struct llc_sap { u8 p_bit; u8 f_bit; llc_prim_call_t req; - llc_prim_call_t resp; llc_prim_call_t ind; llc_prim_call_t conf; struct llc_prim_if_block llc_ind_prim, llc_cfm_prim; diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index 0f68bd457a74..9604dcc3c053 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -81,21 +81,9 @@ int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb) int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); - struct llc_opt *llc = llc_sk(sk); - struct llc_sap *sap = llc->sap; - struct llc_prim_if_block *prim = &sap->llc_cfm_prim; - union llc_u_prim_data *prim_data = prim->data; - prim_data->conn.sk = sk; - prim_data->conn.pri = 0; - prim_data->conn.status = ev->status; - prim_data->conn.link = llc->link; - prim_data->conn.dev = skb->dev; - prim->data = prim_data; - prim->prim = LLC_CONN_PRIM; - prim->sap = sap; - ev->flag = 1; - ev->cfm_prim = prim; + ev->flag = LLC_CONN_PRIM + 1; + ev->cfm_prim = (void *)1; return 0; } @@ -1451,6 +1439,7 @@ void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); + skb->sk = sk; ev->type = LLC_CONN_EV_TYPE_P_TMR; ev->data.tmr.timer_specific = NULL; llc_process_tmr_ev(sk, skb); @@ -1468,6 +1457,7 @@ static void llc_conn_busy_tmr_cb(unsigned long timeout_data) if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); + skb->sk = sk; ev->type = LLC_CONN_EV_TYPE_BUSY_TMR; ev->data.tmr.timer_specific = NULL; llc_process_tmr_ev(sk, skb); @@ -1485,6 +1475,7 @@ void llc_conn_ack_tmr_cb(unsigned long timeout_data) if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); + skb->sk = sk; ev->type = LLC_CONN_EV_TYPE_ACK_TMR; ev->data.tmr.timer_specific = NULL; llc_process_tmr_ev(sk, skb); @@ -1502,6 +1493,7 @@ static void llc_conn_rej_tmr_cb(unsigned long timeout_data) if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); + skb->sk = sk; ev->type = LLC_CONN_EV_TYPE_REJ_TMR; ev->data.tmr.timer_specific = NULL; llc_process_tmr_ev(sk, skb); diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 02d277dab2e4..8e36505f32eb 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -103,9 +103,23 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) } if (!cfm_prim) /* confirmation not required */ goto out; - /* data confirm has preconditions */ + /* data and conn confirm have preconditions */ /* FIXME: see FIXMEs above */ - if (flag != LLC_DATA_PRIM + 1) { + if (flag == LLC_CONN_PRIM + 1) { + struct sock *sk = skb->sk; + + if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT) + goto out_kfree_skb; + if (ev->status) { + sk->socket->state = SS_UNCONNECTED; + sk->state = TCP_CLOSE; + } else { + sk->socket->state = SS_CONNECTED; + sk->state = TCP_ESTABLISHED; + } + sk->state_change(sk); + goto out_kfree_skb; + } else if (flag != LLC_DATA_PRIM + 1) { llc->sap->conf(cfm_prim); goto out; } @@ -115,6 +129,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) skb->sk->write_space(skb->sk); } else rc = llc->failed_data_req = 1; +out_kfree_skb: kfree_skb(skb); out: return rc; diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index 8af1ec3a1417..46cf125ff843 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -32,19 +32,14 @@ static int llc_sap_req(struct llc_prim_if_block *prim); static int llc_unitdata_req_handler(struct llc_prim_if_block *prim); static int llc_test_req_handler(struct llc_prim_if_block *prim); static int llc_xid_req_handler(struct llc_prim_if_block *prim); -static int llc_conn_req_handler(struct llc_prim_if_block *prim); static int llc_disc_req_handler(struct llc_prim_if_block *prim); static int llc_rst_req_handler(struct llc_prim_if_block *prim); static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim); -static int llc_sap_resp(struct llc_prim_if_block *prim); -static int llc_conn_rsp_handler(struct llc_prim_if_block *prim); -static int llc_rst_rsp_handler(struct llc_prim_if_block *prim); -static int llc_no_rsp_handler(struct llc_prim_if_block *prim); /* table of request handler functions */ static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = { [LLC_DATAUNIT_PRIM] = llc_unitdata_req_handler, - [LLC_CONN_PRIM] = llc_conn_req_handler, + [LLC_CONN_PRIM] = NULL, /* replaced by + llc_establish_connection */ [LLC_DATA_PRIM] = NULL, /* replaced by llc_build_and_send_pkt */ [LLC_DISC_PRIM] = llc_disc_req_handler, [LLC_RESET_PRIM] = llc_rst_req_handler, @@ -53,16 +48,6 @@ static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = { [LLC_TEST_PRIM] = llc_test_req_handler, }; -/* table of response handler functions */ -static llc_prim_call_t llc_resp_prim[LLC_NBR_PRIMITIVES] = { - [LLC_DATAUNIT_PRIM] = llc_no_rsp_handler, - [LLC_CONN_PRIM] = llc_conn_rsp_handler, - [LLC_DATA_PRIM] = llc_no_rsp_handler, - [LLC_DISC_PRIM] = llc_no_rsp_handler, - [LLC_RESET_PRIM] = llc_rst_rsp_handler, - [LLC_FLOWCONTROL_PRIM] = llc_no_rsp_handler, -}; - /** * llc_sap_open - open interface to the upper layers. * @nw_indicate: pointer to indicate function of upper layer. @@ -93,7 +78,6 @@ struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate, /* allocated a SAP; initialize it and clear out its memory pool */ sap->laddr.lsap = lsap; sap->req = llc_sap_req; - sap->resp = llc_sap_resp; sap->ind = nw_indicate; sap->conf = nw_confirm; sap->parent_station = llc_station_get(); @@ -273,21 +257,11 @@ out: } /** - * llc_confirm_impossible - Informs upper layer about failed connection - * @prim: pointer to structure that contains confirmation data. - * - * Informs upper layer about failing in connection establishment. This - * function is called by llc_conn_req_handler. - */ -static void llc_confirm_impossible(struct llc_prim_if_block *prim) -{ - prim->data->conn.status = LLC_STATUS_IMPOSSIBLE; - prim->sap->conf(prim); -} - -/** - * llc_conn_req_handler - Called by upper layer to establish a conn - * @prim: pointer to structure that contains service parameters. + * llc_establish_connection - Called by upper layer to establish a conn + * @sk: connection + * @lmac: local mac address + * @dmac: destination mac address + * @dsap: destination sap * * Upper layer calls this to establish an LLC connection with a remote * machine. This function packages a proper event and sends it connection @@ -295,37 +269,28 @@ static void llc_confirm_impossible(struct llc_prim_if_block *prim) * establishment will inform to upper layer via calling it's confirm * function and passing proper information. */ -static int llc_conn_req_handler(struct llc_prim_if_block *prim) +int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap) { - int rc = -EBUSY; - struct llc_sap *sap = prim->sap; - struct sk_buff *skb; - struct net_device *ddev = mac_dev_peer(prim->data->conn.dev, - prim->data->conn.dev->type, - prim->data->conn.daddr.mac), - *sdev = (ddev->flags & IFF_LOOPBACK) ? - ddev : prim->data->conn.dev; + int rc = -EISCONN; struct llc_addr laddr, daddr; - /* network layer supplies addressing required to establish connection; - * package as an event and send it to the connection event handler - */ - struct sock *sk; - - memcpy(laddr.mac, sdev->dev_addr, sizeof(laddr.mac)); - laddr.lsap = prim->data->conn.saddr.lsap; - memcpy(daddr.mac, prim->data->conn.daddr.mac, sizeof(daddr.mac)); - daddr.lsap = prim->data->conn.daddr.lsap; - sk = llc_lookup_established(sap, &daddr, &laddr); - if (sk) { - if (sk->state == TCP_ESTABLISHED) { - llc_confirm_impossible(prim); + struct sk_buff *skb; + struct llc_opt *llc = llc_sk(sk); + struct sock *existing; + + laddr.lsap = llc->sap->laddr.lsap; + daddr.lsap = dsap; + memcpy(daddr.mac, dmac, sizeof(daddr.mac)); + memcpy(laddr.mac, lmac, sizeof(laddr.mac)); + existing = llc_lookup_established(llc->sap, &daddr, &laddr); + if (existing) { + if (existing->state == TCP_ESTABLISHED) { + sk = existing; goto out_put; } else - sock_put(sk); + sock_put(existing); } - rc = -ENOMEM; - sk = prim->data->conn.sk; sock_hold(sk); + rc = -ENOMEM; skb = alloc_skb(0, GFP_ATOMIC); if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); @@ -333,11 +298,9 @@ static int llc_conn_req_handler(struct llc_prim_if_block *prim) ev->type = LLC_CONN_EV_TYPE_PRIM; ev->data.prim.prim = LLC_CONN_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_REQ; - ev->data.prim.data = prim; + ev->data.prim.data = NULL; rc = llc_conn_state_process(sk, skb); } - if (rc) - llc_confirm_impossible(prim); out_put: sock_put(sk); return rc; @@ -417,73 +380,5 @@ static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim) return 1; } -/** - * llc_sap_resp - Sends response to peer - * @prim: pointer to structure that contains service parameters - * - * This function is a interface function to upper layer. Each one who - * wants to response to an indicate can call this function via calling - * sap_resp with proper service parameters. Returns 0 for success, 1 - * otherwise. - */ -static int llc_sap_resp(struct llc_prim_if_block *prim) -{ - u16 rc = 1; - /* network layer RESPONSE primitive received; package primitive - * as an event and send it to the connection event handler - */ - if (prim->prim < LLC_NBR_PRIMITIVES) - /* valid primitive; call the function to handle it */ - rc = llc_resp_prim[prim->prim](prim); - return rc; -} - -/** - * llc_conn_rsp_handler - Response to connect indication - * @prim: pointer to structure that contains response info. - * - * Response to connect indication. - */ -static int llc_conn_rsp_handler(struct llc_prim_if_block *prim) -{ - struct sock *sk = prim->data->conn.sk; - - llc_sk(sk)->link = prim->data->conn.link; - return 0; -} - -/** - * llc_rst_rsp_handler - Response to RESET indication - * @prim: pointer to structure that contains response info - * - * Returns 0 for success, 1 otherwise - */ -static int llc_rst_rsp_handler(struct llc_prim_if_block *prim) -{ - int rc = 1; - /* - * Network layer supplies connection handle; map it to a connection; - * package as event and send it to connection event handler - */ - struct sock *sk = prim->data->res.sk; - struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); - - if (skb) { - struct llc_conn_state_ev *ev = llc_conn_ev(skb); - - ev->type = LLC_CONN_EV_TYPE_PRIM; - ev->data.prim.prim = LLC_RESET_PRIM; - ev->data.prim.type = LLC_PRIM_TYPE_RESP; - ev->data.prim.data = prim; - rc = llc_conn_state_process(sk, skb); - } - return rc; -} - -static int llc_no_rsp_handler(struct llc_prim_if_block *prim) -{ - return 0; -} - EXPORT_SYMBOL(llc_sap_open); EXPORT_SYMBOL(llc_sap_close); diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index 27e1c5d72429..bed351e01c6f 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -124,38 +124,6 @@ static __inline__ u8 llc_ui_header_len(struct sock *sk, return rc; } -/** - * llc_ui_send_conn - send connect command for new llc2 connection - * @sap : Sap the socket is bound to. - * @addr: Source and destination fields provided by the user. - * @dev : Device which this connection should use. - * @link: Link number to assign to this connection. - * - * Send a connect command to the llc layer for a new llc2 connection. - * Returns 0 upon success, non-zero if action didn't succeed. - */ -static int llc_ui_send_conn(struct sock *sk, struct llc_sap *sap, - struct sockaddr_llc *addr, - struct net_device *dev, int link) -{ - struct llc_opt *llc = llc_sk(sk); - union llc_u_prim_data prim_data; - struct llc_prim_if_block prim; - - prim.data = &prim_data; - prim.sap = sap; - prim.prim = LLC_CONN_PRIM; - prim_data.conn.dev = dev; - prim_data.conn.link = link; - prim_data.conn.sk = sk; - prim_data.conn.pri = 0; - prim_data.conn.saddr.lsap = llc->addr.sllc_ssap; - prim_data.conn.daddr.lsap = addr->sllc_dsap; - memcpy(prim_data.conn.saddr.mac, dev->dev_addr, IFHWADDRLEN); - memcpy(prim_data.conn.daddr.mac, addr->sllc_dmac, IFHWADDRLEN); - return sap->req(&prim); -} - /** * llc_ui_send_disc - send disc command to llc layer * @sk: Socket with valid llc information. @@ -709,7 +677,8 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, sock->state = SS_CONNECTING; sk->state = TCP_SYN_SENT; llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap); - rc = llc_ui_send_conn(sk, llc->sap, addr, dev, llc->link); + rc = llc_establish_connection(sk, dev->dev_addr, + addr->sllc_dmac, addr->sllc_dsap); if (rc) { dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__); sock->state = SS_UNCONNECTED; @@ -1440,32 +1409,6 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) return 0; } -/** - * llc_ui_conf_conn - handle CONN confirm. - * @prim: Primitive block provided by the llc layer. - * - * handle CONN confirm. - */ -static void llc_ui_conf_conn(struct llc_prim_if_block *prim) -{ - struct llc_prim_conn *prim_data = &prim->data->conn; - struct sock* sk = prim_data->sk; - - sock_hold(sk); - if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT) - goto out_put; - if (!prim->data->conn.status) { - sk->socket->state = SS_CONNECTED; - sk->state = TCP_ESTABLISHED; - } else { - sk->socket->state = SS_UNCONNECTED; - sk->state = TCP_CLOSE; - } - sk->state_change(sk); -out_put: - sock_put(sk); -} - /** * llc_ui_conf_disc - handle DISC confirm. * @prim: Primitive block provided by the llc layer. @@ -1499,7 +1442,9 @@ static int llc_ui_confirm(struct llc_prim_if_block *prim) { switch (prim->prim) { case LLC_CONN_PRIM: - llc_ui_conf_conn(prim); break; + dprintk("%s: shouldn't happen, LLC_CONN_PRIM " + "is gone for ->conf()...\n", __FUNCTION__); + break; case LLC_DATA_PRIM: dprintk("%s: shouldn't happen, LLC_DATA_PRIM " "is gone for ->conf()...\n", __FUNCTION__); -- cgit v1.2.3 From 221fc77551675149e1a3d2a471a22aa2213c0221 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 12 Sep 2002 07:33:05 -0300 Subject: [LLC] llc_send_disc & LLC_DISC_PRIM bites the dust --- include/net/llc_if.h | 9 +---- net/llc/llc_c_ac.c | 38 ++++++++-------------- net/llc/llc_conn.c | 54 +++++++++++++++++++++--------- net/llc/llc_if.c | 20 ++++++------ net/llc/llc_main.c | 8 +---- net/llc/llc_sock.c | 92 +++++----------------------------------------------- 6 files changed, 73 insertions(+), 148 deletions(-) (limited to 'include') diff --git a/include/net/llc_if.h b/include/net/llc_if.h index 86cf648b7872..1ae97a593ee6 100644 --- a/include/net/llc_if.h +++ b/include/net/llc_if.h @@ -65,13 +65,6 @@ struct llc_addr { u8 mac[IFHWADDRLEN]; }; -/* Primitive-specific data */ -struct llc_prim_disc { - struct sock *sk; - u16 link; - u8 reason; /* not used by request */ -}; - struct llc_prim_reset { struct sock *sk; u16 link; @@ -108,7 +101,6 @@ struct llc_prim_test { }; union llc_u_prim_data { - struct llc_prim_disc disc; struct llc_prim_reset res; struct llc_prim_flow_ctrl fc; struct llc_prim_unit_data udata; /* unit data */ @@ -133,4 +125,5 @@ extern void llc_sap_close(struct llc_sap *sap); extern int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap); extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb); +extern int llc_send_disc(struct sock *sk); #endif /* LLC_IF_H */ diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index 9604dcc3c053..88a3c2f7e6be 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -134,19 +134,15 @@ int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb) rc = 1; } if (!rc) { - struct llc_opt *llc = llc_sk(sk); - struct llc_sap *sap = llc->sap; - struct llc_prim_if_block *prim = &sap->llc_ind_prim; - union llc_u_prim_data *prim_data = prim->data; - - prim_data->disc.sk = sk; - prim_data->disc.reason = reason; - prim_data->disc.link = llc->link; - prim->data = prim_data; - prim->prim = LLC_DISC_PRIM; - prim->sap = llc->sap; - ev->flag = 1; - ev->ind_prim = prim; + /* + * FIXME: ev needs reason field, + * perhaps the ev->status is enough, + * have to check, + * better way to signal its a disc + */ + /* prim_data->disc.reason = reason; */ + ev->flag = LLC_DISC_PRIM + 1; + ev->ind_prim = (void *)1; } return rc; } @@ -154,19 +150,11 @@ int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb) int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); - struct llc_opt *llc = llc_sk(sk); - struct llc_sap *sap = llc->sap; - struct llc_prim_if_block *prim = &sap->llc_cfm_prim; - union llc_u_prim_data *prim_data = prim->data; - prim_data->disc.sk = sk; - prim_data->disc.reason = ev->status; - prim_data->disc.link = llc->link; - prim->data = prim_data; - prim->prim = LLC_DISC_PRIM; - prim->sap = sap; - ev->flag = 1; - ev->cfm_prim = prim; + /* here we use the ev->status, humm */ + /* prim_data->disc.reason = ev->status; */ + ev->flag = LLC_DISC_PRIM + 1; + ev->cfm_prim = (void *)1; return 0; } diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 8e36505f32eb..753208eabc1a 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -60,9 +60,10 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) struct llc_prim_if_block *cfm_prim = ev->cfm_prim; /* - * FIXME: this will vanish as soon I get rid of the double sock crap + * FIXME: this will vanish as soon I get rid of the last prim crap */ - if (flag != LLC_DATA_PRIM + 1 && flag != LLC_CONN_PRIM + 1) + if (flag != LLC_DATA_PRIM + 1 && flag != LLC_CONN_PRIM + 1 && + flag != LLC_DISC_PRIM + 1) llc_conn_free_ev(skb); else if (ind_prim && cfm_prim) skb_get(skb); @@ -76,7 +77,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) */ switch (flag) { case LLC_DATA_PRIM + 1: - if (sock_queue_rcv_skb(skb->sk, skb)) { + if (sock_queue_rcv_skb(sk, skb)) { /* * FIXME: have to sync the LLC state * machine wrt mem usage with @@ -97,17 +98,35 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) sk->state_change(parent); } break; + case LLC_DISC_PRIM + 1: + sock_hold(sk); + if (sk->type == SOCK_STREAM && sk->state == TCP_ESTABLISHED) { + sk->shutdown = SHUTDOWN_MASK; + sk->socket->state = SS_UNCONNECTED; + sk->state = TCP_CLOSE; + if (!sk->dead) { + sk->state_change(sk); + sk->dead = 1; + } + } + sock_put(sk); + break; default: llc->sap->ind(ind_prim); } } if (!cfm_prim) /* confirmation not required */ goto out; - /* data and conn confirm have preconditions */ /* FIXME: see FIXMEs above */ - if (flag == LLC_CONN_PRIM + 1) { - struct sock *sk = skb->sk; - + switch (flag) { + case LLC_DATA_PRIM + 1: + if (!llc_data_accept_state(llc->state)) + /* In this state, we can send I pdu */ + sk->write_space(sk); + else + rc = llc->failed_data_req = 1; + break; + case LLC_CONN_PRIM + 1: if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT) goto out_kfree_skb; if (ev->status) { @@ -118,17 +137,22 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) sk->state = TCP_ESTABLISHED; } sk->state_change(sk); - goto out_kfree_skb; - } else if (flag != LLC_DATA_PRIM + 1) { + break; + case LLC_DISC_PRIM + 1: + sock_hold(sk); + if (sk->type != SOCK_STREAM || sk->state != TCP_CLOSING) { + sock_put(sk); + goto out_kfree_skb; + } + sk->socket->state = SS_UNCONNECTED; + sk->state = TCP_CLOSE; + sk->state_change(sk); + sock_put(sk); + break; + default: llc->sap->conf(cfm_prim); goto out; } - if (!llc_data_accept_state(llc->state)) { - /* In this state, we can send I pdu */ - if (skb->sk) - skb->sk->write_space(skb->sk); - } else - rc = llc->failed_data_req = 1; out_kfree_skb: kfree_skb(skb); out: diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index 46cf125ff843..5af123bea45d 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -32,16 +32,15 @@ static int llc_sap_req(struct llc_prim_if_block *prim); static int llc_unitdata_req_handler(struct llc_prim_if_block *prim); static int llc_test_req_handler(struct llc_prim_if_block *prim); static int llc_xid_req_handler(struct llc_prim_if_block *prim); -static int llc_disc_req_handler(struct llc_prim_if_block *prim); static int llc_rst_req_handler(struct llc_prim_if_block *prim); static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim); /* table of request handler functions */ static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = { [LLC_DATAUNIT_PRIM] = llc_unitdata_req_handler, - [LLC_CONN_PRIM] = NULL, /* replaced by + llc_establish_connection */ + [LLC_CONN_PRIM] = NULL, /* replaced by llc_establish_connection */ [LLC_DATA_PRIM] = NULL, /* replaced by llc_build_and_send_pkt */ - [LLC_DISC_PRIM] = llc_disc_req_handler, + [LLC_DISC_PRIM] = NULL, /* replaced by llc_send_disc */ [LLC_RESET_PRIM] = llc_rst_req_handler, [LLC_FLOWCONTROL_PRIM] = llc_flowcontrol_req_handler, [LLC_XID_PRIM] = llc_xid_req_handler, @@ -307,23 +306,23 @@ out_put: } /** - * llc_disc_req_handler - Called by upper layer to close a connection - * @prim: pointer to structure that contains service parameters. + * llc_send_disc - Called by upper layer to close a connection + * @sk: connection to be closed * * Upper layer calls this when it wants to close an established LLC * connection with a remote machine. This function packages a proper event * and sends it to connection component state machine. Returns 0 for * success, 1 otherwise. */ -static int llc_disc_req_handler(struct llc_prim_if_block *prim) +int llc_send_disc(struct sock *sk) { u16 rc = 1; struct llc_conn_state_ev *ev; struct sk_buff *skb; - struct sock* sk = prim->data->disc.sk; sock_hold(sk); - if (llc_sk(sk)->state == LLC_CONN_STATE_ADM || + if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED || + llc_sk(sk)->state == LLC_CONN_STATE_ADM || llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) goto out; /* @@ -333,11 +332,12 @@ static int llc_disc_req_handler(struct llc_prim_if_block *prim) skb = alloc_skb(0, GFP_ATOMIC); if (!skb) goto out; - ev = llc_conn_ev(skb); + sk->state = TCP_CLOSING; + ev = llc_conn_ev(skb); ev->type = LLC_CONN_EV_TYPE_PRIM; ev->data.prim.prim = LLC_DISC_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_REQ; - ev->data.prim.data = prim; + ev->data.prim.data = NULL; rc = llc_conn_state_process(sk, skb); out: sock_put(sk); diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c index a1768084605b..cdb0b6e6020b 100644 --- a/net/llc/llc_main.c +++ b/net/llc/llc_main.c @@ -315,8 +315,6 @@ void llc_sk_reset(struct sock *sk) static int llc_rtn_all_conns(struct llc_sap *sap) { int rc = 0; - union llc_u_prim_data prim_data; - struct llc_prim_if_block prim; struct list_head *entry, *tmp; spin_lock_bh(&sap->sk_list.lock); @@ -325,12 +323,8 @@ static int llc_rtn_all_conns(struct llc_sap *sap) list_for_each_safe(entry, tmp, &sap->sk_list.list) { struct llc_opt *llc = list_entry(entry, struct llc_opt, node); - prim.sap = sap; - prim_data.disc.sk = llc->sk; - prim.prim = LLC_DISC_PRIM; - prim.data = &prim_data; llc->state = LLC_CONN_STATE_TEMP; - if (sap->req(&prim)) + if (llc_send_disc(llc->sk)) rc = 1; } out: diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index bed351e01c6f..e1ab6010d50d 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -124,36 +124,6 @@ static __inline__ u8 llc_ui_header_len(struct sock *sk, return rc; } -/** - * llc_ui_send_disc - send disc command to llc layer - * @sk: Socket with valid llc information. - * - * Send a disconnect command to the llc layer for an established - * llc2 connection. - * Returns 0 upon success, non-zero if action did not succeed. - */ -static int llc_ui_send_disc(struct sock *sk) -{ - struct llc_opt *llc = llc_sk(sk); - union llc_u_prim_data prim_data; - struct llc_prim_if_block prim; - int rc = 0; - - if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) { - rc = 1; - goto out; - } - sk->state = TCP_CLOSING; - prim.data = &prim_data; - prim.sap = llc->sap; - prim.prim = LLC_DISC_PRIM; - prim_data.disc.sk = sk; - prim_data.disc.link = llc->link; - rc = llc->sap->req(&prim); -out: - return rc; -} - /** * llc_ui_send_data - send data via reliable llc2 connection * @sk: Connection the socket is using. @@ -424,7 +394,7 @@ static int llc_ui_release(struct socket *sock) llc = llc_sk(sk); dprintk("%s: closing local(%02X) remote(%02X)\n", __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap); - if (!llc_ui_send_disc(sk)) + if (!llc_send_disc(sk)) llc_ui_wait_for_disc(sk, sk->rcvtimeo); llc_sap_unassign_sock(llc->sap, sk); release_sock(sk); @@ -614,7 +584,7 @@ static int llc_ui_shutdown(struct socket *sock, int how) rc = -EINVAL; if (how != 2) goto out; - rc = llc_ui_send_disc(sk); + rc = llc_send_disc(sk); if (!rc) rc = llc_ui_wait_for_disc(sk, sk->rcvtimeo); /* Wake up anyone sleeping in poll */ @@ -1348,33 +1318,6 @@ out_put: out:; } -/** - * llc_ui_ind_disc - handle DISC indication - * @prim: Primitive block provided by the llc layer. - * - * handle DISC indication. - */ -static void llc_ui_ind_disc(struct llc_prim_if_block *prim) -{ - struct llc_prim_disc *prim_data = &prim->data->disc; - struct sock* sk = prim_data->sk; - - sock_hold(sk); - if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED) { - dprintk("%s: bad socket...\n", __FUNCTION__); - goto out_put; - } - sk->shutdown = SHUTDOWN_MASK; - sk->socket->state = SS_UNCONNECTED; - sk->state = TCP_CLOSE; - if (!sk->dead) { - sk->state_change(sk); - sk->dead = 1; - } -out_put: - sock_put(sk); -} - /** * llc_ui_indicate - LLC user interface hook into the LLC layer. * @prim: Primitive block provided by the llc layer. @@ -1401,7 +1344,9 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) "is gone for ->ind()...\n", __FUNCTION__); break; case LLC_DISC_PRIM: - llc_ui_ind_disc(prim); break; + dprintk("%s: shouldn't happen, LLC_DISC_PRIM " + "is gone for ->ind()...\n", __FUNCTION__); + break; case LLC_RESET_PRIM: case LLC_FLOWCONTROL_PRIM: default: break; @@ -1409,27 +1354,6 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) return 0; } -/** - * llc_ui_conf_disc - handle DISC confirm. - * @prim: Primitive block provided by the llc layer. - * - * handle DISC confirm. - */ -static void llc_ui_conf_disc(struct llc_prim_if_block *prim) -{ - struct llc_prim_disc *prim_data = &prim->data->disc; - struct sock* sk = prim_data->sk; - - sock_hold(sk); - if (sk->type != SOCK_STREAM || sk->state != TCP_CLOSING) - goto out_put; - sk->socket->state = SS_UNCONNECTED; - sk->state = TCP_CLOSE; - sk->state_change(sk); -out_put: - sock_put(sk); -} - /** * llc_ui_confirm - LLC user interface hook into the LLC layer * @prim: Primitive block provided by the llc layer. @@ -1450,10 +1374,12 @@ static int llc_ui_confirm(struct llc_prim_if_block *prim) "is gone for ->conf()...\n", __FUNCTION__); break; case LLC_DISC_PRIM: - llc_ui_conf_disc(prim); break; + dprintk("%s: shouldn't happen, LLC_DISC_PRIM " + "is gone for ->conf()...\n", __FUNCTION__); + break; case LLC_RESET_PRIM: break; default: - printk(KERN_ERR "%s: unknown prim %d\n", __FUNCTION__, + printk(KERN_ERR "%s: prim not supported%d\n", __FUNCTION__, prim->prim); break; } -- cgit v1.2.3 From b1b28e47bb9c1485f20a227e2f9c826ff2dcc7c4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 12 Sep 2002 09:44:01 -0300 Subject: [LLC] remove unsupported flowcontrol prim bits --- include/net/llc_if.h | 9 +-------- net/llc/llc_if.c | 11 +---------- net/llc/llc_sock.c | 1 - 3 files changed, 2 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/net/llc_if.h b/include/net/llc_if.h index 1ae97a593ee6..ebff514725e3 100644 --- a/include/net/llc_if.h +++ b/include/net/llc_if.h @@ -20,7 +20,7 @@ #define LLC_DATA_PRIM 2 #define LLC_DISC_PRIM 3 #define LLC_RESET_PRIM 4 -#define LLC_FLOWCONTROL_PRIM 5 +#define LLC_FLOWCONTROL_PRIM 5 /* Not supported at this time */ #define LLC_DISABLE_PRIM 6 #define LLC_XID_PRIM 7 #define LLC_TEST_PRIM 8 @@ -71,12 +71,6 @@ struct llc_prim_reset { u8 reason; /* used only by indicate */ }; -struct llc_prim_flow_ctrl { - struct sock *sk; - u16 link; - u32 amount; -}; - /* Sending data in conection-less mode */ struct llc_prim_unit_data { struct llc_addr saddr; @@ -102,7 +96,6 @@ struct llc_prim_test { union llc_u_prim_data { struct llc_prim_reset res; - struct llc_prim_flow_ctrl fc; struct llc_prim_unit_data udata; /* unit data */ struct llc_prim_xid xid; struct llc_prim_test test; diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index 5af123bea45d..126c0d23101c 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -33,7 +33,6 @@ static int llc_unitdata_req_handler(struct llc_prim_if_block *prim); static int llc_test_req_handler(struct llc_prim_if_block *prim); static int llc_xid_req_handler(struct llc_prim_if_block *prim); static int llc_rst_req_handler(struct llc_prim_if_block *prim); -static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim); /* table of request handler functions */ static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = { @@ -42,7 +41,7 @@ static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = { [LLC_DATA_PRIM] = NULL, /* replaced by llc_build_and_send_pkt */ [LLC_DISC_PRIM] = NULL, /* replaced by llc_send_disc */ [LLC_RESET_PRIM] = llc_rst_req_handler, - [LLC_FLOWCONTROL_PRIM] = llc_flowcontrol_req_handler, + [LLC_FLOWCONTROL_PRIM] = NULL, /* Not supported at this time */ [LLC_XID_PRIM] = llc_xid_req_handler, [LLC_TEST_PRIM] = llc_test_req_handler, }; @@ -372,13 +371,5 @@ static int llc_rst_req_handler(struct llc_prim_if_block *prim) return rc; } -/* We don't support flow control. The original code from procom has - * some bits, but for now I'm cleaning this - */ -static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim) -{ - return 1; -} - EXPORT_SYMBOL(llc_sap_open); EXPORT_SYMBOL(llc_sap_close); diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index e1ab6010d50d..f664c4c3d565 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -1348,7 +1348,6 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) "is gone for ->ind()...\n", __FUNCTION__); break; case LLC_RESET_PRIM: - case LLC_FLOWCONTROL_PRIM: default: break; } return 0; -- cgit v1.2.3 From 96b2cae773183e8298385cf05103b3abeb3cfa7e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 13 Sep 2002 04:48:47 -0300 Subject: [LLC] kill sap->req() Intermediate patch for the PF_LLC SOCK_DGRAM prim clean-up, now PF_LLC is prims in the sending side, now to hack the core to not use prims to send to PF_LLC. This also fixes a skb leak on llc_sap_state_process. --- include/net/llc_if.h | 23 +++++++ include/net/llc_sap.h | 1 - net/llc/llc_if.c | 183 ++++++++++++++++++++++---------------------------- net/llc/llc_sap.c | 24 ++----- net/llc/llc_sock.c | 54 ++------------- 5 files changed, 114 insertions(+), 171 deletions(-) (limited to 'include') diff --git a/include/net/llc_if.h b/include/net/llc_if.h index ebff514725e3..e17373a17c00 100644 --- a/include/net/llc_if.h +++ b/include/net/llc_if.h @@ -14,6 +14,8 @@ /* Defines LLC interface to network layer */ /* Available primitives */ #include +#include +#include #define LLC_DATAUNIT_PRIM 0 #define LLC_CONN_PRIM 1 @@ -118,5 +120,26 @@ extern void llc_sap_close(struct llc_sap *sap); extern int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap); extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb); +extern void llc_build_and_send_ui_pkt(struct llc_sap *sap, + struct sk_buff *skb, + struct sockaddr_llc *addr); +extern void llc_build_and_send_xid_pkt(struct llc_sap *sap, + struct sk_buff *skb, + struct sockaddr_llc *addr); +extern void llc_build_and_send_test_pkt(struct llc_sap *sap, + struct sk_buff *skb, + struct sockaddr_llc *addr); extern int llc_send_disc(struct sock *sk); + +/** + * llc_proto_type - return eth protocol for ARP header type + * @arphrd: ARP header type. + * + * Given an ARP header type return the corresponding ethernet protocol. + */ +static __inline__ u16 llc_proto_type(u16 arphrd) +{ + return arphrd == ARPHRD_IEEE802_TR ? + htons(ETH_P_TR_802_2) : htons(ETH_P_802_2); +} #endif /* LLC_IF_H */ diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h index 3132bebd1422..1357da860c04 100644 --- a/include/net/llc_sap.h +++ b/include/net/llc_sap.h @@ -30,7 +30,6 @@ struct llc_sap { u8 state; u8 p_bit; u8 f_bit; - llc_prim_call_t req; llc_prim_call_t ind; llc_prim_call_t conf; struct llc_prim_if_block llc_ind_prim, llc_cfm_prim; diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index 126c0d23101c..393173d91156 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -28,24 +28,6 @@ #include #include -static int llc_sap_req(struct llc_prim_if_block *prim); -static int llc_unitdata_req_handler(struct llc_prim_if_block *prim); -static int llc_test_req_handler(struct llc_prim_if_block *prim); -static int llc_xid_req_handler(struct llc_prim_if_block *prim); -static int llc_rst_req_handler(struct llc_prim_if_block *prim); - -/* table of request handler functions */ -static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = { - [LLC_DATAUNIT_PRIM] = llc_unitdata_req_handler, - [LLC_CONN_PRIM] = NULL, /* replaced by llc_establish_connection */ - [LLC_DATA_PRIM] = NULL, /* replaced by llc_build_and_send_pkt */ - [LLC_DISC_PRIM] = NULL, /* replaced by llc_send_disc */ - [LLC_RESET_PRIM] = llc_rst_req_handler, - [LLC_FLOWCONTROL_PRIM] = NULL, /* Not supported at this time */ - [LLC_XID_PRIM] = llc_xid_req_handler, - [LLC_TEST_PRIM] = llc_test_req_handler, -}; - /** * llc_sap_open - open interface to the upper layers. * @nw_indicate: pointer to indicate function of upper layer. @@ -75,7 +57,6 @@ struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate, goto err; /* allocated a SAP; initialize it and clear out its memory pool */ sap->laddr.lsap = lsap; - sap->req = llc_sap_req; sap->ind = nw_indicate; sap->conf = nw_confirm; sap->parent_station = llc_station_get(); @@ -102,116 +83,115 @@ void llc_sap_close(struct llc_sap *sap) } /** - * llc_sap_req - Request interface for upper layers - * @prim: pointer to structure that contains service parameters. + * llc_build_and_send_ui_pkt - unitdata request interface for upper layers + * @sap: sap to use + * @skb: packet to send + * @addr: destination address * - * Request interface function to upper layer. Each one who wants to - * request a service from LLC, must call this function. Details of - * requested service is defined in input argument(prim). Returns 0 for - * success, 1 otherwise. + * Upper layers calls this function when upper layer wants to send data + * using connection-less mode communication (UI pdu). + * + * Accept data frame from network layer to be sent using connection- + * less mode communication; timeout/retries handled by network layer; + * package primitive as an event and send to SAP event handler */ -static int llc_sap_req(struct llc_prim_if_block *prim) +void llc_build_and_send_ui_pkt(struct llc_sap *sap, + struct sk_buff *skb, + struct sockaddr_llc *addr) { - int rc = 1; + union llc_u_prim_data prim_data; + struct llc_prim_if_block prim; + struct llc_sap_state_ev *ev = llc_sap_ev(skb); - if (prim->prim > 8 || prim->prim == 6) { - printk(KERN_ERR "%s: invalid primitive %d\n", __FUNCTION__, - prim->prim); - goto out; - } - /* receive REQUEST primitive from network layer; call the appropriate - * primitive handler which then packages it up as an event and sends it - * to the SAP or CONNECTION event handler - */ - if (prim->prim < LLC_NBR_PRIMITIVES) - /* valid primitive; call the function to handle it */ - rc = llc_req_prim[prim->prim](prim); -out: - return rc; -} + skb->protocol = llc_proto_type(addr->sllc_arphrd); -/** - * llc_unitdata_req_handler - unitdata request interface for upper layers - * @prim: pointer to structure that contains service parameters - * - * Upper layers calls this function when upper layer wants to send data - * using connection-less mode communication (UI pdu). Returns 0 for - * success, 1 otherwise. - */ -static int llc_unitdata_req_handler(struct llc_prim_if_block *prim) -{ - int rc = 1; - struct llc_sap_state_ev *ev; - /* accept data frame from network layer to be sent using connection- - * less mode communication; timeout/retries handled by network layer; - * package primitive as an event and send to SAP event handler - */ - struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap); + prim.data = &prim_data; + prim.sap = sap; + prim.prim = LLC_DATAUNIT_PRIM; + + prim_data.udata.skb = skb; + prim_data.udata.saddr.lsap = sap->laddr.lsap; + prim_data.udata.daddr.lsap = addr->sllc_dsap; + memcpy(prim_data.udata.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN); + memcpy(prim_data.udata.daddr.mac, addr->sllc_dmac, IFHWADDRLEN); - if (!sap) - goto out; - ev = llc_sap_ev(prim->data->udata.skb); ev->type = LLC_SAP_EV_TYPE_PRIM; ev->data.prim.prim = LLC_DATAUNIT_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_REQ; - ev->data.prim.data = prim; - rc = 0; - llc_sap_state_process(sap, prim->data->udata.skb); -out: - return rc; + ev->data.prim.data = &prim; + llc_sap_state_process(sap, skb); } /** - * llc_test_req_handler - TEST interface for upper layers. - * @prim: pointer to structure that contains service parameters. + * llc_build_and_send_test_pkt - TEST interface for upper layers. + * @sap: sap to use + * @skb: packet to send + * @addr: destination address * * This function is called when upper layer wants to send a TEST pdu. * Returns 0 for success, 1 otherwise. */ -static int llc_test_req_handler(struct llc_prim_if_block *prim) +void llc_build_and_send_test_pkt(struct llc_sap *sap, + struct sk_buff *skb, + struct sockaddr_llc *addr) { - int rc = 1; - struct llc_sap_state_ev *ev; - /* package primitive as an event and send to SAP event handler */ - struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap); - if (!sap) - goto out; - ev = llc_sap_ev(prim->data->udata.skb); + union llc_u_prim_data prim_data; + struct llc_prim_if_block prim; + struct llc_sap_state_ev *ev = llc_sap_ev(skb); + + skb->protocol = llc_proto_type(addr->sllc_arphrd); + + prim.data = &prim_data; + prim.sap = sap; + prim.prim = LLC_TEST_PRIM; + + prim_data.test.skb = skb; + prim_data.test.saddr.lsap = sap->laddr.lsap; + prim_data.test.daddr.lsap = addr->sllc_dsap; + memcpy(prim_data.test.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN); + memcpy(prim_data.test.daddr.mac, addr->sllc_dmac, IFHWADDRLEN); + ev->type = LLC_SAP_EV_TYPE_PRIM; ev->data.prim.prim = LLC_TEST_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_REQ; - ev->data.prim.data = prim; - rc = 0; - llc_sap_state_process(sap, prim->data->udata.skb); -out: - return rc; + ev->data.prim.data = &prim; + llc_sap_state_process(sap, skb); } /** - * llc_xid_req_handler - XID interface for upper layers - * @prim: pointer to structure that contains service parameters. + * llc_build_and_send_xid_pkt - XID interface for upper layers + * @sap: sap to use + * @skb: packet to send + * @addr: destination address * * This function is called when upper layer wants to send a XID pdu. * Returns 0 for success, 1 otherwise. */ -static int llc_xid_req_handler(struct llc_prim_if_block *prim) +void llc_build_and_send_xid_pkt(struct llc_sap *sap, + struct sk_buff *skb, + struct sockaddr_llc *addr) { - int rc = 1; - struct llc_sap_state_ev *ev; - /* package primitive as an event and send to SAP event handler */ - struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap); + union llc_u_prim_data prim_data; + struct llc_prim_if_block prim; + struct llc_sap_state_ev *ev = llc_sap_ev(skb); + + skb->protocol = llc_proto_type(addr->sllc_arphrd); + + prim.data = &prim_data; + prim.sap = sap; + prim.prim = LLC_XID_PRIM; + + prim_data.xid.skb = skb; + prim_data.xid.saddr.lsap = sap->laddr.lsap; + prim_data.xid.daddr.lsap = addr->sllc_dsap; + memcpy(prim_data.xid.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN); + memcpy(prim_data.xid.daddr.mac, addr->sllc_dmac, IFHWADDRLEN); - if (!sap) - goto out; - ev = llc_sap_ev(prim->data->udata.skb); ev->type = LLC_SAP_EV_TYPE_PRIM; ev->data.prim.prim = LLC_XID_PRIM; ev->data.prim.type = LLC_PRIM_TYPE_REQ; - ev->data.prim.data = prim; - rc = 0; - llc_sap_state_process(sap, prim->data->udata.skb); -out: - return rc; + ev->data.prim.data = &prim; + llc_sap_state_process(sap, skb); } /** @@ -344,7 +324,7 @@ out: } /** - * llc_rst_req_handler - Resets an established LLC connection + * llc_build_and_send_reset_pkt - Resets an established LLC connection * @prim: pointer to structure that contains service parameters. * * Called when upper layer wants to reset an established LLC connection @@ -352,13 +332,12 @@ out: * it to connection component state machine. Returns 0 for success, 1 * otherwise. */ -static int llc_rst_req_handler(struct llc_prim_if_block *prim) +int llc_build_and_send_reset_pkt(struct sock *sk, + struct llc_prim_if_block *prim) { - struct sk_buff *skb; int rc = 1; - struct sock *sk = prim->data->res.sk; + struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); - skb = alloc_skb(0, GFP_ATOMIC); if (skb) { struct llc_conn_state_ev *ev = llc_conn_ev(skb); diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index ea58322988ad..15ad186dcdd9 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -23,7 +23,6 @@ #include #include -static void llc_sap_free_ev(struct llc_sap *sap, struct sk_buff *skb); static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb); static int llc_exec_sap_trans_actions(struct llc_sap *sap, struct llc_sap_state_trans *trans, @@ -75,11 +74,13 @@ void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) struct llc_sap_state_ev *ev = llc_sap_ev(skb); llc_sap_next_state(sap, skb); - if (ev->ind_cfm_flag == LLC_IND) { - skb_get(skb); + if (ev->ind_cfm_flag == LLC_IND) sap->ind(ev->prim); - } - llc_sap_free_ev(sap, skb); + else if (ev->type == LLC_SAP_EV_TYPE_PDU) + kfree_skb(skb); + else + printk(KERN_INFO ":%s !kfree_skb & it is %s in a list\n", + __FUNCTION__, skb->list ? "" : "NOT"); } /** @@ -141,19 +142,6 @@ void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb) kfree_skb(skb); } -/** - * llc_sap_free_ev - frees an sap event - * @sap: pointer to SAP - * @skb: released event - */ -static void llc_sap_free_ev(struct llc_sap *sap, struct sk_buff *skb) -{ - struct llc_sap_state_ev *ev = llc_sap_ev(skb); - - if (ev->type == LLC_SAP_EV_TYPE_PDU) - kfree_skb(skb); -} - /** * llc_sap_next_state - finds transition, execs actions & change SAP state * @sap: pointer to SAP diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c index 61ee027c4be3..74a6a6b26e57 100644 --- a/net/llc/llc_sock.c +++ b/net/llc/llc_sock.c @@ -86,23 +86,6 @@ static __inline__ u8 llc_ui_addr_null(struct sockaddr_llc *addr) return !memcmp(addr, &llc_ui_addrnull, sizeof(*addr)); } -/** - * llc_ui_protocol_type - return eth protocol for ARP header type - * @arphrd: ARP header type. - * - * Given an ARP header type return the corresponding ethernet protocol. - * Returns 0 if ARP header type not supported or the corresponding - * ethernet protocol type. - */ -static __inline__ u16 llc_ui_protocol_type(u16 arphrd) -{ - u16 rc = htons(ETH_P_802_2); - - if (arphrd == ARPHRD_IEEE802_TR) - rc = htons(ETH_P_TR_802_2); - return rc; -} - /** * llc_ui_header_len - return length of llc header based on operation * @sk: Socket which contains a valid llc socket type. @@ -140,7 +123,7 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, struct llc_opt* llc = llc_sk(sk); int rc = 0; - skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd); + skb->protocol = llc_proto_type(addr->sllc_arphrd); if (llc_data_accept_state(llc->state) || llc->p_flag) { int timeout = sock_sndtimeo(sk, noblock); @@ -151,35 +134,6 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, return rc; } -/** - * llc_ui_send_llc1 - send llc1 prim data block to llc layer. - * @sap : Sap the socket is bound to. - * @skb : Data the user wishes to send. - * @addr : Source and destination fields provided by the user. - * @primitive: Action the llc layer should perform. - * - * Send an llc1 primitive data block to the llc layer for processing. - * This function is used for test, xid and unit_data messages. - * Returns 0 upon success, non-zero if action did not succeed. - */ -static int llc_ui_send_llc1(struct llc_sap *sap, struct sk_buff *skb, - struct sockaddr_llc *addr, int primitive) -{ - union llc_u_prim_data prim_data; - struct llc_prim_if_block prim; - - prim.data = &prim_data; - prim.sap = sap; - prim.prim = primitive; - prim_data.test.skb = skb; - prim_data.test.saddr.lsap = sap->laddr.lsap; - prim_data.test.daddr.lsap = addr->sllc_dsap; - skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd); - memcpy(prim_data.test.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN); - memcpy(prim_data.test.daddr.mac, addr->sllc_dmac, IFHWADDRLEN); - return sap->req(&prim); -} - /** * llc_ui_find_sap - returns sap struct that matches sap number specified * @sap: Sap number to search for. @@ -993,15 +947,15 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, if (rc) goto out; if (addr->sllc_test) { - rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_TEST_PRIM); + llc_build_and_send_test_pkt(llc->sap, skb, addr); goto out; } if (addr->sllc_xid) { - rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_XID_PRIM); + llc_build_and_send_xid_pkt(llc->sap, skb, addr); goto out; } if (sk->type == SOCK_DGRAM || addr->sllc_ua) { - rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_DATAUNIT_PRIM); + llc_build_and_send_ui_pkt(llc->sap, skb, addr); goto out; } rc = -ENOPROTOOPT; -- cgit v1.2.3