+ udp_addr.sin_family = AF_INET;
+ udp_addr.sin_port = htons( set->eth_port );
+ udp_addr.sin_addr = set->eth_ip;
+
+ kfree( set );
+ mutex_lock( &cegw_mutex );
+ if( cegw_state == CEGW_EXIT )
+ return -1;
+ /* stops threads if exist */
+ cegw_thread_stop();
+
+ /* create and bind sockets */
+ if( sock_create_kern( PF_INET, SOCK_DGRAM, IPPROTO_UDP, &udp_sock) != 0 )
+ {
+ printk( KERN_ERR "canethgw: udp socket creation failed\n" );
+ return -1;
+ }
+
+ if( sock_create_kern( PF_CAN, SOCK_RAW, CAN_RAW, &can_sock) != 0 )
+ {
+ printk( KERN_ERR "canethgw: can socket creation failed\n" );
+ return -1;
+ }
+
+ if( kernel_bind( udp_sock, (struct sockaddr*)&udp_addr, sizeof( udp_addr ) ) != 0 )
+ {
+ printk( KERN_ERR "canethgw: udp socket binding failed\n" );
+ sock_release( udp_sock );
+ sock_release( can_sock );
+ return -1;
+ }
+
+ if( kernel_bind( can_sock, (struct sockaddr*) &can_addr, sizeof(can_addr) ) != 0 )
+ {
+ printk( KERN_ERR "canethgw: can socket binding failed\n" );
+ kernel_sock_shutdown( udp_sock, SHUT_RDWR );
+ sock_release( udp_sock );
+ sock_release( can_sock );
+ return -1;
+ }
+
+ /* start threads */
+ cegw_state = CEGW_RUN;
+
+ eth_to_can = kthread_create( cegw_udp_can, NULL, "canethgw" );
+ if( IS_ERR( eth_to_can ) )
+ {
+ cegw_state = CEGW_STOP;
+ sock_release( udp_sock );
+ sock_release( can_sock );
+ return -1;
+ }
+ get_task_struct( eth_to_can );
+ wake_up_process( eth_to_can );
+
+ can_to_eth = kthread_create( cegw_can_udp, NULL, "canethgw" );
+ if( IS_ERR( can_to_eth ) )
+ {
+ cegw_state = CEGW_STOP;
+ kernel_sock_shutdown( udp_sock, SHUT_RDWR );
+ kthread_stop( eth_to_can );
+ sock_release( udp_sock );
+ sock_release( can_sock );
+ return -1;
+ }
+ /* ToDo: free this? */
+ get_task_struct( can_to_eth );
+ wake_up_process( can_to_eth );