summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@conectiva.com.br>2002-09-13 04:48:47 -0300
committerArnaldo Carvalho de Melo <acme@conectiva.com.br>2002-09-13 04:48:47 -0300
commit96b2cae773183e8298385cf05103b3abeb3cfa7e (patch)
tree31ab1b23c199777eea261535596ccd1d532b5f9b
parentf3fd7056647b5f8c68a8b74d302e680d8c81d1ea (diff)
[LLC] kill sap->req()
Intermediate patch for the PF_LLC SOCK_DGRAM prim clean-up, now PF_LLC is prims in the sending side, now to hack the core to not use prims to send to PF_LLC. This also fixes a skb leak on llc_sap_state_process.
-rw-r--r--include/net/llc_if.h23
-rw-r--r--include/net/llc_sap.h1
-rw-r--r--net/llc/llc_if.c183
-rw-r--r--net/llc/llc_sap.c24
-rw-r--r--net/llc/llc_sock.c54
5 files changed, 114 insertions, 171 deletions
diff --git a/include/net/llc_if.h b/include/net/llc_if.h
index ebff514725e3..e17373a17c00 100644
--- a/include/net/llc_if.h
+++ b/include/net/llc_if.h
@@ -14,6 +14,8 @@
/* Defines LLC interface to network layer */
/* Available primitives */
#include <linux/if.h>
+#include <linux/if_arp.h>
+#include <linux/llc.h>
#define LLC_DATAUNIT_PRIM 0
#define LLC_CONN_PRIM 1
@@ -118,5 +120,26 @@ extern void llc_sap_close(struct llc_sap *sap);
extern int llc_establish_connection(struct sock *sk, u8 *lmac,
u8 *dmac, u8 dsap);
extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
+extern void llc_build_and_send_ui_pkt(struct llc_sap *sap,
+ struct sk_buff *skb,
+ struct sockaddr_llc *addr);
+extern void llc_build_and_send_xid_pkt(struct llc_sap *sap,
+ struct sk_buff *skb,
+ struct sockaddr_llc *addr);
+extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
+ struct sk_buff *skb,
+ struct sockaddr_llc *addr);
extern int llc_send_disc(struct sock *sk);
+
+/**
+ * llc_proto_type - return eth protocol for ARP header type
+ * @arphrd: ARP header type.
+ *
+ * Given an ARP header type return the corresponding ethernet protocol.
+ */
+static __inline__ u16 llc_proto_type(u16 arphrd)
+{
+ return arphrd == ARPHRD_IEEE802_TR ?
+ htons(ETH_P_TR_802_2) : htons(ETH_P_802_2);
+}
#endif /* LLC_IF_H */
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h
index 3132bebd1422..1357da860c04 100644
--- a/include/net/llc_sap.h
+++ b/include/net/llc_sap.h
@@ -30,7 +30,6 @@ struct llc_sap {
u8 state;
u8 p_bit;
u8 f_bit;
- llc_prim_call_t req;
llc_prim_call_t ind;
llc_prim_call_t conf;
struct llc_prim_if_block llc_ind_prim, llc_cfm_prim;
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c
index 126c0d23101c..393173d91156 100644
--- a/net/llc/llc_if.c
+++ b/net/llc/llc_if.c
@@ -28,24 +28,6 @@
#include <net/llc_main.h>
#include <net/llc_mac.h>
-static int llc_sap_req(struct llc_prim_if_block *prim);
-static int llc_unitdata_req_handler(struct llc_prim_if_block *prim);
-static int llc_test_req_handler(struct llc_prim_if_block *prim);
-static int llc_xid_req_handler(struct llc_prim_if_block *prim);
-static int llc_rst_req_handler(struct llc_prim_if_block *prim);
-
-/* table of request handler functions */
-static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = {
- [LLC_DATAUNIT_PRIM] = llc_unitdata_req_handler,
- [LLC_CONN_PRIM] = NULL, /* replaced by llc_establish_connection */
- [LLC_DATA_PRIM] = NULL, /* replaced by llc_build_and_send_pkt */
- [LLC_DISC_PRIM] = NULL, /* replaced by llc_send_disc */
- [LLC_RESET_PRIM] = llc_rst_req_handler,
- [LLC_FLOWCONTROL_PRIM] = NULL, /* Not supported at this time */
- [LLC_XID_PRIM] = llc_xid_req_handler,
- [LLC_TEST_PRIM] = llc_test_req_handler,
-};
-
/**
* llc_sap_open - open interface to the upper layers.
* @nw_indicate: pointer to indicate function of upper layer.
@@ -75,7 +57,6 @@ struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate,
goto err;
/* allocated a SAP; initialize it and clear out its memory pool */
sap->laddr.lsap = lsap;
- sap->req = llc_sap_req;
sap->ind = nw_indicate;
sap->conf = nw_confirm;
sap->parent_station = llc_station_get();
@@ -102,116 +83,115 @@ void llc_sap_close(struct llc_sap *sap)
}
/**
- * llc_sap_req - Request interface for upper layers
- * @prim: pointer to structure that contains service parameters.
+ * llc_build_and_send_ui_pkt - unitdata request interface for upper layers
+ * @sap: sap to use
+ * @skb: packet to send
+ * @addr: destination address
*
- * Request interface function to upper layer. Each one who wants to
- * request a service from LLC, must call this function. Details of
- * requested service is defined in input argument(prim). Returns 0 for
- * success, 1 otherwise.
+ * Upper layers calls this function when upper layer wants to send data
+ * using connection-less mode communication (UI pdu).
+ *
+ * Accept data frame from network layer to be sent using connection-
+ * less mode communication; timeout/retries handled by network layer;
+ * package primitive as an event and send to SAP event handler
*/
-static int llc_sap_req(struct llc_prim_if_block *prim)
+void llc_build_and_send_ui_pkt(struct llc_sap *sap,
+ struct sk_buff *skb,
+ struct sockaddr_llc *addr)
{
- int rc = 1;
+ union llc_u_prim_data prim_data;
+ struct llc_prim_if_block prim;
+ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
- if (prim->prim > 8 || prim->prim == 6) {
- printk(KERN_ERR "%s: invalid primitive %d\n", __FUNCTION__,
- prim->prim);
- goto out;
- }
- /* receive REQUEST primitive from network layer; call the appropriate
- * primitive handler which then packages it up as an event and sends it
- * to the SAP or CONNECTION event handler
- */
- if (prim->prim < LLC_NBR_PRIMITIVES)
- /* valid primitive; call the function to handle it */
- rc = llc_req_prim[prim->prim](prim);
-out:
- return rc;
-}
+ skb->protocol = llc_proto_type(addr->sllc_arphrd);
-/**
- * llc_unitdata_req_handler - unitdata request interface for upper layers
- * @prim: pointer to structure that contains service parameters
- *
- * Upper layers calls this function when upper layer wants to send data
- * using connection-less mode communication (UI pdu). Returns 0 for
- * success, 1 otherwise.
- */
-static int llc_unitdata_req_handler(struct llc_prim_if_block *prim)
-{
- int rc = 1;
- struct llc_sap_state_ev *ev;
- /* accept data frame from network layer to be sent using connection-
- * less mode communication; timeout/retries handled by network layer;
- * package primitive as an event and send to SAP event handler
- */
- struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
+ prim.data = &prim_data;
+ prim.sap = sap;
+ prim.prim = LLC_DATAUNIT_PRIM;
+
+ prim_data.udata.skb = skb;
+ prim_data.udata.saddr.lsap = sap->laddr.lsap;
+ prim_data.udata.daddr.lsap = addr->sllc_dsap;
+ memcpy(prim_data.udata.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+ memcpy(prim_data.udata.daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
- if (!sap)
- goto out;
- ev = llc_sap_ev(prim->data->udata.skb);
ev->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_DATAUNIT_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
- ev->data.prim.data = prim;
- rc = 0;
- llc_sap_state_process(sap, prim->data->udata.skb);
-out:
- return rc;
+ ev->data.prim.data = &prim;
+ llc_sap_state_process(sap, skb);
}
/**
- * llc_test_req_handler - TEST interface for upper layers.
- * @prim: pointer to structure that contains service parameters.
+ * llc_build_and_send_test_pkt - TEST interface for upper layers.
+ * @sap: sap to use
+ * @skb: packet to send
+ * @addr: destination address
*
* This function is called when upper layer wants to send a TEST pdu.
* Returns 0 for success, 1 otherwise.
*/
-static int llc_test_req_handler(struct llc_prim_if_block *prim)
+void llc_build_and_send_test_pkt(struct llc_sap *sap,
+ struct sk_buff *skb,
+ struct sockaddr_llc *addr)
{
- int rc = 1;
- struct llc_sap_state_ev *ev;
- /* package primitive as an event and send to SAP event handler */
- struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
- if (!sap)
- goto out;
- ev = llc_sap_ev(prim->data->udata.skb);
+ union llc_u_prim_data prim_data;
+ struct llc_prim_if_block prim;
+ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+
+ skb->protocol = llc_proto_type(addr->sllc_arphrd);
+
+ prim.data = &prim_data;
+ prim.sap = sap;
+ prim.prim = LLC_TEST_PRIM;
+
+ prim_data.test.skb = skb;
+ prim_data.test.saddr.lsap = sap->laddr.lsap;
+ prim_data.test.daddr.lsap = addr->sllc_dsap;
+ memcpy(prim_data.test.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+ memcpy(prim_data.test.daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
+
ev->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_TEST_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
- ev->data.prim.data = prim;
- rc = 0;
- llc_sap_state_process(sap, prim->data->udata.skb);
-out:
- return rc;
+ ev->data.prim.data = &prim;
+ llc_sap_state_process(sap, skb);
}
/**
- * llc_xid_req_handler - XID interface for upper layers
- * @prim: pointer to structure that contains service parameters.
+ * llc_build_and_send_xid_pkt - XID interface for upper layers
+ * @sap: sap to use
+ * @skb: packet to send
+ * @addr: destination address
*
* This function is called when upper layer wants to send a XID pdu.
* Returns 0 for success, 1 otherwise.
*/
-static int llc_xid_req_handler(struct llc_prim_if_block *prim)
+void llc_build_and_send_xid_pkt(struct llc_sap *sap,
+ struct sk_buff *skb,
+ struct sockaddr_llc *addr)
{
- int rc = 1;
- struct llc_sap_state_ev *ev;
- /* package primitive as an event and send to SAP event handler */
- struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
+ union llc_u_prim_data prim_data;
+ struct llc_prim_if_block prim;
+ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
+
+ skb->protocol = llc_proto_type(addr->sllc_arphrd);
+
+ prim.data = &prim_data;
+ prim.sap = sap;
+ prim.prim = LLC_XID_PRIM;
+
+ prim_data.xid.skb = skb;
+ prim_data.xid.saddr.lsap = sap->laddr.lsap;
+ prim_data.xid.daddr.lsap = addr->sllc_dsap;
+ memcpy(prim_data.xid.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+ memcpy(prim_data.xid.daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
- if (!sap)
- goto out;
- ev = llc_sap_ev(prim->data->udata.skb);
ev->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_XID_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ;
- ev->data.prim.data = prim;
- rc = 0;
- llc_sap_state_process(sap, prim->data->udata.skb);
-out:
- return rc;
+ ev->data.prim.data = &prim;
+ llc_sap_state_process(sap, skb);
}
/**
@@ -344,7 +324,7 @@ out:
}
/**
- * llc_rst_req_handler - Resets an established LLC connection
+ * llc_build_and_send_reset_pkt - Resets an established LLC connection
* @prim: pointer to structure that contains service parameters.
*
* Called when upper layer wants to reset an established LLC connection
@@ -352,13 +332,12 @@ out:
* it to connection component state machine. Returns 0 for success, 1
* otherwise.
*/
-static int llc_rst_req_handler(struct llc_prim_if_block *prim)
+int llc_build_and_send_reset_pkt(struct sock *sk,
+ struct llc_prim_if_block *prim)
{
- struct sk_buff *skb;
int rc = 1;
- struct sock *sk = prim->data->res.sk;
+ struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
- skb = alloc_skb(0, GFP_ATOMIC);
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index ea58322988ad..15ad186dcdd9 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -23,7 +23,6 @@
#include <net/llc_pdu.h>
#include <linux/if_tr.h>
-static void llc_sap_free_ev(struct llc_sap *sap, struct sk_buff *skb);
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,
@@ -75,11 +74,13 @@ void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
llc_sap_next_state(sap, skb);
- if (ev->ind_cfm_flag == LLC_IND) {
- skb_get(skb);
+ if (ev->ind_cfm_flag == LLC_IND)
sap->ind(ev->prim);
- }
- llc_sap_free_ev(sap, skb);
+ else if (ev->type == LLC_SAP_EV_TYPE_PDU)
+ kfree_skb(skb);
+ else
+ printk(KERN_INFO ":%s !kfree_skb & it is %s in a list\n",
+ __FUNCTION__, skb->list ? "" : "NOT");
}
/**
@@ -142,19 +143,6 @@ void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb)
}
/**
- * llc_sap_free_ev - frees an sap event
- * @sap: pointer to SAP
- * @skb: released event
- */
-static void llc_sap_free_ev(struct llc_sap *sap, struct sk_buff *skb)
-{
- struct llc_sap_state_ev *ev = llc_sap_ev(skb);
-
- if (ev->type == LLC_SAP_EV_TYPE_PDU)
- kfree_skb(skb);
-}
-
-/**
* llc_sap_next_state - finds transition, execs actions & change SAP state
* @sap: pointer to SAP
* @skb: happened event
diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c
index 61ee027c4be3..74a6a6b26e57 100644
--- a/net/llc/llc_sock.c
+++ b/net/llc/llc_sock.c
@@ -87,23 +87,6 @@ static __inline__ u8 llc_ui_addr_null(struct sockaddr_llc *addr)
}
/**
- * llc_ui_protocol_type - return eth protocol for ARP header type
- * @arphrd: ARP header type.
- *
- * Given an ARP header type return the corresponding ethernet protocol.
- * Returns 0 if ARP header type not supported or the corresponding
- * ethernet protocol type.
- */
-static __inline__ u16 llc_ui_protocol_type(u16 arphrd)
-{
- u16 rc = htons(ETH_P_802_2);
-
- if (arphrd == ARPHRD_IEEE802_TR)
- rc = htons(ETH_P_TR_802_2);
- return rc;
-}
-
-/**
* llc_ui_header_len - return length of llc header based on operation
* @sk: Socket which contains a valid llc socket type.
* @addr: Complete sockaddr_llc structure received from the user.
@@ -140,7 +123,7 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb,
struct llc_opt* llc = llc_sk(sk);
int rc = 0;
- skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd);
+ skb->protocol = llc_proto_type(addr->sllc_arphrd);
if (llc_data_accept_state(llc->state) || llc->p_flag) {
int timeout = sock_sndtimeo(sk, noblock);
@@ -152,35 +135,6 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb,
}
/**
- * llc_ui_send_llc1 - send llc1 prim data block to llc layer.
- * @sap : Sap the socket is bound to.
- * @skb : Data the user wishes to send.
- * @addr : Source and destination fields provided by the user.
- * @primitive: Action the llc layer should perform.
- *
- * Send an llc1 primitive data block to the llc layer for processing.
- * This function is used for test, xid and unit_data messages.
- * Returns 0 upon success, non-zero if action did not succeed.
- */
-static int llc_ui_send_llc1(struct llc_sap *sap, struct sk_buff *skb,
- struct sockaddr_llc *addr, int primitive)
-{
- union llc_u_prim_data prim_data;
- struct llc_prim_if_block prim;
-
- prim.data = &prim_data;
- prim.sap = sap;
- prim.prim = primitive;
- prim_data.test.skb = skb;
- prim_data.test.saddr.lsap = sap->laddr.lsap;
- prim_data.test.daddr.lsap = addr->sllc_dsap;
- skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd);
- memcpy(prim_data.test.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
- memcpy(prim_data.test.daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
- return sap->req(&prim);
-}
-
-/**
* llc_ui_find_sap - returns sap struct that matches sap number specified
* @sap: Sap number to search for.
*
@@ -993,15 +947,15 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len,
if (rc)
goto out;
if (addr->sllc_test) {
- rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_TEST_PRIM);
+ llc_build_and_send_test_pkt(llc->sap, skb, addr);
goto out;
}
if (addr->sllc_xid) {
- rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_XID_PRIM);
+ llc_build_and_send_xid_pkt(llc->sap, skb, addr);
goto out;
}
if (sk->type == SOCK_DGRAM || addr->sllc_ua) {
- rc = llc_ui_send_llc1(llc->sap, skb, addr, LLC_DATAUNIT_PRIM);
+ llc_build_and_send_ui_pkt(llc->sap, skb, addr);
goto out;
}
rc = -ENOPROTOOPT;