759 lines
19 KiB
C
759 lines
19 KiB
C
/* $Header: /usr/local/cvsroot/wanpipe_common/include/wanpipe_lip.h,v 1.44 2008/03/25 22:46:01 sangoma Exp $ */
|
|
|
|
#ifndef _WANPIPE_LIP_HEADER_
|
|
#define _WANPIPE_LIP_HEADER_
|
|
|
|
#include "wanpipe_includes.h"
|
|
#include "wanpipe_defines.h"
|
|
#include "wanpipe_debug.h"
|
|
#include "wanpipe_common.h"
|
|
#include "wanpipe_abstr.h"
|
|
#include "wanpipe_snmp.h"
|
|
#include "wanproc.h"
|
|
#include "wanpipe.h"
|
|
#include "wanpipe_cfg.h"
|
|
|
|
#if defined (__LINUX__)
|
|
# include "if_wanpipe.h"
|
|
#endif
|
|
|
|
#if defined(__WINDOWS__)
|
|
# include "linux_if_ether.h"
|
|
#endif
|
|
|
|
#include "if_wanpipe_common.h"
|
|
#include "wanpipe_fr_iface.h"
|
|
#include "wanpipe_lip_atm_iface.h"
|
|
#include "wanpipe_sppp_iface.h"
|
|
|
|
#if defined(CONFIG_PRODUCT_WANPIPE_LAPB) || defined(CONFIG_PRODUCT_WANPIPE_LIP_LAPD)
|
|
# include "wanpipe_lapb_iface.h"
|
|
#endif
|
|
#if defined(CONFIG_PRODUCT_WANPIPE_LIP_KATM)
|
|
# include "wanpipe_katm_iface.h"
|
|
#endif
|
|
#if defined(CONFIG_PRODUCT_WANPIPE_XDLC)
|
|
# include "wanpipe_xdlc_iface.h"
|
|
#endif
|
|
#if defined(CONFIG_PRODUCT_WANPIPE_XMTP2)
|
|
# include "wanpipe_xmtp2_iface.h"
|
|
#endif
|
|
#if defined(CONFIG_PRODUCT_WANPIPE_LIP_HDLC)
|
|
# include "wanpipe_lip_hdlc_iface.h"
|
|
#endif
|
|
#include "wanpipe_lip_kernel.h"
|
|
#include "wanpipe_iface.h"
|
|
|
|
#if defined (__LINUX__) && defined (WPLIP_TTY_SUPPORT)
|
|
# include <linux/tty.h>
|
|
# include <linux/tty_driver.h>
|
|
# include <linux/tty_flip.h>
|
|
#endif
|
|
|
|
|
|
#if defined(__WINDOWS__)
|
|
/* Prototypes for interface between LIP and 'sprotocol' code in virt_adap_enum.c: */
|
|
extern int sdla_tx_down(void* dev, void *tx_skb);
|
|
extern int sdla_data_rx_up(void* sdla_net_dev, void *rx_skb);
|
|
extern void netif_carrier_off(void* dev);
|
|
extern void netif_carrier_on(void* dev);
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef WAN_KERNEL
|
|
|
|
/*
|
|
***********************************************************************************
|
|
* *
|
|
* X25HDR.C is the 'C' header file for the Sangoma X.25 code for the S508 adapter. *
|
|
* *
|
|
***********************************************************************************
|
|
*/
|
|
|
|
#define LIP_OK 0
|
|
#define TCPIP 0
|
|
|
|
#define MAX_CALL_REQ_ASYNC_PKT 512
|
|
|
|
#define NON_D_OPT 3
|
|
#define D_OPT 2
|
|
|
|
#define FLOW_CONTROL_MASK 0x1F
|
|
|
|
#define ONE_BYTE 1
|
|
#define MAX_TOKENS 31
|
|
|
|
#define MODNAME "wanpipe_lip"
|
|
|
|
#define MAX_LINK_RX_Q_LEN 10
|
|
#define MAX_TAIL_ROOM 16
|
|
#define MAX_LIP_LINKS 255
|
|
|
|
#if 0
|
|
/* This option defaults the inital network
|
|
* interface state to STOPPED/DISABLED.
|
|
*
|
|
* In this case, all traffic will be blocked
|
|
* and data pushed back up the protocol stack.
|
|
* This can cause memory starvation if there are
|
|
* many interfaces running, because each interface
|
|
* queue can be up to 100 packets, and fames will
|
|
* only be dropped once the queue is overfilled
|
|
*
|
|
* By disabling this option, all packets received
|
|
* by the interface in disconnected state, will be
|
|
* silently discarded with carrier stat incremented.
|
|
*/
|
|
#define WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF
|
|
#endif
|
|
|
|
/* BH flags */
|
|
enum{
|
|
WPLIP_BH_RUNNING,
|
|
WPLIP_RX_FSM_RUNNING,
|
|
WPLIP_SMP_CONFLICT,
|
|
WPLIP_BH_AWAITING_KICK,
|
|
WPLIP_LINK_TIMER_EXPIRED,
|
|
WPLIP_MORE_LINK_TX,
|
|
WPLIP_LINK_DOWN,
|
|
WPLIP_KICK,
|
|
WPLIP_TTY_BUSY
|
|
|
|
};
|
|
|
|
|
|
/* LIP DEV Critical */
|
|
enum {
|
|
WPLIP_TX_WINDOW_CLOSED,
|
|
WPLIP_SEND_AWAITING_KICK,
|
|
WPLIP_TIMER_EXPIRED,
|
|
WPLIP_DEV_DOWN,
|
|
WPLIP_DEV_UNREGISTER,
|
|
WPLIP_RX,
|
|
WPLIP_IOCTL_SMP,
|
|
WPLIP_DEV_SENDING
|
|
};
|
|
|
|
#define MAX_RX_FACIL_CODE 30
|
|
|
|
#define BH_DEBUG 0
|
|
|
|
#define SOFT_INIT 0
|
|
#define HARD_INIT 1
|
|
#define MAX_SOFTIRQ_TIMEOUT 2
|
|
|
|
/*
|
|
* Physical X25 Link
|
|
* Each Link can support multiple logical
|
|
* channels (svc).
|
|
*/
|
|
#define MAX_LCN 255
|
|
#define MAX_DECODE_BUF_SZ 1000
|
|
#if defined(__WINDOWS__)
|
|
#define MAX_PROC_NAME WAN_IFNAME_SZ
|
|
#else
|
|
#define MAX_PROC_NAME 10
|
|
#endif
|
|
|
|
#ifndef MAX_PROC_EVENTS
|
|
#define MAX_PROC_EVENTS 20
|
|
#endif
|
|
#define MAX_PROC_EVENT_SIZE X25_CALL_STR_SZ+200+1
|
|
|
|
|
|
/*#define MAX_TX_BUF 10*/
|
|
#define MAX_TX_BUF 10
|
|
#define MAX_ATM_TX_BUF 35
|
|
#define MAX_RX_Q 32
|
|
|
|
#define WPLIP_MAGIC_LINK 0xDAFE1234
|
|
#define WPLIP_MAGIC_DEV 0xDAFE4321
|
|
#define WPLIP_MAGIC_DEV_EL 0xDAFE4444
|
|
|
|
#define WPLIP_ASSERT_MAGIC(ptr,magic,ret) \
|
|
if ((*(unsigned long*)ptr) != magic) { \
|
|
DEBUG_EVENT("%s:%d: Error Invalid Magic number in Link dev!\n", \
|
|
__FUNCTION__,__LINE__); \
|
|
return ret ; \
|
|
}
|
|
#define WPLIP_ASSERT_MAGIC_VOID(ptr,magic) \
|
|
if ((*(unsigned long*)ptr) != magic) { \
|
|
DEBUG_EVENT("%s:%d: Error Invalid Magic number in Link dev!\n", \
|
|
__FUNCTION__,__LINE__); \
|
|
return; \
|
|
}
|
|
|
|
struct wplip_dev;
|
|
|
|
WAN_LIST_HEAD(wplip_link_list,wplip_link);
|
|
|
|
typedef struct wplip_link
|
|
{
|
|
unsigned long magic;
|
|
WAN_LIST_ENTRY(wplip_link) list_entry;
|
|
|
|
/* List of all Logic channel
|
|
* devices attached to the link
|
|
*
|
|
* Packet direction UP
|
|
* */
|
|
WAN_LIST_HEAD(NAME_PLACEHOLDER,wplip_dev) list_head_ifdev;
|
|
unsigned int dev_cnt;
|
|
wan_rwlock_t dev_list_lock;
|
|
|
|
|
|
/* List of Tx Devices attached
|
|
* to the Link.
|
|
*
|
|
* Packet direction DOWN
|
|
*
|
|
* Eg. Load balancing over multiple
|
|
* links */
|
|
|
|
WAN_LIST_HEAD(NAME_PLACEHOLDER,wplip_dev_list) list_head_tx_ifdev;
|
|
unsigned int tx_dev_cnt;
|
|
wan_rwlock_t tx_dev_list_lock;
|
|
|
|
|
|
unsigned char state;
|
|
unsigned char carrier_state;
|
|
unsigned char prot_state;
|
|
|
|
void *prot;/* this is the pointer to protocol object */
|
|
|
|
wan_timer_t prot_timer;
|
|
|
|
unsigned char protocol;
|
|
|
|
|
|
/* Internal control information */
|
|
wan_timer_info_t timer;
|
|
|
|
unsigned long tq_working;
|
|
|
|
wan_rwlock_t map_lock;
|
|
void *api_sk_id;
|
|
|
|
wan_spinlock_t bh_lock;
|
|
|
|
unsigned char name [MAX_PROC_NAME];
|
|
#if 0
|
|
struct proc_dir_entry *proc_dir;
|
|
unsigned char *proc_event_log [MAX_PROC_EVENTS];
|
|
atomic_t proc_event_offset;
|
|
#endif
|
|
|
|
wan_skb_queue_t tx_queue;
|
|
wan_skb_queue_t rx_queue;
|
|
wan_tasklet_t task;
|
|
#if defined(__FreeBSD__) && defined(WPLIP_TQ_THREAD)
|
|
struct taskqueue *tq;
|
|
#endif
|
|
|
|
struct wplip_dev *cur_tx;
|
|
|
|
int link_num;
|
|
|
|
atomic_t refcnt;
|
|
|
|
unsigned char tty_opt;
|
|
|
|
#ifdef WPLIP_TTY_SUPPORT
|
|
struct tty_struct *tty;
|
|
struct tty_port tty_port;
|
|
unsigned int tty_minor;
|
|
unsigned int tty_open;
|
|
unsigned char *tty_buf;
|
|
wan_skb_queue_t tty_rx;
|
|
wan_taskq_t tty_task_queue;
|
|
unsigned char async_mode;
|
|
#endif
|
|
|
|
wan_taskq_t prot_task;
|
|
u32 latency_qlen;
|
|
|
|
#if defined(__WINDOWS__)
|
|
void *sdla_card; /* for wplip_link_callback_tx_down() */
|
|
#endif
|
|
|
|
} wplip_link_t;
|
|
|
|
|
|
#define CALL_REQUEST_INFO_SZ 512
|
|
|
|
|
|
/*
|
|
* The logic channel per link connection control structure.
|
|
*/
|
|
typedef struct wplip_dev{
|
|
|
|
wanpipe_common_t common;
|
|
|
|
unsigned long magic;
|
|
WAN_LIST_ENTRY(wplip_dev) list_entry;
|
|
|
|
wan_bitmap_t critical;
|
|
|
|
/* Internal control information */
|
|
wan_skb_queue_t tx_queue;
|
|
|
|
/* The link we are part of */
|
|
wplip_link_t *lip_link;
|
|
|
|
void *sk_id;
|
|
unsigned char api_state;
|
|
#if defined(__LINUX__)
|
|
struct proc_dir_entry *dent;
|
|
#endif
|
|
#if defined(__WINDOWS__)
|
|
struct net_device_stats ifstats;
|
|
#endif
|
|
unsigned char used;
|
|
unsigned char protocol;
|
|
|
|
unsigned char name[MAX_PROC_NAME];
|
|
|
|
unsigned char udp_pkt_data[sizeof(wan_udp_pkt_t)+10];
|
|
unsigned int udp_pkt_len;
|
|
|
|
unsigned long ipx_net_num;
|
|
|
|
unsigned int prot_addr;
|
|
|
|
unsigned int max_mtu_sz;
|
|
unsigned int max_mtu_sz_orig;
|
|
|
|
atomic_t refcnt;
|
|
pid_t pid;
|
|
|
|
unsigned int interface_down;
|
|
unsigned int if_down;
|
|
|
|
wan_taskq_t if_task;
|
|
|
|
} wplip_dev_t;
|
|
|
|
typedef struct wplip_dev_list
|
|
{
|
|
unsigned long magic;
|
|
netdevice_t *dev;
|
|
WAN_LIST_ENTRY(wplip_dev_list) list_entry;
|
|
}wplip_dev_list_t;
|
|
|
|
|
|
typedef struct wplip_prot_iface
|
|
{
|
|
unsigned int init;
|
|
wplip_prot_reg_t reg;
|
|
void*(*prot_link_register)(void *link_ptr,
|
|
char *devname,
|
|
void *cfg,
|
|
wplip_prot_reg_t *reg);
|
|
|
|
int (*prot_link_unregister)(void *prot_ptr);
|
|
|
|
void*(*prot_chan_register)(void *if_ptr,
|
|
void *prot_ptr,
|
|
char *devname,
|
|
void *cfg,
|
|
unsigned char type);
|
|
|
|
int (*prot_chan_unregister)(void *chan_ptr);
|
|
|
|
int (*open_chan) (void *chan_ptr);
|
|
int (*close_chan)(void *chan_ptr);
|
|
|
|
int (*tx) (void *chan_ptr, void *skb, int type);
|
|
int (*ioctl) (void *chan_ptr, int cmd, void *arg);
|
|
int (*pipemon)(void *chan,
|
|
int cmd,
|
|
int dlci,
|
|
unsigned char* data,
|
|
unsigned int *len);
|
|
|
|
int (*rx) (void *prot_ptr, void *rx_pkt);
|
|
|
|
int (*timer) (void *prot_ptr, unsigned int *period, unsigned int);
|
|
|
|
int (*bh) (void *);
|
|
int (*snmp) (void *, void *);
|
|
int (*task) (void *prot_ptr);
|
|
|
|
}wplip_prot_iface_t;
|
|
|
|
#define MAX_LIP_PROTOCOLS 255
|
|
|
|
#define WPLIP_PROT_ASSERT(prot,ret) \
|
|
if (prot >= MAX_LIP_PROTOCOLS){ \
|
|
DEBUG_EVENT("%s:%d: Lip Error: Invalid Protocol 0x%X\n",\
|
|
__FUNCTION__,__LINE__,prot);\
|
|
return ret; \
|
|
}
|
|
|
|
#define WPLIP_PROT_FUNC_ASSERT(prot,func,ret) \
|
|
if (prot->func == NULL){ \
|
|
DEBUG_EVENT("%s:%d: Lip Error: Protocol function not supported\n",\
|
|
__FUNCTION__,__LINE__);\
|
|
return ret; \
|
|
}
|
|
|
|
#define WPLIP_PROT_EXIST(prot,ret) \
|
|
if (wplip_prot_ops[prot] == NULL){ \
|
|
DEBUG_EVENT("%s:%d: Lip Error: Unsupported/UnCompiled Protocol 0x%X\n",\
|
|
__FUNCTION__,__LINE__,prot);\
|
|
return ret; \
|
|
}
|
|
|
|
|
|
#define wplip_hold(_dev) wan_atomic_inc(&(_dev)->refcnt)
|
|
#define wplip_put(_dev) wan_atomic_dec(&(_dev)->refcnt)
|
|
|
|
|
|
#define wplip_get_link(_reg) (_reg)->wplip_link
|
|
|
|
/*--------------------------------------------------------------*/
|
|
/* Macros to access lipdev pointer inside of netdevice_t pointer.
|
|
* Use of those macros encouraged for code readability reasons and
|
|
* allows to adapt easily to future modifications in netdevice_t
|
|
* structure. */
|
|
#define wplip_netdev_get_lipdev(_dev) (wplip_dev_t*)wan_netif_priv((_dev))
|
|
#define wplip_netdev_set_lipdev(_dev, _lipdev) wan_netif_set_priv(_dev, _lipdev)
|
|
/*--------------------------------------------------------------*/
|
|
|
|
#define wplip_liplink_magic(_link) ((_link)->magic == WPLIP_MAGIC_LINK)
|
|
#define wplip_lipdev_magic(_lipdev) ((_lipdev)->magic == WPLIP_MAGIC_DEV)
|
|
|
|
|
|
/* Function Prototypes */
|
|
|
|
/* wanpipe_lip_iface.c */
|
|
extern wan_bitmap_t wplip_link_num[];
|
|
extern wan_rwlock_t wplip_link_lock;
|
|
extern struct wplip_link_list list_head_link;
|
|
extern int wplip_data_rx_up(wplip_dev_t* lip_dev, void *skb);
|
|
extern int wplip_data_tx_down(wplip_link_t *lip_link, void *skb);
|
|
extern int wplip_callback_tx_down(void *lip_dev, void *skb);
|
|
extern int wplip_link_callback_tx_down(void *lip_link, void *skb);
|
|
extern int wplip_callback_kick_prot_task(void *lip_link);
|
|
extern int wplip_set_hw_idle_frame (void *liplink_ptr, unsigned char *data, int len);
|
|
|
|
#if defined(__WINDOWS__)
|
|
extern wplip_reg_t wplip_protocol;
|
|
extern int wanpipe_lip_init(void*);
|
|
extern int wanpipe_lip_exit(void*);
|
|
#endif
|
|
|
|
/* wanpipe_lip_sub.c */
|
|
extern wplip_link_t* wplip_create_link(char *devname);
|
|
extern void wplip_remove_link(wplip_link_t *lip_link);
|
|
extern void wplip_insert_link(wplip_link_t *lip_link);
|
|
extern int wplip_link_exists(wplip_link_t *lip_link);
|
|
extern void wplip_free_link(wplip_link_t *lip_link);
|
|
extern int wplip_lipdev_latency_change(wplip_link_t *lip_link);
|
|
|
|
#if defined(__WINDOWS__)
|
|
extern wplip_dev_t* wplip_create_lipdev(netdevice_t *dev, int usedby);
|
|
#else
|
|
extern wplip_dev_t* wplip_create_lipdev(char *dev_name, int usedby);
|
|
#endif
|
|
|
|
extern void wplip_free_lipdev(wplip_dev_t *lip_dev);
|
|
extern int wplip_lipdev_exists(wplip_link_t *lip_link, char *dev_name);
|
|
extern void wplip_remove_lipdev(wplip_link_t *lip_link,
|
|
wplip_dev_t *lip_dev);
|
|
extern void wplip_insert_lipdev(wplip_link_t *wplip_link,
|
|
wplip_dev_t *wplip_dev);
|
|
|
|
extern unsigned int dec_to_uint (unsigned char* str, int len);
|
|
|
|
/* wanpipe_lip_netdev.c */
|
|
extern int wplip_open_dev(netdevice_t *dev);
|
|
extern int wplip_stop_dev(netdevice_t *dev);
|
|
extern struct net_device_stats * wplip_ifstats (netdevice_t *dev);
|
|
extern int wplip_if_send (netskb_t *skb, netdevice_t *dev);
|
|
extern int wplip_if_init(netdevice_t *dev);
|
|
extern void wplip_kick(void *wplip_id,int reason);
|
|
|
|
|
|
# ifdef WPLIP_TTY_SUPPORT
|
|
/* wanpipe_lip_tty.c */
|
|
extern int wplip_reg_tty(wplip_link_t *lip_link, wanif_conf_t *conf);
|
|
extern int wplip_unreg_tty(wplip_link_t *lip_link);
|
|
extern int wanpipe_tty_trigger_poll(wplip_link_t *lip_link);
|
|
extern void wplip_tty_receive(wplip_link_t *lip_link, void *skb);
|
|
#endif
|
|
|
|
/* wanpipe_lip_prot.c */
|
|
extern int wplip_init_prot(void);
|
|
extern int wplip_free_prot(void);
|
|
extern int wplip_reg_link_prot(wplip_link_t *lip_link, wanif_conf_t *conf);
|
|
extern int wplip_unreg_link_prot(wplip_link_t *lip_link);
|
|
extern int wplip_reg_lipdev_prot(wplip_dev_t *lip_dev, wanif_conf_t *conf);
|
|
extern int wplip_unreg_lipdev_prot(wplip_dev_t *lip_dev);
|
|
extern int wplip_open_lipdev_prot(wplip_dev_t *lip_dev);
|
|
extern int wplip_close_lipdev_prot(wplip_dev_t *lip_dev);
|
|
extern int wplip_prot_rx(wplip_link_t *lip_link, netskb_t *skb);
|
|
extern int wplip_change_mtu(netdevice_t *dev, int new_mtu);
|
|
|
|
#if 0
|
|
extern void wplip_prot_rx_kick(wplip_dev_t *lip_dev);
|
|
#endif
|
|
extern int wplip_prot_kick(wplip_link_t *lip_link, wplip_dev_t *lip_dev);
|
|
extern int wplip_prot_tx(wplip_dev_t *lip_dev, wan_api_tx_hdr_t *api_tx_hdr, netskb_t *skb, int type);
|
|
extern int wplip_prot_oob(wplip_dev_t *lip_dev, unsigned char*, int reason);
|
|
extern int wplip_prot_ioctl(wplip_dev_t *lip_dev, int cmd, void *arg);
|
|
extern int wplip_prot_udp_mgmt_pkt(wplip_dev_t * lip_dev, wan_udp_pkt_t *wan_udp_pkt);
|
|
extern int wplip_prot_udp_snmp_pkt(wplip_dev_t * lip_dev, int cmd, struct ifreq* ifr);
|
|
|
|
|
|
extern int wplip_link_prot_change_state(void *wplip_id,
|
|
int state,
|
|
unsigned char*,int);
|
|
extern int wplip_lipdev_prot_change_state(void *wplip_id,
|
|
int state,
|
|
unsigned char*,int);
|
|
|
|
|
|
extern int wplip_lipdev_prot_update_state_change(wplip_dev_t *wplip_id,unsigned char*,int);
|
|
|
|
|
|
extern unsigned int wplip_get_ipv4_addr (void *wplip_id, int type);
|
|
extern int wplip_set_ipv4_addr (void *wplip_id,
|
|
unsigned int,
|
|
unsigned int,
|
|
unsigned int,
|
|
unsigned int);
|
|
extern void wplip_add_gateway(void *wplip_id);
|
|
extern void wplip_trigger_if_task(wplip_dev_t *lip_dev);
|
|
|
|
void wplip_ipxwan_switch_net_num(unsigned char *sendpacket,
|
|
unsigned long network_number,
|
|
unsigned long *orig_dnet,
|
|
unsigned long *orig_snet,
|
|
unsigned char incoming);
|
|
|
|
|
|
void wplip_ipxwan_restore_net_num(unsigned char *sendpacke,
|
|
unsigned long orig_dnet,
|
|
unsigned long orig_snet);
|
|
|
|
|
|
int wplip_handle_ipxwan(wplip_dev_t *lip_dev, void *skb);
|
|
|
|
#if 0
|
|
extern int gdbg_flag;
|
|
#endif
|
|
|
|
static __inline int wplip_trigger_bh(wplip_link_t *lip_link)
|
|
{
|
|
if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){
|
|
return -ENETDOWN;
|
|
}
|
|
|
|
if (wan_skb_queue_len(&lip_link->rx_queue)){
|
|
#if defined(__LINUX__) || !defined(WPLIP_TQ_THREAD)
|
|
WAN_TASKLET_SCHEDULE((&lip_link->task));
|
|
#else
|
|
WAN_TASKQUEUE_SCHEDULE(lip_link->tq,&lip_link->task);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
if (wan_test_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working)){
|
|
#if 0
|
|
if (gdbg_flag){
|
|
DEBUG_EVENT("%s: Waiting for kick!\n",
|
|
__FUNCTION__);
|
|
}
|
|
#endif
|
|
return -EBUSY;
|
|
}
|
|
|
|
#if 0
|
|
gdbg_flag=0;
|
|
#endif
|
|
#if defined(__LINUX__) || !defined(WPLIP_TQ_THREAD)
|
|
WAN_TASKLET_SCHEDULE((&lip_link->task));
|
|
#else
|
|
WAN_TASKQUEUE_SCHEDULE(lip_link->tq,&lip_link->task);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
static __inline int wplip_kick_trigger_bh(wplip_link_t *lip_link)
|
|
{
|
|
wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working);
|
|
#if defined(__LINUX__) || !defined(WPLIP_TQ_THREAD)
|
|
WAN_TASKLET_SCHEDULE((&lip_link->task));
|
|
#else
|
|
WAN_TASKQUEUE_SCHEDULE(lip_link->tq,&lip_link->task);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
static __inline int wplip_decode_protocol(wplip_dev_t *lip_dev, void *ptr)
|
|
{
|
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
|
struct sockaddr *sa = (struct sockaddr *)ptr;
|
|
|
|
|
|
switch (sa->sa_family){
|
|
|
|
case AF_INET:
|
|
return WPLIP_IP;
|
|
case AF_INET6:
|
|
return WPLIP_IPV6;
|
|
case AF_IPX:
|
|
return WPLIP_IPX;
|
|
default:
|
|
return WPLIP_IP;
|
|
}
|
|
|
|
#elif defined(__LINUX__)
|
|
struct sk_buff *skb=(struct sk_buff*)ptr;
|
|
|
|
if (lip_dev->common.usedby == BRIDGE ||
|
|
lip_dev->common.usedby == BRIDGE_NODE){
|
|
return WPLIP_ETH;
|
|
|
|
}
|
|
|
|
if (lip_dev->common.lip_prot == WANCONFIG_LAPD) {
|
|
return WPLIP_LAPD;
|
|
}
|
|
|
|
if (lip_dev->common.usedby == STACK){
|
|
switch (lip_dev->common.lip_prot){
|
|
case WANCONFIG_PPP:
|
|
case WANCONFIG_TTY:
|
|
return WPLIP_PPP;
|
|
case WANCONFIG_FR:
|
|
return WPLIP_FR;
|
|
}
|
|
/* Break out down */
|
|
}
|
|
|
|
switch (htons(skb->protocol)){
|
|
|
|
case ETH_P_IP:
|
|
return WPLIP_IP;
|
|
case ETH_P_IPV6:
|
|
return WPLIP_IPV6;
|
|
case ETH_P_IPX:
|
|
return WPLIP_IPX;
|
|
}
|
|
|
|
return WPLIP_IP;
|
|
#elif defined(__WINDOWS__)
|
|
struct sk_buff *skb=(struct sk_buff*)ptr;
|
|
|
|
DEBUG_LIP("wplip_decode_protocol()\n");
|
|
|
|
switch (wpabs_htons(skb->protocol)){
|
|
|
|
case ETH_P_IP:
|
|
return WPLIP_IP;
|
|
case ETH_P_IPV6:
|
|
return WPLIP_IPV6;
|
|
case ETH_P_IPX:
|
|
return WPLIP_IPX;
|
|
}
|
|
|
|
return WPLIP_IP;
|
|
#else
|
|
# error ("wplip_decode_protocol: Unknown Protocol!\n");
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
#if defined(__LINUX__)
|
|
static __inline void wp_lip_config_bridge_mode(wplip_dev_t *lip_dev)
|
|
{
|
|
netdevice_t * dev = lip_dev->common.dev;
|
|
/* Setup the interface for Bridging */
|
|
int hw_addr=0;
|
|
ether_setup(dev);
|
|
|
|
/* Use a random number to generate the MAC address */
|
|
memcpy(dev->dev_addr, "\xFE\xFC\x00\x00\x00\x00", 6);
|
|
get_random_bytes(&hw_addr, sizeof(hw_addr));
|
|
*(int *)(dev->dev_addr + 2) += hw_addr;
|
|
}
|
|
#endif
|
|
|
|
#if defined(__WINDOWS__)
|
|
#define PACKET_TYPE_DECODE(type) \
|
|
((type == WPLIP_RAW) ? "WPLIP_RAW" : \
|
|
(type == WPLIP_IP) ? "WPLIP_IP" : \
|
|
(type == WPLIP_IPV6) ? "WPLIP_IPV6" : \
|
|
(type == WPLIP_IPX) ? "WPLIP_IPX": \
|
|
(type == WPLIP_FR_ARP) ? "WPLIP_FR_ARP": "Unknown Packet type")
|
|
|
|
/*convert integer definition of a protocol to string*/
|
|
static char * get_protocol_string(int protocol)
|
|
{
|
|
return SDLA_DECODE_PROTOCOL(protocol);
|
|
}
|
|
|
|
#endif
|
|
|
|
/*__KERNEL__*/
|
|
#endif
|
|
|
|
/*_WANPIPE_LIP_HEADER_*/
|
|
#endif
|
|
|
|
|
|
|
|
#define WPLIP_ASSERT(reg,ret) if (!(reg)) {\
|
|
DEBUG_EVENT("%s:%d Assert Error!\n", \
|
|
__FUNCTION__,__LINE__); \
|
|
return ret; \
|
|
}
|
|
|
|
#define WPLIP_ASSERT_VOID(reg) if (!(reg)) {\
|
|
DEBUG_EVENT("%s:%d Assert Error!\n", \
|
|
__FUNCTION__,__LINE__); \
|
|
return; \
|
|
}
|
|
|
|
#define FUNC_BEGIN() DEBUG_EVENT("%s:%d ---Begin---\n",__FUNCTION__,__LINE__);
|
|
#define FUNC_END() DEBUG_EVENT("%s:%d ---End---\n\n",__FUNCTION__,__LINE__);
|
|
|
|
|
|
#define X25_DEBUG_MEM
|
|
|
|
#ifdef X25_DEBUG_MEM
|
|
|
|
#define X25_SKB_DEC(x) atomic_sub(x,&x25_skb_alloc)
|
|
#define X25_SKB_INC(x) atomic_add(x,&x25_skb_alloc)
|
|
|
|
#define ALLOC_SKB(skb,len) { skb = dev_alloc_skb(len); \
|
|
if (skb != NULL){ X25_SKB_INC(skb->truesize);}else{ WAN_MEM_ASSERT("X25");} }
|
|
#define KFREE_SKB(skb) { X25_SKB_DEC(skb->truesize); dev_kfree_skb_any(skb); }
|
|
|
|
|
|
#define X25_MEM_DEC(x) atomic_sub(x,&x25_mem_alloc)
|
|
#define X25_MEM_INC(x) atomic_add(x,&x25_mem_alloc)
|
|
|
|
#define KMALLOC(ptr,len,flag) { ptr=kmalloc(len, flag); \
|
|
if (ptr != NULL){ X25_MEM_INC(len);} else {WAN_MEM_ASSERT("X25");}}
|
|
#define KFREE(ptr) {X25_MEM_DEC(sizeof(*ptr)); kfree(ptr);}
|
|
|
|
#else
|
|
#define KMALLOC(ptr,len,flag) ptr=kmalloc(len, flag)
|
|
#define KFREE(ptr) kfree(ptr)
|
|
|
|
#define ALLOC_SKB(new_skb,len, dsp) new_skb = dev_alloc_skb(len)
|
|
#define KFREE_SKB(skb) dev_kfree_skb_any(skb)
|
|
|
|
#define X25_SKB_DEC(x)
|
|
#define X25_SKB_INC(x)
|
|
#define X25_MEM_DEC(x)
|
|
#define X25_MEM_INC(x)
|
|
#endif
|
|
|
|
#define is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
|