From: Michal Sojka Date: Fri, 4 Apr 2014 14:37:20 +0000 (+0200) Subject: Merge branch 'master' of rtime.felk.cvut.cz:can-eth-gw-linux X-Git-Url: http://rtime.felk.cvut.cz/gitweb/can-eth-gw-linux.git/commitdiff_plain/6617e487023de8582afcf1cf51b532a8e1260902 Merge branch 'master' of rtime.felk.cvut.cz:can-eth-gw-linux Conflicts: include/uapi/linux/can/canethgw.h net/can/canethgw.c --- 6617e487023de8582afcf1cf51b532a8e1260902 diff --cc include/uapi/linux/can/canethgw.h index ba81ee36fdfa,f12e054850d6..4bc96a7845ed --- a/include/uapi/linux/can/canethgw.h +++ b/include/uapi/linux/can/canethgw.h @@@ -9,21 -9,9 +9,9 @@@ struct cegw_ioct __u32 udp_sock; __u32 udp_dstcnt; __u32 udp_addrlen; - struct sockaddr_in udp_dst[0]; + __u8 udp_dst[0]; }; - #ifdef __KERNEL__ - struct cegw_job - { - struct kref refcount; - struct socket* can_sock; - struct socket* udp_sock; - u32 udp_dstcnt; - u32 udp_addrlen; - u8 udp_dst[0]; - }; - #endif - #define CEGW_IOCTL_BASE 'c' #define CEGW_IOCTL_START _IOW(CEGW_IOCTL_BASE, 0, struct cegw_ioctl) diff --cc net/can/canethgw.c index 36da707cc4bf,86e28efaa12f..6c9c8aae64c7 --- a/net/can/canethgw.c +++ b/net/can/canethgw.c @@@ -24,24 -24,37 +24,39 @@@ MODULE_LICENSE("GPL"); + enum msg_types { + CAN_FRAME, + }; + + struct cegw_job + { + struct kref refcount; + struct socket* can_sock; + struct socket* udp_sock; - __u32 udp_dstcnt; - struct sockaddr_in udp_dst[0]; ++ u32 udp_dstcnt; ++ u32 udp_addrlen; ++ u8 udp_dst[0]; + }; + static int cegw_udp2can(void *data); static int cegw_udp_send(struct socket *udp_sock, struct can_frame *cf, - struct sockaddr_in* addr); + struct sockaddr* addr, int addrlen); static int cegw_can2udp(void *data); static int cegw_can_send(struct socket *can_sock, struct can_frame *cf); static int cegw_thread_start(void *data); static int cegw_thread_stop(struct cegw_job *job); static void cegw_job_release(struct kref *ref); -static int cegw_udp_send(struct socket *udp_sock, struct can_frame *cf, struct sockaddr_in* addr) +static int cegw_udp_send(struct socket *udp_sock, struct can_frame *cf, struct sockaddr *addr, + int addrlen) { struct msghdr mh; - struct kvec vec; + struct kvec vec[2]; int err; + __u16 type = CAN_FRAME; mh.msg_name = addr; - mh.msg_namelen = sizeof(*addr); + mh.msg_namelen = addrlen; mh.msg_control = NULL; mh.msg_controllen = 0; mh.msg_flags = 0; @@@ -270,20 -289,14 +296,20 @@@ static long cegw_ioctl_start(struct fil err = copy_from_user(&job->udp_dst, (void __user *)(arg + sizeof(struct cegw_ioctl)), dstcnt*addrlen); if (err != 0) { - kfree(job); - return -EFAULT; + err = -EFAULT; + goto err_free; } - for (i=0; iudp_dst[i].sin_family != AF_INET) { + /* */ + if (dstcnt > 0) + sa = (struct sockaddr *)job->udp_dst; + chckfam = sa->sa_family; + + for (i=1; iudp_dst + i*addrlen); + if (sa->sa_family != chckfam) { - kfree(job); - return -EAFNOSUPPORT; + err = -EAFNOSUPPORT; + goto err_free; } }