Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * llc_conn.c - Driver routines for connection component.
0003  *
0004  * Copyright (c) 1997 by Procom Technology, Inc.
0005  *       2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
0006  *
0007  * This program can be redistributed or modified under the terms of the
0008  * GNU General Public License as published by the Free Software Foundation.
0009  * This program is distributed without any warranty or implied warranty
0010  * of merchantability or fitness for a particular purpose.
0011  *
0012  * See the GNU General Public License for more details.
0013  */
0014 
0015 #include <linux/init.h>
0016 #include <linux/slab.h>
0017 #include <net/llc_sap.h>
0018 #include <net/llc_conn.h>
0019 #include <net/sock.h>
0020 #include <net/tcp_states.h>
0021 #include <net/llc_c_ev.h>
0022 #include <net/llc_c_ac.h>
0023 #include <net/llc_c_st.h>
0024 #include <net/llc_pdu.h>
0025 
0026 #if 0
0027 #define dprintk(args...) printk(KERN_DEBUG args)
0028 #else
0029 #define dprintk(args...)
0030 #endif
0031 
0032 static int llc_find_offset(int state, int ev_type);
0033 static void llc_conn_send_pdus(struct sock *sk);
0034 static int llc_conn_service(struct sock *sk, struct sk_buff *skb);
0035 static int llc_exec_conn_trans_actions(struct sock *sk,
0036                        struct llc_conn_state_trans *trans,
0037                        struct sk_buff *ev);
0038 static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
0039                             struct sk_buff *skb);
0040 
0041 /* Offset table on connection states transition diagram */
0042 static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
0043 
0044 int sysctl_llc2_ack_timeout = LLC2_ACK_TIME * HZ;
0045 int sysctl_llc2_p_timeout = LLC2_P_TIME * HZ;
0046 int sysctl_llc2_rej_timeout = LLC2_REJ_TIME * HZ;
0047 int sysctl_llc2_busy_timeout = LLC2_BUSY_TIME * HZ;
0048 
0049 /**
0050  *  llc_conn_state_process - sends event to connection state machine
0051  *  @sk: connection
0052  *  @skb: occurred event
0053  *
0054  *  Sends an event to connection state machine. After processing event
0055  *  (executing it's actions and changing state), upper layer will be
0056  *  indicated or confirmed, if needed. Returns 0 for success, 1 for
0057  *  failure. The socket lock has to be held before calling this function.
0058  *
0059  *  This function always consumes a reference to the skb.
0060  */
0061 int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
0062 {
0063     int rc;
0064     struct llc_sock *llc = llc_sk(skb->sk);
0065     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0066 
0067     ev->ind_prim = ev->cfm_prim = 0;
0068     /*
0069      * Send event to state machine
0070      */
0071     rc = llc_conn_service(skb->sk, skb);
0072     if (unlikely(rc != 0)) {
0073         printk(KERN_ERR "%s: llc_conn_service failed\n", __func__);
0074         goto out_skb_put;
0075     }
0076 
0077     switch (ev->ind_prim) {
0078     case LLC_DATA_PRIM:
0079         skb_get(skb);
0080         llc_save_primitive(sk, skb, LLC_DATA_PRIM);
0081         if (unlikely(sock_queue_rcv_skb(sk, skb))) {
0082             /*
0083              * shouldn't happen
0084              */
0085             printk(KERN_ERR "%s: sock_queue_rcv_skb failed!\n",
0086                    __func__);
0087             kfree_skb(skb);
0088         }
0089         break;
0090     case LLC_CONN_PRIM:
0091         /*
0092          * Can't be sock_queue_rcv_skb, because we have to leave the
0093          * skb->sk pointing to the newly created struct sock in
0094          * llc_conn_handler. -acme
0095          */
0096         skb_get(skb);
0097         skb_queue_tail(&sk->sk_receive_queue, skb);
0098         sk->sk_state_change(sk);
0099         break;
0100     case LLC_DISC_PRIM:
0101         sock_hold(sk);
0102         if (sk->sk_type == SOCK_STREAM &&
0103             sk->sk_state == TCP_ESTABLISHED) {
0104             sk->sk_shutdown       = SHUTDOWN_MASK;
0105             sk->sk_socket->state  = SS_UNCONNECTED;
0106             sk->sk_state          = TCP_CLOSE;
0107             if (!sock_flag(sk, SOCK_DEAD)) {
0108                 sock_set_flag(sk, SOCK_DEAD);
0109                 sk->sk_state_change(sk);
0110             }
0111         }
0112         sock_put(sk);
0113         break;
0114     case LLC_RESET_PRIM:
0115         /*
0116          * FIXME:
0117          * RESET is not being notified to upper layers for now
0118          */
0119         printk(KERN_INFO "%s: received a reset ind!\n", __func__);
0120         break;
0121     default:
0122         if (ev->ind_prim)
0123             printk(KERN_INFO "%s: received unknown %d prim!\n",
0124                 __func__, ev->ind_prim);
0125         /* No indication */
0126         break;
0127     }
0128 
0129     switch (ev->cfm_prim) {
0130     case LLC_DATA_PRIM:
0131         if (!llc_data_accept_state(llc->state))
0132             sk->sk_write_space(sk);
0133         else
0134             rc = llc->failed_data_req = 1;
0135         break;
0136     case LLC_CONN_PRIM:
0137         if (sk->sk_type == SOCK_STREAM &&
0138             sk->sk_state == TCP_SYN_SENT) {
0139             if (ev->status) {
0140                 sk->sk_socket->state = SS_UNCONNECTED;
0141                 sk->sk_state         = TCP_CLOSE;
0142             } else {
0143                 sk->sk_socket->state = SS_CONNECTED;
0144                 sk->sk_state         = TCP_ESTABLISHED;
0145             }
0146             sk->sk_state_change(sk);
0147         }
0148         break;
0149     case LLC_DISC_PRIM:
0150         sock_hold(sk);
0151         if (sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_CLOSING) {
0152             sk->sk_socket->state = SS_UNCONNECTED;
0153             sk->sk_state         = TCP_CLOSE;
0154             sk->sk_state_change(sk);
0155         }
0156         sock_put(sk);
0157         break;
0158     case LLC_RESET_PRIM:
0159         /*
0160          * FIXME:
0161          * RESET is not being notified to upper layers for now
0162          */
0163         printk(KERN_INFO "%s: received a reset conf!\n", __func__);
0164         break;
0165     default:
0166         if (ev->cfm_prim)
0167             printk(KERN_INFO "%s: received unknown %d prim!\n",
0168                     __func__, ev->cfm_prim);
0169         /* No confirmation */
0170         break;
0171     }
0172 out_skb_put:
0173     kfree_skb(skb);
0174     return rc;
0175 }
0176 
0177 void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
0178 {
0179     /* queue PDU to send to MAC layer */
0180     skb_queue_tail(&sk->sk_write_queue, skb);
0181     llc_conn_send_pdus(sk);
0182 }
0183 
0184 /**
0185  *  llc_conn_rtn_pdu - sends received data pdu to upper layer
0186  *  @sk: Active connection
0187  *  @skb: Received data frame
0188  *
0189  *  Sends received data pdu to upper layer (by using indicate function).
0190  *  Prepares service parameters (prim and prim_data). calling indication
0191  *  function will be done in llc_conn_state_process.
0192  */
0193 void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb)
0194 {
0195     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0196 
0197     ev->ind_prim = LLC_DATA_PRIM;
0198 }
0199 
0200 /**
0201  *  llc_conn_resend_i_pdu_as_cmd - resend all all unacknowledged I PDUs
0202  *  @sk: active connection
0203  *  @nr: NR
0204  *  @first_p_bit: p_bit value of first pdu
0205  *
0206  *  Resend all unacknowledged I PDUs, starting with the NR; send first as
0207  *  command PDU with P bit equal first_p_bit; if more than one send
0208  *  subsequent as command PDUs with P bit equal zero (0).
0209  */
0210 void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit)
0211 {
0212     struct sk_buff *skb;
0213     struct llc_pdu_sn *pdu;
0214     u16 nbr_unack_pdus;
0215     struct llc_sock *llc;
0216     u8 howmany_resend = 0;
0217 
0218     llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus);
0219     if (!nbr_unack_pdus)
0220         goto out;
0221     /*
0222      * Process unack PDUs only if unack queue is not empty; remove
0223      * appropriate PDUs, fix them up, and put them on mac_pdu_q.
0224      */
0225     llc = llc_sk(sk);
0226 
0227     while ((skb = skb_dequeue(&llc->pdu_unack_q)) != NULL) {
0228         pdu = llc_pdu_sn_hdr(skb);
0229         llc_pdu_set_cmd_rsp(skb, LLC_PDU_CMD);
0230         llc_pdu_set_pf_bit(skb, first_p_bit);
0231         skb_queue_tail(&sk->sk_write_queue, skb);
0232         first_p_bit = 0;
0233         llc->vS = LLC_I_GET_NS(pdu);
0234         howmany_resend++;
0235     }
0236     if (howmany_resend > 0)
0237         llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
0238     /* any PDUs to re-send are queued up; start sending to MAC */
0239     llc_conn_send_pdus(sk);
0240 out:;
0241 }
0242 
0243 /**
0244  *  llc_conn_resend_i_pdu_as_rsp - Resend all unacknowledged I PDUs
0245  *  @sk: active connection.
0246  *  @nr: NR
0247  *  @first_f_bit: f_bit value of first pdu.
0248  *
0249  *  Resend all unacknowledged I PDUs, starting with the NR; send first as
0250  *  response PDU with F bit equal first_f_bit; if more than one send
0251  *  subsequent as response PDUs with F bit equal zero (0).
0252  */
0253 void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit)
0254 {
0255     struct sk_buff *skb;
0256     u16 nbr_unack_pdus;
0257     struct llc_sock *llc = llc_sk(sk);
0258     u8 howmany_resend = 0;
0259 
0260     llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus);
0261     if (!nbr_unack_pdus)
0262         goto out;
0263     /*
0264      * Process unack PDUs only if unack queue is not empty; remove
0265      * appropriate PDUs, fix them up, and put them on mac_pdu_q
0266      */
0267     while ((skb = skb_dequeue(&llc->pdu_unack_q)) != NULL) {
0268         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0269 
0270         llc_pdu_set_cmd_rsp(skb, LLC_PDU_RSP);
0271         llc_pdu_set_pf_bit(skb, first_f_bit);
0272         skb_queue_tail(&sk->sk_write_queue, skb);
0273         first_f_bit = 0;
0274         llc->vS = LLC_I_GET_NS(pdu);
0275         howmany_resend++;
0276     }
0277     if (howmany_resend > 0)
0278         llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
0279     /* any PDUs to re-send are queued up; start sending to MAC */
0280     llc_conn_send_pdus(sk);
0281 out:;
0282 }
0283 
0284 /**
0285  *  llc_conn_remove_acked_pdus - Removes acknowledged pdus from tx queue
0286  *  @sk: active connection
0287  *  @nr: NR
0288  *  @how_many_unacked: size of pdu_unack_q after removing acked pdus
0289  *
0290  *  Removes acknowledged pdus from transmit queue (pdu_unack_q). Returns
0291  *  the number of pdus that removed from queue.
0292  */
0293 int llc_conn_remove_acked_pdus(struct sock *sk, u8 nr, u16 *how_many_unacked)
0294 {
0295     int pdu_pos, i;
0296     struct sk_buff *skb;
0297     struct llc_pdu_sn *pdu;
0298     int nbr_acked = 0;
0299     struct llc_sock *llc = llc_sk(sk);
0300     int q_len = skb_queue_len(&llc->pdu_unack_q);
0301 
0302     if (!q_len)
0303         goto out;
0304     skb = skb_peek(&llc->pdu_unack_q);
0305     pdu = llc_pdu_sn_hdr(skb);
0306 
0307     /* finding position of last acked pdu in queue */
0308     pdu_pos = ((int)LLC_2_SEQ_NBR_MODULO + (int)nr -
0309             (int)LLC_I_GET_NS(pdu)) % LLC_2_SEQ_NBR_MODULO;
0310 
0311     for (i = 0; i < pdu_pos && i < q_len; i++) {
0312         skb = skb_dequeue(&llc->pdu_unack_q);
0313         kfree_skb(skb);
0314         nbr_acked++;
0315     }
0316 out:
0317     *how_many_unacked = skb_queue_len(&llc->pdu_unack_q);
0318     return nbr_acked;
0319 }
0320 
0321 /**
0322  *  llc_conn_send_pdus - Sends queued PDUs
0323  *  @sk: active connection
0324  *
0325  *  Sends queued pdus to MAC layer for transmission.
0326  */
0327 static void llc_conn_send_pdus(struct sock *sk)
0328 {
0329     struct sk_buff *skb;
0330 
0331     while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
0332         struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
0333 
0334         if (LLC_PDU_TYPE_IS_I(pdu) &&
0335             !(skb->dev->flags & IFF_LOOPBACK)) {
0336             struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
0337 
0338             skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb);
0339             if (!skb2)
0340                 break;
0341             skb = skb2;
0342         }
0343         dev_queue_xmit(skb);
0344     }
0345 }
0346 
0347 /**
0348  *  llc_conn_service - finds transition and changes state of connection
0349  *  @sk: connection
0350  *  @skb: happened event
0351  *
0352  *  This function finds transition that matches with happened event, then
0353  *  executes related actions and finally changes state of connection.
0354  *  Returns 0 for success, 1 for failure.
0355  */
0356 static int llc_conn_service(struct sock *sk, struct sk_buff *skb)
0357 {
0358     int rc = 1;
0359     struct llc_sock *llc = llc_sk(sk);
0360     struct llc_conn_state_trans *trans;
0361 
0362     if (llc->state > NBR_CONN_STATES)
0363         goto out;
0364     rc = 0;
0365     trans = llc_qualify_conn_ev(sk, skb);
0366     if (trans) {
0367         rc = llc_exec_conn_trans_actions(sk, trans, skb);
0368         if (!rc && trans->next_state != NO_STATE_CHANGE) {
0369             llc->state = trans->next_state;
0370             if (!llc_data_accept_state(llc->state))
0371                 sk->sk_state_change(sk);
0372         }
0373     }
0374 out:
0375     return rc;
0376 }
0377 
0378 /**
0379  *  llc_qualify_conn_ev - finds transition for event
0380  *  @sk: connection
0381  *  @skb: happened event
0382  *
0383  *  This function finds transition that matches with happened event.
0384  *  Returns pointer to found transition on success, %NULL otherwise.
0385  */
0386 static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
0387                             struct sk_buff *skb)
0388 {
0389     struct llc_conn_state_trans **next_trans;
0390     const llc_conn_ev_qfyr_t *next_qualifier;
0391     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0392     struct llc_sock *llc = llc_sk(sk);
0393     struct llc_conn_state *curr_state =
0394                     &llc_conn_state_table[llc->state - 1];
0395 
0396     /* search thru events for this state until
0397      * list exhausted or until no more
0398      */
0399     for (next_trans = curr_state->transitions +
0400         llc_find_offset(llc->state - 1, ev->type);
0401          (*next_trans)->ev; next_trans++) {
0402         if (!((*next_trans)->ev)(sk, skb)) {
0403             /* got POSSIBLE event match; the event may require
0404              * qualification based on the values of a number of
0405              * state flags; if all qualifications are met (i.e.,
0406              * if all qualifying functions return success, or 0,
0407              * then this is THE event we're looking for
0408              */
0409             for (next_qualifier = (*next_trans)->ev_qualifiers;
0410                  next_qualifier && *next_qualifier &&
0411                  !(*next_qualifier)(sk, skb); next_qualifier++)
0412                 /* nothing */;
0413             if (!next_qualifier || !*next_qualifier)
0414                 /* all qualifiers executed successfully; this is
0415                  * our transition; return it so we can perform
0416                  * the associated actions & change the state
0417                  */
0418                 return *next_trans;
0419         }
0420     }
0421     return NULL;
0422 }
0423 
0424 /**
0425  *  llc_exec_conn_trans_actions - executes related actions
0426  *  @sk: connection
0427  *  @trans: transition that it's actions must be performed
0428  *  @skb: event
0429  *
0430  *  Executes actions that is related to happened event. Returns 0 for
0431  *  success, 1 to indicate failure of at least one action.
0432  */
0433 static int llc_exec_conn_trans_actions(struct sock *sk,
0434                        struct llc_conn_state_trans *trans,
0435                        struct sk_buff *skb)
0436 {
0437     int rc = 0;
0438     const llc_conn_action_t *next_action;
0439 
0440     for (next_action = trans->ev_actions;
0441          next_action && *next_action; next_action++) {
0442         int rc2 = (*next_action)(sk, skb);
0443 
0444         if (rc2 == 2) {
0445             rc = rc2;
0446             break;
0447         } else if (rc2)
0448             rc = 1;
0449     }
0450     return rc;
0451 }
0452 
0453 static inline bool llc_estab_match(const struct llc_sap *sap,
0454                    const struct llc_addr *daddr,
0455                    const struct llc_addr *laddr,
0456                    const struct sock *sk)
0457 {
0458     struct llc_sock *llc = llc_sk(sk);
0459 
0460     return llc->laddr.lsap == laddr->lsap &&
0461         llc->daddr.lsap == daddr->lsap &&
0462         ether_addr_equal(llc->laddr.mac, laddr->mac) &&
0463         ether_addr_equal(llc->daddr.mac, daddr->mac);
0464 }
0465 
0466 /**
0467  *  __llc_lookup_established - Finds connection for the remote/local sap/mac
0468  *  @sap: SAP
0469  *  @daddr: address of remote LLC (MAC + SAP)
0470  *  @laddr: address of local LLC (MAC + SAP)
0471  *
0472  *  Search connection list of the SAP and finds connection using the remote
0473  *  mac, remote sap, local mac, and local sap. Returns pointer for
0474  *  connection found, %NULL otherwise.
0475  *  Caller has to make sure local_bh is disabled.
0476  */
0477 static struct sock *__llc_lookup_established(struct llc_sap *sap,
0478                          struct llc_addr *daddr,
0479                          struct llc_addr *laddr)
0480 {
0481     struct sock *rc;
0482     struct hlist_nulls_node *node;
0483     int slot = llc_sk_laddr_hashfn(sap, laddr);
0484     struct hlist_nulls_head *laddr_hb = &sap->sk_laddr_hash[slot];
0485 
0486     rcu_read_lock();
0487 again:
0488     sk_nulls_for_each_rcu(rc, node, laddr_hb) {
0489         if (llc_estab_match(sap, daddr, laddr, rc)) {
0490             /* Extra checks required by SLAB_TYPESAFE_BY_RCU */
0491             if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt)))
0492                 goto again;
0493             if (unlikely(llc_sk(rc)->sap != sap ||
0494                      !llc_estab_match(sap, daddr, laddr, rc))) {
0495                 sock_put(rc);
0496                 continue;
0497             }
0498             goto found;
0499         }
0500     }
0501     rc = NULL;
0502     /*
0503      * if the nulls value we got at the end of this lookup is
0504      * not the expected one, we must restart lookup.
0505      * We probably met an item that was moved to another chain.
0506      */
0507     if (unlikely(get_nulls_value(node) != slot))
0508         goto again;
0509 found:
0510     rcu_read_unlock();
0511     return rc;
0512 }
0513 
0514 struct sock *llc_lookup_established(struct llc_sap *sap,
0515                     struct llc_addr *daddr,
0516                     struct llc_addr *laddr)
0517 {
0518     struct sock *sk;
0519 
0520     local_bh_disable();
0521     sk = __llc_lookup_established(sap, daddr, laddr);
0522     local_bh_enable();
0523     return sk;
0524 }
0525 
0526 static inline bool llc_listener_match(const struct llc_sap *sap,
0527                       const struct llc_addr *laddr,
0528                       const struct sock *sk)
0529 {
0530     struct llc_sock *llc = llc_sk(sk);
0531 
0532     return sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN &&
0533         llc->laddr.lsap == laddr->lsap &&
0534         ether_addr_equal(llc->laddr.mac, laddr->mac);
0535 }
0536 
0537 static struct sock *__llc_lookup_listener(struct llc_sap *sap,
0538                       struct llc_addr *laddr)
0539 {
0540     struct sock *rc;
0541     struct hlist_nulls_node *node;
0542     int slot = llc_sk_laddr_hashfn(sap, laddr);
0543     struct hlist_nulls_head *laddr_hb = &sap->sk_laddr_hash[slot];
0544 
0545     rcu_read_lock();
0546 again:
0547     sk_nulls_for_each_rcu(rc, node, laddr_hb) {
0548         if (llc_listener_match(sap, laddr, rc)) {
0549             /* Extra checks required by SLAB_TYPESAFE_BY_RCU */
0550             if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt)))
0551                 goto again;
0552             if (unlikely(llc_sk(rc)->sap != sap ||
0553                      !llc_listener_match(sap, laddr, rc))) {
0554                 sock_put(rc);
0555                 continue;
0556             }
0557             goto found;
0558         }
0559     }
0560     rc = NULL;
0561     /*
0562      * if the nulls value we got at the end of this lookup is
0563      * not the expected one, we must restart lookup.
0564      * We probably met an item that was moved to another chain.
0565      */
0566     if (unlikely(get_nulls_value(node) != slot))
0567         goto again;
0568 found:
0569     rcu_read_unlock();
0570     return rc;
0571 }
0572 
0573 /**
0574  *  llc_lookup_listener - Finds listener for local MAC + SAP
0575  *  @sap: SAP
0576  *  @laddr: address of local LLC (MAC + SAP)
0577  *
0578  *  Search connection list of the SAP and finds connection listening on
0579  *  local mac, and local sap. Returns pointer for parent socket found,
0580  *  %NULL otherwise.
0581  *  Caller has to make sure local_bh is disabled.
0582  */
0583 static struct sock *llc_lookup_listener(struct llc_sap *sap,
0584                     struct llc_addr *laddr)
0585 {
0586     static struct llc_addr null_addr;
0587     struct sock *rc = __llc_lookup_listener(sap, laddr);
0588 
0589     if (!rc)
0590         rc = __llc_lookup_listener(sap, &null_addr);
0591 
0592     return rc;
0593 }
0594 
0595 static struct sock *__llc_lookup(struct llc_sap *sap,
0596                  struct llc_addr *daddr,
0597                  struct llc_addr *laddr)
0598 {
0599     struct sock *sk = __llc_lookup_established(sap, daddr, laddr);
0600 
0601     return sk ? : llc_lookup_listener(sap, laddr);
0602 }
0603 
0604 /**
0605  *  llc_data_accept_state - designates if in this state data can be sent.
0606  *  @state: state of connection.
0607  *
0608  *  Returns 0 if data can be sent, 1 otherwise.
0609  */
0610 u8 llc_data_accept_state(u8 state)
0611 {
0612     return state != LLC_CONN_STATE_NORMAL && state != LLC_CONN_STATE_BUSY &&
0613            state != LLC_CONN_STATE_REJ;
0614 }
0615 
0616 /**
0617  *  llc_find_next_offset - finds offset for next category of transitions
0618  *  @state: state table.
0619  *  @offset: start offset.
0620  *
0621  *  Finds offset of next category of transitions in transition table.
0622  *  Returns the start index of next category.
0623  */
0624 static u16 __init llc_find_next_offset(struct llc_conn_state *state, u16 offset)
0625 {
0626     u16 cnt = 0;
0627     struct llc_conn_state_trans **next_trans;
0628 
0629     for (next_trans = state->transitions + offset;
0630          (*next_trans)->ev; next_trans++)
0631         ++cnt;
0632     return cnt;
0633 }
0634 
0635 /**
0636  *  llc_build_offset_table - builds offset table of connection
0637  *
0638  *  Fills offset table of connection state transition table
0639  *  (llc_offset_table).
0640  */
0641 void __init llc_build_offset_table(void)
0642 {
0643     struct llc_conn_state *curr_state;
0644     int state, ev_type, next_offset;
0645 
0646     for (state = 0; state < NBR_CONN_STATES; state++) {
0647         curr_state = &llc_conn_state_table[state];
0648         next_offset = 0;
0649         for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) {
0650             llc_offset_table[state][ev_type] = next_offset;
0651             next_offset += llc_find_next_offset(curr_state,
0652                                 next_offset) + 1;
0653         }
0654     }
0655 }
0656 
0657 /**
0658  *  llc_find_offset - finds start offset of category of transitions
0659  *  @state: state of connection
0660  *  @ev_type: type of happened event
0661  *
0662  *  Finds start offset of desired category of transitions. Returns the
0663  *  desired start offset.
0664  */
0665 static int llc_find_offset(int state, int ev_type)
0666 {
0667     int rc = 0;
0668     /* at this stage, llc_offset_table[..][2] is not important. it is for
0669      * init_pf_cycle and I don't know what is it.
0670      */
0671     switch (ev_type) {
0672     case LLC_CONN_EV_TYPE_PRIM:
0673         rc = llc_offset_table[state][0]; break;
0674     case LLC_CONN_EV_TYPE_PDU:
0675         rc = llc_offset_table[state][4]; break;
0676     case LLC_CONN_EV_TYPE_SIMPLE:
0677         rc = llc_offset_table[state][1]; break;
0678     case LLC_CONN_EV_TYPE_P_TMR:
0679     case LLC_CONN_EV_TYPE_ACK_TMR:
0680     case LLC_CONN_EV_TYPE_REJ_TMR:
0681     case LLC_CONN_EV_TYPE_BUSY_TMR:
0682         rc = llc_offset_table[state][3]; break;
0683     }
0684     return rc;
0685 }
0686 
0687 /**
0688  *  llc_sap_add_socket - adds a socket to a SAP
0689  *  @sap: SAP
0690  *  @sk: socket
0691  *
0692  *  This function adds a socket to the hash tables of a SAP.
0693  */
0694 void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk)
0695 {
0696     struct llc_sock *llc = llc_sk(sk);
0697     struct hlist_head *dev_hb = llc_sk_dev_hash(sap, llc->dev->ifindex);
0698     struct hlist_nulls_head *laddr_hb = llc_sk_laddr_hash(sap, &llc->laddr);
0699 
0700     llc_sap_hold(sap);
0701     llc_sk(sk)->sap = sap;
0702 
0703     spin_lock_bh(&sap->sk_lock);
0704     sock_set_flag(sk, SOCK_RCU_FREE);
0705     sap->sk_count++;
0706     sk_nulls_add_node_rcu(sk, laddr_hb);
0707     hlist_add_head(&llc->dev_hash_node, dev_hb);
0708     spin_unlock_bh(&sap->sk_lock);
0709 }
0710 
0711 /**
0712  *  llc_sap_remove_socket - removes a socket from SAP
0713  *  @sap: SAP
0714  *  @sk: socket
0715  *
0716  *  This function removes a connection from the hash tables of a SAP if
0717  *  the connection was in this list.
0718  */
0719 void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
0720 {
0721     struct llc_sock *llc = llc_sk(sk);
0722 
0723     spin_lock_bh(&sap->sk_lock);
0724     sk_nulls_del_node_init_rcu(sk);
0725     hlist_del(&llc->dev_hash_node);
0726     sap->sk_count--;
0727     spin_unlock_bh(&sap->sk_lock);
0728     llc_sap_put(sap);
0729 }
0730 
0731 /**
0732  *  llc_conn_rcv - sends received pdus to the connection state machine
0733  *  @sk: current connection structure.
0734  *  @skb: received frame.
0735  *
0736  *  Sends received pdus to the connection state machine.
0737  */
0738 static int llc_conn_rcv(struct sock *sk, struct sk_buff *skb)
0739 {
0740     struct llc_conn_state_ev *ev = llc_conn_ev(skb);
0741 
0742     ev->type   = LLC_CONN_EV_TYPE_PDU;
0743     ev->reason = 0;
0744     return llc_conn_state_process(sk, skb);
0745 }
0746 
0747 static struct sock *llc_create_incoming_sock(struct sock *sk,
0748                          struct net_device *dev,
0749                          struct llc_addr *saddr,
0750                          struct llc_addr *daddr)
0751 {
0752     struct sock *newsk = llc_sk_alloc(sock_net(sk), sk->sk_family, GFP_ATOMIC,
0753                       sk->sk_prot, 0);
0754     struct llc_sock *newllc, *llc = llc_sk(sk);
0755 
0756     if (!newsk)
0757         goto out;
0758     newllc = llc_sk(newsk);
0759     memcpy(&newllc->laddr, daddr, sizeof(newllc->laddr));
0760     memcpy(&newllc->daddr, saddr, sizeof(newllc->daddr));
0761     newllc->dev = dev;
0762     dev_hold(dev);
0763     llc_sap_add_socket(llc->sap, newsk);
0764     llc_sap_hold(llc->sap);
0765 out:
0766     return newsk;
0767 }
0768 
0769 void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
0770 {
0771     struct llc_addr saddr, daddr;
0772     struct sock *sk;
0773 
0774     llc_pdu_decode_sa(skb, saddr.mac);
0775     llc_pdu_decode_ssap(skb, &saddr.lsap);
0776     llc_pdu_decode_da(skb, daddr.mac);
0777     llc_pdu_decode_dsap(skb, &daddr.lsap);
0778 
0779     sk = __llc_lookup(sap, &saddr, &daddr);
0780     if (!sk)
0781         goto drop;
0782 
0783     bh_lock_sock(sk);
0784     /*
0785      * This has to be done here and not at the upper layer ->accept
0786      * method because of the way the PROCOM state machine works:
0787      * it needs to set several state variables (see, for instance,
0788      * llc_adm_actions_2 in net/llc/llc_c_st.c) and send a packet to
0789      * the originator of the new connection, and this state has to be
0790      * in the newly created struct sock private area. -acme
0791      */
0792     if (unlikely(sk->sk_state == TCP_LISTEN)) {
0793         struct sock *newsk = llc_create_incoming_sock(sk, skb->dev,
0794                                   &saddr, &daddr);
0795         if (!newsk)
0796             goto drop_unlock;
0797         skb_set_owner_r(skb, newsk);
0798     } else {
0799         /*
0800          * Can't be skb_set_owner_r, this will be done at the
0801          * llc_conn_state_process function, later on, when we will use
0802          * skb_queue_rcv_skb to send it to upper layers, this is
0803          * another trick required to cope with how the PROCOM state
0804          * machine works. -acme
0805          */
0806         skb_orphan(skb);
0807         sock_hold(sk);
0808         skb->sk = sk;
0809         skb->destructor = sock_efree;
0810     }
0811     if (!sock_owned_by_user(sk))
0812         llc_conn_rcv(sk, skb);
0813     else {
0814         dprintk("%s: adding to backlog...\n", __func__);
0815         llc_set_backlog_type(skb, LLC_PACKET);
0816         if (sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf)))
0817             goto drop_unlock;
0818     }
0819 out:
0820     bh_unlock_sock(sk);
0821     sock_put(sk);
0822     return;
0823 drop:
0824     kfree_skb(skb);
0825     return;
0826 drop_unlock:
0827     kfree_skb(skb);
0828     goto out;
0829 }
0830 
0831 #undef LLC_REFCNT_DEBUG
0832 #ifdef LLC_REFCNT_DEBUG
0833 static atomic_t llc_sock_nr;
0834 #endif
0835 
0836 /**
0837  *  llc_backlog_rcv - Processes rx frames and expired timers.
0838  *  @sk: LLC sock (p8022 connection)
0839  *  @skb: queued rx frame or event
0840  *
0841  *  This function processes frames that has received and timers that has
0842  *  expired during sending an I pdu (refer to data_req_handler).  frames
0843  *  queue by llc_rcv function (llc_mac.c) and timers queue by timer
0844  *  callback functions(llc_c_ac.c).
0845  */
0846 static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
0847 {
0848     int rc = 0;
0849     struct llc_sock *llc = llc_sk(sk);
0850 
0851     if (likely(llc_backlog_type(skb) == LLC_PACKET)) {
0852         if (likely(llc->state > 1)) /* not closed */
0853             rc = llc_conn_rcv(sk, skb);
0854         else
0855             goto out_kfree_skb;
0856     } else if (llc_backlog_type(skb) == LLC_EVENT) {
0857         /* timer expiration event */
0858         if (likely(llc->state > 1))  /* not closed */
0859             rc = llc_conn_state_process(sk, skb);
0860         else
0861             goto out_kfree_skb;
0862     } else {
0863         printk(KERN_ERR "%s: invalid skb in backlog\n", __func__);
0864         goto out_kfree_skb;
0865     }
0866 out:
0867     return rc;
0868 out_kfree_skb:
0869     kfree_skb(skb);
0870     goto out;
0871 }
0872 
0873 /**
0874  *     llc_sk_init - Initializes a socket with default llc values.
0875  *     @sk: socket to initialize.
0876  *
0877  *     Initializes a socket with default llc values.
0878  */
0879 static void llc_sk_init(struct sock *sk)
0880 {
0881     struct llc_sock *llc = llc_sk(sk);
0882 
0883     llc->state    = LLC_CONN_STATE_ADM;
0884     llc->inc_cntr = llc->dec_cntr = 2;
0885     llc->dec_step = llc->connect_step = 1;
0886 
0887     timer_setup(&llc->ack_timer.timer, llc_conn_ack_tmr_cb, 0);
0888     llc->ack_timer.expire         = sysctl_llc2_ack_timeout;
0889 
0890     timer_setup(&llc->pf_cycle_timer.timer, llc_conn_pf_cycle_tmr_cb, 0);
0891     llc->pf_cycle_timer.expire     = sysctl_llc2_p_timeout;
0892 
0893     timer_setup(&llc->rej_sent_timer.timer, llc_conn_rej_tmr_cb, 0);
0894     llc->rej_sent_timer.expire     = sysctl_llc2_rej_timeout;
0895 
0896     timer_setup(&llc->busy_state_timer.timer, llc_conn_busy_tmr_cb, 0);
0897     llc->busy_state_timer.expire         = sysctl_llc2_busy_timeout;
0898 
0899     llc->n2 = 2;   /* max retransmit */
0900     llc->k  = 2;   /* tx win size, will adjust dynam */
0901     llc->rw = 128; /* rx win size (opt and equal to
0902             * tx_win of remote LLC) */
0903     skb_queue_head_init(&llc->pdu_unack_q);
0904     sk->sk_backlog_rcv = llc_backlog_rcv;
0905 }
0906 
0907 /**
0908  *  llc_sk_alloc - Allocates LLC sock
0909  *  @net: network namespace
0910  *  @family: upper layer protocol family
0911  *  @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
0912  *  @prot: struct proto associated with this new sock instance
0913  *  @kern: is this to be a kernel socket?
0914  *
0915  *  Allocates a LLC sock and initializes it. Returns the new LLC sock
0916  *  or %NULL if there's no memory available for one
0917  */
0918 struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot, int kern)
0919 {
0920     struct sock *sk = sk_alloc(net, family, priority, prot, kern);
0921 
0922     if (!sk)
0923         goto out;
0924     llc_sk_init(sk);
0925     sock_init_data(NULL, sk);
0926 #ifdef LLC_REFCNT_DEBUG
0927     atomic_inc(&llc_sock_nr);
0928     printk(KERN_DEBUG "LLC socket %p created in %s, now we have %d alive\n", sk,
0929         __func__, atomic_read(&llc_sock_nr));
0930 #endif
0931 out:
0932     return sk;
0933 }
0934 
0935 void llc_sk_stop_all_timers(struct sock *sk, bool sync)
0936 {
0937     struct llc_sock *llc = llc_sk(sk);
0938 
0939     if (sync) {
0940         del_timer_sync(&llc->pf_cycle_timer.timer);
0941         del_timer_sync(&llc->ack_timer.timer);
0942         del_timer_sync(&llc->rej_sent_timer.timer);
0943         del_timer_sync(&llc->busy_state_timer.timer);
0944     } else {
0945         del_timer(&llc->pf_cycle_timer.timer);
0946         del_timer(&llc->ack_timer.timer);
0947         del_timer(&llc->rej_sent_timer.timer);
0948         del_timer(&llc->busy_state_timer.timer);
0949     }
0950 
0951     llc->ack_must_be_send = 0;
0952     llc->ack_pf = 0;
0953 }
0954 
0955 /**
0956  *  llc_sk_free - Frees a LLC socket
0957  *  @sk: - socket to free
0958  *
0959  *  Frees a LLC socket
0960  */
0961 void llc_sk_free(struct sock *sk)
0962 {
0963     struct llc_sock *llc = llc_sk(sk);
0964 
0965     llc->state = LLC_CONN_OUT_OF_SVC;
0966     /* Stop all (possibly) running timers */
0967     llc_sk_stop_all_timers(sk, true);
0968 #ifdef DEBUG_LLC_CONN_ALLOC
0969     printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __func__,
0970         skb_queue_len(&llc->pdu_unack_q),
0971         skb_queue_len(&sk->sk_write_queue));
0972 #endif
0973     skb_queue_purge(&sk->sk_receive_queue);
0974     skb_queue_purge(&sk->sk_write_queue);
0975     skb_queue_purge(&llc->pdu_unack_q);
0976 #ifdef LLC_REFCNT_DEBUG
0977     if (refcount_read(&sk->sk_refcnt) != 1) {
0978         printk(KERN_DEBUG "Destruction of LLC sock %p delayed in %s, cnt=%d\n",
0979             sk, __func__, refcount_read(&sk->sk_refcnt));
0980         printk(KERN_DEBUG "%d LLC sockets are still alive\n",
0981             atomic_read(&llc_sock_nr));
0982     } else {
0983         atomic_dec(&llc_sock_nr);
0984         printk(KERN_DEBUG "LLC socket %p released in %s, %d are still alive\n", sk,
0985             __func__, atomic_read(&llc_sock_nr));
0986     }
0987 #endif
0988     sock_put(sk);
0989 }
0990 
0991 /**
0992  *  llc_sk_reset - resets a connection
0993  *  @sk: LLC socket to reset
0994  *
0995  *  Resets a connection to the out of service state. Stops its timers
0996  *  and frees any frames in the queues of the connection.
0997  */
0998 void llc_sk_reset(struct sock *sk)
0999 {
1000     struct llc_sock *llc = llc_sk(sk);
1001 
1002     llc_conn_ac_stop_all_timers(sk, NULL);
1003     skb_queue_purge(&sk->sk_write_queue);
1004     skb_queue_purge(&llc->pdu_unack_q);
1005     llc->remote_busy_flag   = 0;
1006     llc->cause_flag     = 0;
1007     llc->retry_count    = 0;
1008     llc_conn_set_p_flag(sk, 0);
1009     llc->f_flag     = 0;
1010     llc->s_flag     = 0;
1011     llc->ack_pf     = 0;
1012     llc->first_pdu_Ns   = 0;
1013     llc->ack_must_be_send   = 0;
1014     llc->dec_step       = 1;
1015     llc->inc_cntr       = 2;
1016     llc->dec_cntr       = 2;
1017     llc->X          = 0;
1018     llc->failed_data_req    = 0 ;
1019     llc->last_nr        = 0;
1020 }