summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2002-09-24 00:35:39 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2002-09-24 00:35:39 -0700
commit53153960883f512ee000414cbd330eb325bb9608 (patch)
tree657840d2117d29c9f395d4054917826bb0c390e3
parenta9ee74e7051a423db2f5c76723106d12fb756365 (diff)
parent9950c8fea9d3fed4a4a97d12b5988d97ee12c6b0 (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_c_ev.h38
-rw-r--r--include/net/llc_conn.h9
-rw-r--r--include/net/llc_evnt.h24
-rw-r--r--include/net/llc_frame.h98
-rw-r--r--include/net/llc_if.h80
-rw-r--r--include/net/llc_main.h1
-rw-r--r--include/net/llc_name.h7
-rw-r--r--include/net/llc_s_ev.h37
-rw-r--r--include/net/llc_sap.h11
-rw-r--r--include/net/llc_state.h4
-rw-r--r--include/net/p8022.h9
-rw-r--r--net/802/p8022.c6
-rw-r--r--net/802/psnap.c21
-rw-r--r--net/ipx/af_ipx.c18
-rw-r--r--net/llc/llc_c_ac.c49
-rw-r--r--net/llc/llc_c_ev.c30
-rw-r--r--net/llc/llc_conn.c222
-rw-r--r--net/llc/llc_evnt.c8
-rw-r--r--net/llc/llc_if.c125
-rw-r--r--net/llc/llc_mac.c23
-rw-r--r--net/llc/llc_main.c6
-rw-r--r--net/llc/llc_s_ac.c24
-rw-r--r--net/llc/llc_s_ev.c16
-rw-r--r--net/llc/llc_sap.c75
-rw-r--r--net/llc/llc_sock.c282
25 files changed, 346 insertions, 877 deletions
diff --git a/include/net/llc_c_ev.h b/include/net/llc_c_ev.h
index 2a8a0be9040b..20fbfeec34c4 100644
--- a/include/net/llc_c_ev.h
+++ b/include/net/llc_c_ev.h
@@ -110,38 +110,14 @@
#define LLC_CONN_EV_QFY_S_FLAG_EQ_0 11
#define LLC_CONN_EV_QFY_INIT_P_F_CYCLE 12
-/* Event data interface; what is sent in an event package */
-/* Event LLC_CONN_EV_TYPE_SIMPLE interface */
-struct llc_conn_ev_simple_if {
- u8 ev;
-};
-
-/* Event LLC_CONN_EV_TYPE_PRIM interface */
-struct llc_conn_ev_prim_if {
- u8 prim; /* connect, disconnect, reset, ... */
- u8 type; /* request, indicate, response, conf */
- struct llc_prim_if_block *data;
-};
-
-/* Event LLC_CONN_EV_TYPE_PDU interface */
-struct llc_conn_ev_pdu_if {
- u8 ev;
-};
-
-union llc_conn_ev_if {
- struct llc_conn_ev_simple_if a; /* 'a' for simple, easy ... */
- struct llc_conn_ev_prim_if prim;
- struct llc_conn_ev_pdu_if pdu;
-};
-
struct llc_conn_state_ev {
- u8 type;
- u8 reason;
- u8 status;
- u8 flag;
- struct llc_prim_if_block *ind_prim;
- struct llc_prim_if_block *cfm_prim;
- union llc_conn_ev_if data;
+ u8 type;
+ u8 prim;
+ u8 prim_type;
+ u8 reason;
+ u8 status;
+ u8 ind_prim;
+ u8 cfm_prim;
};
static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb)
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
index ac0a2bb7aa22..ec993d032078 100644
--- a/include/net/llc_conn.h
+++ b/include/net/llc_conn.h
@@ -66,12 +66,6 @@ struct llc_opt {
u32 rx_pdu_hdr; /* used for saving header of last pdu
received and caused sending FRMR.
Used for resending FRMR */
-#ifdef DEBUG_LLC_CONN_ALLOC
- char *f_alloc, /* function that allocated this connection */
- *f_free; /* function that freed this connection */
- int l_alloc, /* line that allocated this connection */
- l_free; /* line that freed this connection */
-#endif
};
#define llc_sk(__sk) ((struct llc_opt *)(__sk)->protinfo)
@@ -100,6 +94,9 @@ extern struct sock *llc_lookup_established(struct llc_sap *sap,
struct llc_addr *laddr);
extern struct sock *llc_lookup_listener(struct llc_sap *sap,
struct llc_addr *laddr);
+extern struct sock *llc_lookup_dgram(struct llc_sap *sap,
+ struct llc_addr *laddr);
+extern void llc_save_primitive(struct sk_buff* skb, u8 prim);
extern u8 llc_data_accept_state(u8 state);
extern void llc_build_offset_table(void);
#endif /* LLC_CONN_H */
diff --git a/include/net/llc_evnt.h b/include/net/llc_evnt.h
index 82bca6d937d6..429adcb480e3 100644
--- a/include/net/llc_evnt.h
+++ b/include/net/llc_evnt.h
@@ -31,26 +31,12 @@
#define LLC_STATION_EV_RX_NULL_DSAP_TEST_C 8
#define LLC_STATION_EV_DISABLE_REQ 9
-/* Interfaces for various types of supported events */
-struct llc_stat_ev_simple_if {
- u8 ev;
-};
-
-struct llc_stat_ev_prim_if {
- u8 prim; /* connect, disconnect, reset, ... */
- u8 type; /* request, indicate, response, confirm */
-};
-
-union llc_stat_ev_if {
- struct llc_stat_ev_simple_if a; /* 'a' for simple, easy ... */
- struct llc_stat_ev_prim_if prim;
-};
-
struct llc_station_state_ev {
- u8 type;
- u8 reason;
- union llc_stat_ev_if data;
- struct list_head node; /* node in station->ev_q.list */
+ u8 type;
+ u8 prim;
+ u8 prim_type;
+ u8 reason;
+ struct list_head node; /* node in station->ev_q.list */
};
static __inline__ struct llc_station_state_ev *
diff --git a/include/net/llc_frame.h b/include/net/llc_frame.h
deleted file mode 100644
index e8fb198d19a8..000000000000
--- a/include/net/llc_frame.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* if_ether.h needed for definition of ETH_DATA_LEN and ETH_ALEN
- */
-#include "linux/if_ether.h"
-
-/* frame layout based on par3.2 "LLC PDU format"
- */
-typedef union { /* pdu layout from pages 40 & 44 */
- struct { /* general header, all pdu types */
- unsigned dsap : 8; /* dest service access point */
- unsigned ssap : 8; /* source service access point */
- unsigned f1 : 1; /* I- U- or S- format id bits */
- unsigned f2 : 1;
- unsigned : 6;
- unsigned : 8;
- } pdu_hdr;
- struct {
- char dummy1[2]; /* dsap + ssap */
- char byte1;
- char byte2;
- } pdu_cntl; /* unformatted control bytes */
- struct { /* header of an Information pdu */
- unsigned char dummy2[2];
- unsigned : 1;
- unsigned ns : 7;
- unsigned i_pflag : 1; /* poll/final bit */
- unsigned nr : 7; /* N(R) */
- unsigned char is_info[ ETH_DATA_LEN ];
- } i_hdr;
- struct { /* header of a Supervisory pdu */
- unsigned char dummy3[2];
- unsigned : 2;
- unsigned ss : 2; /* supervisory function bits */
- unsigned : 4;
- unsigned s_pflag : 1; /* poll/final bit */
- unsigned nr : 7; /* N(R) */
- } s_hdr;
-
-/* when accessing the P/F bit or the N(R) field there's no need to distinguish
- I pdus from S pdus i_pflag and s_pflag / i_nr and s_nr map to the same
- physical location.
- */
- struct { /* header of an Unnumbered pdu */
- unsigned char dummy4[2];
- unsigned : 2;
- unsigned mm1 : 2; /* modifier function part1 */
- unsigned u_pflag : 1; /* P/F for U- pdus */
- unsigned mm2 : 3; /* modifier function part2 */
- unsigned char u_info[ ETH_DATA_LEN-1];
- } u_hdr;
- struct { /* mm field in an Unnumbered pdu */
- unsigned char dummy5[2];
- unsigned : 2;
- unsigned mm : 6; /* must be masked to get ridd of P/F ! */
- } u_mm;
-
-} frame_type, *frameptr;
-
-/* frame format test macros: */
-
-#define IS_UFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & ( (fr)->pdu_hdr.f2) )
-
-#define IS_IFRAME( fr ) ( !( (fr)->pdu_hdr.f1) )
-
-#define IS_SFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & !( (fr)->pdu_hdr.f2) )
-
-#define IS_RSP( fr ) ( fr->pdu_hdr.ssap & 0x01 )
-
-
-/* The transition table, the _encode tables and some tests in the
- source code depend on the numeric order of these values.
- Think twice before changing.
- */
-
-/* frame names for TYPE 2 operation: */
-#define I_CMD 0
-#define RR_CMD 1
-#define RNR_CMD 2
-#define REJ_CMD 3
-#define DISC_CMD 4
-#define SABME_CMD 5
-#define I_RSP 6
-#define RR_RSP 7
-#define RNR_RSP 8
-#define REJ_RSP 9
-#define UA_RSP 10
-#define DM_RSP 11
-#define FRMR_RSP 12
-
-/* junk frame name: */
-#define BAD_FRAME 13
-#define NO_FRAME 13
-
-/* frame names for TYPE 1 operation: */
-#define UI_CMD 14
-#define XID_CMD 15
-#define TEST_CMD 16
-#define XID_RSP 17
-#define TEST_RSP 18
diff --git a/include/net/llc_if.h b/include/net/llc_if.h
index 5ae7edc13649..a72591707e20 100644
--- a/include/net/llc_if.h
+++ b/include/net/llc_if.h
@@ -17,17 +17,17 @@
#include <linux/if_arp.h>
#include <linux/llc.h>
-#define LLC_DATAUNIT_PRIM 0
-#define LLC_CONN_PRIM 1
-#define LLC_DATA_PRIM 2
-#define LLC_DISC_PRIM 3
-#define LLC_RESET_PRIM 4
-#define LLC_FLOWCONTROL_PRIM 5 /* Not supported at this time */
-#define LLC_DISABLE_PRIM 6
-#define LLC_XID_PRIM 7
-#define LLC_TEST_PRIM 8
-#define LLC_SAP_ACTIVATION 9
-#define LLC_SAP_DEACTIVATION 10
+#define LLC_DATAUNIT_PRIM 1
+#define LLC_CONN_PRIM 2
+#define LLC_DATA_PRIM 3
+#define LLC_DISC_PRIM 4
+#define LLC_RESET_PRIM 5
+#define LLC_FLOWCONTROL_PRIM 6 /* Not supported at this time */
+#define LLC_DISABLE_PRIM 7
+#define LLC_XID_PRIM 8
+#define LLC_TEST_PRIM 9
+#define LLC_SAP_ACTIVATION 10
+#define LLC_SAP_DEACTIVATION 11
#define LLC_NBR_PRIMITIVES 11
@@ -67,66 +67,22 @@ struct llc_addr {
u8 mac[IFHWADDRLEN];
};
-struct llc_prim_reset {
- struct sock *sk;
- u16 link;
-};
-
- /* Sending data in conection-less mode */
-struct llc_prim_unit_data {
- struct llc_addr saddr;
- struct llc_addr daddr;
- u8 pri;
- struct sk_buff *skb; /* pointer to frame */
- u8 lfb; /* largest frame bit (TR) */
-};
-
-struct llc_prim_xid {
- struct llc_addr saddr;
- struct llc_addr daddr;
- u8 pri;
- struct sk_buff *skb;
-};
-
-struct llc_prim_test {
- struct llc_addr saddr;
- struct llc_addr daddr;
- u8 pri;
- struct sk_buff *skb; /* pointer to frame */
-};
-
-union llc_u_prim_data {
- struct llc_prim_reset res;
- struct llc_prim_unit_data udata; /* unit data */
- struct llc_prim_xid xid;
- struct llc_prim_test test;
-};
-
struct llc_sap;
-/* Information block passed with all called primitives */
-struct llc_prim_if_block {
- struct llc_sap *sap;
- u8 prim;
- union llc_u_prim_data *data;
-};
-typedef int (*llc_prim_call_t)(struct llc_prim_if_block *prim_if);
-
-extern struct llc_sap *llc_sap_open(llc_prim_call_t network_indicate,
- llc_prim_call_t network_confirm, u8 lsap);
+extern struct llc_sap *llc_sap_open(u8 lsap,
+ int (*func)(struct sk_buff *skb,
+ struct net_device *dev,
+ struct packet_type *pt));
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,
+extern void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
u8 *dmac, u8 dsap);
-extern void llc_build_and_send_xid_pkt(struct llc_sap *sap,
- struct sk_buff *skb,
+extern void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
u8 *dmac, u8 dsap);
-extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
- struct sk_buff *skb,
+extern void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
u8 *dmac, u8 dsap);
extern int llc_send_disc(struct sock *sk);
#endif /* LLC_IF_H */
diff --git a/include/net/llc_main.h b/include/net/llc_main.h
index 25d486278da4..61b679128163 100644
--- a/include/net/llc_main.h
+++ b/include/net/llc_main.h
@@ -64,4 +64,5 @@ extern void llc_station_state_process(struct llc_station *station,
extern void llc_station_send_pdu(struct llc_station *station,
struct sk_buff *skb);
extern struct sk_buff *llc_alloc_frame(void);
+extern struct packet_type llc_packet_type;
#endif /* LLC_MAIN_H */
diff --git a/include/net/llc_name.h b/include/net/llc_name.h
deleted file mode 100644
index 72128719f7cc..000000000000
--- a/include/net/llc_name.h
+++ /dev/null
@@ -1,7 +0,0 @@
-char *frame_names[] =
- {"I_CMD","RR_CMD","RNR_CMD","REJ_CMD","DISC_CMD",
- "SABME_CMD","I_RSP","RR_RSP","RNR_RSP","REJ_RSP",
- "UA_RSP","DM_RSP","FRMR_RSP","BAD_FRAME","UI_CMD",
- "XID_CMD","TEST_CMD","XID_RSP","TEST_RSP"
-};
-
diff --git a/include/net/llc_s_ev.h b/include/net/llc_s_ev.h
index 530042ae2be4..e3acb9329e4a 100644
--- a/include/net/llc_s_ev.h
+++ b/include/net/llc_s_ev.h
@@ -34,37 +34,14 @@
#define LLC_SAP_EV_RX_TEST_R 9
#define LLC_SAP_EV_DEACTIVATION_REQ 10
-/* Interfaces for various types of supported events */
-struct llc_sap_ev_simple_if {
- u8 ev;
-};
-
-struct llc_prim_if_block;
-
-struct llc_sap_ev_prim_if {
- u8 prim; /* connect, disconnect, reset, ... */
- u8 type; /* request, indicate, response, conf */
- struct llc_prim_if_block *data;
-};
-
-struct llc_sap_ev_pdu_if {
- u8 ev;
-};
-
-union llc_sap_ev_if {
- struct llc_sap_ev_simple_if a; /* 'a' for simple, easy ... */
- struct llc_sap_ev_prim_if prim;
- struct llc_sap_ev_pdu_if pdu;
-};
-
-struct llc_prim_if_block;
-
struct llc_sap_state_ev {
- u8 type;
- u8 reason;
- u8 ind_cfm_flag;
- struct llc_prim_if_block *prim;
- union llc_sap_ev_if data;
+ u8 prim;
+ u8 prim_type;
+ u8 type;
+ u8 reason;
+ u8 ind_cfm_flag;
+ struct llc_addr saddr;
+ struct llc_addr daddr;
};
static __inline__ struct llc_sap_state_ev *llc_sap_ev(struct sk_buff *skb)
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h
index 412798ab6c0e..5d9dc00a5b36 100644
--- a/include/net/llc_sap.h
+++ b/include/net/llc_sap.h
@@ -12,6 +12,7 @@
* See the GNU General Public License for more details.
*/
#include <linux/skbuff.h>
+#include <net/llc_if.h>
/**
* struct llc_sap - Defines the SAP component
*
@@ -29,10 +30,9 @@ struct llc_sap {
u8 state;
u8 p_bit;
u8 f_bit;
- llc_prim_call_t ind;
- llc_prim_call_t conf;
- struct llc_prim_if_block llc_ind_prim, llc_cfm_prim;
- union llc_u_prim_data llc_ind_data_prim, llc_cfm_data_prim;
+ int (*rcv_func)(struct sk_buff *skb,
+ struct net_device *dev,
+ struct packet_type *pt);
struct llc_addr laddr;
struct list_head node;
struct {
@@ -45,7 +45,8 @@ struct llc_sap_state_ev;
extern void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk);
extern void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk);
-extern void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb);
+extern void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb,
+ struct packet_type *pt);
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb);
#endif /* LLC_SAP_H */
diff --git a/include/net/llc_state.h b/include/net/llc_state.h
deleted file mode 100644
index bb18e9bd1ac8..000000000000
--- a/include/net/llc_state.h
+++ /dev/null
@@ -1,4 +0,0 @@
-char *state_names[] = {
- "ADM","CONN","RESET_WAIT","RESET_CHECK","SETUP",
- "RESET","D_CONN","ERROR","NORMAL"
-};
diff --git a/include/net/p8022.h b/include/net/p8022.h
index 443932810d46..3c99a86c3581 100644
--- a/include/net/p8022.h
+++ b/include/net/p8022.h
@@ -1,9 +1,10 @@
#ifndef _NET_P8022_H
#define _NET_P8022_H
-#include <net/llc_if.h>
-
-extern struct datalink_proto *register_8022_client(unsigned char type,
- int (*indicate)(struct llc_prim_if_block *prim));
+extern struct datalink_proto *
+ register_8022_client(unsigned char type,
+ int (*func)(struct sk_buff *skb,
+ struct net_device *dev,
+ struct packet_type *pt));
extern void unregister_8022_client(struct datalink_proto *proto);
#endif
diff --git a/net/802/p8022.c b/net/802/p8022.c
index b19d8a89071b..3fff5ad047e0 100644
--- a/net/802/p8022.c
+++ b/net/802/p8022.c
@@ -33,7 +33,9 @@ static int p8022_request(struct datalink_proto *dl, struct sk_buff *skb,
}
struct datalink_proto *register_8022_client(unsigned char type,
- int (*indicate)(struct llc_prim_if_block *prim))
+ int (*func)(struct sk_buff *skb,
+ struct net_device *dev,
+ struct packet_type *pt))
{
struct datalink_proto *proto;
@@ -42,7 +44,7 @@ struct datalink_proto *register_8022_client(unsigned char type,
proto->type[0] = type;
proto->header_length = 3;
proto->request = p8022_request;
- proto->sap = llc_sap_open(indicate, NULL, type);
+ proto->sap = llc_sap_open(type, func);
if (!proto->sap) {
kfree(proto);
proto = NULL;
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 228cc88d2bf1..b0dfa847ae0c 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -51,32 +51,23 @@ out:
/*
* A SNAP packet has arrived
*/
-static int snap_indicate(struct llc_prim_if_block *prim)
+static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt)
{
- struct sk_buff *skb;
- struct datalink_proto *proto;
int rc = 1;
- static struct packet_type psnap_packet_type = {
- .type = __constant_htons(ETH_P_SNAP),
- };
-
- if (prim->prim != LLC_DATAUNIT_PRIM)
- goto out;
-
- skb = prim->data->udata.skb;
- proto = find_snap_client(skb->h.raw);
+ struct datalink_proto *proto = find_snap_client(skb->h.raw);
if (proto) {
/* Pass the frame on. */
skb->h.raw += 5;
skb_pull(skb, 5);
- rc = proto->rcvfunc(skb, skb->dev, &psnap_packet_type);
+ rc = proto->rcvfunc(skb, dev, pt);
} else {
skb->sk = NULL;
kfree_skb(skb);
rc = 1;
}
-out:
+
return rc;
}
@@ -99,7 +90,7 @@ EXPORT_SYMBOL(unregister_snap_client);
static int __init snap_init(void)
{
- snap_sap = llc_sap_open(snap_indicate, NULL, 0xAA);
+ snap_sap = llc_sap_open(0xAA, snap_rcv);
if (!snap_sap)
printk(KERN_CRIT "SNAP - unable to register with 802.2\n");
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 7e4b56795c18..a0dedb215d95 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -2252,22 +2252,6 @@ drop: kfree_skb(skb);
out: return ret;
}
-static int ipx_8022_indicate(struct llc_prim_if_block *prim)
-{
- int rc = 1;
- static struct packet_type p8022_packet_type = {
- .type = __constant_htons(ETH_P_802_2),
- };
-
- if (prim->prim == LLC_DATAUNIT_PRIM) {
- struct sk_buff *skb = prim->data->udata.skb;
-
- rc = ipx_rcv(skb, skb->dev, &p8022_packet_type);
- }
-
- return rc;
-}
-
static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len,
struct scm_cookie *scm)
{
@@ -2560,7 +2544,7 @@ static int __init ipx_init(void)
else
printk(ipx_8023_err_msg);
- p8022_datalink = register_8022_client(ipx_8022_type, ipx_8022_indicate);
+ p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv);
if (!p8022_datalink)
printk(ipx_llc_err_msg);
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 8b6c817e87a6..856f39efae9a 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -65,9 +65,7 @@ int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
llc_pdu_decode_sa(skb, llc->daddr.mac);
llc_pdu_decode_da(skb, llc->laddr.mac);
llc->dev = skb->dev;
- /* FIXME: find better way to notify upper layer */
- ev->flag = LLC_CONN_PRIM + 1;
- ev->ind_prim = (void *)1;
+ ev->ind_prim = LLC_CONN_PRIM;
rc = 0;
}
return rc;
@@ -77,8 +75,7 @@ int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- ev->flag = LLC_CONN_PRIM + 1;
- ev->cfm_prim = (void *)1;
+ ev->cfm_prim = LLC_CONN_PRIM;
return 0;
}
@@ -86,12 +83,7 @@ static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- /*
- * FIXME: find better way to tell upper layer that the packet was
- * confirmed by the other endpoint
- */
- ev->flag = LLC_DATA_PRIM + 1;
- ev->cfm_prim = (void *)1;
+ ev->cfm_prim = LLC_DATA_PRIM;
return 0;
}
@@ -130,8 +122,7 @@ int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
}
if (!rc) {
ev->reason = reason;
- ev->flag = LLC_DISC_PRIM + 1;
- ev->ind_prim = (void *)1;
+ ev->ind_prim = LLC_DISC_PRIM;
}
return rc;
}
@@ -141,8 +132,7 @@ int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb)
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
ev->reason = ev->status;
- ev->flag = LLC_DISC_PRIM + 1;
- ev->cfm_prim = (void *)1;
+ ev->cfm_prim = LLC_DISC_PRIM;
return 0;
}
@@ -184,18 +174,8 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
break;
}
if (!rc) {
- struct llc_sap *sap = llc->sap;
- struct llc_prim_if_block *prim = &sap->llc_ind_prim;
- union llc_u_prim_data *prim_data = prim->data;
-
- prim_data->res.sk = sk;
- prim_data->res.link = llc->link;
- prim->data = prim_data;
- prim->prim = LLC_RESET_PRIM;
- prim->sap = sap;
- ev->reason = reason;
- ev->flag = 1;
- ev->ind_prim = prim;
+ ev->reason = reason;
+ ev->ind_prim = LLC_RESET_PRIM;
}
return rc;
}
@@ -203,18 +183,9 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *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->res.sk = sk;
- prim_data->res.link = llc->link;
- prim->data = prim_data;
- prim->prim = LLC_RESET_PRIM;
- prim->sap = sap;
- ev->flag = 1;
- ev->cfm_prim = prim;
+
+ ev->reason = 0;
+ ev->cfm_prim = LLC_RESET_PRIM;
return 0;
}
diff --git a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c
index 9c699fb6b815..85c1489b0a66 100644
--- a/net/llc/llc_c_ev.c
+++ b/net/llc/llc_c_ev.c
@@ -101,48 +101,48 @@ int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- return ev->data.prim.prim == LLC_CONN_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+ return ev->prim == LLC_CONN_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_conn_ev_conn_resp(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- return ev->data.prim.prim == LLC_CONN_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1;
+ return ev->prim == LLC_CONN_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_RESP ? 0 : 1;
}
int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- return ev->data.prim.prim == LLC_DATA_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+ return ev->prim == LLC_DATA_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- return ev->data.prim.prim == LLC_DISC_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+ return ev->prim == LLC_DISC_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- return ev->data.prim.prim == LLC_RESET_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+ return ev->prim == LLC_RESET_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_conn_ev_rst_resp(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- return ev->data.prim.prim == LLC_RESET_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1;
+ return ev->prim == LLC_RESET_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_RESP ? 0 : 1;
}
int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
@@ -150,7 +150,7 @@ int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
- ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
+ ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
}
int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
@@ -158,7 +158,7 @@ int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
- ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
+ ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
}
int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
@@ -666,7 +666,7 @@ int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
- ev->data.a.ev == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
+ ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
}
/* Event qualifier functions
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index 1c1b3b734777..1dafb9e3c965 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -39,12 +39,12 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
/* Offset table on connection states transition diagram */
static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
-void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim)
+void llc_save_primitive(struct sk_buff* skb, u8 prim)
{
struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
/* save primitive for use by the user. */
- addr->sllc_family = sk->family;
+ addr->sllc_family = skb->sk->family;
addr->sllc_arphrd = skb->dev->type;
addr->sllc_test = prim == LLC_TEST_PRIM;
addr->sllc_xid = prim == LLC_XID_PRIM;
@@ -67,110 +67,120 @@ void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim)
*/
int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
{
- /* sending event to state machine */
- int rc = llc_conn_service(sk, skb);
+ int rc;
struct llc_opt *llc = llc_sk(sk);
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- u8 flag = ev->flag;
- u8 status = ev->status;
- struct llc_prim_if_block *ind_prim = ev->ind_prim;
- struct llc_prim_if_block *cfm_prim = ev->cfm_prim;
- /*
- * FIXME: this will vanish as soon I get rid of the last prim crap
- */
- if (flag != LLC_DATA_PRIM + 1 && flag != LLC_CONN_PRIM + 1 &&
- flag != LLC_DISC_PRIM + 1)
- llc_conn_free_ev(skb);
- else if (ind_prim && cfm_prim)
- skb_get(skb);
- if (!flag) /* indicate or confirm not required */
+ ev->ind_prim = ev->cfm_prim = 0;
+ rc = llc_conn_service(sk, skb); /* sending event to state machine */
+ if (rc) {
+ printk(KERN_ERR "%s: llc_conn_service failed\n", __FUNCTION__);
+ goto out_kfree_skb;
+ }
+
+ if (!ev->ind_prim && !ev->cfm_prim) { /* indicate or confirm not required */
+ if (!skb->list)
+ goto out_kfree_skb;
goto out;
- rc = 0;
- if (ind_prim) { /* indication required */
- /*
- * FIXME: this will be saner as soon I get rid of the double
- * sock crap
- */
- switch (flag) {
- case LLC_DATA_PRIM + 1:
- llc_save_primitive(sk, skb, LLC_DATA_PRIM);
- if (sock_queue_rcv_skb(sk, skb)) {
- /*
- * FIXME: have to sync the LLC state
- * machine wrt mem usage with
- * sk->{r,w}mem_alloc, will do
- * this soon 8)
- */
- printk(KERN_ERR
- "%s: sock_queue_rcv_skb failed!\n",
- __FUNCTION__);
- kfree_skb(skb);
- }
- break;
- case LLC_CONN_PRIM + 1: {
- struct sock *parent = skb->sk;
+ }
- skb->sk = sk;
- skb_queue_tail(&parent->receive_queue, skb);
- sk->state_change(parent);
+ if (ev->ind_prim && ev->cfm_prim)
+ skb_get(skb);
+
+ switch (ev->ind_prim) {
+ case LLC_DATA_PRIM:
+ llc_save_primitive(skb, LLC_DATA_PRIM);
+ if (sock_queue_rcv_skb(sk, skb)) {
+ /*
+ * shouldn't happen
+ */
+ printk(KERN_ERR "%s: sock_queue_rcv_skb failed!\n",
+ __FUNCTION__);
+ kfree_skb(skb);
}
- break;
- case LLC_DISC_PRIM + 1:
- sock_hold(sk);
- if (sk->type == SOCK_STREAM && sk->state == TCP_ESTABLISHED) {
- sk->shutdown = SHUTDOWN_MASK;
- sk->socket->state = SS_UNCONNECTED;
- sk->state = TCP_CLOSE;
- if (!sk->dead) {
- sk->state_change(sk);
- sk->dead = 1;
- }
+ break;
+ case LLC_CONN_PRIM: {
+ struct sock *parent = skb->sk;
+
+ skb->sk = sk;
+ skb_queue_tail(&parent->receive_queue, skb);
+ sk->state_change(parent);
+ }
+ break;
+ case LLC_DISC_PRIM:
+ sock_hold(sk);
+ if (sk->type == SOCK_STREAM && sk->state == TCP_ESTABLISHED) {
+ sk->shutdown = SHUTDOWN_MASK;
+ sk->socket->state = SS_UNCONNECTED;
+ sk->state = TCP_CLOSE;
+ if (!sk->dead) {
+ sk->state_change(sk);
+ sk->dead = 1;
}
+ }
+ kfree_skb(skb);
+ sock_put(sk);
+ break;
+ case LLC_RESET_PRIM:
+ /*
+ * FIXME:
+ * RESET is not being notified to upper layers for now
+ */
+ printk(KERN_INFO "%s: received a reset ind!\n", __FUNCTION__);
+ kfree_skb(skb);
+ break;
+ default:
+ if (ev->ind_prim) {
+ printk(KERN_INFO "%s: received unknown %d prim!\n",
+ __FUNCTION__, ev->ind_prim);
kfree_skb(skb);
- sock_put(sk);
- break;
- default:
- llc->sap->ind(ind_prim);
}
+ /* No indication */
+ break;
}
- if (!cfm_prim) /* confirmation not required */
- goto out;
- /* FIXME: see FIXMEs above */
- switch (flag) {
- case LLC_DATA_PRIM + 1:
+
+ switch (ev->cfm_prim) {
+ case LLC_DATA_PRIM:
if (!llc_data_accept_state(llc->state))
- /* In this state, we can send I pdu */
sk->write_space(sk);
else
rc = llc->failed_data_req = 1;
break;
- case LLC_CONN_PRIM + 1:
- if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT)
- goto out_kfree_skb;
- if (status) {
- sk->socket->state = SS_UNCONNECTED;
- sk->state = TCP_CLOSE;
- } else {
- sk->socket->state = SS_CONNECTED;
- sk->state = TCP_ESTABLISHED;
+ case LLC_CONN_PRIM:
+ if (sk->type == SOCK_STREAM && sk->state == TCP_SYN_SENT) {
+ if (ev->status) {
+ sk->socket->state = SS_UNCONNECTED;
+ sk->state = TCP_CLOSE;
+ } else {
+ sk->socket->state = SS_CONNECTED;
+ sk->state = TCP_ESTABLISHED;
+ }
+ sk->state_change(sk);
}
- sk->state_change(sk);
break;
- case LLC_DISC_PRIM + 1:
+ case LLC_DISC_PRIM:
sock_hold(sk);
- if (sk->type != SOCK_STREAM || sk->state != TCP_CLOSING) {
- sock_put(sk);
- goto out_kfree_skb;
+ if (sk->type == SOCK_STREAM && sk->state == TCP_CLOSING) {
+ sk->socket->state = SS_UNCONNECTED;
+ sk->state = TCP_CLOSE;
+ sk->state_change(sk);
}
- sk->socket->state = SS_UNCONNECTED;
- sk->state = TCP_CLOSE;
- sk->state_change(sk);
sock_put(sk);
break;
+ case LLC_RESET_PRIM:
+ /*
+ * FIXME:
+ * RESET is not being notified to upper layers for now
+ */
+ printk(KERN_INFO "%s: received a reset conf!\n", __FUNCTION__);
+ break;
default:
- llc->sap->conf(cfm_prim);
- goto out;
+ if (ev->cfm_prim) {
+ printk(KERN_INFO "%s: received unknown %d prim!\n",
+ __FUNCTION__, ev->cfm_prim);
+ break;
+ }
+ goto out; /* No confirmation */
}
out_kfree_skb:
kfree_skb(skb);
@@ -198,9 +208,7 @@ void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- /* FIXME: indicate that we should send this to the upper layer */
- ev->flag = LLC_DATA_PRIM + 1;
- ev->ind_prim = (void *)1;
+ ev->ind_prim = LLC_DATA_PRIM;
}
/**
@@ -355,12 +363,14 @@ void llc_conn_free_ev(struct sk_buff *skb)
/* 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->flag || !ev->ind_prim)
+ if (LLC_PDU_TYPE_IS_I(pdu) || !ev->ind_prim)
kfree_skb(skb);
} else if (ev->type == LLC_CONN_EV_TYPE_PRIM &&
- ev->data.prim.prim != LLC_DATA_PRIM)
+ ev->prim != LLC_DATA_PRIM)
kfree_skb(skb);
- else if (ev->type == LLC_CONN_EV_TYPE_P_TMR)
+ 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);
}
@@ -541,6 +551,38 @@ out:
}
/**
+ * llc_lookup_dgram - Finds dgram socket for the local sap/mac
+ * @sap: SAP
+ * @laddr: address of local LLC (MAC + SAP)
+ *
+ * Search socket list of the SAP and finds connection using the local
+ * mac, and local sap. Returns pointer for socket found, %NULL otherwise.
+ */
+struct sock *llc_lookup_dgram(struct llc_sap *sap, struct llc_addr *laddr)
+{
+ struct sock *rc = NULL;
+ struct list_head *entry;
+
+ spin_lock_bh(&sap->sk_list.lock);
+ if (list_empty(&sap->sk_list.list))
+ goto out;
+ list_for_each(entry, &sap->sk_list.list) {
+ struct llc_opt *llc = list_entry(entry, struct llc_opt, node);
+
+ if (llc->sk->type == SOCK_DGRAM &&
+ llc->laddr.lsap == laddr->lsap &&
+ llc_mac_match(llc->laddr.mac, laddr->mac)) {
+ rc = llc->sk;
+ break;
+ }
+ }
+ if (rc)
+ sock_hold(rc);
+out:
+ spin_unlock_bh(&sap->sk_list.lock);
+ return rc;
+}
+/**
* llc_data_accept_state - designates if in this state data can be sent.
* @state: state of connection.
*
diff --git a/net/llc/llc_evnt.c b/net/llc/llc_evnt.c
index 181cfb29b44f..6cc65d502c44 100644
--- a/net/llc/llc_evnt.c
+++ b/net/llc/llc_evnt.c
@@ -29,7 +29,7 @@ int llc_stat_ev_enable_with_dup_addr_check(struct llc_station *station,
struct llc_station_state_ev *ev = llc_station_ev(skb);
return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
- ev->data.a.ev ==
+ ev->prim_type ==
LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK ? 0 : 1;
}
@@ -39,7 +39,7 @@ int llc_stat_ev_enable_without_dup_addr_check(struct llc_station *station,
struct llc_station_state_ev *ev = llc_station_ev(skb);
return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
- ev->data.a.ev ==
+ ev->prim_type ==
LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK ? 0 : 1;
}
@@ -120,6 +120,6 @@ int llc_stat_ev_disable_req(struct llc_station *station, struct sk_buff *skb)
struct llc_station_state_ev *ev = llc_station_ev(skb);
return ev->type == LLC_STATION_EV_TYPE_PRIM &&
- ev->data.prim.prim == LLC_DISABLE_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+ ev->prim == LLC_DISABLE_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c
index c876598eea7c..3c6ea87a9837 100644
--- a/net/llc/llc_if.c
+++ b/net/llc/llc_if.c
@@ -30,17 +30,16 @@
/**
* llc_sap_open - open interface to the upper layers.
- * @nw_indicate: pointer to indicate function of upper layer.
- * @nw_confirm: pointer to confirm function of upper layer.
* @lsap: SAP number.
- * @sap: pointer to allocated SAP (output argument).
+ * @func: rcv func for datalink protos
*
* Interface function to upper layer. Each one who wants to get a SAP
* (for example NetBEUI) should call this function. Returns the opened
* SAP for success, NULL for failure.
*/
-struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate,
- llc_prim_call_t nw_confirm, u8 lsap)
+struct llc_sap *llc_sap_open(u8 lsap, int (*func)(struct sk_buff *skb,
+ struct net_device *dev,
+ struct packet_type *pt))
{
/* verify this SAP is not already open; if so, return error */
struct llc_sap *sap;
@@ -57,8 +56,7 @@ 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->ind = nw_indicate;
- sap->conf = nw_confirm;
+ sap->rcv_func = func;
sap->parent_station = llc_station_get();
/* initialized SAP; add it to list of SAPs this station manages */
llc_sap_save(sap);
@@ -99,25 +97,17 @@ void llc_sap_close(struct llc_sap *sap)
void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
u8 *dmac, u8 dsap)
{
- union llc_u_prim_data prim_data;
- struct llc_prim_if_block prim;
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
- prim.data = &prim_data;
- prim.sap = sap;
- prim.prim = LLC_DATAUNIT_PRIM;
+ ev->saddr.lsap = sap->laddr.lsap;
+ ev->daddr.lsap = dsap;
+ memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+ memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
- prim_data.udata.skb = skb;
- prim_data.udata.saddr.lsap = sap->laddr.lsap;
- prim_data.udata.daddr.lsap = dsap;
- memcpy(prim_data.udata.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
- memcpy(prim_data.udata.daddr.mac, dmac, IFHWADDRLEN);
-
- 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;
- llc_sap_state_process(sap, skb);
+ ev->type = LLC_SAP_EV_TYPE_PRIM;
+ ev->prim = LLC_DATAUNIT_PRIM;
+ ev->prim_type = LLC_PRIM_TYPE_REQ;
+ llc_sap_state_process(sap, skb, &llc_packet_type);
}
/**
@@ -130,28 +120,20 @@ void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
* This function is called when upper layer wants to send a TEST pdu.
* Returns 0 for success, 1 otherwise.
*/
-void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
- u8 *dmac, u8 dsap)
+void llc_build_and_send_test_pkt(struct llc_sap *sap,
+ struct sk_buff *skb, u8 *dmac, u8 dsap)
{
- union llc_u_prim_data prim_data;
- struct llc_prim_if_block prim;
struct llc_sap_state_ev *ev = llc_sap_ev(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 = dsap;
- memcpy(prim_data.test.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
- memcpy(prim_data.test.daddr.mac, dmac, IFHWADDRLEN);
+ ev->saddr.lsap = sap->laddr.lsap;
+ ev->daddr.lsap = dsap;
+ memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+ memcpy(ev->daddr.mac, 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;
- llc_sap_state_process(sap, skb);
+ ev->type = LLC_SAP_EV_TYPE_PRIM;
+ ev->prim = LLC_TEST_PRIM;
+ ev->prim_type = LLC_PRIM_TYPE_REQ;
+ llc_sap_state_process(sap, skb, &llc_packet_type);
}
/**
@@ -167,25 +149,17 @@ void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
u8 *dmac, u8 dsap)
{
- union llc_u_prim_data prim_data;
- struct llc_prim_if_block prim;
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
- 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 = dsap;
- memcpy(prim_data.xid.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
- memcpy(prim_data.xid.daddr.mac, dmac, IFHWADDRLEN);
+ ev->saddr.lsap = sap->laddr.lsap;
+ ev->daddr.lsap = dsap;
+ memcpy(ev->saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+ memcpy(ev->daddr.mac, dmac, IFHWADDRLEN);
- 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;
- llc_sap_state_process(sap, skb);
+ ev->type = LLC_SAP_EV_TYPE_PRIM;
+ ev->prim = LLC_XID_PRIM;
+ ev->prim_type = LLC_PRIM_TYPE_REQ;
+ llc_sap_state_process(sap, skb, &llc_packet_type);
}
/**
@@ -219,11 +193,10 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
goto out;
}
ev = llc_conn_ev(skb);
- ev->type = LLC_CONN_EV_TYPE_PRIM;
- ev->data.prim.prim = LLC_DATA_PRIM;
- ev->data.prim.type = LLC_PRIM_TYPE_REQ;
- ev->data.prim.data = NULL;
- skb->dev = llc->dev;
+ ev->type = LLC_CONN_EV_TYPE_PRIM;
+ ev->prim = LLC_DATA_PRIM;
+ ev->prim_type = LLC_PRIM_TYPE_REQ;
+ skb->dev = llc->dev;
rc = llc_conn_state_process(sk, skb);
out:
return rc;
@@ -268,10 +241,9 @@ int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- ev->type = LLC_CONN_EV_TYPE_PRIM;
- ev->data.prim.prim = LLC_CONN_PRIM;
- ev->data.prim.type = LLC_PRIM_TYPE_REQ;
- ev->data.prim.data = NULL;
+ ev->type = LLC_CONN_EV_TYPE_PRIM;
+ ev->prim = LLC_CONN_PRIM;
+ ev->prim_type = LLC_PRIM_TYPE_REQ;
rc = llc_conn_state_process(sk, skb);
}
out_put:
@@ -306,12 +278,11 @@ int llc_send_disc(struct sock *sk)
skb = alloc_skb(0, GFP_ATOMIC);
if (!skb)
goto out;
- sk->state = TCP_CLOSING;
- ev = llc_conn_ev(skb);
- ev->type = LLC_CONN_EV_TYPE_PRIM;
- ev->data.prim.prim = LLC_DISC_PRIM;
- ev->data.prim.type = LLC_PRIM_TYPE_REQ;
- ev->data.prim.data = NULL;
+ sk->state = TCP_CLOSING;
+ ev = llc_conn_ev(skb);
+ ev->type = LLC_CONN_EV_TYPE_PRIM;
+ ev->prim = LLC_DISC_PRIM;
+ ev->prim_type = LLC_PRIM_TYPE_REQ;
rc = llc_conn_state_process(sk, skb);
out:
sock_put(sk);
@@ -327,8 +298,7 @@ out:
* it to connection component state machine. Returns 0 for success, 1
* otherwise.
*/
-int llc_build_and_send_reset_pkt(struct sock *sk,
- struct llc_prim_if_block *prim)
+int llc_build_and_send_reset_pkt(struct sock *sk)
{
int rc = 1;
struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
@@ -336,10 +306,9 @@ int llc_build_and_send_reset_pkt(struct sock *sk,
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- ev->type = LLC_CONN_EV_TYPE_PRIM;
- ev->data.prim.prim = LLC_RESET_PRIM;
- ev->data.prim.type = LLC_PRIM_TYPE_REQ;
- ev->data.prim.data = prim;
+ ev->type = LLC_CONN_EV_TYPE_PRIM;
+ ev->prim = LLC_RESET_PRIM;
+ ev->prim_type = LLC_PRIM_TYPE_REQ;
rc = llc_conn_state_process(sk, skb);
}
return rc;
diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c
index 19eddd8ce38a..820d49540376 100644
--- a/net/llc/llc_mac.c
+++ b/net/llc/llc_mac.c
@@ -37,7 +37,8 @@ u8 llc_mac_null_var[IFHWADDRLEN];
static void fix_up_incoming_skb(struct sk_buff *skb);
static void llc_station_rcv(struct sk_buff *skb);
-static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb);
+static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb,
+ struct packet_type *pt);
/**
* mac_send_pdu - Sends PDU to specific device.
@@ -82,7 +83,7 @@ out:
* data now), it queues this frame in the connection's backlog.
*/
int llc_rcv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *pt)
+ struct packet_type *pt)
{
struct llc_sap *sap;
struct llc_pdu_sn *pdu;
@@ -113,8 +114,16 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
}
llc_decode_pdu_type(skb, &dest);
if (dest == LLC_DEST_SAP) { /* type 1 services */
- dprintk("%s: calling llc_sap_rcv!\n", __FUNCTION__);
- llc_sap_rcv(sap, skb);
+ struct llc_addr laddr;
+ struct sock *sk;
+
+ llc_pdu_decode_da(skb, laddr.mac);
+ llc_pdu_decode_dsap(skb, &laddr.lsap);
+
+ skb->sk = sk = llc_lookup_dgram(sap, &laddr);
+ llc_sap_rcv(sap, skb, pt);
+ if (sk)
+ sock_put(sk);
} else if (dest == LLC_DEST_CONN) {
struct llc_addr saddr, daddr;
struct sock *sk;
@@ -245,16 +254,18 @@ int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
* llc_sap_rcv - sends received pdus to the sap state machine
* @sap: current sap component structure.
* @skb: received frame.
+ * @pt: packet type
*
* Sends received pdus to the sap state machine.
*/
-static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb)
+static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb,
+ struct packet_type *pt)
{
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
ev->type = LLC_SAP_EV_TYPE_PDU;
ev->reason = 0;
- llc_sap_state_process(sap, skb);
+ llc_sap_state_process(sap, skb, pt);
}
/**
diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c
index 4326773996ec..43e231dc6dec 100644
--- a/net/llc/llc_main.c
+++ b/net/llc/llc_main.c
@@ -73,8 +73,6 @@ struct llc_sap *llc_sap_alloc(void)
spin_lock_init(&sap->sk_list.lock);
INIT_LIST_HEAD(&sap->sk_list.list);
skb_queue_head_init(&sap->mac_pdu_q);
- sap->llc_ind_prim.data = &sap->llc_ind_data_prim;
- sap->llc_cfm_prim.data = &sap->llc_cfm_data_prim;
}
return sap;
}
@@ -621,7 +619,7 @@ unlock:
return len;
}
-static struct packet_type llc_packet_type = {
+struct packet_type llc_packet_type = {
.type = __constant_htons(ETH_P_802_2),
.func = llc_rcv,
.data = (void *)1,
@@ -669,7 +667,7 @@ static int __init llc_init(void)
llc_main_station.maximum_retry = 1;
llc_main_station.state = LLC_STATION_STATE_DOWN;
ev->type = LLC_STATION_EV_TYPE_SIMPLE;
- ev->data.a.ev = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
+ ev->prim_type = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
rc = llc_station_next_state(&llc_main_station, skb);
proc_net_create("802.2", 0, llc_proc_get_info);
llc_ui_init();
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
index e3f8ff640a82..d56556925db1 100644
--- a/net/llc/llc_s_ac.c
+++ b/net/llc/llc_s_ac.c
@@ -51,14 +51,12 @@ int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
- struct llc_prim_if_block *prim = ev->data.prim.data;
- struct llc_prim_unit_data *prim_data = &prim->data->udata;
int rc;
- llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
- prim_data->daddr.lsap, LLC_PDU_CMD);
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+ ev->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_ui_cmd(skb);
- rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+ rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
if (!rc)
llc_sap_send_pdu(sap, skb);
return rc;
@@ -76,14 +74,12 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
- struct llc_prim_if_block *prim = ev->data.prim.data;
- struct llc_prim_xid *prim_data = &prim->data->xid;
int rc;
- llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
- prim_data->daddr.lsap, LLC_PDU_CMD);
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+ ev->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
- rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+ rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
if (!rc)
llc_sap_send_pdu(sap, skb);
return rc;
@@ -132,14 +128,12 @@ out:
int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
- struct llc_prim_if_block *prim = ev->data.prim.data;
- struct llc_prim_test *prim_data = &prim->data->test;
int rc;
- llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
- prim_data->daddr.lsap, LLC_PDU_CMD);
+ llc_pdu_header_init(skb, LLC_PDU_TYPE_U, ev->saddr.lsap,
+ ev->daddr.lsap, LLC_PDU_CMD);
llc_pdu_init_as_test_cmd(skb);
- rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+ rc = lan_hdrs_init(skb, ev->saddr.mac, ev->daddr.mac);
if (!rc)
llc_sap_send_pdu(sap, skb);
return rc;
diff --git a/net/llc/llc_s_ev.c b/net/llc/llc_s_ev.c
index 6d172d0eee3a..3b1e02f88dcd 100644
--- a/net/llc/llc_s_ev.c
+++ b/net/llc/llc_s_ev.c
@@ -25,7 +25,7 @@ int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb)
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
- ev->data.a.ev == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1;
+ ev->prim_type == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1;
}
int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb)
@@ -43,8 +43,8 @@ int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb)
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
return ev->type == LLC_SAP_EV_TYPE_PRIM &&
- ev->data.prim.prim == LLC_DATAUNIT_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+ ev->prim == LLC_DATAUNIT_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
@@ -53,8 +53,8 @@ int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb)
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
return ev->type == LLC_SAP_EV_TYPE_PRIM &&
- ev->data.prim.prim == LLC_XID_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+ ev->prim == LLC_XID_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb)
@@ -82,8 +82,8 @@ int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb)
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
return ev->type == LLC_SAP_EV_TYPE_PRIM &&
- ev->data.prim.prim == LLC_TEST_PRIM &&
- ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+ ev->prim == LLC_TEST_PRIM &&
+ ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
}
int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb)
@@ -111,5 +111,5 @@ int llc_sap_ev_deactivation_req(struct llc_sap *sap, struct sk_buff *skb)
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
- ev->data.a.ev == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1;
+ ev->prim_type == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1;
}
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 2285728c2261..9dddee811b18 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -18,6 +18,7 @@
#include <net/llc_s_ac.h>
#include <net/llc_s_st.h>
#include <net/sock.h>
+#include <linux/tcp.h>
#include <net/llc_main.h>
#include <net/llc_mac.h>
#include <net/llc_pdu.h>
@@ -63,21 +64,45 @@ void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk)
/**
* llc_sap_state_process - sends event to SAP state machine
- * @sap: pointer to SAP
+ * @sap: sap to use
* @skb: pointer to occurred event
+ * @pt: packet type, for datalink protos
*
* After executing actions of the event, upper layer will be indicated
- * if needed(on receiving an UI frame).
+ * 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)
+void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb,
+ struct packet_type *pt)
{
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
llc_sap_next_state(sap, skb);
- if (ev->ind_cfm_flag == LLC_IND)
- sap->ind(ev->prim);
- else if (ev->type == LLC_SAP_EV_TYPE_PDU)
+ if (ev->ind_cfm_flag == LLC_IND) {
+ if (sap->rcv_func) {
+ /* FIXME:
+ * Ugly hack, still trying to figure it
+ * out if this is a bug in IPX or here
+ * in LLC Land... But hey, it even works,
+ * no leaks 8)
+ */
+ if (skb->list)
+ skb_get(skb);
+ sap->rcv_func(skb, skb->dev, pt);
+ } else {
+ if (skb->sk->state == TCP_LISTEN)
+ goto drop;
+
+ llc_save_primitive(skb, ev->prim);
+
+ /* queue skb to the user. */
+ if (sock_queue_rcv_skb(skb->sk, skb))
+ kfree_skb(skb);
+ }
+ } else if (ev->type == LLC_SAP_EV_TYPE_PDU) {
+drop:
kfree_skb(skb);
+ }
}
/**
@@ -89,43 +114,17 @@ 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_prim_if_block *prim = &sap->llc_ind_prim;
- union llc_u_prim_data *prim_data = prim->data;
- u8 lfb;
- llc_pdu_decode_sa(skb, prim_data->udata.saddr.mac);
- llc_pdu_decode_da(skb, prim_data->udata.daddr.mac);
- llc_pdu_decode_dsap(skb, &prim_data->udata.daddr.lsap);
- llc_pdu_decode_ssap(skb, &prim_data->udata.saddr.lsap);
- prim_data->udata.pri = 0;
- prim_data->udata.skb = skb;
pdu = llc_pdu_un_hdr(skb);
switch (LLC_U_PDU_RSP(pdu)) {
- case LLC_1_PDU_CMD_TEST:
- prim->prim = LLC_TEST_PRIM;
- break;
- case LLC_1_PDU_CMD_XID:
- prim->prim = LLC_XID_PRIM;
- break;
- case LLC_1_PDU_CMD_UI:
- if (skb->protocol == ntohs(ETH_P_TR_802_2)) {
- if (((struct trh_hdr *)skb->mac.raw)->rcf) {
- lfb = ntohs(((struct trh_hdr *)
- skb->mac.raw)->rcf) &
- 0x0070;
- prim_data->udata.lfb = lfb >> 4;
- } else {
- lfb = 0xFF;
- prim_data->udata.lfb = 0xFF;
- }
- }
- prim->prim = LLC_DATAUNIT_PRIM;
- break;
+ case LLC_1_PDU_CMD_TEST:
+ ev->prim = LLC_TEST_PRIM; break;
+ case LLC_1_PDU_CMD_XID:
+ ev->prim = LLC_XID_PRIM; break;
+ case LLC_1_PDU_CMD_UI:
+ ev->prim = LLC_DATAUNIT_PRIM; break;
}
- prim->data = prim_data;
- prim->sap = sap;
ev->ind_cfm_flag = LLC_IND;
- ev->prim = prim;
}
/**
diff --git a/net/llc/llc_sock.c b/net/llc/llc_sock.c
index 5db767d647a3..3376f48d1227 100644
--- a/net/llc/llc_sock.c
+++ b/net/llc/llc_sock.c
@@ -51,11 +51,7 @@ static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
static u16 llc_ui_sap_link_no_max[256];
static struct sockaddr_llc llc_ui_addrnull;
static struct proto_ops llc_ui_ops;
-static struct sock *llc_ui_sockets;
-static rwlock_t llc_ui_sockets_lock = RW_LOCK_UNLOCKED;
-static int llc_ui_indicate(struct llc_prim_if_block *prim);
-static int llc_ui_confirm(struct llc_prim_if_block *prim);
static int llc_ui_wait_for_conn(struct sock *sk, int timeout);
static int llc_ui_wait_for_disc(struct sock *sk, int timeout);
static int llc_ui_wait_for_data(struct sock *sk, int timeout);
@@ -145,103 +141,6 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock)
return rc;
}
-/**
- * __llc_ui_find_sk_by_addr - return socket matching local mac + sap.
- * @addr: Local address to match.
- *
- * Search the local socket list and return the socket which has a matching
- * local (mac + sap) address (allows null mac). This search will work on
- * unconnected and connected sockets, though find_by_link_no is recommend
- * for connected sockets.
- * Returns sock upon match, %NULL otherwise.
- */
-static struct sock *__llc_ui_find_sk_by_addr(struct llc_addr *laddr,
- struct llc_addr *daddr,
- struct net_device *dev)
-{
- struct sock *sk;
-
- for (sk = llc_ui_sockets; sk; sk = sk->next) {
- struct llc_opt *llc = llc_sk(sk);
-
- if (llc->addr.sllc_ssap != laddr->lsap)
- continue;
- if (llc_mac_null(llc->addr.sllc_smac)) {
- if (!llc_mac_null(llc->addr.sllc_mmac) &&
- !llc_mac_match(llc->addr.sllc_mmac,
- laddr->mac))
- continue;
- break;
- }
- if (dev && !llc_mac_null(llc->addr.sllc_mmac) &&
- llc_mac_match(llc->addr.sllc_mmac, laddr->mac) &&
- llc_mac_match(llc->addr.sllc_smac, dev->dev_addr))
- break;
- if (dev->flags & IFF_LOOPBACK)
- break;
- if (!llc_mac_match(llc->addr.sllc_smac, laddr->mac))
- continue;
- if (llc_mac_null(llc->addr.sllc_dmac))
- break;
- }
- return sk;
-}
-
-static struct sock *llc_ui_find_sk_by_addr(struct llc_addr *addr,
- struct llc_addr *daddr,
- struct net_device *dev)
-{
- struct sock *sk;
-
- read_lock(&llc_ui_sockets_lock);
- sk = __llc_ui_find_sk_by_addr(addr, daddr, dev);
- if (sk)
- sock_hold(sk);
- read_unlock(&llc_ui_sockets_lock);
- return sk;
-}
-
-/**
- * llc_ui_insert_socket - insert socket into list
- * @sk: Socket to insert.
- *
- * Insert a socket into the local llc socket list.
- */
-static __inline__ void llc_ui_insert_socket(struct sock *sk)
-{
- write_lock_bh(&llc_ui_sockets_lock);
- sk->next = llc_ui_sockets;
- if (sk->next)
- llc_ui_sockets->pprev = &sk->next;
- llc_ui_sockets = sk;
- sk->pprev = &llc_ui_sockets;
- sock_hold(sk);
- write_unlock_bh(&llc_ui_sockets_lock);
-}
-
-/**
- * llc_ui_remove_socket - remove socket from list
- * @sk: Socket to remove.
- *
- * Remove a socket from the local llc socket list.
- */
-static __inline__ void llc_ui_remove_socket(struct sock *sk)
-{
- write_lock_bh(&llc_ui_sockets_lock);
- if (sk->pprev) {
- if (sk->next)
- sk->next->pprev = sk->pprev;
- *sk->pprev = sk->next;
- sk->pprev = NULL;
- /*
- * This only makes sense if the socket was inserted on the
- * list, if sk->pprev is NULL it wasn't
- */
- sock_put(sk);
- }
- write_unlock_bh(&llc_ui_sockets_lock);
-}
-
static void llc_ui_sk_init(struct socket *sock, struct sock *sk)
{
sk->type = sock->type;
@@ -296,10 +195,8 @@ static int llc_ui_release(struct socket *sock)
llc->laddr.lsap, llc->daddr.lsap);
if (!llc_send_disc(sk))
llc_ui_wait_for_disc(sk, sk->rcvtimeo);
- if (!sk->zapped) {
+ if (!sk->zapped)
llc_sap_unassign_sock(llc->sap, sk);
- llc_ui_remove_socket(sk);
- }
release_sock(sk);
if (llc->sap && list_empty(&llc->sap->sk_list.list))
llc_sap_close(llc->sap);
@@ -384,8 +281,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
}
sap = llc_sap_find(addr->sllc_ssap);
if (!sap) {
- sap = llc_sap_open(llc_ui_indicate, llc_ui_confirm,
- addr->sllc_ssap);
+ sap = llc_sap_open(addr->sllc_ssap, NULL);
rc = -EBUSY; /* some other network layer is using the sap */
if (!sap)
goto out;
@@ -420,7 +316,6 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
llc->daddr.lsap = addr->sllc_dsap;
memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
memcpy(&llc->addr, addr, sizeof(llc->addr));
- llc_ui_insert_socket(sk);
/* assign new connection to it's SAP */
llc_sap_assign_sock(sap, sk);
rc = sk->zapped = 0;
@@ -769,7 +664,6 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
/* put original socket back into a clean listen state. */
sk->state = TCP_LISTEN;
sk->ack_backlog--;
- llc_ui_insert_socket(newsk);
skb->sk = NULL;
dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
llc_sk(sk)->addr.sllc_ssap, newllc->addr.sllc_dsap);
@@ -1126,178 +1020,6 @@ out:
return rc;
}
-/**
- * llc_ui_ind_test - handle TEST indication
- * @prim: Primitive block provided by the llc layer.
- *
- * handle TEST indication.
- */
-static void llc_ui_ind_test(struct llc_prim_if_block *prim)
-{
- struct llc_prim_test *prim_data = &prim->data->test;
- struct sk_buff *skb = prim_data->skb;
- struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
- struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
- &prim_data->saddr, skb->dev);
- if (!sk)
- goto out;
- if (sk->state == TCP_LISTEN)
- goto out_put;
- /* save primitive for use by the user. */
- addr->sllc_family = AF_LLC;
- addr->sllc_arphrd = skb->dev->type;
- addr->sllc_test = 1;
- addr->sllc_xid = 0;
- addr->sllc_ua = 0;
- addr->sllc_dsap = prim_data->daddr.lsap;
- memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
- addr->sllc_ssap = prim_data->saddr.lsap;
- memcpy(addr->sllc_smac, prim_data->saddr.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_xid - handle XID indication
- * @prim: Primitive block provided by the llc layer.
- *
- * handle XID indication.
- */
-static void llc_ui_ind_xid(struct llc_prim_if_block *prim)
-{
- struct llc_prim_xid *prim_data = &prim->data->xid;
- struct sk_buff *skb = prim_data->skb;
- struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
- struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
- &prim_data->saddr, skb->dev);
- if (!sk)
- goto out;
- if (sk->state == TCP_LISTEN)
- goto out_put;
- /* save primitive for use by the user. */
- addr->sllc_family = AF_LLC;
- addr->sllc_arphrd = 0;
- addr->sllc_test = 0;
- addr->sllc_xid = 1;
- addr->sllc_ua = 0;
- addr->sllc_dsap = prim_data->daddr.lsap;
- memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
- addr->sllc_ssap = prim_data->saddr.lsap;
- memcpy(addr->sllc_smac, prim_data->saddr.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_dataunit - handle DATAUNIT indication
- * @prim: Primitive block provided by the llc layer.
- *
- * handle DATAUNIT indication.
- */
-static void llc_ui_ind_dataunit(struct llc_prim_if_block *prim)
-{
- struct llc_prim_unit_data *prim_data = &prim->data->udata;
- struct sk_buff *skb = prim_data->skb;
- struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
- struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
- &prim_data->saddr, skb->dev);
- if (!sk)
- goto out;
- if (sk->state == TCP_LISTEN)
- goto out_put;
- /* save primitive for use by the user. */
- addr->sllc_family = AF_LLC;
- addr->sllc_arphrd = skb->dev->type;
- addr->sllc_test = 0;
- addr->sllc_xid = 0;
- addr->sllc_ua = 1;
- addr->sllc_dsap = prim_data->daddr.lsap;
- memcpy(addr->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
- addr->sllc_ssap = prim_data->saddr.lsap;
- memcpy(addr->sllc_smac, prim_data->saddr.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_indicate - LLC user interface hook into the LLC layer.
- * @prim: Primitive block provided by the llc layer.
- *
- * LLC user interface hook into the LLC layer, every llc_ui sap references
- * this function as its indicate handler.
- * Always returns 0 to indicate reception of primitive.
- */
-static int llc_ui_indicate(struct llc_prim_if_block *prim)
-{
- switch (prim->prim) {
- case LLC_TEST_PRIM:
- llc_ui_ind_test(prim); break;
- case LLC_XID_PRIM:
- llc_ui_ind_xid(prim); break;
- case LLC_DATAUNIT_PRIM:
- llc_ui_ind_dataunit(prim); break;
- case LLC_CONN_PRIM:
- dprintk("%s: shouldn't happen, LLC_CONN_PRIM "
- "is gone for ->ind()...\n", __FUNCTION__);
- break;
- case LLC_DATA_PRIM:
- dprintk("%s: shouldn't happen, LLC_DATA_PRIM "
- "is gone for ->ind()...\n", __FUNCTION__);
- break;
- case LLC_DISC_PRIM:
- dprintk("%s: shouldn't happen, LLC_DISC_PRIM "
- "is gone for ->ind()...\n", __FUNCTION__);
- break;
- case LLC_RESET_PRIM:
- default: break;
- }
- return 0;
-}
-
-/**
- * llc_ui_confirm - LLC user interface hook into the LLC layer
- * @prim: Primitive block provided by the llc layer.
- *
- * LLC user interface hook into the LLC layer, every llc_ui sap references
- * this function as its confirm handler.
- * Always returns 0 to indicate reception of primitive.
- */
-static int llc_ui_confirm(struct llc_prim_if_block *prim)
-{
- switch (prim->prim) {
- case LLC_CONN_PRIM:
- dprintk("%s: shouldn't happen, LLC_CONN_PRIM "
- "is gone for ->conf()...\n", __FUNCTION__);
- break;
- case LLC_DATA_PRIM:
- dprintk("%s: shouldn't happen, LLC_DATA_PRIM "
- "is gone for ->conf()...\n", __FUNCTION__);
- break;
- case LLC_DISC_PRIM:
- dprintk("%s: shouldn't happen, LLC_DISC_PRIM "
- "is gone for ->conf()...\n", __FUNCTION__);
- break;
- case LLC_RESET_PRIM: break;
- default:
- printk(KERN_ERR "%s: prim not supported%d\n", __FUNCTION__,
- prim->prim);
- break;
- }
- return 0;
-}
-
#ifdef CONFIG_PROC_FS
#define MAC_FORMATTED_SIZE 17
static void llc_ui_format_mac(char *bf, unsigned char *mac)