Commit 0c0548ba authored by Steven Whitehouse's avatar Steven Whitehouse Committed by David S. Miller

[DECNET]: Add netfilter subdir for decnet and add the routing grabulator.

parent f507310c
......@@ -17,11 +17,11 @@ config DECNET_ROUTER
depends on DECNET && EXPERIMENTAL
---help---
Add support for turning your DECnet Endnode into a level 1 or 2
router. This is an unfinished option for developers only. If you
router. This is an experimental, but functional option. If you
do say Y here, then make sure that you also say Y to "Kernel/User
network link driver", "Routing messages" and "Network packet
filtering". The first two are required to allow configuration via
rtnetlink (currently you need Alexey Kuznetsov's iproute2 package
rtnetlink (you will need Alexey Kuznetsov's iproute2 package
from <ftp://ftp.inr.ac.ru/>). The "Network packet filtering" option
will be required for the forthcoming routing daemon to work.
......@@ -35,3 +35,5 @@ config DECNET_ROUTE_FWMARK
packets with different FWMARK ("firewalling mark") values
(see ipchains(8), "-m" argument).
source "net/decnet/netfilter/Kconfig"
obj-$(CONFIG_DECNET) += decnet.o
decnet-y := af_decnet.o dn_nsp_in.o dn_nsp_out.o dn_route.o dn_dev.o dn_neigh.o dn_timer.o
decnet-y := af_decnet.o dn_nsp_in.o dn_nsp_out.o \
dn_route.o dn_dev.o dn_neigh.o dn_timer.o
decnet-$(CONFIG_DECNET_ROUTER) += dn_fib.o dn_rules.o dn_table.o
decnet-$(CONFIG_DECNET_FW) += dn_fw.o
decnet-y += sysctl_net_decnet.o
obj-$(CONFIG_NETFILTER) += netfilter/
#
# DECnet netfilter configuration
#
menu "DECnet: Netfilter Configuration"
depends on DECNET && NETFILTER && EXPERIMENTAL
config DECNET_NF_GRABULATOR
tristate "Routing message grabulator (for userland routing daemon)"
help
Enable this module if you want to use the userland DECnet routing
daemon. You will also need to enable routing support for DECnet
unless you just want to monitor routing messages from other nodes.
endmenu
#
# Makefile for DECnet netfilter modules
#
obj-$(CONFIG_DECNET_NF_GRABULATOR) += dn_rtmsg.o
/*
* DECnet An implementation of the DECnet protocol suite for the LINUX
* operating system. DECnet is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* DECnet Routing Message Grabulator
*
* (C) 2000 ChyGwyn Limited - http://www.chygwyn.com/
* This code may be copied under the GPL v.2 or at your option
* any later version.
*
* Author: Steven Whitehouse <steve@chygwyn.com>
*
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/spinlock.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <net/flow.h>
#include <net/dn.h>
#include <net/dn_route.h>
#include <linux/netfilter_decnet.h>
static struct sock *dnrmg = NULL;
static struct sk_buff *dnrmg_build_message(struct sk_buff *rt_skb, int *errp)
{
struct sk_buff *skb = NULL;
size_t size;
unsigned char *old_tail;
struct nlmsghdr *nlh;
unsigned char *ptr;
struct nf_dn_rtmsg *rtm;
size = NLMSG_SPACE(rt_skb->len);
size += NLMSG_ALIGN(sizeof(struct nf_dn_rtmsg));
skb = alloc_skb(size, GFP_ATOMIC);
if (!skb)
goto nlmsg_failure;
old_tail = skb->tail;
nlh = NLMSG_PUT(skb, 0, 0, 0, size - sizeof(*nlh));
rtm = (struct nf_dn_rtmsg *)NLMSG_DATA(nlh);
rtm->nfdn_ifindex = rt_skb->dev->ifindex;
ptr = NFDN_RTMSG(rtm);
memcpy(ptr, rt_skb->data, rt_skb->len);
nlh->nlmsg_len = skb->tail - old_tail;
return skb;
nlmsg_failure:
if (skb)
kfree(skb);
*errp = -ENOMEM;
if (net_ratelimit())
printk(KERN_ERR "dn_rtmsg: error creating netlink message\n");
return NULL;
}
static void dnrmg_send_peer(struct sk_buff *skb)
{
struct sk_buff *skb2;
int status = 0;
int group = 0;
unsigned char flags = *skb->data;
switch(flags & DN_RT_CNTL_MSK) {
case DN_RT_PKT_L1RT:
group = DNRMG_L1_GROUP;
break;
case DN_RT_PKT_L2RT:
group = DNRMG_L2_GROUP;
break;
default:
return;
}
skb2 = dnrmg_build_message(skb, &status);
if (skb2 == NULL)
return;
NETLINK_CB(skb2).dst_groups = group;
netlink_broadcast(dnrmg, skb2, 0, group, GFP_ATOMIC);
}
static unsigned int dnrmg_hook(unsigned int hook,
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
dnrmg_send_peer(*pskb);
return NF_ACCEPT;
}
#define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
{
struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
return;
if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
RCV_SKB_FAIL(-EPERM);
/* Eventually we might send routing messages too */
RCV_SKB_FAIL(-EINVAL);
}
static void dnrmg_receive_user_sk(struct sock *sk, int len)
{
struct sk_buff *skb;
while((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
dnrmg_receive_user_skb(skb);
kfree_skb(skb);
}
}
static struct nf_hook_ops dnrmg_ops = {
.hook = dnrmg_hook,
.pf = PF_DECnet,
.hooknum = NF_DN_ROUTE,
.priority = NF_DN_PRI_DNRTMSG,
};
static int __init init(void)
{
int rv = 0;
dnrmg = netlink_kernel_create(NETLINK_DNRTMSG, dnrmg_receive_user_sk);
if (dnrmg == NULL) {
printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket");
return -ENOMEM;
}
rv = nf_register_hook(&dnrmg_ops);
if (rv) {
sock_release(dnrmg->socket);
}
return rv;
}
static void __exit fini(void)
{
nf_unregister_hook(&dnrmg_ops);
sock_release(dnrmg->socket);
}
MODULE_DESCRIPTION("DECnet Routing Message Grabulator");
MODULE_AUTHOR("Steven Whitehouse <steve@chygwyn.com>");
MODULE_LICENSE("GPL");
module_init(init);
module_exit(fini);
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