summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2002-09-30 00:05:51 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2002-09-30 00:05:51 -0700
commit4e87a098903d4de48f6b43f6a5d52c59b3bbeb6e (patch)
tree5c363e21ae28f4021cf8f2a48fae815e9bfde987
parentf32a9e2a558d518a39f73d56a93529c2df1d4666 (diff)
parentc96542edd5bf18453a433ffb149c3cb8977f8a28 (diff)
Merge master.kernel.org:/home/acme/BK/llc-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
-rw-r--r--include/net/llc_conn.h1
-rw-r--r--include/net/llc_mac.h2
-rw-r--r--net/llc/af_llc.c7
-rw-r--r--net/llc/llc_c_ac.c2
-rw-r--r--net/llc/llc_conn.c81
-rw-r--r--net/llc/llc_if.c1
-rw-r--r--net/llc/llc_mac.c24
-rw-r--r--net/llc/llc_main.c12
-rw-r--r--net/llc/llc_pdu.c1
-rw-r--r--net/llc/llc_sap.c154
10 files changed, 124 insertions, 161 deletions
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
index b27ee7332c3b..3dd6d0b19f6b 100644
--- a/include/net/llc_conn.h
+++ b/include/net/llc_conn.h
@@ -79,7 +79,6 @@ extern int llc_sk_init(struct sock *sk);
extern int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
-extern void llc_conn_free_ev(struct sk_buff *skb);
extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr,
u8 first_p_bit);
extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr,
diff --git a/include/net/llc_mac.h b/include/net/llc_mac.h
index e87850701db6..ded7c830b8a8 100644
--- a/include/net/llc_mac.h
+++ b/include/net/llc_mac.h
@@ -13,8 +13,6 @@
*/
extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt);
-extern struct net_device *mac_dev_peer(struct net_device *current_dev,
- int type, u8 *mac);
extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da);
extern int llc_conn_rcv(struct sock *sk, struct sk_buff *skb);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index e55b54574499..2144915eee5b 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -569,6 +569,13 @@ static int llc_ui_wait_for_data(struct sock *sk, int timeout)
rc = -EAGAIN;
if (!timeout)
break;
+ /*
+ * Well, if we have backlog, try to process it now.
+ */
+ if (sk->backlog.tail) {
+ release_sock(sk);
+ lock_sock(sk);
+ }
rc = 0;
if (skb_queue_empty(&sk->receive_queue)) {
release_sock(sk);
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 856f39efae9a..2a96a6a6178d 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -1487,7 +1487,7 @@ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
printk(KERN_WARNING "%s: timer called on closed connection\n",
__FUNCTION__);
- llc_conn_free_ev(skb);
+ kfree_skb(skb);
} else {
if (!sk->lock.users)
llc_conn_state_process(sk, skb);
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index 161cff1c450b..e20cec698566 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -71,6 +71,12 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
struct llc_opt *llc = llc_sk(sk);
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
+ /*
+ * We have to hold the skb, because llc_conn_service will kfree it in
+ * the sending path and we need to look at the skb->cb, where we encode
+ * llc_conn_state_ev.
+ */
+ skb_get(skb);
ev->ind_prim = ev->cfm_prim = 0;
rc = llc_conn_service(sk, skb); /* sending event to state machine */
if (rc) {
@@ -81,10 +87,10 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
if (!ev->ind_prim && !ev->cfm_prim) { /* indicate or confirm not required */
if (!skb->list)
goto out_kfree_skb;
- goto out;
+ goto out_skb_put;
}
- if (ev->ind_prim && ev->cfm_prim)
+ if (ev->ind_prim && ev->cfm_prim) /* Paranoia */
skb_get(skb);
switch (ev->ind_prim) {
@@ -180,11 +186,12 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
__FUNCTION__, ev->cfm_prim);
break;
}
- goto out; /* No confirmation */
+ goto out_skb_put; /* No confirmation */
}
out_kfree_skb:
kfree_skb(skb);
-out:
+out_skb_put:
+ kfree_skb(skb);
return rc;
}
@@ -226,25 +233,29 @@ void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit)
struct sk_buff *skb;
struct llc_pdu_sn *pdu;
u16 nbr_unack_pdus;
+ struct llc_opt *llc;
u8 howmany_resend = 0;
llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus);
if (!nbr_unack_pdus)
goto out;
- /* process unack PDUs only if unack queue is not empty; remove
+ /*
+ * Process unack PDUs only if unack queue is not empty; remove
* appropriate PDUs, fix them up, and put them on mac_pdu_q.
*/
- while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) {
- pdu = (struct llc_pdu_sn *)skb->nh.raw;
+ llc = llc_sk(sk);
+
+ while ((skb = skb_dequeue(&llc->pdu_unack_q)) != NULL) {
+ pdu = llc_pdu_sn_hdr(skb);
llc_pdu_set_cmd_rsp(skb, LLC_PDU_CMD);
llc_pdu_set_pf_bit(skb, first_p_bit);
skb_queue_tail(&sk->write_queue, skb);
first_p_bit = 0;
- llc_sk(sk)->vS = LLC_I_GET_NS(pdu);
+ llc->vS = LLC_I_GET_NS(pdu);
howmany_resend++;
}
if (howmany_resend > 0)
- llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO;
+ llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
/* any PDUs to re-send are queued up; start sending to MAC */
llc_conn_send_pdus(sk);
out:;
@@ -263,27 +274,29 @@ out:;
void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit)
{
struct sk_buff *skb;
- struct llc_pdu_sn *pdu;
u16 nbr_unack_pdus;
+ struct llc_opt *llc = llc_sk(sk);
u8 howmany_resend = 0;
llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus);
if (!nbr_unack_pdus)
goto out;
- /* process unack PDUs only if unack queue is not empty; remove
+ /*
+ * Process unack PDUs only if unack queue is not empty; remove
* appropriate PDUs, fix them up, and put them on mac_pdu_q
*/
- while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) {
- pdu = (struct llc_pdu_sn *)skb->nh.raw;
+ while ((skb = skb_dequeue(&llc->pdu_unack_q)) != NULL) {
+ struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
+
llc_pdu_set_cmd_rsp(skb, LLC_PDU_RSP);
llc_pdu_set_pf_bit(skb, first_f_bit);
skb_queue_tail(&sk->write_queue, skb);
first_f_bit = 0;
- llc_sk(sk)->vS = LLC_I_GET_NS(pdu);
+ llc->vS = LLC_I_GET_NS(pdu);
howmany_resend++;
}
if (howmany_resend > 0)
- llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO;
+ llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
/* any PDUs to re-send are queued up; start sending to MAC */
llc_conn_send_pdus(sk);
out:;
@@ -304,25 +317,26 @@ int llc_conn_remove_acked_pdus(struct sock *sk, u8 nr, u16 *how_many_unacked)
struct sk_buff *skb;
struct llc_pdu_sn *pdu;
int nbr_acked = 0;
- int q_len = skb_queue_len(&llc_sk(sk)->pdu_unack_q);
+ struct llc_opt *llc = llc_sk(sk);
+ int q_len = skb_queue_len(&llc->pdu_unack_q);
if (!q_len)
goto out;
- skb = skb_peek(&llc_sk(sk)->pdu_unack_q);
- pdu = (struct llc_pdu_sn *)skb->nh.raw;
+ skb = skb_peek(&llc->pdu_unack_q);
+ pdu = llc_pdu_sn_hdr(skb);
/* finding position of last acked pdu in queue */
pdu_pos = ((int)LLC_2_SEQ_NBR_MODULO + (int)nr -
(int)LLC_I_GET_NS(pdu)) % LLC_2_SEQ_NBR_MODULO;
for (i = 0; i < pdu_pos && i < q_len; i++) {
- skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q);
+ skb = skb_dequeue(&llc->pdu_unack_q);
if (skb)
kfree_skb(skb);
nbr_acked++;
}
out:
- *how_many_unacked = skb_queue_len(&llc_sk(sk)->pdu_unack_q);
+ *how_many_unacked = skb_queue_len(&llc->pdu_unack_q);
return nbr_acked;
}
@@ -337,7 +351,7 @@ static void llc_conn_send_pdus(struct sock *sk)
struct sk_buff *skb;
while ((skb = skb_dequeue(&sk->write_queue)) != NULL) {
- struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
+ struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
if (!LLC_PDU_TYPE_IS_I(pdu) &&
!(skb->dev->flags & IFF_LOOPBACK)) {
@@ -353,31 +367,6 @@ static void llc_conn_send_pdus(struct sock *sk)
}
/**
- * llc_conn_free_ev - free event
- * @skb: event to free
- *
- * Free allocated event.
- */
-void llc_conn_free_ev(struct sk_buff *skb)
-{
- struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-
- if (ev->type == LLC_CONN_EV_TYPE_PDU) {
- /* free the frame that is bound to this event */
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
-
- if (LLC_PDU_TYPE_IS_I(pdu) || !ev->ind_prim)
- kfree_skb(skb);
- } else if (ev->type == LLC_CONN_EV_TYPE_PRIM &&
- ev->prim != LLC_DATA_PRIM)
- kfree_skb(skb);
- else if (ev->type == LLC_CONN_EV_TYPE_P_TMR ||
- ev->type == LLC_CONN_EV_TYPE_BUSY_TMR ||
- ev->type == LLC_CONN_EV_TYPE_REJ_TMR)
- kfree_skb(skb);
-}
-
-/**
* llc_conn_service - finds transition and changes state of connection
* @sk: connection
* @skb: happened event
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c
index ee1f20a51958..1f1d241732a6 100644
--- a/net/llc/llc_if.c
+++ b/net/llc/llc_if.c
@@ -26,7 +26,6 @@
#include <net/llc_c_ac.h>
#include <net/llc_c_st.h>
#include <net/llc_main.h>
-#include <net/llc_mac.h>
/**
* llc_sap_open - open interface to the upper layers.
diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c
index 7015d55ce748..ae97f73a607b 100644
--- a/net/llc/llc_mac.c
+++ b/net/llc/llc_mac.c
@@ -294,27 +294,3 @@ u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da)
}
return rc;
}
-
-/**
- * mac_dev_peer - search the appropriate dev to send packets to peer
- * @current_dev - Current device suggested by upper layer
- * @type - hardware type
- * @mac - mac address
- *
- * Check if the we should use loopback to send packets, i.e., if the
- * dmac belongs to one of the local interfaces, returning the pointer
- * to the loopback &net_device struct or the current_dev if it is not
- * local.
- */
-struct net_device *mac_dev_peer(struct net_device *current_dev, int type,
- u8 *mac)
-{
- struct net_device *dev;
-
- rtnl_lock();
- dev = dev_getbyhwaddr(type, mac);
- if (dev)
- dev = __dev_get_by_name("lo");
- rtnl_unlock();
- return dev ? : current_dev;
-}
diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c
index 044fce7207e7..f7b54e15882d 100644
--- a/net/llc/llc_main.c
+++ b/net/llc/llc_main.c
@@ -147,20 +147,22 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
if (llc->state > 1) /* not closed */
rc = llc_conn_rcv(sk, skb);
else
- kfree_skb(skb);
+ goto out_kfree_skb;
} else if (llc_backlog_type(skb) == LLC_EVENT) {
/* timer expiration event */
if (llc->state > 1) /* not closed */
rc = llc_conn_state_process(sk, skb);
else
- llc_conn_free_ev(skb);
- kfree_skb(skb);
+ goto out_kfree_skb;
} else {
printk(KERN_ERR "%s: invalid skb in backlog\n", __FUNCTION__);
- kfree_skb(skb);
+ goto out_kfree_skb;
}
-
+out:
return rc;
+out_kfree_skb:
+ kfree_skb(skb);
+ goto out;
}
/**
diff --git a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c
index 069ec96c9312..b5d047e9154f 100644
--- a/net/llc/llc_pdu.c
+++ b/net/llc/llc_pdu.c
@@ -15,7 +15,6 @@
#include <linux/if_tr.h>
#include <net/llc_pdu.h>
#include <net/llc_if.h>
-#include <net/llc_mac.h>
#include <net/llc_main.h>
static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type);
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 28ae6a659658..7cd6bb115a8b 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -20,17 +20,9 @@
#include <net/sock.h>
#include <linux/tcp.h>
#include <net/llc_main.h>
-#include <net/llc_mac.h>
#include <net/llc_pdu.h>
#include <linux/if_tr.h>
-static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb);
-static int llc_exec_sap_trans_actions(struct llc_sap *sap,
- struct llc_sap_state_trans *trans,
- struct sk_buff *skb);
-static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
- struct sk_buff *skb);
-
/**
* llc_sap_assign_sock - adds a connection to a SAP
* @sap: pointer to SAP.
@@ -76,51 +68,15 @@ void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk)
}
/**
- * llc_sap_state_process - sends event to SAP state machine
- * @sap: sap to use
- * @skb: pointer to occurred event
- *
- * After executing actions of the event, upper layer will be indicated
- * if needed(on receiving an UI frame). sk can be null for the
- * datalink_proto case.
- */
-void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
-{
- struct llc_sap_state_ev *ev = llc_sap_ev(skb);
-
- /*
- * We have to hold the skb, because llc_sap_next_state
- * will kfree it in the sending path and we need to
- * look at the skb->cb, where we encode llc_sap_state_ev.
- */
- skb_get(skb);
- ev->ind_cfm_flag = 0;
- llc_sap_next_state(sap, skb);
- if (ev->ind_cfm_flag == LLC_IND) {
- if (skb->sk->state == TCP_LISTEN)
- kfree_skb(skb);
- else {
- llc_save_primitive(skb, ev->prim);
-
- /* queue skb to the user. */
- if (sock_queue_rcv_skb(skb->sk, skb))
- kfree_skb(skb);
- }
- }
- kfree_skb(skb);
-}
-
-/**
* llc_sap_rtn_pdu - Informs upper layer on rx of an UI, XID or TEST pdu.
* @sap: pointer to SAP
* @skb: received pdu
*/
void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb)
{
- struct llc_pdu_un *pdu;
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+ struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
- pdu = llc_pdu_un_hdr(skb);
switch (LLC_U_PDU_RSP(pdu)) {
case LLC_1_PDU_CMD_TEST:
ev->prim = LLC_TEST_PRIM; break;
@@ -133,38 +89,6 @@ void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb)
}
/**
- * llc_sap_next_state - finds transition, execs actions & change SAP state
- * @sap: pointer to SAP
- * @skb: happened event
- *
- * This function finds transition that matches with happened event, then
- * executes related actions and finally changes state of SAP. It returns
- * 0 on success and 1 for failure.
- */
-static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb)
-{
- int rc = 1;
- struct llc_sap_state_trans *trans;
-
- if (sap->state <= LLC_NR_SAP_STATES) {
- trans = llc_find_sap_trans(sap, skb);
- if (trans) {
- /* got the state to which we next transition; perform
- * the actions associated with this transition before
- * actually transitioning to the next state
- */
- rc = llc_exec_sap_trans_actions(sap, trans, skb);
- if (!rc)
- /* transition SAP to next state if all actions
- * execute successfully
- */
- sap->state = trans->next_state;
- }
- }
- return rc;
-}
-
-/**
* llc_find_sap_trans - finds transition for event
* @sap: pointer to SAP
* @skb: happened event
@@ -180,13 +104,13 @@ static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
struct llc_sap_state_trans *rc = NULL;
struct llc_sap_state_trans **next_trans;
struct llc_sap_state *curr_state = &llc_sap_state_table[sap->state - 1];
- /* search thru events for this state until list exhausted or until
+ /*
+ * Search thru events for this state until list exhausted or until
* its obvious the event is not valid for the current state
*/
for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
if (!next_trans[i]->ev(sap, skb)) {
- /* got event match; return it */
- rc = next_trans[i];
+ rc = next_trans[i]; /* got event match; return it */
break;
}
return rc;
@@ -213,3 +137,73 @@ static int llc_exec_sap_trans_actions(struct llc_sap *sap,
rc = 1;
return rc;
}
+
+/**
+ * llc_sap_next_state - finds transition, execs actions & change SAP state
+ * @sap: pointer to SAP
+ * @skb: happened event
+ *
+ * This function finds transition that matches with happened event, then
+ * executes related actions and finally changes state of SAP. It returns
+ * 0 on success and 1 for failure.
+ */
+static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb)
+{
+ int rc = 1;
+ struct llc_sap_state_trans *trans;
+
+ if (sap->state > LLC_NR_SAP_STATES)
+ goto out;
+ trans = llc_find_sap_trans(sap, skb);
+ if (!trans)
+ goto out;
+ /*
+ * Got the state to which we next transition; perform the actions
+ * associated with this transition before actually transitioning to the
+ * next state
+ */
+ rc = llc_exec_sap_trans_actions(sap, trans, skb);
+ if (rc)
+ goto out;
+ /*
+ * Transition SAP to next state if all actions execute successfully
+ */
+ sap->state = trans->next_state;
+out:
+ return rc;
+}
+
+/**
+ * llc_sap_state_process - sends event to SAP state machine
+ * @sap: sap to use
+ * @skb: pointer to occurred event
+ *
+ * After executing actions of the event, upper layer will be indicated
+ * if needed(on receiving an UI frame). sk can be null for the
+ * datalink_proto case.
+ */
+void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
+{
+ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+
+ /*
+ * We have to hold the skb, because llc_sap_next_state
+ * will kfree it in the sending path and we need to
+ * look at the skb->cb, where we encode llc_sap_state_ev.
+ */
+ skb_get(skb);
+ ev->ind_cfm_flag = 0;
+ llc_sap_next_state(sap, skb);
+ if (ev->ind_cfm_flag == LLC_IND) {
+ if (skb->sk->state == TCP_LISTEN)
+ kfree_skb(skb);
+ else {
+ llc_save_primitive(skb, ev->prim);
+
+ /* queue skb to the user. */
+ if (sock_queue_rcv_skb(skb->sk, skb))
+ kfree_skb(skb);
+ }
+ }
+ kfree_skb(skb);
+}