o LLC: trim down llc_core to the very basic support needed by IPX et all

Renaming the basic support module to llc.ko and introducing llc_core.c,
that has just the basic output path for llc_build_and_send_ui_pkt.

Next step will be to rename llc_main.c to llc_station.c, then consolidate
all the llc station code in this file, removing all the not needed
llc_station parameters and killing struct llc_station altogether,
no sense in having it as there is just one station, always. BTW in
this changeset parts of llc_main_station was already moved to llc_core.c,
namely the sap list and lock.
parent 4d44110b
......@@ -9,7 +9,7 @@ menu "Token Ring devices"
config TR
bool "Token Ring driver support"
depends on (PCI || ISA || MCA || CCW)
select LLC_CORE
select LLC
help
Token Ring is IBM's way of communication on a local network; the
rest of the world uses Ethernet. To participate on a Token Ring
......
......@@ -12,15 +12,55 @@
* See the GNU General Public License for more details.
*/
#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
#define LLC_DEST_SAP 1 /* Type 1 goes here */
#define LLC_DEST_CONN 2 /* Type 2 goes here */
#include <linux/if.h>
#include <linux/list.h>
#include <linux/spinlock.h>
struct llc_sap;
struct net_device;
struct packet_type;
struct sk_buff;
struct llc_addr {
unsigned char lsap;
unsigned char mac[IFHWADDRLEN];
};
#define LLC_SAP_STATE_INACTIVE 1
#define LLC_SAP_STATE_ACTIVE 2
/**
* struct llc_sap - Defines the SAP component
*
* @station - station this sap belongs to
* @state - sap state
* @p_bit - only lowest-order bit used
* @f_bit - only lowest-order bit used
* @laddr - SAP value in this 'lsap'
* @node - entry in station sap_list
* @sk_list - LLC sockets this one manages
*/
struct llc_sap {
unsigned char state;
unsigned char p_bit;
unsigned char f_bit;
int (*rcv_func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt);
struct llc_addr laddr;
struct list_head node;
struct {
rwlock_t lock;
struct hlist_head list;
} sk_list;
};
#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
#define LLC_DEST_SAP 1 /* Type 1 goes here */
#define LLC_DEST_CONN 2 /* Type 2 goes here */
extern struct list_head llc_sap_list;
extern rwlock_t llc_sap_list_lock;
extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt);
......@@ -29,4 +69,13 @@ extern void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
extern void llc_remove_pack(int type);
extern void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
extern struct llc_sap *llc_sap_open(unsigned char lsap,
int (*rcv)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt));
extern void llc_sap_close(struct llc_sap *sap);
extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
unsigned char *dmac, unsigned char dsap);
#endif /* LLC_H */
......@@ -45,6 +45,8 @@ static __inline__ struct llc_station_state_ev *
return (struct llc_station_state_ev *)skb->cb;
}
struct llc_station;
typedef int (*llc_station_ev_t)(struct llc_station *station,
struct sk_buff *skb);
......
......@@ -16,6 +16,7 @@
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/llc.h>
#include <net/llc.h>
#define LLC_DATAUNIT_PRIM 1
#define LLC_CONN_PRIM 2
......@@ -60,13 +61,6 @@
#define LLC_STATUS_CONFLICT 7 /* disconnect conn */
#define LLC_STATUS_RESET_DONE 8 /* */
/* Structures and types */
/* SAP/MAC Address pair */
struct llc_addr {
u8 lsap;
u8 mac[IFHWADDRLEN];
};
extern u8 llc_mac_null_var[IFHWADDRLEN];
/**
......
......@@ -11,6 +11,9 @@
*
* See the GNU General Public License for more details.
*/
#include <linux/skbuff.h>
#define LLC_EVENT 1
#define LLC_PACKET 2
#define LLC_TYPE_1 1
......@@ -39,10 +42,6 @@ struct llc_station {
u8 retry_count;
u8 maximum_retry;
u8 mac_sa[6];
struct {
rwlock_t lock;
struct list_head list;
} sap_list;
struct {
struct sk_buff_head list;
spinlock_t lock;
......@@ -50,15 +49,10 @@ struct llc_station {
struct sk_buff_head mac_pdu_q;
};
extern struct llc_sap *llc_sap_alloc(void);
extern void llc_sap_save(struct llc_sap *sap);
extern void llc_free_sap(struct llc_sap *sap);
extern struct llc_sap *llc_sap_find(u8 lsap);
extern void llc_station_state_process(struct llc_station *station,
struct sk_buff *skb);
extern void llc_station_send_pdu(struct llc_station *station,
struct sk_buff *skb);
extern struct sk_buff *llc_alloc_frame(void);
extern struct llc_station llc_main_station;
extern int __init llc_station_init(void);
extern void __exit llc_station_exit(void);
#endif /* LLC_MAIN_H */
......@@ -11,10 +11,7 @@
*
* See the GNU General Public License for more details.
*/
/* Defines SAP component states */
#define LLC_SAP_STATE_INACTIVE 1
#define LLC_SAP_STATE_ACTIVE 2
#define LLC_NR_SAP_STATES 2 /* size of state table */
/* structures and types */
......
......@@ -2,7 +2,7 @@
#define LLC_SAP_H
/*
* Copyright (c) 1997 by Procom Technology,Inc.
* 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
* This program can be redistributed or modified under the terms of the
* GNU General Public License as published by the Free Software Foundation.
......@@ -11,50 +11,20 @@
*
* 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
*
* @station - station this sap belongs to
* @state - sap state
* @p_bit - only lowest-order bit used
* @f_bit - only lowest-order bit used
* @laddr - SAP value in this 'lsap'
* @node - entry in station sap_list
* @sk_list - LLC sockets this one manages
*/
struct llc_sap {
struct llc_station *station;
u8 state;
u8 p_bit;
u8 f_bit;
int (*rcv_func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt);
struct llc_addr laddr;
struct list_head node;
struct {
rwlock_t lock;
struct hlist_head list;
} sk_list;
};
struct llc_sap;
struct sk_buff;
extern void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_save_primitive(struct sk_buff* skb, u8 prim);
extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim);
extern struct sk_buff *llc_alloc_frame(void);
extern struct llc_sap *llc_sap_open(u8 lsap,
int (*rcv)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt));
extern void llc_sap_close(struct llc_sap *sap);
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,
u8 *dmac, u8 dsap);
extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
struct sk_buff *skb, u8 *dmac, u8 dsap);
struct sk_buff *skb,
unsigned char *dmac,
unsigned char dsap);
extern void llc_build_and_send_xid_pkt(struct llc_sap *sap,
struct sk_buff *skb,
unsigned char *dmac,
unsigned char dsap);
#endif /* LLC_SAP_H */
......@@ -22,8 +22,8 @@
#include <linux/mm.h>
#include <linux/in.h>
#include <linux/init.h>
#include <net/llc.h>
#include <net/p8022.h>
#include <net/llc_sap.h>
static int p8022_request(struct datalink_proto *dl, struct sk_buff *skb,
unsigned char *dest)
......
......@@ -15,8 +15,8 @@
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <net/datalink.h>
#include <net/llc.h>
#include <net/psnap.h>
#include <net/llc_sap.h>
#include <linux/mm.h>
#include <linux/in.h>
#include <linux/init.h>
......
......@@ -374,7 +374,7 @@ source "net/llc/Kconfig"
config IPX
tristate "The IPX protocol"
select LLC_CORE
select LLC
---help---
This is support for the Novell networking protocol, IPX, commonly
used for local networks of Windows machines. You need it if you
......@@ -411,7 +411,7 @@ source "net/ipx/Kconfig"
config ATALK
tristate "Appletalk protocol support"
select LLC_CORE
select LLC
---help---
AppleTalk is the protocol that Apple computers can use to communicate
on a network. If your Linux box is connected to such a network and you
......
......@@ -12,7 +12,7 @@ obj-$(CONFIG_NET) := socket.o core/
obj-$(CONFIG_COMPAT) += compat.o
# LLC has to be linked before the files in net/802/
obj-$(CONFIG_LLC_CORE) += llc/
obj-$(CONFIG_LLC) += llc/
obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/
obj-$(CONFIG_INET) += ipv4/ xfrm/
obj-$(CONFIG_UNIX) += unix/
......
config LLC_CORE
config LLC
tristate
depends on NET
config LLC2
tristate "ANSI/IEEE 802.2 LLC type 2 Support"
select LLC_CORE
select LLC
help
This is a Logical Link Layer type 2, connection oriented support.
Select this if you want to have support for PF_LLC sockets.
......@@ -12,14 +12,14 @@
# See the GNU General Public License for more details.
###########################################################################
obj-$(CONFIG_LLC_CORE) += llc_core.o
obj-$(CONFIG_LLC) += llc.o
llc_core-y := llc_input.o llc_output.o llc_s_st.o llc_s_ac.o llc_s_ev.o \
llc_main.o llc_actn.o llc_stat.o llc_evnt.o llc_sap.o
llc-y := llc_core.o llc_input.o llc_output.o
obj-$(CONFIG_LLC2) += llc2.o
llc2-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_conn.o llc_c_st.o llc_pdu.o \
af_llc.o
llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_main.o \
llc_actn.o llc_stat.o llc_evnt.o
llc2-$(CONFIG_PROC_FS) += llc_proc.o
......@@ -1053,6 +1053,7 @@ static int __init llc2_init(void)
int rc;
llc_build_offset_table();
llc_station_init();
llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
rc = llc_proc_init();
if (!rc) {
......@@ -1065,6 +1066,7 @@ static int __init llc2_init(void)
static void __exit llc2_exit(void)
{
llc_station_exit();
llc_remove_pack(LLC_DEST_SAP);
llc_remove_pack(LLC_DEST_CONN);
sock_unregister(PF_LLC);
......
/*
* llc_core.c - Minimum needed routines for sap handling and module init/exit
*
* Copyright (c) 1997 by Procom Technology, Inc.
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
* This program can be redistributed or modified under the terms of the
* GNU General Public License as published by the Free Software Foundation.
* This program is distributed without any warranty or implied warranty
* of merchantability or fitness for a particular purpose.
*
* See the GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/if_ether.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <net/llc.h>
LIST_HEAD(llc_sap_list);
rwlock_t llc_sap_list_lock = RW_LOCK_UNLOCKED;
unsigned char llc_station_mac_sa[ETH_ALEN];
/**
* llc_sap_alloc - allocates and initializes sap.
*
* Allocates and initializes sap.
*/
struct llc_sap *llc_sap_alloc(void)
{
struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC);
if (sap) {
memset(sap, 0, sizeof(*sap));
sap->state = LLC_SAP_STATE_ACTIVE;
memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
rwlock_init(&sap->sk_list.lock);
}
return sap;
}
/**
* llc_add_sap - add sap to station list
* @sap: Address of the sap
*
* Adds a sap to the LLC's station sap list.
*/
void llc_add_sap(struct llc_sap *sap)
{
write_lock_bh(&llc_sap_list_lock);
list_add_tail(&sap->node, &llc_sap_list);
write_unlock_bh(&llc_sap_list_lock);
}
/**
* llc_del_sap - del sap from station list
* @sap: Address of the sap
*
* Removes a sap to the LLC's station sap list.
*/
void llc_del_sap(struct llc_sap *sap)
{
write_lock_bh(&llc_sap_list_lock);
list_del(&sap->node);
write_unlock_bh(&llc_sap_list_lock);
}
/**
* llc_sap_find - searchs a SAP in station
* @sap_value: sap to be found
*
* Searchs for a sap in the sap list of the LLC's station upon the sap ID.
* Returns the sap or %NULL if not found.
*/
struct llc_sap *llc_sap_find(unsigned char sap_value)
{
struct llc_sap* sap = NULL;
struct list_head *entry;
read_lock_bh(&llc_sap_list_lock);
list_for_each(entry, &llc_sap_list) {
sap = list_entry(entry, struct llc_sap, node);
if (sap->laddr.lsap == sap_value)
break;
}
if (entry == &llc_sap_list) /* not found */
sap = NULL;
read_unlock_bh(&llc_sap_list_lock);
return sap;
}
/**
* llc_sap_open - open interface to the upper layers.
* @lsap: SAP number.
* @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(unsigned char lsap,
int (*func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt))
{
struct llc_sap *sap = llc_sap_find(lsap);
if (sap) { /* SAP already exists */
sap = NULL;
goto out;
}
sap = llc_sap_alloc();
if (!sap)
goto out;
sap->laddr.lsap = lsap;
sap->rcv_func = func;
llc_add_sap(sap);
out:
return sap;
}
/**
* llc_sap_close - close interface for upper layers.
* @sap: SAP to be closed.
*
* Close interface function to upper layer. Each one who wants to
* close an open SAP (for example NetBEUI) should call this function.
* Removes this sap from the list of saps in the station and then
* frees the memory for this sap.
*/
void llc_sap_close(struct llc_sap *sap)
{
WARN_ON(!hlist_empty(&sap->sk_list.list));
llc_del_sap(sap);
kfree(sap);
}
static struct packet_type llc_packet_type = {
.type = __constant_htons(ETH_P_802_2),
.func = llc_rcv,
.data = (void *)1,
};
static struct packet_type llc_tr_packet_type = {
.type = __constant_htons(ETH_P_TR_802_2),
.func = llc_rcv,
.data = (void *)1,
};
static int __init llc_init(void)
{
if (dev_base->next)
memcpy(llc_station_mac_sa, dev_base->next->dev_addr, ETH_ALEN);
else
memset(llc_station_mac_sa, 0, ETH_ALEN);
dev_add_pack(&llc_packet_type);
dev_add_pack(&llc_tr_packet_type);
return 0;
}
static void __exit llc_exit(void)
{
dev_remove_pack(&llc_packet_type);
dev_remove_pack(&llc_tr_packet_type);
}
module_init(llc_init);
module_exit(llc_exit);
EXPORT_SYMBOL(llc_sap_list);
EXPORT_SYMBOL(llc_sap_list_lock);
EXPORT_SYMBOL(llc_sap_find);
EXPORT_SYMBOL(llc_sap_open);
EXPORT_SYMBOL(llc_sap_close);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
MODULE_DESCRIPTION("LLC IEEE 802.2 core support");
......@@ -43,44 +43,8 @@ static u16 llc_exec_station_trans_actions(struct llc_station *station,
static struct llc_station_state_trans *
llc_find_station_trans(struct llc_station *station,
struct sk_buff *skb);
struct llc_station llc_main_station; /* only one of its kind */
/**
* llc_sap_save - add sap to station list
* @sap: Address of the sap
*
* Adds a sap to the LLC's station sap list.
*/
void llc_sap_save(struct llc_sap *sap)
{
write_lock_bh(&llc_main_station.sap_list.lock);
list_add_tail(&sap->node, &llc_main_station.sap_list.list);
write_unlock_bh(&llc_main_station.sap_list.lock);
}
/**
* llc_sap_find - searchs a SAP in station
* @sap_value: sap to be found
*
* Searchs for a sap in the sap list of the LLC's station upon the sap ID.
* Returns the sap or %NULL if not found.
*/
struct llc_sap *llc_sap_find(u8 sap_value)
{
struct llc_sap* sap = NULL;
struct list_head *entry;
read_lock_bh(&llc_main_station.sap_list.lock);
list_for_each(entry, &llc_main_station.sap_list.list) {
sap = list_entry(entry, struct llc_sap, node);
if (sap->laddr.lsap == sap_value)
break;
}
if (entry == &llc_main_station.sap_list.list) /* not found */
sap = NULL;
read_unlock_bh(&llc_main_station.sap_list.lock);
return sap;
}
static struct llc_station llc_main_station;
/**
* llc_station_state_process: queue event and try to process queue.
......@@ -265,49 +229,12 @@ static void llc_station_rcv(struct sk_buff *skb)
llc_station_state_process(&llc_main_station, skb);
}
/**
* llc_alloc_frame - allocates sk_buff for frame
*
* Allocates an sk_buff for frame and initializes sk_buff fields.
* Returns allocated skb or %NULL when out of memory.
*/
struct sk_buff *llc_alloc_frame(void)
{
struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
if (skb) {
skb_reserve(skb, 50);
skb->nh.raw = skb->h.raw = skb->data;
skb->protocol = htons(ETH_P_802_2);
skb->dev = dev_base->next;
skb->mac.raw = skb->head;
}
return skb;
}
static struct packet_type llc_packet_type = {
.type = __constant_htons(ETH_P_802_2),
.func = llc_rcv,
.data = (void *)1,
};
static struct packet_type llc_tr_packet_type = {
.type = __constant_htons(ETH_P_TR_802_2),
.func = llc_rcv,
.data = (void *)1,
};
static char llc_error_msg[] __initdata =
KERN_ERR "LLC install NOT successful.\n";
static int __init llc_init(void)
int __init llc_station_init(void)
{
u16 rc = 0;
u16 rc = -ENOBUFS;
struct sk_buff *skb;
struct llc_station_state_ev *ev;
INIT_LIST_HEAD(&llc_main_station.sap_list.list);
rwlock_init(&llc_main_station.sap_list.lock);
skb_queue_head_init(&llc_main_station.mac_pdu_q);
skb_queue_head_init(&llc_main_station.ev_q.list);
spin_lock_init(&llc_main_station.ev_q.lock);
......@@ -317,46 +244,22 @@ static int __init llc_init(void)
skb = alloc_skb(0, GFP_ATOMIC);
if (!skb)
goto err;
goto out;
rc = 0;
llc_set_station_handler(llc_station_rcv);
ev = llc_station_ev(skb);
memset(ev, 0, sizeof(*ev));
if (dev_base->next)
memcpy(llc_main_station.mac_sa,
dev_base->next->dev_addr, ETH_ALEN);
else
memset(llc_main_station.mac_sa, 0, ETH_ALEN);
llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
llc_main_station.maximum_retry = 1;
llc_main_station.state = LLC_STATION_STATE_DOWN;
ev->type = LLC_STATION_EV_TYPE_SIMPLE;
ev->prim_type = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
rc = llc_station_next_state(&llc_main_station, skb);
dev_add_pack(&llc_packet_type);
dev_add_pack(&llc_tr_packet_type);
out:
return rc;
err:
printk(llc_error_msg);
rc = 1;
goto out;
}
static void __exit llc_exit(void)
void __exit llc_station_exit(void)
{
dev_remove_pack(&llc_packet_type);
dev_remove_pack(&llc_tr_packet_type);
llc_set_station_handler(NULL);
}
module_init(llc_init);
module_exit(llc_exit);
EXPORT_SYMBOL(llc_sap_find);
EXPORT_SYMBOL(llc_alloc_frame);
EXPORT_SYMBOL(llc_main_station);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Procom 1997, Jay Schullist 2001, Arnaldo C. Melo 2001-2003");
MODULE_DESCRIPTION("LLC IEEE 802.2 extended support");
MODULE_ALIAS_NETPROTO(PF_LLC);
/*
* llc_output.c - LLC output path
* llc_output.c - LLC minimal output path
*
* Copyright (c) 1997 by Procom Technology, Inc.
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
......@@ -17,6 +17,8 @@
#include <linux/if_tr.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <net/llc.h>
#include <net/llc_pdu.h>
/**
* llc_mac_hdr_init - fills MAC header fields
......@@ -72,4 +74,32 @@ int llc_mac_hdr_init(struct sk_buff *skb, unsigned char *sa, unsigned char *da)
return rc;
}
/**
* llc_build_and_send_ui_pkt - unitdata request interface for upper layers
* @sap: sap to use
* @skb: packet to send
* @dmac: destination mac address
* @dsap: destination sap
*
* 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
*/
int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
unsigned char *dmac, unsigned char dsap)
{
int rc;
llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
dsap, LLC_PDU_CMD);
llc_pdu_init_as_ui_cmd(skb);
rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
if (!rc)
rc = dev_queue_xmit(skb);
return rc;
}
EXPORT_SYMBOL(llc_mac_hdr_init);
EXPORT_SYMBOL(llc_build_and_send_ui_pkt);
......@@ -20,12 +20,11 @@
#include <linux/errno.h>
#include <linux/seq_file.h>
#include <net/sock.h>
#include <net/llc.h>
#include <net/llc_c_ac.h>
#include <net/llc_c_ev.h>
#include <net/llc_c_st.h>
#include <net/llc_conn.h>
#include <net/llc_main.h>
#include <net/llc_sap.h>
static void llc_ui_format_mac(struct seq_file *seq, unsigned char *mac)
{
......@@ -40,7 +39,7 @@ static struct sock *llc_get_sk_idx(loff_t pos)
struct hlist_node *node;
struct sock *sk = NULL;
list_for_each(sap_entry, &llc_main_station.sap_list.list) {
list_for_each(sap_entry, &llc_sap_list) {
sap = list_entry(sap_entry, struct llc_sap, node);
read_lock_bh(&sap->sk_list.lock);
......@@ -65,7 +64,7 @@ static void *llc_seq_start(struct seq_file *seq, loff_t *pos)
{
loff_t l = *pos;
read_lock_bh(&llc_main_station.sap_list.lock);
read_lock_bh(&llc_sap_list_lock);
return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
}
......@@ -91,7 +90,7 @@ static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
read_unlock_bh(&sap->sk_list.lock);
sk = NULL;
for (;;) {
if (sap->node.next == &llc_main_station.sap_list.list)
if (sap->node.next == &llc_sap_list)
break;
sap = list_entry(sap->node.next, struct llc_sap, node);
read_lock_bh(&sap->sk_list.lock);
......@@ -114,7 +113,7 @@ static void llc_seq_stop(struct seq_file *seq, void *v)
read_unlock_bh(&sap->sk_list.lock);
}
read_unlock_bh(&llc_main_station.sap_list.lock);
read_unlock_bh(&llc_sap_list_lock);
}
static int llc_seq_socket_show(struct seq_file *seq, void *v)
......
......@@ -23,6 +23,26 @@
#include <net/llc_pdu.h>
#include <linux/if_tr.h>
/**
* llc_alloc_frame - allocates sk_buff for frame
*
* Allocates an sk_buff for frame and initializes sk_buff fields.
* Returns allocated skb or %NULL when out of memory.
*/
struct sk_buff *llc_alloc_frame(void)
{
struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
if (skb) {
skb_reserve(skb, 50);
skb->nh.raw = skb->h.raw = skb->data;
skb->protocol = htons(ETH_P_802_2);
skb->dev = dev_base->next;
skb->mac.raw = skb->head;
}
return skb;
}
void llc_save_primitive(struct sk_buff* skb, u8 prim)
{
struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
......@@ -180,36 +200,6 @@ void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
kfree_skb(skb);
}
/**
* llc_build_and_send_ui_pkt - unitdata request interface for upper layers
* @sap: sap to use
* @skb: packet to send
* @dmac: destination mac address
* @dsap: destination sap
*
* 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
*/
void llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
u8 *dmac, u8 dsap)
{
struct llc_sap_state_ev *ev = llc_sap_ev(skb);
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->prim = LLC_DATAUNIT_PRIM;
ev->prim_type = LLC_PRIM_TYPE_REQ;
llc_sap_state_process(sap, skb);
}
/**
* llc_build_and_send_test_pkt - TEST interface for upper layers.
* @sap: sap to use
......@@ -325,79 +315,6 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
kfree_skb(skb);
}
/**
* llc_sap_alloc - allocates and initializes sap.
*
* Allocates and initializes sap.
*/
struct llc_sap *llc_sap_alloc(void)
{
struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC);
if (sap) {
memset(sap, 0, sizeof(*sap));
sap->state = LLC_SAP_STATE_ACTIVE;
memcpy(sap->laddr.mac, llc_main_station.mac_sa, ETH_ALEN);
rwlock_init(&sap->sk_list.lock);
}
return sap;
}
/**
* llc_sap_open - open interface to the upper layers.
* @lsap: SAP number.
* @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(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;
sap = llc_sap_find(lsap);
if (sap) { /* SAP already exists */
sap = NULL;
goto out;
}
/* sap requested does not yet exist */
sap = llc_sap_alloc();
if (!sap)
goto out;
/* allocated a SAP; initialize it and clear out its memory pool */
sap->laddr.lsap = lsap;
sap->rcv_func = func;
sap->station = &llc_main_station;
/* initialized SAP; add it to list of SAPs this station manages */
llc_sap_save(sap);
out:
return sap;
}
/**
* llc_sap_close - close interface for upper layers.
* @sap: SAP to be closed.
*
* Close interface function to upper layer. Each one who wants to
* close an open SAP (for example NetBEUI) should call this function.
* Removes this sap from the list of saps in the station and then
* frees the memory for this sap.
*/
void llc_sap_close(struct llc_sap *sap)
{
WARN_ON(!hlist_empty(&sap->sk_list.list));
write_lock_bh(&sap->station->sap_list.lock);
list_del(&sap->node);
write_unlock_bh(&sap->station->sap_list.lock);
kfree(sap);
}
EXPORT_SYMBOL(llc_sap_open);
EXPORT_SYMBOL(llc_sap_close);
EXPORT_SYMBOL(llc_save_primitive);
EXPORT_SYMBOL(llc_build_and_send_test_pkt);
EXPORT_SYMBOL(llc_build_and_send_ui_pkt);
......
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