[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.
parent f3fd7056
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
/* Defines LLC interface to network layer */ /* Defines LLC interface to network layer */
/* Available primitives */ /* Available primitives */
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/llc.h>
#define LLC_DATAUNIT_PRIM 0 #define LLC_DATAUNIT_PRIM 0
#define LLC_CONN_PRIM 1 #define LLC_CONN_PRIM 1
...@@ -118,5 +120,26 @@ extern void llc_sap_close(struct llc_sap *sap); ...@@ -118,5 +120,26 @@ extern void llc_sap_close(struct llc_sap *sap);
extern int llc_establish_connection(struct sock *sk, u8 *lmac, extern int llc_establish_connection(struct sock *sk, u8 *lmac,
u8 *dmac, u8 dsap); u8 *dmac, u8 dsap);
extern int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb); 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); 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 */ #endif /* LLC_IF_H */
...@@ -30,7 +30,6 @@ struct llc_sap { ...@@ -30,7 +30,6 @@ struct llc_sap {
u8 state; u8 state;
u8 p_bit; u8 p_bit;
u8 f_bit; u8 f_bit;
llc_prim_call_t req;
llc_prim_call_t ind; llc_prim_call_t ind;
llc_prim_call_t conf; llc_prim_call_t conf;
struct llc_prim_if_block llc_ind_prim, llc_cfm_prim; struct llc_prim_if_block llc_ind_prim, llc_cfm_prim;
......
...@@ -28,24 +28,6 @@ ...@@ -28,24 +28,6 @@
#include <net/llc_main.h> #include <net/llc_main.h>
#include <net/llc_mac.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. * llc_sap_open - open interface to the upper layers.
* @nw_indicate: pointer to indicate function of upper layer. * @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, ...@@ -75,7 +57,6 @@ struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate,
goto err; goto err;
/* allocated a SAP; initialize it and clear out its memory pool */ /* allocated a SAP; initialize it and clear out its memory pool */
sap->laddr.lsap = lsap; sap->laddr.lsap = lsap;
sap->req = llc_sap_req;
sap->ind = nw_indicate; sap->ind = nw_indicate;
sap->conf = nw_confirm; sap->conf = nw_confirm;
sap->parent_station = llc_station_get(); sap->parent_station = llc_station_get();
...@@ -102,116 +83,115 @@ void llc_sap_close(struct llc_sap *sap) ...@@ -102,116 +83,115 @@ void llc_sap_close(struct llc_sap *sap)
} }
/** /**
* llc_sap_req - Request interface for upper layers * llc_build_and_send_ui_pkt - unitdata request interface for upper layers
* @prim: pointer to structure that contains service parameters. * @sap: sap to use
* @skb: packet to send
* @addr: destination address
* *
* Request interface function to upper layer. Each one who wants to * Upper layers calls this function when upper layer wants to send data
* request a service from LLC, must call this function. Details of * using connection-less mode communication (UI pdu).
* requested service is defined in input argument(prim). Returns 0 for *
* success, 1 otherwise. * 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) { skb->protocol = llc_proto_type(addr->sllc_arphrd);
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;
}
/** prim.data = &prim_data;
* llc_unitdata_req_handler - unitdata request interface for upper layers prim.sap = sap;
* @prim: pointer to structure that contains service parameters prim.prim = LLC_DATAUNIT_PRIM;
*
* Upper layers calls this function when upper layer wants to send data prim_data.udata.skb = skb;
* using connection-less mode communication (UI pdu). Returns 0 for prim_data.udata.saddr.lsap = sap->laddr.lsap;
* success, 1 otherwise. prim_data.udata.daddr.lsap = addr->sllc_dsap;
*/ memcpy(prim_data.udata.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
static int llc_unitdata_req_handler(struct llc_prim_if_block *prim) memcpy(prim_data.udata.daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
{
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);
if (!sap)
goto out;
ev = llc_sap_ev(prim->data->udata.skb);
ev->type = LLC_SAP_EV_TYPE_PRIM; ev->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_DATAUNIT_PRIM; ev->data.prim.prim = LLC_DATAUNIT_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim; ev->data.prim.data = &prim;
rc = 0; llc_sap_state_process(sap, skb);
llc_sap_state_process(sap, prim->data->udata.skb);
out:
return rc;
} }
/** /**
* llc_test_req_handler - TEST interface for upper layers. * llc_build_and_send_test_pkt - TEST interface for upper layers.
* @prim: pointer to structure that contains service parameters. * @sap: sap to use
* @skb: packet to send
* @addr: destination address
* *
* This function is called when upper layer wants to send a TEST pdu. * This function is called when upper layer wants to send a TEST pdu.
* Returns 0 for success, 1 otherwise. * 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; union llc_u_prim_data prim_data;
struct llc_sap_state_ev *ev; struct llc_prim_if_block prim;
/* package primitive as an event and send to SAP event handler */ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
if (!sap) skb->protocol = llc_proto_type(addr->sllc_arphrd);
goto out;
ev = llc_sap_ev(prim->data->udata.skb); 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->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_TEST_PRIM; ev->data.prim.prim = LLC_TEST_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim; ev->data.prim.data = &prim;
rc = 0; llc_sap_state_process(sap, skb);
llc_sap_state_process(sap, prim->data->udata.skb);
out:
return rc;
} }
/** /**
* llc_xid_req_handler - XID interface for upper layers * llc_build_and_send_xid_pkt - XID interface for upper layers
* @prim: pointer to structure that contains service parameters. * @sap: sap to use
* @skb: packet to send
* @addr: destination address
* *
* This function is called when upper layer wants to send a XID pdu. * This function is called when upper layer wants to send a XID pdu.
* Returns 0 for success, 1 otherwise. * 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; union llc_u_prim_data prim_data;
struct llc_sap_state_ev *ev; struct llc_prim_if_block prim;
/* package primitive as an event and send to SAP event handler */ struct llc_sap_state_ev *ev = llc_sap_ev(skb);
struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
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->type = LLC_SAP_EV_TYPE_PRIM;
ev->data.prim.prim = LLC_XID_PRIM; ev->data.prim.prim = LLC_XID_PRIM;
ev->data.prim.type = LLC_PRIM_TYPE_REQ; ev->data.prim.type = LLC_PRIM_TYPE_REQ;
ev->data.prim.data = prim; ev->data.prim.data = &prim;
rc = 0; llc_sap_state_process(sap, skb);
llc_sap_state_process(sap, prim->data->udata.skb);
out:
return rc;
} }
/** /**
...@@ -344,7 +324,7 @@ int llc_send_disc(struct sock *sk) ...@@ -344,7 +324,7 @@ int llc_send_disc(struct sock *sk)
} }
/** /**
* 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. * @prim: pointer to structure that contains service parameters.
* *
* Called when upper layer wants to reset an established LLC connection * Called when upper layer wants to reset an established LLC connection
...@@ -352,13 +332,12 @@ int llc_send_disc(struct sock *sk) ...@@ -352,13 +332,12 @@ int llc_send_disc(struct sock *sk)
* it to connection component state machine. Returns 0 for success, 1 * it to connection component state machine. Returns 0 for success, 1
* otherwise. * 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; 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) { if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb); struct llc_conn_state_ev *ev = llc_conn_ev(skb);
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <net/llc_pdu.h> #include <net/llc_pdu.h>
#include <linux/if_tr.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_sap_next_state(struct llc_sap *sap, struct sk_buff *skb);
static int llc_exec_sap_trans_actions(struct llc_sap *sap, static int llc_exec_sap_trans_actions(struct llc_sap *sap,
struct llc_sap_state_trans *trans, struct llc_sap_state_trans *trans,
...@@ -75,11 +74,13 @@ void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) ...@@ -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); struct llc_sap_state_ev *ev = llc_sap_ev(skb);
llc_sap_next_state(sap, skb); llc_sap_next_state(sap, skb);
if (ev->ind_cfm_flag == LLC_IND) { if (ev->ind_cfm_flag == LLC_IND)
skb_get(skb);
sap->ind(ev->prim); sap->ind(ev->prim);
} else if (ev->type == LLC_SAP_EV_TYPE_PDU)
llc_sap_free_ev(sap, skb); kfree_skb(skb);
else
printk(KERN_INFO ":%s !kfree_skb & it is %s in a list\n",
__FUNCTION__, skb->list ? "" : "NOT");
} }
/** /**
...@@ -141,19 +142,6 @@ void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb) ...@@ -141,19 +142,6 @@ void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb)
kfree_skb(skb); kfree_skb(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 * llc_sap_next_state - finds transition, execs actions & change SAP state
* @sap: pointer to SAP * @sap: pointer to SAP
......
...@@ -86,23 +86,6 @@ static __inline__ u8 llc_ui_addr_null(struct sockaddr_llc *addr) ...@@ -86,23 +86,6 @@ static __inline__ u8 llc_ui_addr_null(struct sockaddr_llc *addr)
return !memcmp(addr, &llc_ui_addrnull, sizeof(*addr)); return !memcmp(addr, &llc_ui_addrnull, sizeof(*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 * llc_ui_header_len - return length of llc header based on operation
* @sk: Socket which contains a valid llc socket type. * @sk: Socket which contains a valid llc socket type.
...@@ -140,7 +123,7 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, ...@@ -140,7 +123,7 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb,
struct llc_opt* llc = llc_sk(sk); struct llc_opt* llc = llc_sk(sk);
int rc = 0; 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) { if (llc_data_accept_state(llc->state) || llc->p_flag) {
int timeout = sock_sndtimeo(sk, noblock); int timeout = sock_sndtimeo(sk, noblock);
...@@ -151,35 +134,6 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, ...@@ -151,35 +134,6 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb,
return rc; return rc;
} }
/**
* 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 * llc_ui_find_sap - returns sap struct that matches sap number specified
* @sap: Sap number to search for. * @sap: Sap number to search for.
...@@ -993,15 +947,15 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, ...@@ -993,15 +947,15 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len,
if (rc) if (rc)
goto out; goto out;
if (addr->sllc_test) { 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; goto out;
} }
if (addr->sllc_xid) { 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; goto out;
} }
if (sk->type == SOCK_DGRAM || addr->sllc_ua) { 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; goto out;
} }
rc = -ENOPROTOOPT; rc = -ENOPROTOOPT;
......
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