Commit 7f1bc512 authored by David S. Miller's avatar David S. Miller

Merge bk://kernel.bkbits.net/acme/llc-2.6

into nuts.ninka.net:/disk1/davem/BK/net-2.5
parents 0d2cfd9d 06f3b6fd
...@@ -67,6 +67,39 @@ struct llc_addr { ...@@ -67,6 +67,39 @@ struct llc_addr {
u8 mac[IFHWADDRLEN]; u8 mac[IFHWADDRLEN];
}; };
extern u8 llc_mac_null_var[IFHWADDRLEN];
/**
* llc_mac_null - determines if a address is a null mac address
* @mac: Mac address to test if null.
*
* Determines if a given address is a null mac address. Returns 0 if the
* address is not a null mac, 1 if the address is a null mac.
*/
static __inline__ int llc_mac_null(u8 *mac)
{
return !memcmp(mac, llc_mac_null_var, IFHWADDRLEN);
}
static __inline__ int llc_addrany(struct llc_addr *addr)
{
return llc_mac_null(addr->mac) && !addr->lsap;
}
/**
* llc_mac_match - determines if two mac addresses are the same
* @mac1: First mac address to compare.
* @mac2: Second mac address to compare.
*
* Determines if two given mac address are the same. Returns 0 if there
* is not a complete match up to len, 1 if a complete match up to len is
* found.
*/
static __inline__ int llc_mac_match(u8 *mac1, u8 *mac2)
{
return !memcmp(mac1, mac2, IFHWADDRLEN);
}
struct llc_sap; struct llc_sap;
extern struct llc_sap *llc_sap_open(u8 lsap, extern struct llc_sap *llc_sap_open(u8 lsap,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define LLC_MAC_H #define LLC_MAC_H
/* /*
* Copyright (c) 1997 by Procom Technology, Inc. * Copyright (c) 1997 by Procom Technology, Inc.
* 2001, 2002 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 * This program can be redistributed or modified under the terms of the
* GNU General Public License as published by the Free Software Foundation. * GNU General Public License as published by the Free Software Foundation.
...@@ -11,10 +11,14 @@ ...@@ -11,10 +11,14 @@
* *
* See the GNU General Public License for more details. * 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 */
extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt); struct packet_type *pt);
extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da); extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da);
extern int llc_conn_rcv(struct sock *sk, struct sk_buff *skb);
static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type) static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type)
{ {
...@@ -25,37 +29,4 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb) ...@@ -25,37 +29,4 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
{ {
return skb->cb[sizeof(skb->cb) - 1]; return skb->cb[sizeof(skb->cb) - 1];
} }
extern u8 llc_mac_null_var[IFHWADDRLEN];
/**
* llc_mac_null - determines if a address is a null mac address
* @mac: Mac address to test if null.
*
* Determines if a given address is a null mac address. Returns 0 if the
* address is not a null mac, 1 if the address is a null mac.
*/
static __inline__ int llc_mac_null(u8 *mac)
{
return !memcmp(mac, llc_mac_null_var, IFHWADDRLEN);
}
static __inline__ int llc_addrany(struct llc_addr *addr)
{
return llc_mac_null(addr->mac) && !addr->lsap;
}
/**
* llc_mac_match - determines if two mac addresses are the same
* @mac1: First mac address to compare.
* @mac2: Second mac address to compare.
*
* Determines if two given mac address are the same. Returns 0 if there
* is not a complete match up to len, 1 if a complete match up to len is
* found.
*/
static __inline__ int llc_mac_match(u8 *mac1, u8 *mac2)
{
return !memcmp(mac1, mac2, IFHWADDRLEN);
}
#endif /* LLC_MAC_H */ #endif /* LLC_MAC_H */
...@@ -19,9 +19,6 @@ ...@@ -19,9 +19,6 @@
#define LLC_ACK_TIME 1 #define LLC_ACK_TIME 1
#define LLC_REJ_TIME 3 #define LLC_REJ_TIME 3
#define LLC_BUSY_TIME 3 #define LLC_BUSY_TIME 3
#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 */
/** /**
* struct llc_station - LLC station component * struct llc_station - LLC station component
......
...@@ -243,7 +243,6 @@ extern void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa); ...@@ -243,7 +243,6 @@ extern void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa);
extern void llc_pdu_decode_da(struct sk_buff *skb, u8 *ds); extern void llc_pdu_decode_da(struct sk_buff *skb, u8 *ds);
extern void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap); extern void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap);
extern void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap); extern void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap);
extern void llc_decode_pdu_type(struct sk_buff *skb, u8 *destination);
extern void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap, extern void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap,
u8 dsap, u8 cr); u8 dsap, u8 cr);
extern void llc_pdu_init_as_ui_cmd(struct sk_buff *skb); extern void llc_pdu_init_as_ui_cmd(struct sk_buff *skb);
......
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
#include <net/llc_pdu.h> #include <net/llc_pdu.h>
#include <net/llc_s_ev.h> #include <net/llc_s_ev.h>
#if 0
#define dprintk(args...) printk(KERN_DEBUG args)
#else
#define dprintk(args...)
#endif
static int llc_find_offset(int state, int ev_type); static int llc_find_offset(int state, int ev_type);
static void llc_conn_send_pdus(struct sock *sk); static void llc_conn_send_pdus(struct sock *sk);
static int llc_conn_service(struct sock *sk, struct sk_buff *skb); static int llc_conn_service(struct sock *sk, struct sk_buff *skb);
...@@ -651,3 +657,75 @@ static int llc_find_offset(int state, int ev_type) ...@@ -651,3 +657,75 @@ static int llc_find_offset(int state, int ev_type)
} }
return rc; return rc;
} }
/**
* llc_conn_rcv - sends received pdus to the connection state machine
* @sk: current connection structure.
* @skb: received frame.
*
* Sends received pdus to the connection state machine.
*/
int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
if (!llc->dev)
llc->dev = skb->dev;
ev->type = LLC_CONN_EV_TYPE_PDU;
ev->reason = 0;
return llc_conn_state_process(sk, skb);
}
void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_addr saddr, daddr;
struct sock *sk;
llc_pdu_decode_sa(skb, saddr.mac);
llc_pdu_decode_ssap(skb, &saddr.lsap);
llc_pdu_decode_da(skb, daddr.mac);
llc_pdu_decode_dsap(skb, &daddr.lsap);
sk = llc_lookup_established(sap, &saddr, &daddr);
if (!sk) {
/*
* Didn't find an active connection; verify if there
* is a listening socket for this llc addr
*/
struct llc_opt *llc;
struct sock *parent = llc_lookup_listener(sap, &daddr);
if (!parent) {
dprintk("llc_lookup_listener failed!\n");
goto drop;
}
sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC);
if (!sk) {
sock_put(parent);
goto drop;
}
llc = llc_sk(sk);
memcpy(&llc->laddr, &daddr, sizeof(llc->laddr));
memcpy(&llc->daddr, &saddr, sizeof(llc->daddr));
llc_sap_assign_sock(sap, sk);
sock_hold(sk);
sock_put(parent);
skb->sk = parent;
} else
skb->sk = sk;
bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
llc_conn_rcv(sk, skb);
else {
dprintk("%s: adding to backlog...\n", __FUNCTION__);
llc_set_backlog_type(skb, LLC_PACKET);
sk_add_backlog(sk, skb);
}
bh_unlock_sock(sk);
sock_put(sk);
return;
drop:
kfree_skb(skb);
}
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <net/llc_c_st.h> #include <net/llc_c_st.h>
#include <net/llc_main.h> #include <net/llc_main.h>
u8 llc_mac_null_var[IFHWADDRLEN];
/** /**
* llc_sap_open - open interface to the upper layers. * llc_sap_open - open interface to the upper layers.
* @lsap: SAP number. * @lsap: SAP number.
......
...@@ -15,16 +15,11 @@ ...@@ -15,16 +15,11 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/if_tr.h> #include <linux/if_tr.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <net/llc_if.h>
#include <net/llc_mac.h> #include <net/llc_mac.h>
#include <net/llc_pdu.h> #include <net/llc_pdu.h>
#include <net/llc_sap.h> #include <net/llc_sap.h>
#include <net/llc_conn.h>
#include <net/sock.h>
#include <net/llc_main.h> #include <net/llc_main.h>
#include <net/llc_evnt.h> #include <net/llc_evnt.h>
#include <net/llc_c_ev.h>
#include <net/llc_s_ev.h>
#include <linux/trdevice.h> #include <linux/trdevice.h>
#if 0 #if 0
...@@ -33,11 +28,54 @@ ...@@ -33,11 +28,54 @@
#define dprintk(args...) #define dprintk(args...)
#endif #endif
u8 llc_mac_null_var[IFHWADDRLEN];
static int fix_up_incoming_skb(struct sk_buff *skb); static int fix_up_incoming_skb(struct sk_buff *skb);
static void llc_station_rcv(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);
extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
/*
* Packet handlers for LLC_DEST_SAP and LLC_DEST_CONN.
* FIXME: There will be a registration service in next changesets.
*/
static void (*llc_type_handlers[2])(struct llc_sap *sap,
struct sk_buff *skb) = {
[LLC_DEST_SAP - 1] = llc_sap_handler,
[LLC_DEST_CONN - 1] = llc_conn_handler,
};
/**
* llc_pdu_type - returns which LLC component must handle for PDU
* @skb: input skb
*
* This function returns which LLC component must handle this PDU.
*/
static __inline__ int llc_pdu_type(struct sk_buff *skb)
{
int type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
goto out;
switch (LLC_U_PDU_CMD(pdu)) {
case LLC_1_PDU_CMD_XID:
case LLC_1_PDU_CMD_UI:
case LLC_1_PDU_CMD_TEST:
type = LLC_DEST_SAP;
break;
case LLC_2_PDU_CMD_SABME:
case LLC_2_PDU_CMD_DISC:
case LLC_2_PDU_RSP_UA:
case LLC_2_PDU_RSP_DM:
case LLC_2_PDU_RSP_FRMR:
break;
default:
type = LLC_DEST_INVALID;
break;
}
out:
return type;
}
/** /**
* llc_rcv - 802.2 entry point from net lower layers * llc_rcv - 802.2 entry point from net lower layers
...@@ -56,7 +94,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -56,7 +94,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
{ {
struct llc_sap *sap; struct llc_sap *sap;
struct llc_pdu_sn *pdu; struct llc_pdu_sn *pdu;
u8 dest; int dest;
/* /*
* When the interface is in promisc. mode, drop all the crap that it * When the interface is in promisc. mode, drop all the crap that it
...@@ -83,80 +121,18 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -83,80 +121,18 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
pdu->dsap); pdu->dsap);
goto drop; goto drop;
} }
llc_decode_pdu_type(skb, &dest); /*
if (dest == LLC_DEST_SAP) { /* type 1 services */ * First the upper layer protocols that don't need the full
if (sap->rcv_func) * LLC functionality
sap->rcv_func(skb, dev, pt); */
else { if (sap->rcv_func) {
struct llc_addr laddr; sap->rcv_func(skb, dev, pt);
struct sock *sk; goto out;
}
llc_pdu_decode_da(skb, laddr.mac); dest = llc_pdu_type(skb);
llc_pdu_decode_dsap(skb, &laddr.lsap); if (unlikely(!dest || !llc_type_handlers[dest - 1]))
goto drop;
sk = llc_lookup_dgram(sap, &laddr); llc_type_handlers[dest - 1](sap, skb);
if (!sk)
goto drop;
skb->sk = sk;
llc_sap_rcv(sap, skb);
sock_put(sk);
}
} else if (dest == LLC_DEST_CONN) {
struct llc_addr saddr, daddr;
struct sock *sk;
int rc;
llc_pdu_decode_sa(skb, saddr.mac);
llc_pdu_decode_ssap(skb, &saddr.lsap);
llc_pdu_decode_da(skb, daddr.mac);
llc_pdu_decode_dsap(skb, &daddr.lsap);
sk = llc_lookup_established(sap, &saddr, &daddr);
if (!sk) {
/*
* Didn't find an active connection; verify if there
* is a listening socket for this llc addr
*/
struct llc_opt *llc;
struct sock *parent;
parent = llc_lookup_listener(sap, &daddr);
if (!parent) {
dprintk("llc_lookup_listener failed!\n");
goto drop;
}
sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC);
if (!sk) {
sock_put(parent);
goto drop;
}
llc = llc_sk(sk);
memcpy(&llc->laddr, &daddr, sizeof(llc->laddr));
memcpy(&llc->daddr, &saddr, sizeof(llc->daddr));
llc_sap_assign_sock(sap, sk);
sock_hold(sk);
sock_put(parent);
skb->sk = parent;
} else
skb->sk = sk;
bh_lock_sock(sk);
if (!sock_owned_by_user(sk)) {
/* rc = */ llc_conn_rcv(sk, skb);
rc = 0;
} else {
dprintk("%s: adding to backlog...\n", __FUNCTION__);
llc_set_backlog_type(skb, LLC_PACKET);
sk_add_backlog(sk, skb);
rc = 0;
}
bh_unlock_sock(sk);
sock_put(sk);
if (rc)
goto drop;
} else /* unknown or not supported pdu */
goto drop;
out: out:
return 0; return 0;
drop: drop:
...@@ -211,42 +187,6 @@ static void llc_station_rcv(struct sk_buff *skb) ...@@ -211,42 +187,6 @@ static void llc_station_rcv(struct sk_buff *skb)
llc_station_state_process(&llc_main_station, skb); llc_station_state_process(&llc_main_station, skb);
} }
/**
* llc_conn_rcv - sends received pdus to the connection state machine
* @sk: current connection structure.
* @skb: received frame.
*
* Sends received pdus to the connection state machine.
*/
int llc_conn_rcv(struct sock* sk, struct sk_buff *skb)
{
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
struct llc_opt *llc = llc_sk(sk);
if (!llc->dev)
llc->dev = skb->dev;
ev->type = LLC_CONN_EV_TYPE_PDU;
ev->reason = 0;
return llc_conn_state_process(sk, skb);
}
/**
* llc_sap_rcv - sends received pdus to the sap state machine
* @sap: current sap component structure.
* @skb: received frame.
*
* Sends received pdus to the sap state machine.
*/
static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb)
{
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);
}
/** /**
* lan_hdrs_init - fills MAC header fields * lan_hdrs_init - fills MAC header fields
* @skb: Address of the frame to initialize its MAC header * @skb: Address of the frame to initialize its MAC header
......
...@@ -123,6 +123,12 @@ struct llc_sap *llc_sap_find(u8 sap_value) ...@@ -123,6 +123,12 @@ struct llc_sap *llc_sap_find(u8 sap_value)
return sap; return sap;
} }
/*
* FIXME: this will not be needed in next changesets, when this
* will move to llc_conn
*/
extern int llc_conn_rcv(struct sock* sk, struct sk_buff *skb);
/** /**
* llc_backlog_rcv - Processes rx frames and expired timers. * llc_backlog_rcv - Processes rx frames and expired timers.
* @sk: LLC sock (p8022 connection) * @sk: LLC sock (p8022 connection)
...@@ -536,9 +542,6 @@ static struct packet_type llc_tr_packet_type = { ...@@ -536,9 +542,6 @@ static struct packet_type llc_tr_packet_type = {
.data = (void *)1, .data = (void *)1,
}; };
static char llc_banner[] __initdata =
KERN_INFO "LLC 2.0 by Procom, 1997, Arnaldo C. Melo, 2001, 2002\n"
KERN_INFO "NET 4.0 IEEE 802.2 extended support\n";
static char llc_error_msg[] __initdata = static char llc_error_msg[] __initdata =
KERN_ERR "LLC install NOT successful.\n"; KERN_ERR "LLC install NOT successful.\n";
...@@ -548,7 +551,6 @@ static int __init llc_init(void) ...@@ -548,7 +551,6 @@ static int __init llc_init(void)
struct sk_buff *skb; struct sk_buff *skb;
struct llc_station_state_ev *ev; struct llc_station_state_ev *ev;
printk(llc_banner);
INIT_LIST_HEAD(&llc_main_station.sap_list.list); INIT_LIST_HEAD(&llc_main_station.sap_list.list);
rwlock_init(&llc_main_station.sap_list.lock); 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.mac_pdu_q);
......
...@@ -532,40 +532,6 @@ static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type) ...@@ -532,40 +532,6 @@ static void llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type)
*type = LLC_PDU_TYPE_I; *type = LLC_PDU_TYPE_I;
} }
/**
* llc_decode_pdu_type - designates component LLC must handle for PDU
* @skb: input skb
* @dest: destination component
*
* This function designates which component of LLC must handle this PDU.
*/
void llc_decode_pdu_type(struct sk_buff *skb, u8 *dest)
{
u8 type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
goto out;
switch (LLC_U_PDU_CMD(pdu)) {
case LLC_1_PDU_CMD_XID:
case LLC_1_PDU_CMD_UI:
case LLC_1_PDU_CMD_TEST:
type = LLC_DEST_SAP;
break;
case LLC_2_PDU_CMD_SABME:
case LLC_2_PDU_CMD_DISC:
case LLC_2_PDU_RSP_UA:
case LLC_2_PDU_RSP_DM:
case LLC_2_PDU_RSP_FRMR:
break;
default:
type = LLC_DEST_INVALID;
break;
}
out:
*dest = type;
}
/** /**
* llc_get_hdr_len - designates LLC header length * llc_get_hdr_len - designates LLC header length
* @type: type of PDU. * @type: type of PDU.
......
...@@ -193,3 +193,36 @@ void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) ...@@ -193,3 +193,36 @@ void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb)
} }
kfree_skb(skb); kfree_skb(skb);
} }
/**
* llc_sap_rcv - sends received pdus to the sap state machine
* @sap: current sap component structure.
* @skb: received frame.
*
* Sends received pdus to the sap state machine.
*/
static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb)
{
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);
}
void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)
{
struct llc_addr laddr;
struct sock *sk;
llc_pdu_decode_da(skb, laddr.mac);
llc_pdu_decode_dsap(skb, &laddr.lsap);
sk = llc_lookup_dgram(sap, &laddr);
if (sk) {
skb->sk = sk;
llc_sap_rcv(sap, skb);
sock_put(sk);
} else
kfree_skb(skb);
}
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