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
Translation
void ce_gw_can2net (struct sk_buff *eth_skb, struct sk_buff *can_skb, struct net_device *eth_dev, struct net_device *can_dev, unsigned char *mac_dst, unsigned char *mac_src)
 for CE_GW_TYPE_NET: copy CAN-Frame into ethernet payload More...
 
struct sk_buff * ce_gw_can2net_alloc (struct sk_buff *can_skb, struct net_device *eth_dev, struct net_device *can_dev, unsigned char *mac_dst, unsigned char *mac_src)
 for CE_GW_TYPE_NET: copy CAN-Frame into ethernet payload and allocate More...
 
struct sk_buff * ce_gw_net2can_alloc (struct sk_buff *eth_skb, struct net_device *can_dev)
 for CE_GW_TYPE_NET: Copy the can-frame from eth_skb to a new can skb. More...
 
void ce_gw_canfd2net (struct sk_buff *eth_skb, struct sk_buff *can_skb, struct net_device *eth_dev, struct net_device *can_dev, unsigned char *mac_dst, unsigned char *mac_src)
 for CE_GW_TYPE_NET: copy CAN-Frame into ethernet payload More...
 
struct sk_buff * ce_gw_canfd2net_alloc (struct sk_buff *can_skb, struct net_device *eth_dev, struct net_device *can_dev, unsigned char *mac_dst, unsigned char *mac_src)
 for CE_GW_TYPE_NET: copy canfd-Frame into ethernet payload and allocate More...
 
struct sk_buff * ce_gw_net2canfd_alloc (struct sk_buff *eth_skb, struct net_device *can_dev, struct net_device *eth_dev)
 for CE_GW_TYPE_NET: Copy the canfd-frame from eth_skb to a new can skb. More...
 
struct sk_buff * ce_gw_can_to_eth (unsigned char *dest, unsigned char *source, __be16 type, struct sk_buff *can_buffer, struct net_device *dev)
 converts sk buffer including can frame into sk buffer including ethernet_frame More...
 
struct sk_buff * ce_gw_canfd_to_eth (unsigned char *dest, unsigned char *source, __be16 type, struct sk_buff *canfd_skb, struct net_device *dev)
 converts sk buffer including canfd frame into sk buffer including ethernet frame More...
 
struct sk_buff * ce_gw_eth_to_can (canid_t id, struct sk_buff *eth_buff, struct net_device *dev)
 converst sk_buffer including an ethernet frame to sk_buffer including a can_frame More...
 
struct sk_buff * ce_gw_eth_to_canfd (canid_t id, __u8 flags, __u8 res0, __u8 res1, struct sk_buff *eth_skb, struct net_device *dev)
 converst sk buffer including an ethernet frame to sk buffer including a canfd frame More...
 

Detailed Description

Function Documentation

void ce_gw_can2net ( struct sk_buff *  eth_skb,
struct sk_buff *  can_skb,
struct net_device *  eth_dev,
struct net_device *  can_dev,
unsigned char *  mac_dst,
unsigned char *  mac_src 
)

for CE_GW_TYPE_NET: copy CAN-Frame into ethernet payload

Parameters
eth_skbThe sk_buff where the frame should copy to. Must be already allocated and must have sizeof(struct ethhdr) + sizeof(struct can_frame) headroom.
can_skbThe sk_buff where the can-frame is located.
eth_devThe device which will later redirect the eth_skb. (this function does not redirect)
can_devThe device where can_skb was received.
mac_dstThe dest MAC Address for the eth_skb.
mac_srcThe source MAC Address for the eth_skb
Warning
you must free can_skb yourself

It create an ethernet header in the empty param eth_skb and copy the can-frame from param can_skb as an an network layer protocol into the payload. It sets the layer pointer and the ethernet type.

Definition at line 240 of file ce_gw_main.c.

Referenced by ce_gw_can2net_alloc(), and ce_gw_canfd2net_alloc().

243 {
244 # ifdef NET_SKBUFF_DATA_USES_OFFSET
245 # else /* NET_SKBUFF_DATA_USES_OFFSET */
246 # endif /* NET_SKBUFF_DATA_USES_OFFSET */
247 
248  /* set transport to data. if data == tail (what normally should be)
249  * that means there is no transport layer */
250  skb_set_transport_header(eth_skb, 0);
251 
252  /* network layer */
253  struct can_frame *eth_canf;
254  eth_canf = (struct can_frame *)skb_push(
255  eth_skb, sizeof(struct can_frame));
256  skb_set_network_header(eth_skb, 0);
257 
258  struct can_frame *can_canf;
259  can_canf = (struct can_frame *) can_skb->data;
260 
261  memcpy(eth_canf, can_canf, sizeof(struct can_frame));
262 
263  /* hardware layer */
264  struct ethhdr *eth_ethh;
265  eth_ethh = (struct ethhdr *)skb_push(eth_skb, sizeof(struct ethhdr));
266  skb_set_mac_header(eth_skb, 0);
267 
268  memcpy(eth_ethh->h_dest, mac_dst , ETH_ALEN);
269  memcpy(eth_ethh->h_source, mac_src, ETH_ALEN);
270  eth_ethh->h_proto = htons(ETH_P_CAN);
271 }

Here is the caller graph for this function:

struct sk_buff * ce_gw_can2net_alloc ( struct sk_buff *  can_skb,
struct net_device *  eth_dev,
struct net_device *  can_dev,
unsigned char *  mac_dst,
unsigned char *  mac_src 
)
read

for CE_GW_TYPE_NET: copy CAN-Frame into ethernet payload and allocate

Parameters
can_skbThe sk_buff where the can-frame is located.
eth_devThe device which will redirect the eth_skb.
can_devThe device where can_skb was received.
mac_dstThe dest MAC Address for the eth_skb.
mac_srcThe source MAC Address for the eth_skb
Warning
you must free can_skb yourself
Return values
NULLif an error occured
sk_buffAn allocated sk_buff with an ethernet header and the can frame as payload.

It create an ethernet header in a new sk_buff and copy the can-frame from param can_skb as an an network layer protocol into the payload. It allocates a new socket buffer and sets some default skb settings. The returned sk_buff will be set to a PACKET_BROADCAST.

Definition at line 295 of file ce_gw_main.c.

References ce_gw_can2net().

Referenced by ce_gw_can_rcv().

299  {
300  int err;
301  struct sk_buff *eth_skb;
302  eth_skb = netdev_alloc_skb(eth_dev, sizeof(struct ethhdr) +
303  sizeof(struct can_frame));
304  if (eth_skb == NULL) {
305  err = -ENOMEM;
306  pr_err("ce_gw: Error during ce_gw_can2net_alloc: %d\n", err);
307  return NULL;
308  }
309 
310  skb_reserve(eth_skb, sizeof(struct ethhdr) + sizeof(struct can_frame));
311  /* On CAN only broatcast possible */
312  eth_skb->pkt_type = PACKET_BROADCAST;
313  ce_gw_can2net(eth_skb, can_skb, eth_dev, can_dev, mac_dst, mac_src);
314 
315  return eth_skb;
316 
317 ce_gw_can2net_alloc_error:
318  kfree_skb(eth_skb);
319  return NULL;
320 }

Here is the call graph for this function:

Here is the caller graph for this function:

struct sk_buff * ce_gw_can_to_eth ( unsigned char *  dest,
unsigned char *  source,
__be16  type,
struct sk_buff *  can_buffer,
struct net_device *  dev 
)
read

converts sk buffer including can frame into sk buffer including ethernet_frame

Parameters
destMAC address of destination
sourceMAC address of source
typetype of layer3 message (example: ipv4 or ipv6 ...)
can_buffersk buffer including a can frame
devdevice of destination
Return values
sk_bufferon success including ethernet frame
NULLif unsuccessful
Todo:
not tested yet

Definition at line 533 of file ce_gw_main.c.

535  {
536  struct can_frame *can_frame_skb = (struct can_frame *)
537  can_buffer->data;
538  struct ethhdr *ethhdr;
539  u8 canlen = can_dlc2len(can_frame_skb->can_dlc);
540  struct sk_buff *eth_skb = dev_alloc_skb(sizeof(struct ethhdr) + sizeof
541  (struct can_frame) + 64);
542  if (eth_skb == NULL) {
543  printk (KERN_ERR "ce_gw_main.c: kmalloc failed in function"
544  "ce_gw_can_to_eth \n");
545  return NULL;
546  }
547  eth_skb->dev = dev;
548 
549  /*updates data pointer to tail */
550  skb_reserve(eth_skb, sizeof(struct ethhdr) + sizeof(struct can_frame) +
551  64);
552  /*updates data pointer to start of network header*/
553  eth_skb->data = skb_push(eth_skb, (const int) canlen);
554 
555  /*copys data from can sk buffer into ethernet sk buffer */
556  memcpy(eth_skb->data, can_buffer->data + sizeof(struct can_frame) -
557  - canlen, canlen);
558  /*update network_header */
559  skb_set_network_header(eth_skb, 0);
560  /*updates transport header */
561  skb_set_transport_header(eth_skb, (const int) canlen);
562 
563  /*updates data pointer to mac header */
564  eth_skb->data = skb_push(eth_skb, (const int) sizeof(struct ethhdr));
565  /*updates mac_header*/
566  skb_set_mac_header(eth_skb, 0);
567  /*fills ethhdr with data */
568  ethhdr = eth_hdr(eth_skb);
569  memcpy(ethhdr->h_dest, dest, ETH_ALEN);
570  memcpy(ethhdr->h_source, source, ETH_ALEN);
571  ethhdr->h_proto = type;
572 
573  return eth_skb;
574 }
void ce_gw_canfd2net ( struct sk_buff *  eth_skb,
struct sk_buff *  can_skb,
struct net_device *  eth_dev,
struct net_device *  can_dev,
unsigned char *  mac_dst,
unsigned char *  mac_src 
)

for CE_GW_TYPE_NET: copy CAN-Frame into ethernet payload

Parameters
eth_skbThe sk_buff where the frame should copy to. Must be already allocated and must have sizeof(struct ethhdr) + sizeof(struct can_frame) headroom.
can_skbThe sk_buff where the canfd-frame is located.
eth_devThe device which will later redirect the eth_skb. (this function does not redirect)
can_devThe device where can_skb was received.
mac_dstThe dest MAC Address for the eth_skb.
mac_srcThe source MAC Address for the eth_skb
Warning
you must free can_skb yourself
Todo:
not tested yet but its the same as ce_gw_can2net()

It create an ethernet header in the empty param eth_skb and copy the canfd-frame from param can_skb as an an network layer protocol into the payload. It sets the layer pointer and the ethernet type.

Definition at line 387 of file ce_gw_main.c.

390 {
391 # ifdef NET_SKBUFF_DATA_USES_OFFSET
392 # else /* NET_SKBUFF_DATA_USES_OFFSET */
393 # endif /* NET_SKBUFF_DATA_USES_OFFSET */
394 
395  /* set transport to data. if data == tail (what normally should be)
396  * that means there is no transport layer */
397  skb_set_transport_header(eth_skb, 0);
398 
399  /* network layer */
400  struct canfd_frame *eth_canf;
401  eth_canf = (struct canfd_frame *)skb_push(
402  eth_skb, sizeof(struct canfd_frame));
403  skb_set_network_header(eth_skb, 0);
404 
405  struct canfd_frame *can_canf;
406  can_canf = (struct canfd_frame *) can_skb->data;
407 
408  memcpy(eth_canf, can_canf, sizeof(struct canfd_frame));
409 
410  /* hardware layer */
411  struct ethhdr *eth_ethh;
412  eth_ethh = (struct ethhdr *)skb_push(eth_skb, sizeof(struct ethhdr));
413  skb_set_mac_header(eth_skb, 0);
414 
415  memcpy(eth_ethh->h_dest, mac_dst, ETH_ALEN);
416  memcpy(eth_ethh->h_source, mac_src, ETH_ALEN);
417  eth_ethh->h_proto = htons(ETH_P_CANFD);
418 }
struct sk_buff * ce_gw_canfd2net_alloc ( struct sk_buff *  can_skb,
struct net_device *  eth_dev,
struct net_device *  can_dev,
unsigned char *  mac_dst,
unsigned char *  mac_src 
)
read

for CE_GW_TYPE_NET: copy canfd-Frame into ethernet payload and allocate

Parameters
can_skbThe sk_buff where the canfd-frame is located.
eth_devThe device which will redirect the eth_skb.
can_devThe device where can_skb was received.
mac_dstThe dest MAC Address for the eth_skb.
mac_srcThe source MAC Address for the eth_skb
Warning
you must free can_skb yourself
Return values
NULLif an error occured
sk_buffAn allocated sk_buff with an ethernet header and the can frame as payload.

It create an ethernet header in a new sk_buff and copy the canfd-frame from param can_skb as an an network layer protocol into the payload. It allocates a new socket buffer and sets some default skb settings. The returned sk_buff will be set to a PACKET_BROADCAST.

Todo:
not tested yet but its the same as ce_gw_can2net_alloc()

Definition at line 444 of file ce_gw_main.c.

References ce_gw_can2net().

448  {
449  int err;
450  struct sk_buff *eth_skb;
451  eth_skb = netdev_alloc_skb(eth_dev, sizeof(struct ethhdr) +
452  sizeof(struct canfd_frame));
453  if (eth_skb == NULL) {
454  err = -ENOMEM;
455  pr_err("ce_gw: Allocation failed: %d\n", err);
456  return NULL;
457  }
458 
459  skb_reserve(eth_skb, sizeof(struct ethhdr) +
460  sizeof(struct canfd_frame));
461  eth_skb->pkt_type = PACKET_BROADCAST;
462 
463  ce_gw_can2net(eth_skb, can_skb, eth_dev, can_dev, mac_dst, mac_src);
464  return eth_skb;
465 
466 ce_gw_can2net_alloc_error:
467  kfree_skb(eth_skb);
468  return NULL;
469 }

Here is the call graph for this function:

struct sk_buff * ce_gw_canfd_to_eth ( unsigned char *  dest,
unsigned char *  scource,
__be16  type,
struct sk_buff *  canfd_skb,
struct net_device *  dev 
)
read

converts sk buffer including canfd frame into sk buffer including ethernet frame

Parameters
destMAC address of destination
sourceMAC address of source
typetype of layer3 message (example: ipv4 or ipv6 ...)
canfd_skbsk buffer including a canfd_frame
devdevice of the destination
Return values
sk_buffincluding ethernet frame if successful
NULLif unsuccessful
Todo:
not tested yet

Definition at line 577 of file ce_gw_main.c.

579  {
580  struct sk_buff *eth_skb = dev_alloc_skb(sizeof(struct ethhdr) +
581  sizeof(struct canfd_frame) + 64);
582  if (eth_skb == NULL) {
583  printk (KERN_ERR "ce_gw_main.c: kmalloc failed in function"
584  "ce_gw_canfd_to_eth \n");
585  return NULL;
586  }
587  struct ethhdr *ethhdr;
588  struct canfd_frame *canfd_frame_skb = (struct canfd_frame *)
589  canfd_skb->data;
590  u8 canlen = can_dlc2len(canfd_frame_skb->len);
591  unsigned int iplen = ip_hdrlen(canfd_skb);
592  eth_skb->dev = dev;
593 
594  /*updates data pointer to tail */
595  skb_reserve(eth_skb, sizeof(struct ethhdr) + sizeof(struct canfd_frame)
596  + 64);
597  /*updates data pointer to start of network header*/
598  eth_skb->data = skb_push(eth_skb, (const int) canlen);
599 
600  /*copys data from canfd sk buffer into ethernet sk buffer */
601  memcpy(eth_skb->data, canfd_skb->data + sizeof(struct canfd_frame) -
602  sizeof(__u8)*64, canlen);
603  /*update network_header */
604  skb_set_network_header(eth_skb, 0);
605  /*updates transport header */
606  if (canlen >= iplen) {
607  skb_set_transport_header(eth_skb, (const int) iplen);
608  } else {
609  skb_set_transport_header(eth_skb, (const int) sizeof(__u8)*64);
610  }
611  /*updates data pointer to start of mac header*/
612  eth_skb->data = skb_push(eth_skb, (const int) sizeof(struct ethhdr));
613  /*updates mac_header*/
614  skb_set_mac_header(eth_skb, 0);
615  /*fills eth_skb with data*/
616  ethhdr = eth_hdr(eth_skb);
617  memcpy(ethhdr->h_dest, &dest, ETH_ALEN);
618  memcpy(ethhdr->h_source, &source, ETH_ALEN);
619  ethhdr->h_proto = type;
620 
621  return eth_skb;
622 }
struct sk_buff * ce_gw_eth_to_can ( canid_t  id,
struct sk_buff *  eth_buff,
struct net_device *  dev 
)
read

converst sk_buffer including an ethernet frame to sk_buffer including a can_frame

Parameters
ididentifier of can_frame (see ce_gw_get_header for more information
eth_buffsk_buffer including an ethernet frame
devdevice of the destination
Returns
sk_buffer including a can frame
Todo:
not tested yet

Definition at line 625 of file ce_gw_main.c.

References ce_gw_alloc_can_frame(), and ce_gw_free_can_frame().

626  {
627  struct sk_buff *can_buff;
628  struct can_frame *can = ce_gw_alloc_can_frame();
629  if (can == NULL) {
630  printk (KERN_ERR "ce_gw_main.c: kmalloc failed in function"
631  "ce_gw_eth_to_can \n");
632  return NULL;
633  }
634  unsigned int ethdatalen = (skb_tail_pointer(eth_buff) - (eth_buff->data
635  + sizeof(struct ethhdr)));
636  /* unsigned int iplen = ip_hdrlen(eth_buff); */
637 
638  /*fills can header */
639  can->can_id = id;
640  can->can_dlc = (__u8) eth_buff->data_len - sizeof(struct ethhdr);
641 
642  can_buff = dev_alloc_skb(sizeof(struct can_frame) + ethdatalen + 64);
643  if (can_buff == NULL) {
644  printk (KERN_ERR "ce_gw_main.c: kmalloc failed in function"
645  "ce_gw_eth_to_can \n");
646  return NULL;
647  }
648  can_buff->dev = dev;
649 
650  /*updates data pointer to tail */
651  skb_reserve(can_buff, sizeof(struct can_frame) + ethdatalen + 64);
652  /*updates data pointer to start of network header*/
653  can_buff->data = skb_push(can_buff, (const int) ethdatalen);
654 
655  /*copys data from ethernet sk buffer into can buffer */
656  memcpy(can_buff->data, eth_buff->data + sizeof(struct ethhdr),
657  sizeof(u64));
658  /*update network_header */
659  skb_set_network_header(can_buff, 0);
660  /*updates transport header */
661  skb_set_transport_header(can_buff, (const int) sizeof(u64));
662 
663  /*updates data pointer to start of mac header */
664  can_buff->data = skb_push(can_buff, (const int) sizeof(__u32) +
665  sizeof(__u8));
666  /*updates mac header */
667  skb_set_mac_header(can_buff, 0);
668  /*copys can header at the beginning of sk buffer */
669  memcpy(skb_mac_header(can_buff), &can->can_id, sizeof(__u32) +
670  sizeof(__u8));
671 
673 
674  return can_buff;
675 }

Here is the call graph for this function:

struct sk_buff * ce_gw_eth_to_canfd ( canid_t  id,
__u8  flags,
__u8  res0,
__u8  res1,
struct sk_buff *  eth_skb,
struct net_device *  dev 
)
read

converst sk buffer including an ethernet frame to sk buffer including a canfd frame

Parameters
ididentifier of canfd (see ce_gw_get_canfd_header for more information)
flagsadditional flags for CAN FD
res0reserved / padding
res1reserved / padding
eth_skbsk buffer including ethernet frame
devdevice of the destination
Returns
sk buffer including canfd frame
Todo:
not tested yet

Definition at line 678 of file ce_gw_main.c.

References ce_gw_alloc_canfd_frame(), and ce_gw_free_canfd_frame().

680  {
681  struct sk_buff *canfd_skb;
682  struct canfd_frame *canfd = ce_gw_alloc_canfd_frame();
683  if (canfd == NULL) {
684  printk (KERN_ERR "ce_gw_main.c: kmalloc failed in function"
685  "ce_gw_eth_to_canfd \n");
686  return NULL;
687  }
688  /* unsigned int ethdatalen = (skb_tail_pointer(eth_skb) - (eth_skb->data
689  + sizeof(struct ethhdr))); */
690  unsigned int iplen = ip_hdrlen(eth_skb);
691 
692  /*fills canfd header */
693  canfd->can_id = id;
694  canfd->flags = flags;
695  canfd->__res0 = res0;
696  canfd->__res1 = res1;
697  canfd->len = (__u8) eth_skb->data_len - sizeof(struct ethhdr);
698 
699  canfd_skb = dev_alloc_skb(sizeof(struct canfd_frame) + 64);
700  if (canfd_skb == NULL) {
701  printk (KERN_ERR "ce_gw_main.c: kmalloc failed in function"
702  "ce_gw_eth_to_canfd \n");
703  return NULL;
704  }
705  canfd_skb->dev = dev;
706 
707  /*updates data pointer to tail */
708  skb_reserve(canfd_skb, sizeof(struct canfd_frame) + 64);
709  /*updates data pointer to start of network header*/
710  canfd_skb->data = skb_push(canfd_skb, (const int) sizeof(__u8)*64);
711 
712  /*copys data from ethernet sk buffer into canfd sk buffer */
713  memcpy(canfd_skb->data, eth_skb->data + sizeof(struct ethhdr),
714  sizeof(__u8)*64);
715  /*update network_header */
716  skb_set_network_header(canfd_skb, 0);
717  /*checks if can data length >= iplen*/
718  /*updates transport header */
719  if (sizeof(__u8)*64 >= iplen) {
720  skb_set_transport_header(canfd_skb, (const int) iplen);
721  } else {
722  skb_set_transport_header(canfd_skb, sizeof(__u8)*64);
723  }
724  /*updates data pointer to start of mac header */
725  canfd_skb->data = skb_push(canfd_skb, (const int) sizeof(struct
726  canfd_frame) - sizeof(__u8)*64);
727  /*updates mac header */
728  skb_set_mac_header(canfd_skb, 0);
729  /*copys canfd header into sk buffer */
730  memcpy(skb_mac_header(canfd_skb), &canfd->can_id, sizeof(struct
731  canfd_frame) - sizeof(__u8)*64);
732  ce_gw_free_canfd_frame(canfd);
733 
734  return canfd_skb;
735 }

Here is the call graph for this function:

struct sk_buff * ce_gw_net2can_alloc ( struct sk_buff *  eth_skb,
struct net_device *  can_dev 
)
read

for CE_GW_TYPE_NET: Copy the can-frame from eth_skb to a new can skb.

Parameters
eth_skbAn ethernet header as hardware layer and a can-frame as network layer.
can_devCAN net device where the package will be later redirect to (this function does not redirect)
Warning
you must free eth_skb yourself
Return values
NULLon error
sk_buffon success including can-frame

Copy the can-frame from the network layer in eth_skb to hardware layer in a new sk_buff. This Function allocates a new sk_buff and set some settings. The returned sk_buff will be set to a PACKET_BROADCAST.

Definition at line 338 of file ce_gw_main.c.

Referenced by ce_gw_eth_rcv().

339  {
340  int err;
341 
342  /* No transport layer */
343  /* No network layer */
344 
345  /* hardware (mac) layer */
346  struct sk_buff *can_skb;
347  /* canf is the pointer where you can later copy the data to buffer */
348  struct can_frame *canf;
349  can_skb = alloc_can_skb(can_dev, &canf);
350  if (!can_skb) {
351  err = -ENOMEM;
352  pr_err("ce_gw: Allocation failed: %d\n", err);
353  goto ce_gw_net2can_alloc_error;
354  }
355 
356  /* Get Can frame at network layer start */
357  memcpy(canf, skb_network_header(eth_skb), sizeof(struct can_frame));
358 
359  return can_skb;
360 
361 ce_gw_net2can_alloc_error:
362  kfree_skb(can_skb);
363  return NULL;
364 }

Here is the caller graph for this function:

struct sk_buff * ce_gw_net2canfd_alloc ( struct sk_buff *  eth_skb,
struct net_device *  can_dev,
struct net_device *  eth_dev 
)
read

for CE_GW_TYPE_NET: Copy the canfd-frame from eth_skb to a new can skb.

Parameters
eth_skbAn ethernet header as hardware layer and a canfd-frame as network layer.
can_devCAN net device where the package will be later redirect to (this function does not redirect)
Warning
you must free eth_skb yourself
Return values
NULLon error
sk_buffon success including canfd-frame

Copy the canfd-frame from the network layer in eth_skb to hardware layer in a new sk_buff. This Function allocates a new sk_buff and set some settings. The returned sk_buff will be set to a PACKET_BROADCAST.

Todo:

not tested yet.

there might be a better way to allocted the new skb.

Definition at line 490 of file ce_gw_main.c.

492  {
493  int err;
494 
495  /* No transport layer */
496  /* No network layer */
497 
498  /* hardware layer */
499  struct sk_buff *can_skb;
500  /* canf is the pointer where you can later copy the data to buffer */
501  struct can_frame *canf;
502  can_skb = alloc_can_skb(can_dev, &canf);
503  if (can_skb == NULL) {
504  err = -ENOMEM;
505  pr_err("ce_gw: Allocation failed: %d\n", err);
506  goto ce_gw_net2can_alloc_error;
507  }
508 
509  /* expand the sk_buff because alloc_can_skb only allocates space for
510  * an can_frame and not the larger canfd_frame. So it will be
511  * expanded by the difference
512  * TODO This is quite a bad idea but there is no alloc_can_skb function
513  * for canfd_frame. Anyway there might exist a better way */
514  skb_copy_expand(can_skb, 0, sizeof(struct canfd_frame) -
515  sizeof(struct can_frame), GFP_ATOMIC);
516  skb_put(can_skb, sizeof(struct canfd_frame) - sizeof(struct can_frame));
517  can_skb->protocol = htons(ETH_P_CANFD);
518 
519  struct canfd_frame *canfdf;
520  canfdf = (struct canfd_frame *) canf;
521 
522  /* copy canfd_frame */
523  memcpy(canfdf, skb_network_header(eth_skb), sizeof(struct canfd_frame));
524 
525  return can_skb;
526 
527 ce_gw_net2can_alloc_error:
528  kfree_skb(can_skb);
529  return NULL;
530 }