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 { ...@@ -97,14 +97,6 @@ struct llc_prim_flow_ctrl {
u32 amount; 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 */ /* Sending data in conection-less mode */
struct llc_prim_unit_data { struct llc_prim_unit_data {
struct llc_addr saddr; struct llc_addr saddr;
...@@ -133,7 +125,6 @@ union llc_u_prim_data { ...@@ -133,7 +125,6 @@ union llc_u_prim_data {
struct llc_prim_disc disc; struct llc_prim_disc disc;
struct llc_prim_reset res; struct llc_prim_reset res;
struct llc_prim_flow_ctrl fc; struct llc_prim_flow_ctrl fc;
struct llc_prim_data data; /* data */
struct llc_prim_unit_data udata; /* unit data */ struct llc_prim_unit_data udata; /* unit data */
struct llc_prim_xid xid; struct llc_prim_xid xid;
struct llc_prim_test test; struct llc_prim_test test;
......
...@@ -112,21 +112,13 @@ int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb) ...@@ -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) 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_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; * FIXME: find better way to tell upper layer that the packet was
prim_data->data.link = llc->link; * confirmed by the other endpoint
prim_data->data.status = LLC_STATUS_RECEIVED; */
prim_data->data.skb = NULL; ev->flag = LLC_DATA_PRIM + 1;
prim->data = prim_data; ev->cfm_prim = (void *)1;
prim->prim = LLC_DATA_PRIM;
prim->sap = sap;
ev->flag = 1;
ev->cfm_prim = prim;
return 0; return 0;
} }
......
...@@ -58,7 +58,13 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) ...@@ -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 *ind_prim = ev->ind_prim;
struct llc_prim_if_block *cfm_prim = ev->cfm_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 #ifdef THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY
/* check if the connection was freed by the state machine by /* check if the connection was freed by the state machine by
* means of llc_conn_disc */ * means of llc_conn_disc */
...@@ -71,25 +77,41 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) ...@@ -71,25 +77,41 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
if (!flag) /* indicate or confirm not required */ if (!flag) /* indicate or confirm not required */
goto out; goto out;
rc = 0; rc = 0;
if (ind_prim) /* indication required */ if (ind_prim) { /* indication required */
llc->sap->ind(ind_prim); /*
* 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 */ if (!cfm_prim) /* confirmation not required */
goto out; goto out;
/* data confirm has preconditions */ /* 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); llc->sap->conf(cfm_prim);
goto out; goto out;
} }
if (!llc_data_accept_state(llc->state)) { if (!llc_data_accept_state(llc->state)) {
/* In this state, we can send I pdu */ /* In this state, we can send I pdu */
/* FIXME: check if we don't need to see if sk->lock.users != 0 struct sock* upper = llc_sk(skb->sk)->handler;
* is needed here
*/ if (upper)
rc = llc->sap->conf(cfm_prim); wake_up(upper->sleep);
if (rc) /* confirmation didn't accept by upper layer */
llc->failed_data_req = 1;
} else } else
llc->failed_data_req = 1; rc = llc->failed_data_req = 1;
kfree_skb(skb);
out: out:
return rc; return rc;
} }
...@@ -114,24 +136,10 @@ void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb) ...@@ -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) void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb)
{ {
struct llc_conn_state_ev *ev = llc_conn_ev(skb); struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
struct llc_sap *sap = llc->sap; /* FIXME: indicate that we should send this to the upper layer */
struct llc_prim_if_block *prim = &sap->llc_ind_prim; ev->flag = LLC_DATA_PRIM + 1;
union llc_u_prim_data *prim_data = prim->data; ev->ind_prim = (void *)1;
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;
} }
/** /**
......
...@@ -133,6 +133,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -133,6 +133,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
llc_sap_assign_sock(sap, sk); llc_sap_assign_sock(sap, sk);
sock_hold(sk); sock_hold(sk);
} }
skb->sk = sk;
bh_lock_sock(sk); bh_lock_sock(sk);
if (!sk->lock.users) if (!sk->lock.users)
rc = llc_pdu_router(llc_sk(sk)->sap, sk, skb, 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) ...@@ -1423,44 +1423,6 @@ static void llc_ui_ind_conn(struct llc_prim_if_block *prim)
out:; 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 * llc_ui_ind_disc - handle DISC indication
* @prim: Primitive block provided by the llc layer. * @prim: Primitive block provided by the llc layer.
...@@ -1510,7 +1472,9 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim) ...@@ -1510,7 +1472,9 @@ static int llc_ui_indicate(struct llc_prim_if_block *prim)
case LLC_CONN_PRIM: case LLC_CONN_PRIM:
llc_ui_ind_conn(prim); break; llc_ui_ind_conn(prim); break;
case LLC_DATA_PRIM: 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: case LLC_DISC_PRIM:
llc_ui_ind_disc(prim); break; llc_ui_ind_disc(prim); break;
case LLC_RESET_PRIM: case LLC_RESET_PRIM:
...@@ -1553,21 +1517,6 @@ static void llc_ui_conf_conn(struct llc_prim_if_block *prim) ...@@ -1553,21 +1517,6 @@ static void llc_ui_conf_conn(struct llc_prim_if_block *prim)
out:; 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. * llc_ui_conf_disc - handle DISC confirm.
* @prim: Primitive block provided by the llc layer. * @prim: Primitive block provided by the llc layer.
...@@ -1607,7 +1556,9 @@ static int llc_ui_confirm(struct llc_prim_if_block *prim) ...@@ -1607,7 +1556,9 @@ static int llc_ui_confirm(struct llc_prim_if_block *prim)
case LLC_CONN_PRIM: case LLC_CONN_PRIM:
llc_ui_conf_conn(prim); break; llc_ui_conf_conn(prim); break;
case LLC_DATA_PRIM: 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: case LLC_DISC_PRIM:
llc_ui_conf_disc(prim); break; llc_ui_conf_disc(prim); break;
case LLC_RESET_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