+#include "gw.h" /* override */
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/net.h>
#include <linux/can/core.h>
#include <linux/can.h>
+#include <net/rtnetlink.h>
#include "canethgw.h"
MODULE_LICENSE( "GPL" );
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;
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;
* CAN
***********************/
-int gw_can_recv( void* data )
+static int gw_can_recv( void* data )
{
struct msghdr mh;
struct kvec vec;
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;
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
***********************/
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" );