From: Radek Matějka Date: Fri, 8 Feb 2013 22:44:01 +0000 (-0600) Subject: support for ipv6 added X-Git-Url: http://rtime.felk.cvut.cz/gitweb/can-eth-gw-linux.git/commitdiff_plain/daa61222602b864ea80e4fb1e7e428136b392c6d support for ipv6 added --- diff --git a/include/linux/can/canethgw.h b/include/linux/can/canethgw.h index 65d9cc51b8e9..ba81ee36fdfa 100644 --- a/include/linux/can/canethgw.h +++ b/include/linux/can/canethgw.h @@ -9,7 +9,7 @@ struct cegw_ioctl __u32 udp_sock; __u32 udp_dstcnt; __u32 udp_addrlen; - struct sockaddr_in udp_dst[0]; + __u8 udp_dst[0]; }; #ifdef __KERNEL__ @@ -18,8 +18,9 @@ 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]; }; #endif @@ -27,4 +28,3 @@ struct cegw_job #define CEGW_IOCTL_START _IOW(CEGW_IOCTL_BASE, 0, struct cegw_ioctl) #endif /* CANETHGW_H */ - diff --git a/net/can/canethgw.c b/net/can/canethgw.c index d5b030215614..36da707cc4bf 100644 --- a/net/can/canethgw.c +++ b/net/can/canethgw.c @@ -26,21 +26,22 @@ MODULE_LICENSE("GPL"); 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; int err; 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; @@ -117,6 +118,7 @@ static int cegw_can2udp(void* data) { struct msghdr mh; struct kvec vec; + struct sockaddr *udst; struct can_frame cf; struct cegw_job* job = (struct cegw_job*)data; struct socket* udp_sock = job->udp_sock; @@ -137,7 +139,8 @@ static int cegw_can2udp(void* data) cf.can_id = cpu_to_be32(cf.can_id); for (i=0; iudp_dstcnt; i++) { - cegw_udp_send(udp_sock, &cf, &job->udp_dst[i]); + udst = (struct sockaddr *)(job->udp_dst + i*job->udp_addrlen); + cegw_udp_send(udp_sock, &cf, udst, job->udp_addrlen); } } @@ -242,9 +245,11 @@ static int cegw_release(struct inode *inode, struct file *file) static long cegw_ioctl_start(struct file *file, unsigned long arg) { int i; + int chckfam; int err = 0; __u32 dstcnt = 0; __u32 addrlen = 0; + struct sockaddr *sa; struct cegw_ioctl gwctl; struct cegw_job *job = NULL; @@ -255,11 +260,11 @@ static long cegw_ioctl_start(struct file *file, unsigned long arg) dstcnt = gwctl.udp_dstcnt; addrlen = gwctl.udp_addrlen; - if (addrlen != sizeof(struct sockaddr_in)) + if (addrlen != sizeof(struct sockaddr_in) && addrlen != sizeof(struct sockaddr_in6)) return -EAFNOSUPPORT; - /* */ - job = kmalloc(GFP_KERNEL, sizeof(*job) + dstcnt*addrlen ); + /* ToDo: consider dstcnt maximum */ + job = kmalloc(GFP_KERNEL, sizeof(*job) + dstcnt*addrlen); if (job == NULL) return -ENOMEM; @@ -269,8 +274,14 @@ static long cegw_ioctl_start(struct file *file, unsigned long arg) return -EFAULT; } - 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; } @@ -290,6 +301,7 @@ static long cegw_ioctl_start(struct file *file, unsigned long arg) } job->udp_dstcnt = dstcnt; + job->udp_addrlen = addrlen; err = cegw_thread_start(job); if (err != 0)