can_eth_gw Gateway Module  0.1
A bidirectional CAN to Ethernet Gateway (Kernel Module)
 All Data Structures Files Functions Variables Enumerations Enumerator Macros Groups Pages
Processing
void ce_gw_can_rcv (struct sk_buff *can_skb, void *data)
 The gateway function for incoming CAN frames Receive CAN frame –> process –> send to ETH dev (skbuffer, struct receiver->data) More...
 
void ce_gw_eth_rcv (struct sk_buff *eth_skb, void *data)
 The gateway function for incoming ETH frames Receive skb from ETH dev –> process –> send to CAN bus. More...
 

Detailed Description

Function Documentation

void ce_gw_can_rcv ( struct sk_buff *  can_skb,
void *  data 
)

The gateway function for incoming CAN frames Receive CAN frame –> process –> send to ETH dev (skbuffer, struct receiver->data)

Parameters
can_skbCAN sk buffer which should be translated to an ETH packet
datagwjob which is responsible for triggering this function
Todo:

check also for canfd flag not only Type and call function. You must also check then if the message then is really a canfd-frame or not.

call other translation functions. check for canfd-frame or only use canfd-frame casts.

Definition at line 759 of file ce_gw_main.c.

References ce_gw_can2net_alloc(), CE_GW_TYPE_ETH, CE_GW_TYPE_NET, CE_GW_TYPE_TCP, CE_GW_TYPE_UDP, ce_gw_job::dev, ce_gw_job::dropped_frames, ce_gw_job::dst, ce_gw_job::handled_frames, ce_gw_job::src, and ce_gw_job::type.

Referenced by ce_gw_register_can_src(), and ce_gw_unregister_can_src().

760 {
761  int err = 0;
762  struct can_frame *cf;
763  /* CAN frame (id, dlc, data)*/
764  cf = (struct can_frame *)can_skb->data;
765  pr_debug("Incoming msg from can dev: can_id %x, len %i, can_msg %x\n",
766  cf->can_id, cf->can_dlc, cf->data[0]);
767 
768  struct ce_gw_job *cgj = (struct ce_gw_job *)data;
769  struct sk_buff *eth_skb = NULL;
770 
771  long long dmac = 0xffffffffffff;
772  long long smac = 0x000000000000;
773 
774  switch (cgj->type) {
775 
776  case CE_GW_TYPE_ETH:
777  pr_info("Translation ETH not implemented yet.");
778  break;
779 
780  case CE_GW_TYPE_NET:
781  eth_skb = ce_gw_can2net_alloc(can_skb,
782  cgj->dst.dev,
783  cgj->src.dev,
784  (unsigned char *) &dmac,
785  (unsigned char *) &smac);
786  break;
787 
788  case CE_GW_TYPE_TCP:
789  pr_info("Translation IP TCP not implemented yet.");
790  break;
791 
792  case CE_GW_TYPE_UDP:
793  pr_info("Translation IP UDP not implemented yet.");
794  break;
795 
796  default:
797  pr_err("ce_gw: Translation type of ce_gw_job not "
798  "implemented. BUG: Some module inserted an invalid "
799  "type. Use enum ce_gw_type instead.");
800  goto drop_frame;
801  break;
802  }
803 
804  err = netif_rx_ni(eth_skb);
805  if (err != 0) {
806  pr_err("ce_gw: send to kernel failed");
807  cgj->dropped_frames++;
808  goto exit_error;
809  }
810  cgj->handled_frames++;
811 
812  /* TODO If you use kfree_skb(can_skb) the system hang up completely
813  * without printing stack trace. But a few packets normally passed
814  * before sytem hang up. But <linux/can/dev.h> uses kfree_skb(). There
815  * is no refdata count left. The reason why hang up is completely
816  * unknown. */
817 exit_error:
818  pr_info("ce_gw: WARNING can skb will not be freed");
819  /*kfree_skb(can_skb);*/
820  return;
821 
822 drop_frame:
823  cgj->dropped_frames++;
824  dev_kfree_skb(eth_skb);
825  return;
826 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void ce_gw_eth_rcv ( struct sk_buff *  eth_skb,
void *  data 
)

The gateway function for incoming ETH frames Receive skb from ETH dev –> process –> send to CAN bus.

Parameters
eth_skbETH sk buffer with CAN frame as payload. Exact location of CAN frame depends on translation type (see enum ce_gw_type)
datagwjob which is responsible for triggering this function
Todo:
check for canfd-frame or only use canfd-frame casts.

Definition at line 829 of file ce_gw_main.c.

References ce_gw_net2can_alloc(), CE_GW_TYPE_ETH, CE_GW_TYPE_NET, CE_GW_TYPE_TCP, CE_GW_TYPE_UDP, ce_gw_job::dev, ce_gw_job::dropped_frames, ce_gw_job::dst, ce_gw_job::handled_frames, ce_gw_job::id, and ce_gw_job::type.

Referenced by ce_gw_dev_start_xmit().

830 {
831  struct ce_gw_job *gwj = (struct ce_gw_job *)data;
832 
833  /* Create Can skb and convert incoming Eth sk buffer depending on
834  * type (ce_gw_type in gwj)
835  */
836  struct sk_buff *can_skb = NULL;
837 
838  switch (gwj->type) {
839 
840  case CE_GW_TYPE_ETH:
841  pr_info("Translation ETH not implemented yet.");
842  break;
843 
844  case CE_GW_TYPE_NET:
845  can_skb = ce_gw_net2can_alloc(eth_skb, gwj->dst.dev);
846  break;
847 
848  case CE_GW_TYPE_TCP:
849  pr_info("Translation IP TCP not implemented yet.");
850  break;
851 
852  case CE_GW_TYPE_UDP:
853  pr_info("Translation IP UDP not implemented yet.");
854  break;
855 
856  default:
857  printk(KERN_ERR "ce_gw: Translation type of ce_gw_job not "
858  "implemented. BUG: Some module inserted an invalid "
859  "type. Use enum ce_gw_type instead.");
860  goto drop_frame;
861  break;
862  }
863 
864  /* Memory allocation or translation ETH -> CAN failed */
865  if (!can_skb)
866  goto drop_frame;
867 
868  struct can_frame *cf;
869  cf = (struct can_frame *)can_skb->data;
870  pr_debug("Incoming msg from eth dev (gwj %i): "
871  "can_id %x, len %i, can_msg(1) %x\n",
872  gwj->id, cf->can_id, cf->can_dlc, cf->data[0]);
873 
874  /* send to CAN netdevice (with echo flag for loopback devices) */
875  if (can_send(can_skb, 0x01))
876  goto drop_frame;
877  else
878  gwj->handled_frames++;
879 
880  return; /* Receive + process + send to CAN successful */
881 
882 drop_frame:
883  gwj->dropped_frames++;
884  dev_kfree_skb(can_skb);
885  return;
886 }

Here is the call graph for this function:

Here is the caller graph for this function: