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

Reply via email to