Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
b498a583
Commit
b498a583
authored
Sep 28, 2002
by
Arnaldo Carvalho de Melo
Committed by
David S. Miller
Sep 28, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
o X25: use refcnts and protect x25_neigh structs and list
Simplify some other code.
parent
92acfab5
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
218 additions
and
202 deletions
+218
-202
include/net/x25.h
include/net/x25.h
+14
-1
net/x25/af_x25.c
net/x25/af_x25.c
+22
-16
net/x25/x25_dev.c
net/x25/x25_dev.c
+57
-64
net/x25/x25_facilities.c
net/x25/x25_facilities.c
+2
-2
net/x25/x25_link.c
net/x25/x25_link.c
+123
-119
No files found.
include/net/x25.h
View file @
b498a583
...
...
@@ -118,7 +118,7 @@ struct x25_route {
};
struct
x25_neigh
{
struct
x25_neigh
*
next
;
struct
list_head
node
;
struct
net_device
*
dev
;
unsigned
int
state
;
unsigned
int
extended
;
...
...
@@ -126,6 +126,7 @@ struct x25_neigh {
unsigned
long
t20
;
struct
timer_list
t20timer
;
unsigned
long
global_facil_mask
;
atomic_t
refcnt
;
};
struct
x25_opt
{
...
...
@@ -199,6 +200,18 @@ extern int x25_subscr_ioctl(unsigned int, void *);
extern
struct
x25_neigh
*
x25_get_neigh
(
struct
net_device
*
);
extern
void
x25_link_free
(
void
);
/* x25_neigh.c */
static
__inline__
void
x25_neigh_hold
(
struct
x25_neigh
*
nb
)
{
atomic_inc
(
&
nb
->
refcnt
);
}
static
__inline__
void
x25_neigh_put
(
struct
x25_neigh
*
nb
)
{
if
(
atomic_dec_and_test
(
&
nb
->
refcnt
))
kfree
(
nb
);
}
/* x25_out.c */
extern
int
x25_output
(
struct
sock
*
,
struct
sk_buff
*
);
extern
void
x25_kick
(
struct
sock
*
);
...
...
net/x25/af_x25.c
View file @
b498a583
...
...
@@ -188,7 +188,7 @@ static void x25_kill_by_device(struct net_device *dev)
static
int
x25_device_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
struct
net_device
*
dev
=
ptr
;
struct
x25_neigh
*
n
eigh
;
struct
x25_neigh
*
n
b
;
if
(
dev
->
type
==
ARPHRD_X25
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
...
...
@@ -200,8 +200,11 @@ static int x25_device_event(struct notifier_block *this, unsigned long event, vo
x25_link_device_up
(
dev
);
break
;
case
NETDEV_GOING_DOWN
:
if
((
neigh
=
x25_get_neigh
(
dev
)))
x25_terminate_link
(
neigh
);
nb
=
x25_get_neigh
(
dev
);
if
(
nb
)
{
x25_terminate_link
(
nb
);
x25_neigh_put
(
nb
);
}
break
;
case
NETDEV_DOWN
:
x25_kill_by_device
(
dev
);
...
...
@@ -255,7 +258,7 @@ static struct sock *x25_find_listener(struct x25_address *addr)
/*
* Find a connected X.25 socket given my LCI and neighbour.
*/
struct
sock
*
x25_find_socket
(
unsigned
int
lci
,
struct
x25_neigh
*
n
eigh
)
struct
sock
*
x25_find_socket
(
unsigned
int
lci
,
struct
x25_neigh
*
n
b
)
{
struct
sock
*
s
;
unsigned
long
flags
;
...
...
@@ -264,7 +267,7 @@ struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *neigh)
cli
();
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
lci
==
lci
&&
x25_sk
(
s
)
->
neighbour
==
n
eigh
)
if
(
x25_sk
(
s
)
->
lci
==
lci
&&
x25_sk
(
s
)
->
neighbour
==
n
b
)
break
;
restore_flags
(
flags
);
...
...
@@ -274,11 +277,11 @@ struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *neigh)
/*
* Find a unique LCI for a given device.
*/
unsigned
int
x25_new_lci
(
struct
x25_neigh
*
n
eigh
)
unsigned
int
x25_new_lci
(
struct
x25_neigh
*
n
b
)
{
unsigned
int
lci
=
1
;
while
(
x25_find_socket
(
lci
,
n
eigh
))
while
(
x25_find_socket
(
lci
,
n
b
))
if
(
++
lci
==
4096
)
{
lci
=
0
;
break
;
...
...
@@ -631,11 +634,11 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
x25
->
lci
=
x25_new_lci
(
x25
->
neighbour
);
if
(
!
x25
->
lci
)
goto
out_put_
route
;
goto
out_put_
neigh
;
rc
=
-
EINVAL
;
if
(
sk
->
zapped
)
/* Must bind first - autobinding does not work */
goto
out_put_
route
;
goto
out_put_
neigh
;
if
(
!
strcmp
(
x25
->
source_addr
.
x25_addr
,
null_x25_address
.
x25_addr
))
memset
(
&
x25
->
source_addr
,
'\0'
,
X25_ADDR_LEN
);
...
...
@@ -656,7 +659,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
/* Now the loop */
rc
=
-
EINPROGRESS
;
if
(
sk
->
state
!=
TCP_ESTABLISHED
&&
(
flags
&
O_NONBLOCK
))
goto
out_put_
route
;
goto
out_put_
neigh
;
cli
();
/* To avoid races on the sleep */
...
...
@@ -681,6 +684,9 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
rc
=
0
;
out_unlock:
sti
();
out_put_neigh:
if
(
rc
)
x25_neigh_put
(
x25
->
neighbour
);
out_put_route:
x25_route_put
(
rt
);
out:
...
...
@@ -758,7 +764,7 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_l
return
0
;
}
int
x25_rx_call_request
(
struct
sk_buff
*
skb
,
struct
x25_neigh
*
n
eigh
,
unsigned
int
lci
)
int
x25_rx_call_request
(
struct
sk_buff
*
skb
,
struct
x25_neigh
*
n
b
,
unsigned
int
lci
)
{
struct
sock
*
sk
;
struct
sock
*
make
;
...
...
@@ -800,7 +806,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
* on certain facilties
*/
x25_limit_facilities
(
&
facilities
,
neigh
);
x25_limit_facilities
(
&
facilities
,
nb
);
/*
* Try to create a new socket.
...
...
@@ -821,7 +827,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
makex25
->
lci
=
lci
;
makex25
->
dest_addr
=
dest_addr
;
makex25
->
source_addr
=
source_addr
;
makex25
->
neighbour
=
n
eigh
;
makex25
->
neighbour
=
n
b
;
makex25
->
facilities
=
facilities
;
makex25
->
vc_facil_mask
=
x25_sk
(
sk
)
->
vc_facil_mask
;
...
...
@@ -853,7 +859,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *neigh, unsigned i
return
rc
;
out_clear_request:
rc
=
0
;
x25_transmit_clear_request
(
n
eigh
,
lci
,
0x01
);
x25_transmit_clear_request
(
n
b
,
lci
,
0x01
);
goto
out
;
}
...
...
@@ -1358,12 +1364,12 @@ struct notifier_block x25_dev_notifier = {
.
notifier_call
=
x25_device_event
,
};
void
x25_kill_by_neigh
(
struct
x25_neigh
*
n
eigh
)
void
x25_kill_by_neigh
(
struct
x25_neigh
*
n
b
)
{
struct
sock
*
s
;
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
neighbour
==
n
eigh
)
if
(
x25_sk
(
s
)
->
neighbour
==
n
b
)
x25_disconnect
(
s
,
ENETUNREACH
,
0
,
0
);
}
...
...
net/x25/x25_dev.c
View file @
b498a583
...
...
@@ -44,7 +44,7 @@
#include <linux/if_arp.h>
#include <net/x25.h>
static
int
x25_receive_data
(
struct
sk_buff
*
skb
,
struct
x25_neigh
*
n
eigh
)
static
int
x25_receive_data
(
struct
sk_buff
*
skb
,
struct
x25_neigh
*
n
b
)
{
struct
sock
*
sk
;
unsigned
short
frametype
;
...
...
@@ -58,14 +58,14 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh)
* frame.
*/
if
(
lci
==
0
)
{
x25_link_control
(
skb
,
n
eigh
,
frametype
);
x25_link_control
(
skb
,
n
b
,
frametype
);
return
0
;
}
/*
* Find an existing socket.
*/
if
((
sk
=
x25_find_socket
(
lci
,
n
eigh
))
!=
NULL
)
{
if
((
sk
=
x25_find_socket
(
lci
,
n
b
))
!=
NULL
)
{
int
queued
=
1
;
skb
->
h
.
raw
=
skb
->
data
;
...
...
@@ -83,91 +83,87 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh)
* Is is a Call Request ? if so process it.
*/
if
(
frametype
==
X25_CALL_REQUEST
)
return
x25_rx_call_request
(
skb
,
n
eigh
,
lci
);
return
x25_rx_call_request
(
skb
,
n
b
,
lci
);
/*
* Its not a Call Request, nor is it a control frame.
* Let caller throw it away.
*/
/*
x25_transmit_clear_request(n
eigh
, lci, 0x0D);
x25_transmit_clear_request(n
b
, lci, 0x0D);
*/
printk
(
KERN_DEBUG
"x25_receive_data(): unknown frame type %2x
\n
"
,
frametype
);
return
0
;
}
int
x25_lapb_receive_frame
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
ptype
)
int
x25_lapb_receive_frame
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
ptype
)
{
struct
x25_neigh
*
neigh
;
int
queued
;
struct
x25_neigh
*
nb
;
skb
->
sk
=
NULL
;
/*
*
Packet received from unrecognised device, throw it away.
*
Packet received from unrecognised device, throw it away.
*/
if
((
neigh
=
x25_get_neigh
(
dev
))
==
NULL
)
{
nb
=
x25_get_neigh
(
dev
);
if
(
!
nb
)
{
printk
(
KERN_DEBUG
"X.25: unknown neighbour - %s
\n
"
,
dev
->
name
);
kfree_skb
(
skb
);
return
0
;
goto
drop
;
}
switch
(
skb
->
data
[
0
])
{
case
0x00
:
skb_pull
(
skb
,
1
);
queued
=
x25_receive_data
(
skb
,
neigh
);
if
(
!
queued
)
/* We need to free the skb ourselves because
* net_bh() won't care about our return code.
*/
kfree_skb
(
skb
);
return
0
;
if
(
x25_receive_data
(
skb
,
nb
))
{
x25_neigh_put
(
nb
);
goto
out
;
}
break
;
case
0x01
:
x25_link_established
(
neigh
);
kfree_skb
(
skb
);
return
0
;
x25_link_established
(
nb
);
break
;
case
0x02
:
x25_link_terminated
(
neigh
);
kfree_skb
(
skb
);
return
0
;
case
0x03
:
kfree_skb
(
skb
);
return
0
;
default:
kfree_skb
(
skb
);
return
0
;
x25_link_terminated
(
nb
);
break
;
}
x25_neigh_put
(
nb
);
drop:
kfree_skb
(
skb
);
out:
return
0
;
}
int
x25_llc_receive_frame
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
ptype
)
int
x25_llc_receive_frame
(
struct
sk_buff
*
skb
,
struct
net_device
*
dev
,
struct
packet_type
*
ptype
)
{
struct
x25_neigh
*
neigh
;
struct
x25_neigh
*
nb
;
int
rc
=
0
;
skb
->
sk
=
NULL
;
/*
*
Packet received from unrecognised device, throw it away.
*
Packet received from unrecognised device, throw it away.
*/
if
((
neigh
=
x25_get_neigh
(
dev
))
==
NULL
)
{
nb
=
x25_get_neigh
(
dev
);
if
(
!
nb
)
{
printk
(
KERN_DEBUG
"X.25: unknown_neighbour - %s
\n
"
,
dev
->
name
);
kfree_skb
(
skb
);
return
0
;
}
else
{
rc
=
x25_receive_data
(
skb
,
nb
);
x25_neigh_put
(
nb
);
}
return
x25_receive_data
(
skb
,
neigh
)
;
return
rc
;
}
void
x25_establish_link
(
struct
x25_neigh
*
n
eigh
)
void
x25_establish_link
(
struct
x25_neigh
*
n
b
)
{
struct
sk_buff
*
skb
;
unsigned
char
*
ptr
;
switch
(
n
eigh
->
dev
->
type
)
{
switch
(
n
b
->
dev
->
type
)
{
case
ARPHRD_X25
:
if
((
skb
=
alloc_skb
(
1
,
GFP_ATOMIC
))
==
NULL
)
{
printk
(
KERN_ERR
"x25_dev: out of memory
\n
"
);
...
...
@@ -186,47 +182,44 @@ void x25_establish_link(struct x25_neigh *neigh)
}
skb
->
protocol
=
htons
(
ETH_P_X25
);
skb
->
dev
=
n
eigh
->
dev
;
skb
->
dev
=
n
b
->
dev
;
dev_queue_xmit
(
skb
);
}
void
x25_terminate_link
(
struct
x25_neigh
*
n
eigh
)
void
x25_terminate_link
(
struct
x25_neigh
*
n
b
)
{
struct
sk_buff
*
skb
;
unsigned
char
*
ptr
;
switch
(
neigh
->
dev
->
type
)
{
case
ARPHRD_X25
:
if
((
skb
=
alloc_skb
(
1
,
GFP_ATOMIC
))
==
NULL
)
{
printk
(
KERN_ERR
"x25_dev: out of memory
\n
"
);
return
;
}
ptr
=
skb_put
(
skb
,
1
);
*
ptr
=
0x02
;
break
;
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
case
ARPHRD_ETHER
:
return
;
if
(
nb
->
dev
->
type
==
ARPHRD_ETHER
)
return
;
#endif
default:
return
;
if
(
nb
->
dev
->
type
!=
ARPHRD_X25
)
return
;
skb
=
alloc_skb
(
1
,
GFP_ATOMIC
);
if
(
!
skb
)
{
printk
(
KERN_ERR
"x25_dev: out of memory
\n
"
);
return
;
}
skb
->
protocol
=
htons
(
ETH_P_X25
);
skb
->
dev
=
neigh
->
dev
;
ptr
=
skb_put
(
skb
,
1
);
*
ptr
=
0x02
;
skb
->
protocol
=
htons
(
ETH_P_X25
);
skb
->
dev
=
nb
->
dev
;
dev_queue_xmit
(
skb
);
}
void
x25_send_frame
(
struct
sk_buff
*
skb
,
struct
x25_neigh
*
n
eigh
)
void
x25_send_frame
(
struct
sk_buff
*
skb
,
struct
x25_neigh
*
n
b
)
{
unsigned
char
*
dptr
;
skb
->
nh
.
raw
=
skb
->
data
;
switch
(
n
eigh
->
dev
->
type
)
{
switch
(
n
b
->
dev
->
type
)
{
case
ARPHRD_X25
:
dptr
=
skb_push
(
skb
,
1
);
*
dptr
=
0x00
;
...
...
@@ -243,7 +236,7 @@ void x25_send_frame(struct sk_buff *skb, struct x25_neigh *neigh)
}
skb
->
protocol
=
htons
(
ETH_P_X25
);
skb
->
dev
=
n
eigh
->
dev
;
skb
->
dev
=
n
b
->
dev
;
dev_queue_xmit
(
skb
);
}
net/x25/x25_facilities.c
View file @
b498a583
...
...
@@ -229,10 +229,10 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
* currently attached x25 link.
*/
void
x25_limit_facilities
(
struct
x25_facilities
*
facilities
,
struct
x25_neigh
*
n
eighbour
)
struct
x25_neigh
*
n
b
)
{
if
(
!
n
eighbour
->
extended
)
{
if
(
!
n
b
->
extended
)
{
if
(
facilities
->
winsize_in
>
7
)
{
printk
(
KERN_DEBUG
"X.25: incoming winsize limited to 7
\n
"
);
facilities
->
winsize_in
=
7
;
...
...
net/x25/x25_link.c
View file @
b498a583
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment