* See the GNU General Public License for more details.
*/
#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/if_tr.h>
-#include <linux/rtnetlink.h>
#include <net/llc_mac.h>
#include <net/llc_pdu.h>
#include <net/llc_sap.h>
#include <net/llc_main.h>
-#include <net/llc_evnt.h>
-#include <linux/trdevice.h>
#if 0
#define dprintk(args...) printk(KERN_DEBUG args)
#define dprintk(args...)
#endif
-static void llc_station_rcv(struct sk_buff *skb);
+/*
+ * Packet handler for the station, registerable because in the minimal
+ * LLC core that is taking shape only the very minimal subset of LLC that
+ * is needed for things like IPX, Appletalk, etc will stay, with all the
+ * rest in the llc1 and llc2 modules.
+ */
+static void (*llc_station_handler)(struct sk_buff *skb);
/*
* Packet handlers for LLC_DEST_SAP and LLC_DEST_CONN.
*/
static void (*llc_type_handlers[2])(struct llc_sap *sap,
- struct sk_buff *skb);
+ struct sk_buff *skb);
void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
struct sk_buff *skb))
llc_type_handlers[type] = NULL;
}
+void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
+{
+ llc_station_handler = handler;
+}
+
/**
* llc_pdu_type - returns which LLC component must handle for PDU
* @skb: input skb
if (unlikely(!llc_fixup_skb(skb)))
goto drop;
pdu = llc_pdu_sn_hdr(skb);
- if (unlikely(!pdu->dsap)) { /* NULL DSAP, refer to station */
- dprintk("%s: calling llc_station_rcv!\n", __FUNCTION__);
- llc_station_rcv(skb);
- goto out;
- }
+ if (unlikely(!pdu->dsap)) /* NULL DSAP, refer to station */
+ goto handle_station;
sap = llc_sap_find(pdu->dsap);
if (unlikely(!sap)) {/* unknown SAP */
dprintk("%s: llc_sap_find(%02X) failed!\n", __FUNCTION__,
drop:
kfree_skb(skb);
goto out;
-}
-
-/*
- * llc_station_rcv - send received pdu to the station state machine
- * @skb: received frame.
- *
- * Sends data unit to station state machine.
- */
-static void llc_station_rcv(struct sk_buff *skb)
-{
- struct llc_station_state_ev *ev = llc_station_ev(skb);
-
- ev->type = LLC_STATION_EV_TYPE_PDU;
- ev->reason = 0;
- llc_station_state_process(&llc_main_station, skb);
+handle_station:
+ if (!llc_station_handler)
+ goto drop;
+ llc_station_handler(skb);
+ goto out;
}
EXPORT_SYMBOL(llc_add_pack);
EXPORT_SYMBOL(llc_remove_pack);
+EXPORT_SYMBOL(llc_set_station_handler);
return rc;
}
+/*
+ * llc_station_rcv - send received pdu to the station state machine
+ * @skb: received frame.
+ *
+ * Sends data unit to station state machine.
+ */
+static void llc_station_rcv(struct sk_buff *skb)
+{
+ struct llc_station_state_ev *ev = llc_station_ev(skb);
+
+ ev->type = LLC_STATION_EV_TYPE_PDU;
+ ev->reason = 0;
+ llc_station_state_process(&llc_main_station, skb);
+}
+
/**
* llc_alloc_frame - allocates sk_buff for frame
*
skb = alloc_skb(0, GFP_ATOMIC);
if (!skb)
goto err;
+ llc_set_station_handler(llc_station_rcv);
ev = llc_station_ev(skb);
memset(ev, 0, sizeof(*ev));
if (dev_base->next)
{
dev_remove_pack(&llc_packet_type);
dev_remove_pack(&llc_tr_packet_type);
+ llc_set_station_handler(NULL);
}
module_init(llc_init);