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 :-)
parent c34311f7
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
}
/**
......
......@@ -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,
......
......@@ -1423,44 +1423,6 @@ static void llc_ui_ind_conn(struct llc_prim_if_block *prim)
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:
......@@ -1553,21 +1517,6 @@ static void llc_ui_conf_conn(struct llc_prim_if_block *prim)
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment