diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2015-06-24 04:23:46 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-06-24 10:03:18 +0200 |
commit | e5067d7cd967cb17067de24a162306b79f432b20 (patch) | |
tree | 541f101762df32a5742bec354009986a96d8e564 /net/ax25/ax25_netlink.c | |
parent | 86a981e836404006efc35881ebf3d5ae36925e82 (diff) |
Import newax25-2.4.3.patch.1.bz2HEADnewax25-2.4.3-1
And cleanup the *.orig and *.rej files and whitespace errors that are part
of the original patch.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'net/ax25/ax25_netlink.c')
-rw-r--r-- | net/ax25/ax25_netlink.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/net/ax25/ax25_netlink.c b/net/ax25/ax25_netlink.c new file mode 100644 index 000000000..73e25e234 --- /dev/null +++ b/net/ax25/ax25_netlink.c @@ -0,0 +1,110 @@ +/* + * ax25_netlink.c: NETLINK interface for NEW-AX.25 + * + * Authors: Jens David (DG1KJD), Matthias Welwarsky (DG2FEF), Jonathan ( + * Alan Cox (GW4PTS), Joerg (DL1BKE), et al + * + * Comment: It is intended to develop a new AX.25 routing daemon using t + * method to communicate with the kernel part. Recent developme + * Linux' realtime abilities, however, suggest removing AX.25 c + * from kernel space. + * + * Changelog: + * + * License: This module is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. +*/ + +#include <linux/skbuff.h> +#include <linux/netlink.h> +#include <linux/ax25.h> +#include <net/sock.h> +#include <net/ax25.h> + +#include "ax25_netlink.h" +#include "ax25_route.h" + +static struct sock *axrtnl; + +static void ax25_netlink_rcv(struct sock *sk, int len) +{ + struct ax25_nlmsg *nlmsg; + struct sk_buff *skb; + struct net_device *dev; + + while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) { + if (skb->len < sizeof(struct ax25_nlmsg)) { + kfree_skb(skb); + break; + } + nlmsg = (struct ax25_nlmsg *)skb->data; + + switch (nlmsg->msg_type) { + case AX25_MSG_SETRT: + if ((dev = dev_get(nlmsg->msg.pathmsg.port_name)) != NULL + && nlmsg->msg.pathmsg.path.dcount <= AX25_MAX_DIGIS) + ax25_add_route(&nlmsg->msg.pathmsg.path, dev); + break; + + case AX25_MSG_DELRT: + if ((dev = dev_get(nlmsg->msg.pathmsg.port_name)) != NULL) + ax25_del_route(&nlmsg->msg.pathmsg.path.addr); + break; + + case AX25_MSG_OPTRT: + if ((dev = dev_get(nlmsg->msg.pathmsg.port_name)) != NULL + && nlmsg->msg.pathmsg.path.dcount <= AX25_MAX_DIGIS) + { + ax25_add_route(&nlmsg->msg.pathmsg.path, dev); + ax25_ipopt_route(&nlmsg->msg.pathmsg.path.addr, nlmsg->msg.pathmsg.mode); + } + } + kfree_skb(skb); + } +} + +void ax25_nlpost_route(ax25_pktinfo *pkt, struct net_device *dev) +{ + struct ax25_nlmsg *nlmsg; + struct sk_buff *skb; + + skb = alloc_skb(sizeof(struct ax25_nlmsg), GFP_ATOMIC); + if (!skb) + return; + nlmsg = (struct ax25_nlmsg *)skb_put(skb, sizeof(struct ax25_nlmsg)); + + nlmsg->msg_type = AX25_MSG_RTINFO; + strncpy(nlmsg->msg.rtmsg.port_name, dev->name, sizeof(nlmsg->msg.rtmsg.port_name)); + nlmsg->msg.rtmsg.addr = pkt->addr; + netlink_broadcast(axrtnl, skb, 0, ~0, GFP_KERNEL); +} + +void ax25_nlpost_armsg(unsigned int ip_addr, ax25_address *ax_addr, struct net_device *dev) +{ + struct ax25_nlmsg *nlmsg; + struct sk_buff *skb; + + skb = alloc_skb(sizeof(struct ax25_nlmsg), GFP_ATOMIC); + if (!skb) + return; + nlmsg = (struct ax25_nlmsg *)skb_put(skb, sizeof(struct ax25_nlmsg)); + + nlmsg->msg_type = AX25_MSG_ARINFO; + strncpy(nlmsg->msg.armsg.port_name, dev->name, sizeof(nlmsg->msg.armsg.port_name)); + nlmsg->msg.armsg.ip_addr = ip_addr; + nlmsg->msg.armsg.ax_addr = *ax_addr; + + netlink_broadcast(axrtnl, skb, 0, ~0, GFP_KERNEL); +} + +void ax25_netlink_init(void) +{ + axrtnl = netlink_kernel_create(NETLINK_AX25, ax25_netlink_rcv); +} + +void ax25_netlink_cleanup(void) +{ + sock_release(axrtnl->socket); +} |