0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
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
0051
0052
0053
0054
0055
0056
0057
0058
0059
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
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
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
0093
0094
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
0117
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
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
0161
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
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
0180 skb_queue_tail(&sk->sk_write_queue, skb);
0181 llc_conn_send_pdus(sk);
0182 }
0183
0184
0185
0186
0187
0188
0189
0190
0191
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
0202
0203
0204
0205
0206
0207
0208
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
0223
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
0239 llc_conn_send_pdus(sk);
0240 out:;
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
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
0265
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
0280 llc_conn_send_pdus(sk);
0281 out:;
0282 }
0283
0284
0285
0286
0287
0288
0289
0290
0291
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
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
0323
0324
0325
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
0349
0350
0351
0352
0353
0354
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
0380
0381
0382
0383
0384
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
0397
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
0404
0405
0406
0407
0408
0409 for (next_qualifier = (*next_trans)->ev_qualifiers;
0410 next_qualifier && *next_qualifier &&
0411 !(*next_qualifier)(sk, skb); next_qualifier++)
0412 ;
0413 if (!next_qualifier || !*next_qualifier)
0414
0415
0416
0417
0418 return *next_trans;
0419 }
0420 }
0421 return NULL;
0422 }
0423
0424
0425
0426
0427
0428
0429
0430
0431
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
0468
0469
0470
0471
0472
0473
0474
0475
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
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
0504
0505
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
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
0563
0564
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
0575
0576
0577
0578
0579
0580
0581
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
0606
0607
0608
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
0618
0619
0620
0621
0622
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
0637
0638
0639
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
0659
0660
0661
0662
0663
0664
0665 static int llc_find_offset(int state, int ev_type)
0666 {
0667 int rc = 0;
0668
0669
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
0689
0690
0691
0692
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
0713
0714
0715
0716
0717
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
0733
0734
0735
0736
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
0786
0787
0788
0789
0790
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
0801
0802
0803
0804
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
0838
0839
0840
0841
0842
0843
0844
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))
0853 rc = llc_conn_rcv(sk, skb);
0854 else
0855 goto out_kfree_skb;
0856 } else if (llc_backlog_type(skb) == LLC_EVENT) {
0857
0858 if (likely(llc->state > 1))
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
0875
0876
0877
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;
0900 llc->k = 2;
0901 llc->rw = 128;
0902
0903 skb_queue_head_init(&llc->pdu_unack_q);
0904 sk->sk_backlog_rcv = llc_backlog_rcv;
0905 }
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
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
0957
0958
0959
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
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
0993
0994
0995
0996
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 }