This source file includes following definitions.
- llc_build_and_send_pkt
- llc_establish_connection
- llc_send_disc
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <linux/gfp.h>
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/netdevice.h>
18 #include <linux/errno.h>
19 #include <net/llc_if.h>
20 #include <net/llc_sap.h>
21 #include <net/llc_s_ev.h>
22 #include <net/llc_conn.h>
23 #include <net/sock.h>
24 #include <net/llc_c_ev.h>
25 #include <net/llc_c_ac.h>
26 #include <net/llc_c_st.h>
27 #include <net/tcp_states.h>
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
45 {
46 struct llc_conn_state_ev *ev;
47 int rc = -ECONNABORTED;
48 struct llc_sock *llc = llc_sk(sk);
49
50 if (unlikely(llc->state == LLC_CONN_STATE_ADM))
51 goto out_free;
52 rc = -EBUSY;
53 if (unlikely(llc_data_accept_state(llc->state) ||
54 llc->p_flag)) {
55 llc->failed_data_req = 1;
56 goto out_free;
57 }
58 ev = llc_conn_ev(skb);
59 ev->type = LLC_CONN_EV_TYPE_PRIM;
60 ev->prim = LLC_DATA_PRIM;
61 ev->prim_type = LLC_PRIM_TYPE_REQ;
62 skb->dev = llc->dev;
63 return llc_conn_state_process(sk, skb);
64
65 out_free:
66 kfree_skb(skb);
67 return rc;
68 }
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
84 {
85 int rc = -EISCONN;
86 struct llc_addr laddr, daddr;
87 struct sk_buff *skb;
88 struct llc_sock *llc = llc_sk(sk);
89 struct sock *existing;
90
91 laddr.lsap = llc->sap->laddr.lsap;
92 daddr.lsap = dsap;
93 memcpy(daddr.mac, dmac, sizeof(daddr.mac));
94 memcpy(laddr.mac, lmac, sizeof(laddr.mac));
95 existing = llc_lookup_established(llc->sap, &daddr, &laddr);
96 if (existing) {
97 if (existing->sk_state == TCP_ESTABLISHED) {
98 sk = existing;
99 goto out_put;
100 } else
101 sock_put(existing);
102 }
103 sock_hold(sk);
104 rc = -ENOMEM;
105 skb = alloc_skb(0, GFP_ATOMIC);
106 if (skb) {
107 struct llc_conn_state_ev *ev = llc_conn_ev(skb);
108
109 ev->type = LLC_CONN_EV_TYPE_PRIM;
110 ev->prim = LLC_CONN_PRIM;
111 ev->prim_type = LLC_PRIM_TYPE_REQ;
112 skb_set_owner_w(skb, sk);
113 rc = llc_conn_state_process(sk, skb);
114 }
115 out_put:
116 sock_put(sk);
117 return rc;
118 }
119
120
121
122
123
124
125
126
127
128
129 int llc_send_disc(struct sock *sk)
130 {
131 u16 rc = 1;
132 struct llc_conn_state_ev *ev;
133 struct sk_buff *skb;
134
135 sock_hold(sk);
136 if (sk->sk_type != SOCK_STREAM || sk->sk_state != TCP_ESTABLISHED ||
137 llc_sk(sk)->state == LLC_CONN_STATE_ADM ||
138 llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC)
139 goto out;
140
141
142
143
144 skb = alloc_skb(0, GFP_ATOMIC);
145 if (!skb)
146 goto out;
147 skb_set_owner_w(skb, sk);
148 sk->sk_state = TCP_CLOSING;
149 ev = llc_conn_ev(skb);
150 ev->type = LLC_CONN_EV_TYPE_PRIM;
151 ev->prim = LLC_DISC_PRIM;
152 ev->prim_type = LLC_PRIM_TYPE_REQ;
153 rc = llc_conn_state_process(sk, skb);
154 out:
155 sock_put(sk);
156 return rc;
157 }