// SPDX-License-Identifier: GPL-2.0-or-later
/*
* X . 25 Packet Layer release 002
*
* This is ALPHA test software . This code may break your machine ,
* randomly fail to work with new releases , misbehave and / or generally
* screw up . It might even work .
*
* This code REQUIRES 2 . 1 . 15 or higher
*
* History
* X . 25 001 Jonathan Naylor Started coding .
*/
#include <linux/if_arp.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <net/x25.h>
LIST_HEAD(x25_route_list);
DEFINE_RWLOCK(x25_route_list_lock);
/*
* Add a new route .
*/
static int x25_add_route(struct x25_address *address, unsigned int sigdigits,
struct net_device *dev)
{
struct x25_route *rt;
int rc = -EINVAL;
write_lock_bh(&x25_route_list_lock);
list_for_each_entry(rt, &x25_route_list, node) {
if (!memcmp(&rt->address, address, sigdigits) &&
rt->sigdigits == sigdigits)
goto out;
}
rt = kmalloc(sizeof (*rt), GFP_ATOMIC);
rc = -ENOMEM;
if (!rt)
goto out;
strcpy(rt->address.x25_addr, "000000000000000" );
memcpy(rt->address.x25_addr, address->x25_addr, sigdigits);
rt->sigdigits = sigdigits;
rt->dev = dev;
refcount_set(&rt->refcnt, 1 );
list_add(&rt->node, &x25_route_list);
rc = 0 ;
out:
write_unlock_bh(&x25_route_list_lock);
return rc;
}
/**
* _ _ x25_remove_route - remove route from x25_route_list
* @ rt : route to remove
*
* Remove route from x25_route_list . If it was there .
* Caller must hold x25_route_list_lock .
*/
static void __x25_remove_route(struct x25_route *rt)
{
if (rt->node.next) {
list_del(&rt->node);
x25_route_put(rt);
}
}
static int x25_del_route(struct x25_address *address, unsigned int sigdigits,
struct net_device *dev)
{
struct x25_route *rt;
int rc = -EINVAL;
write_lock_bh(&x25_route_list_lock);
list_for_each_entry(rt, &x25_route_list, node) {
if (!memcmp(&rt->address, address, sigdigits) &&
rt->sigdigits == sigdigits && rt->dev == dev) {
__x25_remove_route(rt);
rc = 0 ;
break ;
}
}
write_unlock_bh(&x25_route_list_lock);
return rc;
}
/*
* A device has been removed , remove its routes .
*/
void x25_route_device_down(struct net_device *dev)
{
struct x25_route *rt;
struct list_head *entry, *tmp;
write_lock_bh(&x25_route_list_lock);
list_for_each_safe(entry, tmp, &x25_route_list) {
rt = list_entry(entry, struct x25_route, node);
if (rt->dev == dev)
__x25_remove_route(rt);
}
write_unlock_bh(&x25_route_list_lock);
}
/*
* Check that the device given is a valid X . 25 interface that is " up " .
*/
struct net_device *x25_dev_get(char *devname)
{
struct net_device *dev = dev_get_by_name(&init_net, devname);
if (dev && (!(dev->flags & IFF_UP) || dev->type != ARPHRD_X25)) {
dev_put(dev);
dev = NULL;
}
return dev;
}
/**
* x25_get_route - Find a route given an X . 25 address .
* @ addr : - address to find a route for
*
* Find a route given an X . 25 address .
*/
struct x25_route *x25_get_route(struct x25_address *addr)
{
struct x25_route *rt, *use = NULL;
read_lock_bh(&x25_route_list_lock);
list_for_each_entry(rt, &x25_route_list, node) {
if (!memcmp(&rt->address, addr, rt->sigdigits)) {
if (!use)
use = rt;
else if (rt->sigdigits > use->sigdigits)
use = rt;
}
}
if (use)
x25_route_hold(use);
read_unlock_bh(&x25_route_list_lock);
return use;
}
/*
* Handle the ioctls that control the routing functions .
*/
int x25_route_ioctl(unsigned int cmd, void __user *arg)
{
struct x25_route_struct rt;
struct net_device *dev;
int rc = -EINVAL;
if (cmd != SIOCADDRT && cmd != SIOCDELRT)
goto out;
rc = -EFAULT;
if (copy_from_user(&rt, arg, sizeof (rt)))
goto out;
rc = -EINVAL;
if (rt.sigdigits > 15 )
goto out;
dev = x25_dev_get(rt.device);
if (!dev)
goto out;
if (cmd == SIOCADDRT)
rc = x25_add_route(&rt.address, rt.sigdigits, dev);
else
rc = x25_del_route(&rt.address, rt.sigdigits, dev);
dev_put(dev);
out:
return rc;
}
/*
* Release all memory associated with X . 25 routing structures .
*/
void __exit x25_route_free(void )
{
struct x25_route *rt;
struct list_head *entry, *tmp;
write_lock_bh(&x25_route_list_lock);
list_for_each_safe(entry, tmp, &x25_route_list) {
rt = list_entry(entry, struct x25_route, node);
__x25_remove_route(rt);
}
write_unlock_bh(&x25_route_list_lock);
}
Messung V0.5 in Prozent C=96 H=84 G=90
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland