staging: ipx: delete it from the tree
The ipx code moved into the staging tree back in November 2017 and no one has complained or even noticed it was gone. Because of that, let's just delete it. Note, the ipx header files are not removed here, that will come later through the networking tree, as that takes a bit more work to unwind. Cc: Stephen Hemminger <stephen@networkplumber.org> Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
05e98465e0
commit
7a2e838d28
|
@ -24,8 +24,6 @@ menuconfig STAGING
|
|||
|
||||
if STAGING
|
||||
|
||||
source "drivers/staging/ipx/Kconfig"
|
||||
|
||||
source "drivers/staging/wlan-ng/Kconfig"
|
||||
|
||||
source "drivers/staging/comedi/Kconfig"
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
obj-y += media/
|
||||
obj-y += typec/
|
||||
obj-$(CONFIG_IPX) += ipx/
|
||||
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
||||
obj-$(CONFIG_COMEDI) += comedi/
|
||||
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
#
|
||||
# IPX configuration
|
||||
#
|
||||
config IPX
|
||||
tristate "The IPX protocol"
|
||||
depends on NET
|
||||
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
|
||||
want to access Novell NetWare file or print servers using the Linux
|
||||
Novell client ncpfs (available from
|
||||
<ftp://platan.vc.cvut.cz/pub/linux/ncpfs/>) or from
|
||||
within the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO,
|
||||
available from <http://www.tldp.org/docs.html#howto>). In order
|
||||
to do the former, you'll also have to say Y to "NCP file system
|
||||
support", below.
|
||||
|
||||
IPX is similar in scope to IP, while SPX, which runs on top of IPX,
|
||||
is similar to TCP.
|
||||
|
||||
To turn your Linux box into a fully featured NetWare file server and
|
||||
IPX router, say Y here and fetch either lwared from
|
||||
<ftp://ibiblio.org/pub/Linux/system/network/daemons/> or
|
||||
mars_nwe from <ftp://www.compu-art.de/mars_nwe/>. For more
|
||||
information, read the IPX-HOWTO available from
|
||||
<http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
The IPX driver would enlarge your kernel by about 16 KB. To compile
|
||||
this driver as a module, choose M here: the module will be called ipx.
|
||||
Unless you want to integrate your Linux box with a local Novell
|
||||
network, say N.
|
||||
|
||||
config IPX_INTERN
|
||||
bool "IPX: Full internal IPX network"
|
||||
depends on IPX
|
||||
---help---
|
||||
Every IPX network has an address that identifies it. Sometimes it is
|
||||
useful to give an IPX "network" address to your Linux box as well
|
||||
(for example if your box is acting as a file server for different
|
||||
IPX networks: it will then be accessible from everywhere using the
|
||||
same address). The way this is done is to create a virtual internal
|
||||
"network" inside your box and to assign an IPX address to this
|
||||
network. Say Y here if you want to do this; read the IPX-HOWTO at
|
||||
<http://www.tldp.org/docs.html#howto> for details.
|
||||
|
||||
The full internal IPX network enables you to allocate sockets on
|
||||
different virtual nodes of the internal network. This is done by
|
||||
evaluating the field sipx_node of the socket address given to the
|
||||
bind call. So applications should always initialize the node field
|
||||
to 0 when binding a socket on the primary network. In this case the
|
||||
socket is assigned the default node that has been given to the
|
||||
kernel when the internal network was created. By enabling the full
|
||||
internal IPX network the cross-forwarding of packets targeted at
|
||||
'special' sockets to sockets listening on the primary network is
|
||||
disabled. This might break existing applications, especially RIP/SAP
|
||||
daemons. A RIP/SAP daemon that works well with the full internal net
|
||||
can be found on <ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/>.
|
||||
|
||||
If you don't know what you are doing, say N.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# Makefile for the Linux IPX layer.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_IPX) += ipx.o
|
||||
|
||||
ipx-y := af_ipx.o ipx_route.o ipx_proc.o pe2.o
|
||||
ipx-$(CONFIG_SYSCTL) += sysctl_net_ipx.o
|
|
@ -1,4 +0,0 @@
|
|||
The ipx code will be removed soon from the kernel tree as it is old and
|
||||
obsolete and broken.
|
||||
|
||||
Don't worry about fixing up anything here, it's not needed.
|
File diff suppressed because it is too large
Load Diff
|
@ -1,338 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* IPX proc routines
|
||||
*
|
||||
* Copyright(C) Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2002
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#ifdef CONFIG_PROC_FS
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/export.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/tcp_states.h>
|
||||
#include <net/ipx.h>
|
||||
|
||||
static void *ipx_seq_interface_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
spin_lock_bh(&ipx_interfaces_lock);
|
||||
return seq_list_start_head(&ipx_interfaces, *pos);
|
||||
}
|
||||
|
||||
static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
return seq_list_next(v, &ipx_interfaces, pos);
|
||||
}
|
||||
|
||||
static void ipx_seq_interface_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
spin_unlock_bh(&ipx_interfaces_lock);
|
||||
}
|
||||
|
||||
static int ipx_seq_interface_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct ipx_interface *i;
|
||||
|
||||
if (v == &ipx_interfaces) {
|
||||
seq_puts(seq, "Network Node_Address Primary Device "
|
||||
"Frame_Type");
|
||||
#ifdef IPX_REFCNT_DEBUG
|
||||
seq_puts(seq, " refcnt");
|
||||
#endif
|
||||
seq_puts(seq, "\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
i = list_entry(v, struct ipx_interface, node);
|
||||
seq_printf(seq, "%08X ", ntohl(i->if_netnum));
|
||||
seq_printf(seq, "%02X%02X%02X%02X%02X%02X ",
|
||||
i->if_node[0], i->if_node[1], i->if_node[2],
|
||||
i->if_node[3], i->if_node[4], i->if_node[5]);
|
||||
seq_printf(seq, "%-9s", i == ipx_primary_net ? "Yes" : "No");
|
||||
seq_printf(seq, "%-11s", ipx_device_name(i));
|
||||
seq_printf(seq, "%-9s", ipx_frame_name(i->if_dlink_type));
|
||||
#ifdef IPX_REFCNT_DEBUG
|
||||
seq_printf(seq, "%6d", refcount_read(&i->refcnt));
|
||||
#endif
|
||||
seq_puts(seq, "\n");
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *ipx_seq_route_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
read_lock_bh(&ipx_routes_lock);
|
||||
return seq_list_start_head(&ipx_routes, *pos);
|
||||
}
|
||||
|
||||
static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
return seq_list_next(v, &ipx_routes, pos);
|
||||
}
|
||||
|
||||
static void ipx_seq_route_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
read_unlock_bh(&ipx_routes_lock);
|
||||
}
|
||||
|
||||
static int ipx_seq_route_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct ipx_route *rt;
|
||||
|
||||
if (v == &ipx_routes) {
|
||||
seq_puts(seq, "Network Router_Net Router_Node\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rt = list_entry(v, struct ipx_route, node);
|
||||
|
||||
seq_printf(seq, "%08X ", ntohl(rt->ir_net));
|
||||
if (rt->ir_routed)
|
||||
seq_printf(seq, "%08X %02X%02X%02X%02X%02X%02X\n",
|
||||
ntohl(rt->ir_intrfc->if_netnum),
|
||||
rt->ir_router_node[0], rt->ir_router_node[1],
|
||||
rt->ir_router_node[2], rt->ir_router_node[3],
|
||||
rt->ir_router_node[4], rt->ir_router_node[5]);
|
||||
else
|
||||
seq_puts(seq, "Directly Connected\n");
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ struct sock *ipx_get_socket_idx(loff_t pos)
|
||||
{
|
||||
struct sock *s = NULL;
|
||||
struct ipx_interface *i;
|
||||
|
||||
list_for_each_entry(i, &ipx_interfaces, node) {
|
||||
spin_lock_bh(&i->if_sklist_lock);
|
||||
sk_for_each(s, &i->if_sklist) {
|
||||
if (!pos)
|
||||
break;
|
||||
--pos;
|
||||
}
|
||||
spin_unlock_bh(&i->if_sklist_lock);
|
||||
if (!pos) {
|
||||
if (s)
|
||||
goto found;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s = NULL;
|
||||
found:
|
||||
return s;
|
||||
}
|
||||
|
||||
static void *ipx_seq_socket_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
loff_t l = *pos;
|
||||
|
||||
spin_lock_bh(&ipx_interfaces_lock);
|
||||
return l ? ipx_get_socket_idx(--l) : SEQ_START_TOKEN;
|
||||
}
|
||||
|
||||
static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct sock* sk, *next;
|
||||
struct ipx_interface *i;
|
||||
struct ipx_sock *ipxs;
|
||||
|
||||
++*pos;
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
sk = NULL;
|
||||
i = ipx_interfaces_head();
|
||||
if (!i)
|
||||
goto out;
|
||||
sk = sk_head(&i->if_sklist);
|
||||
if (sk)
|
||||
spin_lock_bh(&i->if_sklist_lock);
|
||||
goto out;
|
||||
}
|
||||
sk = v;
|
||||
next = sk_next(sk);
|
||||
if (next) {
|
||||
sk = next;
|
||||
goto out;
|
||||
}
|
||||
ipxs = ipx_sk(sk);
|
||||
i = ipxs->intrfc;
|
||||
spin_unlock_bh(&i->if_sklist_lock);
|
||||
sk = NULL;
|
||||
for (;;) {
|
||||
if (i->node.next == &ipx_interfaces)
|
||||
break;
|
||||
i = list_entry(i->node.next, struct ipx_interface, node);
|
||||
spin_lock_bh(&i->if_sklist_lock);
|
||||
if (!hlist_empty(&i->if_sklist)) {
|
||||
sk = sk_head(&i->if_sklist);
|
||||
break;
|
||||
}
|
||||
spin_unlock_bh(&i->if_sklist_lock);
|
||||
}
|
||||
out:
|
||||
return sk;
|
||||
}
|
||||
|
||||
static int ipx_seq_socket_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct sock *s;
|
||||
struct ipx_sock *ipxs;
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
#ifdef CONFIG_IPX_INTERN
|
||||
seq_puts(seq, "Local_Address "
|
||||
"Remote_Address Tx_Queue "
|
||||
"Rx_Queue State Uid\n");
|
||||
#else
|
||||
seq_puts(seq, "Local_Address Remote_Address "
|
||||
"Tx_Queue Rx_Queue State Uid\n");
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
|
||||
s = v;
|
||||
ipxs = ipx_sk(s);
|
||||
#ifdef CONFIG_IPX_INTERN
|
||||
seq_printf(seq, "%08X:%02X%02X%02X%02X%02X%02X:%04X ",
|
||||
ntohl(ipxs->intrfc->if_netnum),
|
||||
ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3],
|
||||
ipxs->node[4], ipxs->node[5], ntohs(ipxs->port));
|
||||
#else
|
||||
seq_printf(seq, "%08X:%04X ", ntohl(ipxs->intrfc->if_netnum),
|
||||
ntohs(ipxs->port));
|
||||
#endif /* CONFIG_IPX_INTERN */
|
||||
if (s->sk_state != TCP_ESTABLISHED)
|
||||
seq_printf(seq, "%-28s", "Not_Connected");
|
||||
else {
|
||||
seq_printf(seq, "%08X:%02X%02X%02X%02X%02X%02X:%04X ",
|
||||
ntohl(ipxs->dest_addr.net),
|
||||
ipxs->dest_addr.node[0], ipxs->dest_addr.node[1],
|
||||
ipxs->dest_addr.node[2], ipxs->dest_addr.node[3],
|
||||
ipxs->dest_addr.node[4], ipxs->dest_addr.node[5],
|
||||
ntohs(ipxs->dest_addr.sock));
|
||||
}
|
||||
|
||||
seq_printf(seq, "%08X %08X %02X %03u\n",
|
||||
sk_wmem_alloc_get(s),
|
||||
sk_rmem_alloc_get(s),
|
||||
s->sk_state,
|
||||
from_kuid_munged(seq_user_ns(seq), sock_i_uid(s)));
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations ipx_seq_interface_ops = {
|
||||
.start = ipx_seq_interface_start,
|
||||
.next = ipx_seq_interface_next,
|
||||
.stop = ipx_seq_interface_stop,
|
||||
.show = ipx_seq_interface_show,
|
||||
};
|
||||
|
||||
static const struct seq_operations ipx_seq_route_ops = {
|
||||
.start = ipx_seq_route_start,
|
||||
.next = ipx_seq_route_next,
|
||||
.stop = ipx_seq_route_stop,
|
||||
.show = ipx_seq_route_show,
|
||||
};
|
||||
|
||||
static const struct seq_operations ipx_seq_socket_ops = {
|
||||
.start = ipx_seq_socket_start,
|
||||
.next = ipx_seq_socket_next,
|
||||
.stop = ipx_seq_interface_stop,
|
||||
.show = ipx_seq_socket_show,
|
||||
};
|
||||
|
||||
static int ipx_seq_route_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &ipx_seq_route_ops);
|
||||
}
|
||||
|
||||
static int ipx_seq_interface_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &ipx_seq_interface_ops);
|
||||
}
|
||||
|
||||
static int ipx_seq_socket_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &ipx_seq_socket_ops);
|
||||
}
|
||||
|
||||
static const struct file_operations ipx_seq_interface_fops = {
|
||||
.open = ipx_seq_interface_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static const struct file_operations ipx_seq_route_fops = {
|
||||
.open = ipx_seq_route_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static const struct file_operations ipx_seq_socket_fops = {
|
||||
.open = ipx_seq_socket_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static struct proc_dir_entry *ipx_proc_dir;
|
||||
|
||||
int __init ipx_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
int rc = -ENOMEM;
|
||||
|
||||
ipx_proc_dir = proc_mkdir("ipx", init_net.proc_net);
|
||||
|
||||
if (!ipx_proc_dir)
|
||||
goto out;
|
||||
p = proc_create("interface", S_IRUGO,
|
||||
ipx_proc_dir, &ipx_seq_interface_fops);
|
||||
if (!p)
|
||||
goto out_interface;
|
||||
|
||||
p = proc_create("route", S_IRUGO, ipx_proc_dir, &ipx_seq_route_fops);
|
||||
if (!p)
|
||||
goto out_route;
|
||||
|
||||
p = proc_create("socket", S_IRUGO, ipx_proc_dir, &ipx_seq_socket_fops);
|
||||
if (!p)
|
||||
goto out_socket;
|
||||
|
||||
rc = 0;
|
||||
out:
|
||||
return rc;
|
||||
out_socket:
|
||||
remove_proc_entry("route", ipx_proc_dir);
|
||||
out_route:
|
||||
remove_proc_entry("interface", ipx_proc_dir);
|
||||
out_interface:
|
||||
remove_proc_entry("ipx", init_net.proc_net);
|
||||
goto out;
|
||||
}
|
||||
|
||||
void __exit ipx_proc_exit(void)
|
||||
{
|
||||
remove_proc_entry("interface", ipx_proc_dir);
|
||||
remove_proc_entry("route", ipx_proc_dir);
|
||||
remove_proc_entry("socket", ipx_proc_dir);
|
||||
remove_proc_entry("ipx", init_net.proc_net);
|
||||
}
|
||||
|
||||
#else /* CONFIG_PROC_FS */
|
||||
|
||||
int __init ipx_proc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __exit ipx_proc_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PROC_FS */
|
|
@ -1,293 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* 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/list.h>
|
||||
#include <linux/route.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <net/ipx.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
LIST_HEAD(ipx_routes);
|
||||
DEFINE_RWLOCK(ipx_routes_lock);
|
||||
|
||||
extern struct ipx_interface *ipx_internal_net;
|
||||
|
||||
extern struct ipx_interface *ipxitf_find_using_net(__be32 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);
|
||||
|
||||
struct ipx_route *ipxrtr_lookup(__be32 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(__be32 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;
|
||||
|
||||
refcount_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(__be32 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 msghdr *msg, size_t len, int noblock)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct ipx_sock *ipxs = ipx_sk(sk);
|
||||
struct ipx_interface *intrfc;
|
||||
struct ipxhdr *ipx;
|
||||
size_t 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_reset_network_header(skb);
|
||||
skb_reset_transport_header(skb);
|
||||
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_from_msg(skb_put(skb, len), msg, len);
|
||||
if (rc) {
|
||||
kfree_skb(skb);
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
/* Apply checksum. Not allowed on 802.3 links. */
|
||||
if (sk->sk_no_check_tx ||
|
||||
intrfc->if_dlink_type == htons(IPX_FRAME_8023))
|
||||
ipx->ipx_checksum = htons(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 __user *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;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/in.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <net/datalink.h>
|
||||
|
||||
static int pEII_request(struct datalink_proto *dl,
|
||||
struct sk_buff *skb, unsigned char *dest_node)
|
||||
{
|
||||
struct net_device *dev = skb->dev;
|
||||
|
||||
skb->protocol = htons(ETH_P_IPX);
|
||||
dev_hard_header(skb, dev, ETH_P_IPX, dest_node, NULL, skb->len);
|
||||
return dev_queue_xmit(skb);
|
||||
}
|
||||
|
||||
struct datalink_proto *make_EII_client(void)
|
||||
{
|
||||
struct datalink_proto *proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
|
||||
|
||||
if (proto) {
|
||||
proto->header_length = 0;
|
||||
proto->request = pEII_request;
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
void destroy_EII_client(struct datalink_proto *dl)
|
||||
{
|
||||
kfree(dl);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* -*- linux-c -*-
|
||||
* sysctl_net_ipx.c: sysctl interface to net IPX subsystem.
|
||||
*
|
||||
* Begun April 1, 1996, Mike Shaver.
|
||||
* Added /proc/sys/net/ipx directory entry (empty =) ). [MS]
|
||||
* Added /proc/sys/net/ipx/ipx_pprop_broadcasting - acme March 4, 2001
|
||||
*/
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/ipx.h>
|
||||
|
||||
#ifndef CONFIG_SYSCTL
|
||||
#error This file should not be compiled without CONFIG_SYSCTL defined
|
||||
#endif
|
||||
|
||||
static struct ctl_table ipx_table[] = {
|
||||
{
|
||||
.procname = "ipx_pprop_broadcasting",
|
||||
.data = &sysctl_ipx_pprop_broadcasting,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct ctl_table_header *ipx_table_header;
|
||||
|
||||
void ipx_register_sysctl(void)
|
||||
{
|
||||
ipx_table_header = register_net_sysctl(&init_net, "net/ipx", ipx_table);
|
||||
}
|
||||
|
||||
void ipx_unregister_sysctl(void)
|
||||
{
|
||||
unregister_net_sysctl_table(ipx_table_header);
|
||||
}
|
Loading…
Reference in New Issue