On Sun, May 01, 2011 at 07:16:54PM +0200, Oliver Hartkopp wrote:
> On 27.04.2011 10:57, Kurt Van Dijck wrote:
> > This patch adds rtnetlink support for AF_CAN. This support is really
> > a multiplexer towards the different CAN protocols.
>
> Hello Kurt,
>
> i applied all your patches for the can-utils and the network layer stuff to
> the BerliOS SVN in socketcan/branches/j1939 for testing.
>
[...]
>
> The can-j1939.ko builds properly in the SVN against 2.6.39-rc5 and the
> net-next-2.6 tree - and e.g. against a debian wheezy kernel:
Since we're actually building this on a 2.6.25 yet, I added some version
checks for the berlios svn. It makes it build for older kernels than 2.6.38.
Biggest change is that:
$ ip link set can0 j1939 on
will not work. before 2.6.36, you must:
$ echo can0 > /proc/net/can-j1939/net
and likewise, '$ ip link set can0 j1939 off' is replaced by
'$ echo -can0 > /proc/net/can-j1939/net'
Kurt
---
Index: net/can/j1939/rtnl.c
===================================================================
--- net/can/j1939/rtnl.c (revision 1249)
+++ net/can/j1939/rtnl.c (working copy)
@@ -36,8 +36,10 @@
struct nlattr *nla, *tb[IFA_J1939_MAX];
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
if (!net_eq(sock_net(skb->sk), &init_net))
return -EINVAL;
+#endif
nla = nlmsg_find_attr(nlh, sizeof(*ifm), IFA_LOCAL);
if (!nla)
@@ -96,8 +98,10 @@
int ret;
struct nlattr *nla, *tb[IFA_J1939_MAX];
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
if (!net_eq(sock_net(skb->sk), &init_net))
return -EINVAL;
+#endif
nla = nlmsg_find_attr(nlh, sizeof(*ifm), IFA_LOCAL);
if (!nla)
@@ -180,8 +184,10 @@
struct j1939_ecu *ecu;
struct addr_ent *ent;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
if (!net_eq(sock_net(skb->sk), &init_net))
return 0;
+#endif
ndev = 0;
for_each_netdev(&init_net, netdev) {
@@ -243,6 +249,7 @@
return skb->len;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
/*
* rtnl_link_ops
*/
@@ -305,4 +312,5 @@
.validate_link_af = j1939_validate_link_af,
.set_link_af = j1939_set_link_af,
};
+#endif
Index: net/can/j1939/j1939-priv.h
===================================================================
--- net/can/j1939/j1939-priv.h (revision 1249)
+++ net/can/j1939/j1939-priv.h (working copy)
@@ -19,7 +19,11 @@
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <socketcan/can/j1939.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
#include <linux/atomic.h>
+#else
+#include <asm/atomic.h>
+#endif
/* TODO: return ENETRESET on busoff. */
@@ -306,7 +310,9 @@
extern void j1939tp_module_exit(void);
/* rtnetlink */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
extern const struct rtnl_af_ops j1939_rtnl_af_ops;
+#endif
extern int j1939rtnl_new_addr(struct sk_buff *, struct nlmsghdr *, void *arg);
extern int j1939rtnl_del_addr(struct sk_buff *, struct nlmsghdr *, void *arg);
extern int j1939rtnl_dump_addr(struct sk_buff *, struct netlink_callback *);
Index: net/can/j1939/proc.c
===================================================================
--- net/can/j1939/proc.c (revision 1249)
+++ net/can/j1939/proc.c (working copy)
@@ -90,15 +90,26 @@
__init int j1939_proc_module_init(void)
{
/* create /proc/net/can directory */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
rootdir = proc_mkdir(j1939_procname, init_net.proc_net);
+#else
+ rootdir = proc_mkdir(j1939_procname, proc_net);
+#endif
if (!rootdir)
return -EINVAL;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+ rootdir->owner = THIS_MODULE;
+#endif
return 0;
}
void j1939_proc_module_exit(void)
{
if (rootdir)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
proc_net_remove(&init_net, j1939_procname);
+#else
+ proc_net_remove(j1939_procname);
+#endif
}
Index: net/can/j1939/main.c
===================================================================
--- net/can/j1939/main.c (revision 1249)
+++ net/can/j1939/main.c (working copy)
@@ -381,8 +381,13 @@
struct net_device *netdev = (struct net_device *)data;
struct j1939_segment *jseg;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
if (!net_eq(dev_net(netdev), &init_net))
return NOTIFY_DONE;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ if (netdev->nd_net != &init_net)
+ return NOTIFY_DONE;
+#endif
if (netdev->type != ARPHRD_CAN)
return NOTIFY_DONE;
Index: net/can/j1939/socket.c
===================================================================
--- net/can/j1939/socket.c (revision 1249)
+++ net/can/j1939/socket.c (working copy)
@@ -544,8 +544,13 @@
return tmp;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
static int j1939sk_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen)
+#else
+static int j1939sk_setsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int optlen)
+#endif
{
struct sock *sk = sock->sk;
struct j1939_sock *jsk = j1939_sk(sk);
@@ -555,6 +560,11 @@
if (level != SOL_CAN_J1939)
return -EINVAL;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+ if (optlen < 0)
+ return -EINVAL;
+#endif
+
switch (optname) {
case SO_J1939_FILTER:
if (optval) {
@@ -938,7 +948,9 @@
.ops = &j1939_ops,
.prot = &j1939_proto,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
.rtnl_link_ops = &j1939_rtnl_af_ops,
+#endif
.rtnl_new_addr = j1939rtnl_new_addr,
.rtnl_del_addr = j1939rtnl_del_addr,
.rtnl_dump_addr = j1939rtnl_dump_addr,
Index: net/can/j1939/bus.c
===================================================================
--- net/can/j1939/bus.c (revision 1249)
+++ net/can/j1939/bus.c (working copy)
@@ -489,11 +489,82 @@
return 0;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
+static int j1939_proc_net(struct seq_file *sqf, void *v)
+{
+ struct j1939_segment *jseg;
+ struct net_device *netdev;
+
+ seq_printf(sqf, "ifindex\tiface\tid\n");
+ spin_lock_bh(&segments.lock);
+ list_for_each_entry(jseg, &segments.list, flist) {
+ get_j1939_segment(jseg);
+ netdev = dev_get_by_index(&init_net, jseg->ifindex);
+ if (!netdev) {
+ pr_alert("j1939 proc: ifindex %i not found\n",
+ jseg->ifindex);
+ put_j1939_segment(jseg);
+ continue;
+ }
+ seq_printf(sqf, "%i\t%s\n", jseg->ifindex,
+ netdev ? netdev->name : "!");
+ if (netdev)
+ dev_put(netdev);
+ put_j1939_segment(jseg);
+ }
+ spin_unlock_bh(&segments.lock);
+ return 0;
+}
+
+static int j1939_proc_wr_net(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ int ret;
+ char *arg;
+ int opt;
+ struct net_device *netdev = NULL;
+ char buf[IFNAMSIZ+4];
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ if (count >= sizeof(buf))
+ return -EINVAL;
+ if (copy_from_user(buf, buffer, count))
+ return -EFAULT;
+ buf[count] = 0;
+ arg = strstrip(buf);
+
+ opt = '+';
+ if (strchr("+-~!", arg[0])) {
+ opt = arg[0];
+ ++arg;
+ }
+ netdev = dev_get_by_name(&init_net, arg);
+ if (!netdev)
+ return -ENOENT;
+ if (strchr("+", opt))
+ ret = j1939_segment_attach(netdev);
+ else
+ ret = j1939_segment_detach(netdev);
+ if (ret < 0)
+ goto failed;
+ ret = count;
+
+failed:
+ if (netdev)
+ dev_put(netdev);
+ return ret;
+}
+#endif
+
/* exported init */
int __init j1939bus_module_init(void)
{
INIT_LIST_HEAD(&segments.list);
spin_lock_init(&segments.lock);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
+ j1939_proc_add("net", j1939_proc_net, j1939_proc_wr_net);
+#endif
j1939_proc_add("addr", j1939_proc_addr, NULL);
j1939_proc_add("ecu", j1939_proc_ecu, NULL);
return 0;
@@ -518,6 +589,9 @@
j1939_proc_remove("ecu");
j1939_proc_remove("addr");
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
+ j1939_proc_remove("net");
+#endif
}
Index: net/can/j1939/transport.c
===================================================================
--- net/can/j1939/transport.c (revision 1249)
+++ net/can/j1939/transport.c (working copy)
@@ -1298,8 +1298,13 @@
struct net_device *netdev = (struct net_device *)data;
struct session *session, *saved;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
if (!net_eq(dev_net(netdev), &init_net))
return NOTIFY_DONE;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ if (netdev->nd_net != &init_net)
+ return NOTIFY_DONE;
+#endif
if (netdev->type != ARPHRD_CAN)
return NOTIFY_DONE;
Index: net/can/af_can.c
===================================================================
--- net/can/af_can.c (revision 1249)
+++ net/can/af_can.c (working copy)
@@ -1090,6 +1090,7 @@
/*
* LINK AF properties
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
static size_t can_get_link_af_size(const struct net_device *dev)
{
int ret, j, total;
@@ -1218,6 +1219,7 @@
.validate_link_af = can_validate_link_af,
.set_link_af = can_set_link_af,
};
+#endif
/* exported init */
@@ -1259,7 +1261,9 @@
register_netdevice_notifier(&can_netdev_notifier);
dev_add_pack(&can_packet);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
rtnl_af_register(&can_rtnl_af_ops);
+#endif
rtnl_register(PF_CAN, RTM_NEWADDR, can_rtnl_doit, NULL);
rtnl_register(PF_CAN, RTM_DELADDR, can_rtnl_doit, NULL);
rtnl_register(PF_CAN, RTM_GETADDR, NULL, can_rtnl_dump_addr);
@@ -1278,7 +1282,9 @@
rtnl_unregister(PF_CAN, RTM_NEWADDR);
rtnl_unregister(PF_CAN, RTM_DELADDR);
rtnl_unregister(PF_CAN, RTM_GETADDR);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
rtnl_af_unregister(&can_rtnl_af_ops);
+#endif
can_remove_proc();
Index: Makefile
===================================================================
--- Makefile (revision 1249)
+++ Makefile (working copy)
@@ -37,6 +37,7 @@
export CONFIG_CAN_RAW=m
export CONFIG_CAN_BCM=m
export CONFIG_CAN_ISOTP=m
+export CONFIG_CAN_J1939=m
modules modules_install clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) $@ TOPDIR=$(TOPDIR)
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core