16 #include <linux/slab.h>
27 #define dprintk(args...) printk(KERN_DEBUG args)
29 #define dprintk(args...)
32 static int llc_find_offset(
int state,
int ev_type);
33 static void llc_conn_send_pdus(
struct sock *
sk);
35 static int llc_exec_conn_trans_actions(
struct sock *
sk,
75 rc = llc_conn_service(skb->
sk, skb);
200 llc_conn_send_pdus(sk);
235 u8 howmany_resend = 0;
247 pdu = llc_pdu_sn_hdr(skb);
255 if (howmany_resend > 0)
258 llc_conn_send_pdus(sk);
277 u8 howmany_resend = 0;
296 if (howmany_resend > 0)
299 llc_conn_send_pdus(sk);
324 pdu = llc_pdu_sn_hdr(skb);
330 for (i = 0; i < pdu_pos && i <
q_len; i++) {
336 *how_many_unacked = skb_queue_len(&llc->
pdu_unack_q);
346 static void llc_conn_send_pdus(
struct sock *
sk)
375 static int llc_conn_service(
struct sock *sk,
struct sk_buff *skb)
384 trans = llc_qualify_conn_ev(sk, skb);
386 rc = llc_exec_conn_trans_actions(sk, trans, skb);
419 llc_find_offset(llc->
state - 1, ev->
type);
420 (*next_trans)->ev; next_trans++) {
421 if (!((*next_trans)->ev)(sk, skb)) {
428 for (next_qualifier = (*next_trans)->ev_qualifiers;
429 next_qualifier && *next_qualifier &&
430 !(*next_qualifier)(sk, skb); next_qualifier++)
432 if (!next_qualifier || !*next_qualifier)
452 static int llc_exec_conn_trans_actions(
struct sock *sk,
460 next_action && *next_action; next_action++) {
461 int rc2 = (*next_action)(
sk,
skb);
472 static inline bool llc_estab_match(
const struct llc_sap *sap,
475 const struct sock *sk)
481 llc_mac_match(llc->
laddr.mac, laddr->
mac) &&
482 llc_mac_match(llc->
daddr.mac, daddr->
mac);
496 static struct sock *__llc_lookup_established(
struct llc_sap *sap,
502 int slot = llc_sk_laddr_hashfn(sap, laddr);
508 if (llc_estab_match(sap, daddr, laddr, rc)) {
512 if (
unlikely(llc_sk(rc)->sap != sap ||
513 !llc_estab_match(sap, daddr, laddr, rc))) {
526 if (
unlikely(get_nulls_value(node) != slot))
540 sk = __llc_lookup_established(sap, daddr, laddr);
545 static inline bool llc_listener_match(
const struct llc_sap *sap,
547 const struct sock *sk)
553 llc_mac_match(llc->
laddr.mac, laddr->
mac);
556 static struct sock *__llc_lookup_listener(
struct llc_sap *sap,
561 int slot = llc_sk_laddr_hashfn(sap, laddr);
567 if (llc_listener_match(sap, laddr, rc)) {
571 if (
unlikely(llc_sk(rc)->sap != sap ||
572 !llc_listener_match(sap, laddr, rc))) {
585 if (
unlikely(get_nulls_value(node) != slot))
602 static struct sock *llc_lookup_listener(
struct llc_sap *sap,
606 struct sock *rc = __llc_lookup_listener(sap, laddr);
609 rc = __llc_lookup_listener(sap, &
null_addr);
614 static struct sock *__llc_lookup(
struct llc_sap *sap,
618 struct sock *sk = __llc_lookup_established(sap, daddr, laddr);
620 return sk ? : llc_lookup_listener(sap, laddr);
649 (*next_trans)->ev; next_trans++)
663 int state, ev_type, next_offset;
668 for (ev_type = 0; ev_type <
NBR_CONN_EV; ev_type++) {
669 llc_offset_table[
state][ev_type] = next_offset;
670 next_offset += llc_find_next_offset(curr_state,
684 static int llc_find_offset(
int state,
int ev_type)
692 rc = llc_offset_table[
state][0];
break;
694 rc = llc_offset_table[
state][4];
break;
696 rc = llc_offset_table[
state][1];
break;
701 rc = llc_offset_table[
state][3];
break;
716 struct hlist_head *dev_hb = llc_sk_dev_hash(sap, llc->
dev->ifindex);
720 llc_sk(sk)->sap = sap;
724 sk_nulls_add_node_rcu(sk, laddr_hb);
742 sk_nulls_del_node_init_rcu(sk);
756 static int llc_conn_rcv(
struct sock* sk,
struct sk_buff *skb)
765 static struct sock *llc_create_incoming_sock(
struct sock *sk,
772 struct llc_sock *newllc, *llc = llc_sk(sk);
776 newllc = llc_sk(newsk);
782 llc_sap_hold(llc->
sap);
792 llc_pdu_decode_sa(skb, saddr.
mac);
793 llc_pdu_decode_ssap(skb, &saddr.
lsap);
794 llc_pdu_decode_da(skb, daddr.
mac);
795 llc_pdu_decode_dsap(skb, &daddr.
lsap);
797 sk = __llc_lookup(sap, &saddr, &daddr);
811 struct sock *newsk = llc_create_incoming_sock(sk, skb->
dev,
815 skb_set_owner_r(skb, newsk);
827 llc_conn_rcv(sk, skb);
829 dprintk(
"%s: adding to backlog...\n", __func__);
831 if (sk_add_backlog(sk, skb, sk->
sk_rcvbuf))
846 #undef LLC_REFCNT_DEBUG
847 #ifdef LLC_REFCNT_DEBUG
861 static int llc_backlog_rcv(
struct sock *sk,
struct sk_buff *skb)
868 rc = llc_conn_rcv(sk, skb);
871 }
else if (llc_backlog_type(skb) ==
LLC_EVENT) {
894 static void llc_sk_init(
struct sock* sk)
936 struct sock *sk =
sk_alloc(net, family, priority, prot);
942 #ifdef LLC_REFCNT_DEBUG
944 printk(
KERN_DEBUG "LLC socket %p created in %s, now we have %d alive\n", sk,
964 #ifdef DEBUG_LLC_CONN_ALLOC
972 #ifdef LLC_REFCNT_DEBUG