]> rtime.felk.cvut.cz Git - can-eth-gw.git/blobdiff - kernel/canethgw.c
switch to new config utility cegw
[can-eth-gw.git] / kernel / canethgw.c
index a3307bfe9dc5468287367b28723ea52aee984bbc..6c02f15d1ea608b4209b6a77e2174bc6e19030b9 100644 (file)
@@ -1,3 +1,5 @@
+#include "gw.h" /* override */
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
@@ -9,6 +11,7 @@
 #include <linux/net.h>
 #include <linux/can/core.h>
 #include <linux/can.h>
+#include <net/rtnetlink.h>
 #include "canethgw.h"
 
 MODULE_LICENSE( "GPL" );
@@ -18,11 +21,59 @@ static struct socket* udp_sock;
 static struct socket* can_sock;
 static struct net_device* can_dev;
 
+struct can_can_gw {
+       struct can_filter filter;
+       int src_idx;
+       int dst_idx;
+};
+
+struct can_eth_gw
+{
+       int src_if_index;
+       struct in_addr dst_addr;
+       unsigned short dst_port;
+};
+
+struct eth_can_gw
+{
+       int dst_if;
+};
+
+struct cegw_setting
+{
+       struct can_filter filter;
+       int src_idx;
+       /* bind on if */
+       struct in_addr dst_addr;
+       unsigned short dst_port;
+};
+
+/* list entry for CAN gateways jobs */
+struct cgw_job {
+       struct hlist_node list;
+       struct rcu_head rcu;
+       u32 handled_frames;
+       u32 dropped_frames;
+       union {
+               /* CAN frame data source */
+               struct net_device *dev;
+       } src;
+       union {
+               /* CAN frame data destination */
+               struct net_device *dev;
+       } dst;
+       union {
+               struct can_can_gw ccgw;
+               /* tbc */
+       };
+       u8 gwtype;
+       u16 flags;
+};
 /***********************
  *   UDP
  ***********************/
 
-int gw_udp_recv( void* data )
+static int gw_udp_recv( void* data )
 {
        struct can_frame cf;
        struct kvec vec;
@@ -51,7 +102,7 @@ int gw_udp_recv( void* data )
        return 0;
 }
 
-void gw_udp_send( struct can_frame* cf )
+static void gw_udp_send( struct can_frame* cf )
 {
        struct msghdr mh;
        struct sockaddr_in addr;
@@ -77,7 +128,7 @@ void gw_udp_send( struct can_frame* cf )
  *   CAN
  ***********************/
 
-int gw_can_recv( void* data )
+static int gw_can_recv( void* data )
 {
        struct msghdr mh;
        struct kvec vec;
@@ -104,7 +155,7 @@ int gw_can_recv( void* data )
        return 0;
 }
 
-void gw_can_send( struct can_frame* cf )
+static void gw_can_send( struct can_frame* cf )
 {
        struct msghdr mh;
        struct kvec vec;        
@@ -121,6 +172,40 @@ void gw_can_send( struct can_frame* cf )
        kernel_sendmsg( can_sock, &mh, &vec, 1, sizeof( *cf ) );
 }
 
+/**/
+
+static int cgw_create_job( struct sk_buff* skb, struct nlmsghdr* nlh,
+                     void* arg )
+{
+       struct nlattr* tb[ CGW_MAX+1 ];
+       struct rtcanmsg *r;
+       struct cgw_job *gwj;
+       int err = 0;
+       
+       if (nlmsg_len(nlh) < sizeof(*r))
+               return -EINVAL;
+               
+       r = nlmsg_data(nlh);
+       if (r->can_family != AF_CAN)
+               return -EPFNOSUPPORT;
+       /* so far we only support CAN -> CAN routings */
+       if (r->gwtype == CGW_TYPE_CAN_ETH_UDP)
+               printk( KERN_INFO "canethgw: TYPE_CAN_ETH" );
+       else
+               return -1;
+               
+       err = nlmsg_parse( nlh, sizeof( struct rtcanmsg ), tb, CGW_MAX, NULL );
+       if( err < 0 )
+               return err;
+
+       printk( KERN_INFO "can:%d\n", *(u16*)nla_data( tb[CGW_CAN_IF] ) );
+       printk( KERN_INFO "eth addr:%x\n", *(u16*)nla_data( tb[CGW_ETH_IP] ) );
+       printk( KERN_INFO "eth port:%hu\n", *(u16*)nla_data( tb[CGW_ETH_PORT] ) );
+
+       return 0;
+}
+
 /***********************
  *   module init/exit
  ***********************/
@@ -176,7 +261,12 @@ static int __init cangw_init( void )
                return -1;
        }
        
-       /* 3. run bridging threads */
+       /* 3. subscribe to netlink */
+       //if( __rtnl_register( PF_CAN, RTM_GETROUTE,  ) != 0 )
+       __rtnl_register( PF_CAN, RTM_NEWROUTE, cgw_create_job, NULL, NULL );
+       //__rtnl_register( PF_CAN, RTM_DELROUTE,  )     
+       
+       /* 4. run threads */
        eth_to_can = kthread_run( gw_udp_recv, NULL, "cangw" );
        can_to_eth = kthread_run( gw_can_recv, NULL, "cangw" );