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
Kirill Smelkov
linux
Commits
c4890c9b
Commit
c4890c9b
authored
May 16, 2003
by
Arnaldo Carvalho de Melo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
o ipx: move route functions to net/ipx/ipx_route.c
parent
910d5f2d
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
360 additions
and
336 deletions
+360
-336
include/net/ipx.h
include/net/ipx.h
+32
-0
net/ipx/Makefile
net/ipx/Makefile
+1
-1
net/ipx/af_ipx.c
net/ipx/af_ipx.c
+33
-334
net/ipx/ipx_proc.c
net/ipx/ipx_proc.c
+1
-1
net/ipx/ipx_route.c
net/ipx/ipx_route.c
+293
-0
No files found.
include/net/ipx.h
View file @
c4890c9b
...
...
@@ -125,4 +125,36 @@ extern void ipx_proc_exit(void);
extern
const
char
*
ipx_frame_name
(
unsigned
short
);
extern
const
char
*
ipx_device_name
(
struct
ipx_interface
*
intrfc
);
static
__inline__
void
ipxitf_hold
(
struct
ipx_interface
*
intrfc
)
{
atomic_inc
(
&
intrfc
->
refcnt
);
}
extern
void
ipxitf_down
(
struct
ipx_interface
*
intrfc
);
static
__inline__
void
ipxitf_put
(
struct
ipx_interface
*
intrfc
)
{
if
(
atomic_dec_and_test
(
&
intrfc
->
refcnt
))
ipxitf_down
(
intrfc
);
}
extern
void
__ipxitf_down
(
struct
ipx_interface
*
intrfc
);
static
__inline__
void
__ipxitf_put
(
struct
ipx_interface
*
intrfc
)
{
if
(
atomic_dec_and_test
(
&
intrfc
->
refcnt
))
__ipxitf_down
(
intrfc
);
}
static
__inline__
void
ipxrtr_hold
(
struct
ipx_route
*
rt
)
{
atomic_inc
(
&
rt
->
refcnt
);
}
static
__inline__
void
ipxrtr_put
(
struct
ipx_route
*
rt
)
{
if
(
atomic_dec_and_test
(
&
rt
->
refcnt
))
kfree
(
rt
);
}
#endif
/* _NET_INET_IPX_H_ */
net/ipx/Makefile
View file @
c4890c9b
...
...
@@ -4,5 +4,5 @@
obj-$(CONFIG_IPX)
+=
ipx.o
ipx-y
:=
af_ipx.o ipx_proc.o
ipx-y
:=
af_ipx.o ipx_
route.o ipx_
proc.o
ipx-$(CONFIG_SYSCTL)
+=
sysctl_net_ipx.o
net/ipx/af_ipx.c
View file @
c4890c9b
This diff is collapsed.
Click to expand it.
net/ipx/ipx_proc.c
View file @
c4890c9b
...
...
@@ -5,6 +5,7 @@
*/
#include <linux/config.h>
#ifdef CONFIG_PROC_FS
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
...
...
@@ -12,7 +13,6 @@
#include <linux/tcp.h>
#include <net/ipx.h>
#ifdef CONFIG_PROC_FS
static
__inline__
struct
ipx_interface
*
ipx_get_interface_idx
(
loff_t
pos
)
{
struct
ipx_interface
*
i
;
...
...
net/ipx/ipx_route.c
0 → 100644
View file @
c4890c9b
/*
* Implements the IPX routing routines.
* Code moved from af_ipx.c.
*
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2003
*
* See net/ipx/ChangeLog.
*/
#include <linux/config.h>
#include <linux/list.h>
#include <linux/route.h>
#include <linux/spinlock.h>
#include <net/ipx.h>
#include <net/sock.h>
LIST_HEAD
(
ipx_routes
);
rwlock_t
ipx_routes_lock
=
RW_LOCK_UNLOCKED
;
extern
struct
ipx_interface
*
ipx_internal_net
;
extern
__u16
ipx_cksum
(
struct
ipxhdr
*
packet
,
int
length
);
extern
struct
ipx_interface
*
ipxitf_find_using_net
(
__u32
net
);
extern
int
ipxitf_demux_socket
(
struct
ipx_interface
*
intrfc
,
struct
sk_buff
*
skb
,
int
copy
);
extern
int
ipxitf_demux_socket
(
struct
ipx_interface
*
intrfc
,
struct
sk_buff
*
skb
,
int
copy
);
extern
int
ipxitf_send
(
struct
ipx_interface
*
intrfc
,
struct
sk_buff
*
skb
,
char
*
node
);
extern
struct
ipx_interface
*
ipxitf_find_using_net
(
__u32
net
);
struct
ipx_route
*
ipxrtr_lookup
(
__u32
net
)
{
struct
ipx_route
*
r
;
read_lock_bh
(
&
ipx_routes_lock
);
list_for_each_entry
(
r
,
&
ipx_routes
,
node
)
if
(
r
->
ir_net
==
net
)
{
ipxrtr_hold
(
r
);
goto
unlock
;
}
r
=
NULL
;
unlock:
read_unlock_bh
(
&
ipx_routes_lock
);
return
r
;
}
/*
* Caller must hold a reference to intrfc
*/
int
ipxrtr_add_route
(
__u32
network
,
struct
ipx_interface
*
intrfc
,
unsigned
char
*
node
)
{
struct
ipx_route
*
rt
;
int
rc
;
/* Get a route structure; either existing or create */
rt
=
ipxrtr_lookup
(
network
);
if
(
!
rt
)
{
rt
=
kmalloc
(
sizeof
(
*
rt
),
GFP_ATOMIC
);
rc
=
-
EAGAIN
;
if
(
!
rt
)
goto
out
;
atomic_set
(
&
rt
->
refcnt
,
1
);
ipxrtr_hold
(
rt
);
write_lock_bh
(
&
ipx_routes_lock
);
list_add
(
&
rt
->
node
,
&
ipx_routes
);
write_unlock_bh
(
&
ipx_routes_lock
);
}
else
{
rc
=
-
EEXIST
;
if
(
intrfc
==
ipx_internal_net
)
goto
out_put
;
}
rt
->
ir_net
=
network
;
rt
->
ir_intrfc
=
intrfc
;
if
(
!
node
)
{
memset
(
rt
->
ir_router_node
,
'\0'
,
IPX_NODE_LEN
);
rt
->
ir_routed
=
0
;
}
else
{
memcpy
(
rt
->
ir_router_node
,
node
,
IPX_NODE_LEN
);
rt
->
ir_routed
=
1
;
}
rc
=
0
;
out_put:
ipxrtr_put
(
rt
);
out:
return
rc
;
}
void
ipxrtr_del_routes
(
struct
ipx_interface
*
intrfc
)
{
struct
ipx_route
*
r
,
*
tmp
;
write_lock_bh
(
&
ipx_routes_lock
);
list_for_each_entry_safe
(
r
,
tmp
,
&
ipx_routes
,
node
)
if
(
r
->
ir_intrfc
==
intrfc
)
{
list_del
(
&
r
->
node
);
ipxrtr_put
(
r
);
}
write_unlock_bh
(
&
ipx_routes_lock
);
}
static
int
ipxrtr_create
(
struct
ipx_route_definition
*
rd
)
{
struct
ipx_interface
*
intrfc
;
int
rc
=
-
ENETUNREACH
;
/* Find the appropriate interface */
intrfc
=
ipxitf_find_using_net
(
rd
->
ipx_router_network
);
if
(
!
intrfc
)
goto
out
;
rc
=
ipxrtr_add_route
(
rd
->
ipx_network
,
intrfc
,
rd
->
ipx_router_node
);
ipxitf_put
(
intrfc
);
out:
return
rc
;
}
static
int
ipxrtr_delete
(
long
net
)
{
struct
ipx_route
*
r
,
*
tmp
;
int
rc
;
write_lock_bh
(
&
ipx_routes_lock
);
list_for_each_entry_safe
(
r
,
tmp
,
&
ipx_routes
,
node
)
if
(
r
->
ir_net
==
net
)
{
/* Directly connected; can't lose route */
rc
=
-
EPERM
;
if
(
!
r
->
ir_routed
)
goto
out
;
list_del
(
&
r
->
node
);
ipxrtr_put
(
r
);
rc
=
0
;
goto
out
;
}
rc
=
-
ENOENT
;
out:
write_unlock_bh
(
&
ipx_routes_lock
);
return
rc
;
}
/*
* The skb has to be unshared, we'll end up calling ipxitf_send, that'll
* modify the packet
*/
int
ipxrtr_route_skb
(
struct
sk_buff
*
skb
)
{
struct
ipxhdr
*
ipx
=
ipx_hdr
(
skb
);
struct
ipx_route
*
r
=
ipxrtr_lookup
(
IPX_SKB_CB
(
skb
)
->
ipx_dest_net
);
if
(
!
r
)
{
/* no known route */
kfree_skb
(
skb
);
return
0
;
}
ipxitf_hold
(
r
->
ir_intrfc
);
ipxitf_send
(
r
->
ir_intrfc
,
skb
,
r
->
ir_routed
?
r
->
ir_router_node
:
ipx
->
ipx_dest
.
node
);
ipxitf_put
(
r
->
ir_intrfc
);
ipxrtr_put
(
r
);
return
0
;
}
/*
* Route an outgoing frame from a socket.
*/
int
ipxrtr_route_packet
(
struct
sock
*
sk
,
struct
sockaddr_ipx
*
usipx
,
struct
iovec
*
iov
,
int
len
,
int
noblock
)
{
struct
sk_buff
*
skb
;
struct
ipx_opt
*
ipxs
=
ipx_sk
(
sk
);
struct
ipx_interface
*
intrfc
;
struct
ipxhdr
*
ipx
;
int
size
;
int
ipx_offset
;
struct
ipx_route
*
rt
=
NULL
;
int
rc
;
/* Find the appropriate interface on which to send packet */
if
(
!
usipx
->
sipx_network
&&
ipx_primary_net
)
{
usipx
->
sipx_network
=
ipx_primary_net
->
if_netnum
;
intrfc
=
ipx_primary_net
;
}
else
{
rt
=
ipxrtr_lookup
(
usipx
->
sipx_network
);
rc
=
-
ENETUNREACH
;
if
(
!
rt
)
goto
out
;
intrfc
=
rt
->
ir_intrfc
;
}
ipxitf_hold
(
intrfc
);
ipx_offset
=
intrfc
->
if_ipx_offset
;
size
=
sizeof
(
struct
ipxhdr
)
+
len
+
ipx_offset
;
skb
=
sock_alloc_send_skb
(
sk
,
size
,
noblock
,
&
rc
);
if
(
!
skb
)
goto
out_put
;
skb_reserve
(
skb
,
ipx_offset
);
skb
->
sk
=
sk
;
/* Fill in IPX header */
skb
->
h
.
raw
=
skb
->
nh
.
raw
=
skb_put
(
skb
,
sizeof
(
struct
ipxhdr
));
ipx
=
ipx_hdr
(
skb
);
ipx
->
ipx_pktsize
=
htons
(
len
+
sizeof
(
struct
ipxhdr
));
IPX_SKB_CB
(
skb
)
->
ipx_tctrl
=
0
;
ipx
->
ipx_type
=
usipx
->
sipx_type
;
IPX_SKB_CB
(
skb
)
->
last_hop
.
index
=
-
1
;
#ifdef CONFIG_IPX_INTERN
IPX_SKB_CB
(
skb
)
->
ipx_source_net
=
ipxs
->
intrfc
->
if_netnum
;
memcpy
(
ipx
->
ipx_source
.
node
,
ipxs
->
node
,
IPX_NODE_LEN
);
#else
rc
=
ntohs
(
ipxs
->
port
);
if
(
rc
==
0x453
||
rc
==
0x452
)
{
/* RIP/SAP special handling for mars_nwe */
IPX_SKB_CB
(
skb
)
->
ipx_source_net
=
intrfc
->
if_netnum
;
memcpy
(
ipx
->
ipx_source
.
node
,
intrfc
->
if_node
,
IPX_NODE_LEN
);
}
else
{
IPX_SKB_CB
(
skb
)
->
ipx_source_net
=
ipxs
->
intrfc
->
if_netnum
;
memcpy
(
ipx
->
ipx_source
.
node
,
ipxs
->
intrfc
->
if_node
,
IPX_NODE_LEN
);
}
#endif
/* CONFIG_IPX_INTERN */
ipx
->
ipx_source
.
sock
=
ipxs
->
port
;
IPX_SKB_CB
(
skb
)
->
ipx_dest_net
=
usipx
->
sipx_network
;
memcpy
(
ipx
->
ipx_dest
.
node
,
usipx
->
sipx_node
,
IPX_NODE_LEN
);
ipx
->
ipx_dest
.
sock
=
usipx
->
sipx_port
;
rc
=
memcpy_fromiovec
(
skb_put
(
skb
,
len
),
iov
,
len
);
if
(
rc
)
{
kfree_skb
(
skb
);
goto
out_put
;
}
/* Apply checksum. Not allowed on 802.3 links. */
if
(
sk
->
no_check
||
intrfc
->
if_dlink_type
==
IPX_FRAME_8023
)
ipx
->
ipx_checksum
=
0xFFFF
;
else
ipx
->
ipx_checksum
=
ipx_cksum
(
ipx
,
len
+
sizeof
(
struct
ipxhdr
));
rc
=
ipxitf_send
(
intrfc
,
skb
,
(
rt
&&
rt
->
ir_routed
)
?
rt
->
ir_router_node
:
ipx
->
ipx_dest
.
node
);
out_put:
ipxitf_put
(
intrfc
);
if
(
rt
)
ipxrtr_put
(
rt
);
out:
return
rc
;
}
/*
* We use a normal struct rtentry for route handling
*/
int
ipxrtr_ioctl
(
unsigned
int
cmd
,
void
*
arg
)
{
struct
rtentry
rt
;
/* Use these to behave like 'other' stacks */
struct
sockaddr_ipx
*
sg
,
*
st
;
int
rc
=
-
EFAULT
;
if
(
copy_from_user
(
&
rt
,
arg
,
sizeof
(
rt
)))
goto
out
;
sg
=
(
struct
sockaddr_ipx
*
)
&
rt
.
rt_gateway
;
st
=
(
struct
sockaddr_ipx
*
)
&
rt
.
rt_dst
;
rc
=
-
EINVAL
;
if
(
!
(
rt
.
rt_flags
&
RTF_GATEWAY
)
||
/* Direct routes are fixed */
sg
->
sipx_family
!=
AF_IPX
||
st
->
sipx_family
!=
AF_IPX
)
goto
out
;
switch
(
cmd
)
{
case
SIOCDELRT
:
rc
=
ipxrtr_delete
(
st
->
sipx_network
);
break
;
case
SIOCADDRT
:
{
struct
ipx_route_definition
f
;
f
.
ipx_network
=
st
->
sipx_network
;
f
.
ipx_router_network
=
sg
->
sipx_network
;
memcpy
(
f
.
ipx_router_node
,
sg
->
sipx_node
,
IPX_NODE_LEN
);
rc
=
ipxrtr_create
(
&
f
);
break
;
}
}
out:
return
rc
;
}
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