diff options
| author | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 2002-09-11 07:38:34 -0300 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 2002-09-11 07:38:34 -0300 |
| commit | c3be6700f35fdcf9f81a0d46f6472e9952f15229 (patch) | |
| tree | ec92abb0bd5f97eb8500f569db419068d57a037a | |
| parent | c34311f78b8bf3b79380c6e2f8d9b3c143357d5e (diff) | |
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 :-)
| -rw-r--r-- | include/net/llc_if.h | 9 | ||||
| -rw-r--r-- | net/llc/llc_c_ac.c | 20 | ||||
| -rw-r--r-- | net/llc/llc_conn.c | 66 | ||||
| -rw-r--r-- | net/llc/llc_mac.c | 1 | ||||
| -rw-r--r-- | net/llc/llc_sock.c | 61 |
5 files changed, 50 insertions, 107 deletions
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 @@ -1424,44 +1424,6 @@ 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: @@ -1554,21 +1518,6 @@ 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; |
