diff options
| author | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 2002-09-13 04:48:47 -0300 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | 2002-09-13 04:48:47 -0300 |
| commit | 96b2cae773183e8298385cf05103b3abeb3cfa7e (patch) | |
| tree | 31ab1b23c199777eea261535596ccd1d532b5f9b | |
| parent | f3fd7056647b5f8c68a8b74d302e680d8c81d1ea (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.h | 23 | ||||
| -rw-r--r-- | include/net/llc_sap.h | 1 | ||||
| -rw-r--r-- | net/llc/llc_if.c | 183 | ||||
| -rw-r--r-- | net/llc/llc_sap.c | 24 | ||||
| -rw-r--r-- | net/llc/llc_sock.c | 54 |
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; |
