Re: [net-next 05/13] can: dev: move skb related into seperate file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun. 10 Jan. 2021 at 02:40, Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> wrote:
>
> This patch moves the skb related code of the CAN device infrastructure into a
> separate file.
>
> Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx>
> ---
>  drivers/net/can/dev/dev.c | 213 ------------------------------------
>  drivers/net/can/dev/skb.c | 220 ++++++++++++++++++++++++++++++++++++++
>  include/linux/can/dev.h   |  76 -------------
>  include/linux/can/skb.h   |  77 +++++++++++++
>  4 files changed, 297 insertions(+), 289 deletions(-)
>  create mode 100644 drivers/net/can/dev/skb.c
>
> diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
> index 3372e99d5db7..fe71ff9ef8c9 100644
> --- a/drivers/net/can/dev/dev.c
> +++ b/drivers/net/can/dev/dev.c
> @@ -132,149 +132,6 @@ void can_change_state(struct net_device *dev, struct can_frame *cf,
>  }
>  EXPORT_SYMBOL_GPL(can_change_state);
>
> -/* Local echo of CAN messages
> - *
> - * CAN network devices *should* support a local echo functionality
> - * (see Documentation/networking/can.rst). To test the handling of CAN
> - * interfaces that do not support the local echo both driver types are
> - * implemented. In the case that the driver does not support the echo
> - * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core
> - * to perform the echo as a fallback solution.
> - */
> -static void can_flush_echo_skb(struct net_device *dev)
> -{
> -       struct can_priv *priv = netdev_priv(dev);
> -       struct net_device_stats *stats = &dev->stats;
> -       int i;
> -
> -       for (i = 0; i < priv->echo_skb_max; i++) {
> -               if (priv->echo_skb[i]) {
> -                       kfree_skb(priv->echo_skb[i]);
> -                       priv->echo_skb[i] = NULL;
> -                       stats->tx_dropped++;
> -                       stats->tx_aborted_errors++;
> -               }
> -       }
> -}
> -
> -/* Put the skb on the stack to be looped backed locally lateron
> - *
> - * The function is typically called in the start_xmit function
> - * of the device driver. The driver must protect access to
> - * priv->echo_skb, if necessary.
> - */
> -int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
> -                    unsigned int idx)
> -{
> -       struct can_priv *priv = netdev_priv(dev);
> -
> -       BUG_ON(idx >= priv->echo_skb_max);
> -
> -       /* check flag whether this packet has to be looped back */
> -       if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK ||
> -           (skb->protocol != htons(ETH_P_CAN) &&
> -            skb->protocol != htons(ETH_P_CANFD))) {
> -               kfree_skb(skb);
> -               return 0;
> -       }
> -
> -       if (!priv->echo_skb[idx]) {
> -               skb = can_create_echo_skb(skb);
> -               if (!skb)
> -                       return -ENOMEM;
> -
> -               /* make settings for echo to reduce code in irq context */
> -               skb->pkt_type = PACKET_BROADCAST;
> -               skb->ip_summed = CHECKSUM_UNNECESSARY;
> -               skb->dev = dev;
> -
> -               /* save this skb for tx interrupt echo handling */
> -               priv->echo_skb[idx] = skb;
> -       } else {
> -               /* locking problem with netif_stop_queue() ?? */
> -               netdev_err(dev, "%s: BUG! echo_skb %d is occupied!\n", __func__, idx);
> -               kfree_skb(skb);
> -               return -EBUSY;
> -       }
> -
> -       return 0;
> -}
> -EXPORT_SYMBOL_GPL(can_put_echo_skb);
> -
> -struct sk_buff *
> -__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
> -{
> -       struct can_priv *priv = netdev_priv(dev);
> -
> -       if (idx >= priv->echo_skb_max) {
> -               netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
> -                          __func__, idx, priv->echo_skb_max);
> -               return NULL;
> -       }
> -
> -       if (priv->echo_skb[idx]) {
> -               /* Using "struct canfd_frame::len" for the frame
> -                * length is supported on both CAN and CANFD frames.
> -                */
> -               struct sk_buff *skb = priv->echo_skb[idx];
> -               struct canfd_frame *cf = (struct canfd_frame *)skb->data;
> -
> -               /* get the real payload length for netdev statistics */
> -               if (cf->can_id & CAN_RTR_FLAG)
> -                       *len_ptr = 0;
> -               else
> -                       *len_ptr = cf->len;
> -
> -               priv->echo_skb[idx] = NULL;
> -
> -               return skb;
> -       }
> -
> -       return NULL;
> -}
> -
> -/* Get the skb from the stack and loop it back locally
> - *
> - * The function is typically called when the TX done interrupt
> - * is handled in the device driver. The driver must protect
> - * access to priv->echo_skb, if necessary.
> - */
> -unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
> -{
> -       struct sk_buff *skb;
> -       u8 len;
> -
> -       skb = __can_get_echo_skb(dev, idx, &len);
> -       if (!skb)
> -               return 0;
> -
> -       skb_get(skb);
> -       if (netif_rx(skb) == NET_RX_SUCCESS)
> -               dev_consume_skb_any(skb);
> -       else
> -               dev_kfree_skb_any(skb);
> -
> -       return len;
> -}
> -EXPORT_SYMBOL_GPL(can_get_echo_skb);
> -
> -/* Remove the skb from the stack and free it.
> - *
> - * The function is typically called when TX failed.
> - */
> -void can_free_echo_skb(struct net_device *dev, unsigned int idx)
> -{
> -       struct can_priv *priv = netdev_priv(dev);
> -
> -       BUG_ON(idx >= priv->echo_skb_max);
> -
> -       if (priv->echo_skb[idx]) {
> -               dev_kfree_skb_any(priv->echo_skb[idx]);
> -               priv->echo_skb[idx] = NULL;
> -       }
> -}
> -EXPORT_SYMBOL_GPL(can_free_echo_skb);
> -
>  /* CAN device restart for bus-off recovery */
>  static void can_restart(struct net_device *dev)
>  {
> @@ -379,76 +236,6 @@ static void can_setup(struct net_device *dev)
>         dev->features = NETIF_F_HW_CSUM;
>  }
>
> -struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
> -{
> -       struct sk_buff *skb;
> -
> -       skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
> -                              sizeof(struct can_frame));
> -       if (unlikely(!skb))
> -               return NULL;
> -
> -       skb->protocol = htons(ETH_P_CAN);
> -       skb->pkt_type = PACKET_BROADCAST;
> -       skb->ip_summed = CHECKSUM_UNNECESSARY;
> -
> -       skb_reset_mac_header(skb);
> -       skb_reset_network_header(skb);
> -       skb_reset_transport_header(skb);
> -
> -       can_skb_reserve(skb);
> -       can_skb_prv(skb)->ifindex = dev->ifindex;
> -       can_skb_prv(skb)->skbcnt = 0;
> -
> -       *cf = skb_put_zero(skb, sizeof(struct can_frame));
> -
> -       return skb;
> -}
> -EXPORT_SYMBOL_GPL(alloc_can_skb);
> -
> -struct sk_buff *alloc_canfd_skb(struct net_device *dev,
> -                               struct canfd_frame **cfd)
> -{
> -       struct sk_buff *skb;
> -
> -       skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
> -                              sizeof(struct canfd_frame));
> -       if (unlikely(!skb))
> -               return NULL;
> -
> -       skb->protocol = htons(ETH_P_CANFD);
> -       skb->pkt_type = PACKET_BROADCAST;
> -       skb->ip_summed = CHECKSUM_UNNECESSARY;
> -
> -       skb_reset_mac_header(skb);
> -       skb_reset_network_header(skb);
> -       skb_reset_transport_header(skb);
> -
> -       can_skb_reserve(skb);
> -       can_skb_prv(skb)->ifindex = dev->ifindex;
> -       can_skb_prv(skb)->skbcnt = 0;
> -
> -       *cfd = skb_put_zero(skb, sizeof(struct canfd_frame));
> -
> -       return skb;
> -}
> -EXPORT_SYMBOL_GPL(alloc_canfd_skb);
> -
> -struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
> -{
> -       struct sk_buff *skb;
> -
> -       skb = alloc_can_skb(dev, cf);
> -       if (unlikely(!skb))
> -               return NULL;
> -
> -       (*cf)->can_id = CAN_ERR_FLAG;
> -       (*cf)->len = CAN_ERR_DLC;
> -
> -       return skb;
> -}
> -EXPORT_SYMBOL_GPL(alloc_can_err_skb);
> -
>  /* Allocate and setup space for the CAN network device */
>  struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
>                                     unsigned int txqs, unsigned int rxqs)
> diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
> new file mode 100644
> index 000000000000..26cd597ff771
> --- /dev/null
> +++ b/drivers/net/can/dev/skb.c
> @@ -0,0 +1,220 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
> + * Copyright (C) 2006 Andrey Volkov, Varma Electronics
> + * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@xxxxxxxxxxxxxx>
> + */
> +
> +#include <linux/can/dev.h>
> +
> +/* Local echo of CAN messages
> + *
> + * CAN network devices *should* support a local echo functionality
> + * (see Documentation/networking/can.rst). To test the handling of CAN
> + * interfaces that do not support the local echo both driver types are
> + * implemented. In the case that the driver does not support the echo
> + * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core
> + * to perform the echo as a fallback solution.
> + */
> +void can_flush_echo_skb(struct net_device *dev)
> +{
> +       struct can_priv *priv = netdev_priv(dev);
> +       struct net_device_stats *stats = &dev->stats;
> +       int i;
> +
> +       for (i = 0; i < priv->echo_skb_max; i++) {
> +               if (priv->echo_skb[i]) {
> +                       kfree_skb(priv->echo_skb[i]);
> +                       priv->echo_skb[i] = NULL;
> +                       stats->tx_dropped++;
> +                       stats->tx_aborted_errors++;
> +               }
> +       }
> +}
> +
> +/* Put the skb on the stack to be looped backed locally lateron
> + *
> + * The function is typically called in the start_xmit function
> + * of the device driver. The driver must protect access to
> + * priv->echo_skb, if necessary.
> + */
> +int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
> +                    unsigned int idx)
> +{
> +       struct can_priv *priv = netdev_priv(dev);
> +
> +       BUG_ON(idx >= priv->echo_skb_max);
> +
> +       /* check flag whether this packet has to be looped back */
> +       if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK ||
> +           (skb->protocol != htons(ETH_P_CAN) &&
> +            skb->protocol != htons(ETH_P_CANFD))) {
> +               kfree_skb(skb);
> +               return 0;
> +       }
> +
> +       if (!priv->echo_skb[idx]) {
> +               skb = can_create_echo_skb(skb);
> +               if (!skb)
> +                       return -ENOMEM;
> +
> +               /* make settings for echo to reduce code in irq context */
> +               skb->pkt_type = PACKET_BROADCAST;
> +               skb->ip_summed = CHECKSUM_UNNECESSARY;
> +               skb->dev = dev;
> +
> +               /* save this skb for tx interrupt echo handling */
> +               priv->echo_skb[idx] = skb;
> +       } else {
> +               /* locking problem with netif_stop_queue() ?? */
> +               netdev_err(dev, "%s: BUG! echo_skb %d is occupied!\n", __func__, idx);
> +               kfree_skb(skb);
> +               return -EBUSY;
> +       }
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(can_put_echo_skb);
> +
> +struct sk_buff *
> +__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
> +{
> +       struct can_priv *priv = netdev_priv(dev);
> +
> +       if (idx >= priv->echo_skb_max) {
> +               netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
> +                          __func__, idx, priv->echo_skb_max);
> +               return NULL;
> +       }
> +
> +       if (priv->echo_skb[idx]) {
> +               /* Using "struct canfd_frame::len" for the frame
> +                * length is supported on both CAN and CANFD frames.
> +                */
> +               struct sk_buff *skb = priv->echo_skb[idx];
> +               struct canfd_frame *cf = (struct canfd_frame *)skb->data;
> +
> +               /* get the real payload length for netdev statistics */
> +               if (cf->can_id & CAN_RTR_FLAG)
> +                       *len_ptr = 0;
> +               else
> +                       *len_ptr = cf->len;
> +
> +               priv->echo_skb[idx] = NULL;
> +
> +               return skb;
> +       }
> +
> +       return NULL;
> +}
> +
> +/* Get the skb from the stack and loop it back locally
> + *
> + * The function is typically called when the TX done interrupt
> + * is handled in the device driver. The driver must protect
> + * access to priv->echo_skb, if necessary.
> + */
> +unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
> +{
> +       struct sk_buff *skb;
> +       u8 len;
> +
> +       skb = __can_get_echo_skb(dev, idx, &len);
> +       if (!skb)
> +               return 0;
> +
> +       skb_get(skb);
> +       if (netif_rx(skb) == NET_RX_SUCCESS)
> +               dev_consume_skb_any(skb);
> +       else
> +               dev_kfree_skb_any(skb);
> +
> +       return len;
> +}
> +EXPORT_SYMBOL_GPL(can_get_echo_skb);
> +
> +/* Remove the skb from the stack and free it.
> + *
> + * The function is typically called when TX failed.
> + */
> +void can_free_echo_skb(struct net_device *dev, unsigned int idx)
> +{
> +       struct can_priv *priv = netdev_priv(dev);
> +
> +       BUG_ON(idx >= priv->echo_skb_max);
> +
> +       if (priv->echo_skb[idx]) {
> +               dev_kfree_skb_any(priv->echo_skb[idx]);
> +               priv->echo_skb[idx] = NULL;
> +       }
> +}
> +EXPORT_SYMBOL_GPL(can_free_echo_skb);
> +
> +struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
> +{
> +       struct sk_buff *skb;
> +
> +       skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
> +                              sizeof(struct can_frame));
> +       if (unlikely(!skb))
> +               return NULL;
> +
> +       skb->protocol = htons(ETH_P_CAN);
> +       skb->pkt_type = PACKET_BROADCAST;
> +       skb->ip_summed = CHECKSUM_UNNECESSARY;
> +
> +       skb_reset_mac_header(skb);
> +       skb_reset_network_header(skb);
> +       skb_reset_transport_header(skb);
> +
> +       can_skb_reserve(skb);
> +       can_skb_prv(skb)->ifindex = dev->ifindex;
> +       can_skb_prv(skb)->skbcnt = 0;
> +
> +       *cf = skb_put_zero(skb, sizeof(struct can_frame));
> +
> +       return skb;
> +}
> +EXPORT_SYMBOL_GPL(alloc_can_skb);
> +
> +struct sk_buff *alloc_canfd_skb(struct net_device *dev,
> +                               struct canfd_frame **cfd)
> +{
> +       struct sk_buff *skb;
> +
> +       skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
> +                              sizeof(struct canfd_frame));
> +       if (unlikely(!skb))
> +               return NULL;
> +
> +       skb->protocol = htons(ETH_P_CANFD);
> +       skb->pkt_type = PACKET_BROADCAST;
> +       skb->ip_summed = CHECKSUM_UNNECESSARY;
> +
> +       skb_reset_mac_header(skb);
> +       skb_reset_network_header(skb);
> +       skb_reset_transport_header(skb);
> +
> +       can_skb_reserve(skb);
> +       can_skb_prv(skb)->ifindex = dev->ifindex;
> +       can_skb_prv(skb)->skbcnt = 0;
> +
> +       *cfd = skb_put_zero(skb, sizeof(struct canfd_frame));
> +
> +       return skb;
> +}
> +EXPORT_SYMBOL_GPL(alloc_canfd_skb);
> +
> +struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
> +{
> +       struct sk_buff *skb;
> +
> +       skb = alloc_can_skb(dev, cf);
> +       if (unlikely(!skb))
> +               return NULL;
> +
> +       (*cf)->can_id = CAN_ERR_FLAG;
> +       (*cf)->len = CAN_ERR_DLC;
> +
> +       return skb;
> +}
> +EXPORT_SYMBOL_GPL(alloc_can_err_skb);
> diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
> index d75fba1d030a..4a26e128af7f 100644
> --- a/include/linux/can/dev.h
> +++ b/include/linux/can/dev.h
> @@ -84,69 +84,6 @@ struct can_priv {
>  #endif
>  };
>
> -/* Check for outgoing skbs that have not been created by the CAN subsystem */
> -static inline bool can_skb_headroom_valid(struct net_device *dev,
> -                                         struct sk_buff *skb)
> -{
> -       /* af_packet creates a headroom of HH_DATA_MOD bytes which is fine */
> -       if (WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct can_skb_priv)))
> -               return false;
> -
> -       /* af_packet does not apply CAN skb specific settings */
> -       if (skb->ip_summed == CHECKSUM_NONE) {
> -               /* init headroom */
> -               can_skb_prv(skb)->ifindex = dev->ifindex;
> -               can_skb_prv(skb)->skbcnt = 0;
> -
> -               skb->ip_summed = CHECKSUM_UNNECESSARY;
> -
> -               /* perform proper loopback on capable devices */
> -               if (dev->flags & IFF_ECHO)
> -                       skb->pkt_type = PACKET_LOOPBACK;
> -               else
> -                       skb->pkt_type = PACKET_HOST;
> -
> -               skb_reset_mac_header(skb);
> -               skb_reset_network_header(skb);
> -               skb_reset_transport_header(skb);
> -       }
> -
> -       return true;
> -}
> -
> -/* Drop a given socketbuffer if it does not contain a valid CAN frame. */
> -static inline bool can_dropped_invalid_skb(struct net_device *dev,
> -                                         struct sk_buff *skb)
> -{
> -       const struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
> -
> -       if (skb->protocol == htons(ETH_P_CAN)) {
> -               if (unlikely(skb->len != CAN_MTU ||
> -                            cfd->len > CAN_MAX_DLEN))
> -                       goto inval_skb;
> -       } else if (skb->protocol == htons(ETH_P_CANFD)) {
> -               if (unlikely(skb->len != CANFD_MTU ||
> -                            cfd->len > CANFD_MAX_DLEN))
> -                       goto inval_skb;
> -       } else
> -               goto inval_skb;
> -
> -       if (!can_skb_headroom_valid(dev, skb))
> -               goto inval_skb;
> -
> -       return false;
> -
> -inval_skb:
> -       kfree_skb(skb);
> -       dev->stats.tx_dropped++;
> -       return true;
> -}
> -
> -static inline bool can_is_canfd_skb(const struct sk_buff *skb)
> -{
> -       /* the CAN specific type of skb is identified by its data length */
> -       return skb->len == CANFD_MTU;
> -}
>
>  /* helper to define static CAN controller features at device creation time */
>  static inline void can_set_static_ctrlmode(struct net_device *dev,
> @@ -187,23 +124,10 @@ void can_bus_off(struct net_device *dev);
>  void can_change_state(struct net_device *dev, struct can_frame *cf,
>                       enum can_state tx_state, enum can_state rx_state);
>
> -int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
> -                    unsigned int idx);
> -struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx,
> -                                  u8 *len_ptr);
> -unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
> -void can_free_echo_skb(struct net_device *dev, unsigned int idx);
> -
>  #ifdef CONFIG_OF
>  void of_can_transceiver(struct net_device *dev);
>  #else
>  static inline void of_can_transceiver(struct net_device *dev) { }
>  #endif
>
> -struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
> -struct sk_buff *alloc_canfd_skb(struct net_device *dev,
> -                               struct canfd_frame **cfd);
> -struct sk_buff *alloc_can_err_skb(struct net_device *dev,
> -                                 struct can_frame **cf);
> -
>  #endif /* !_CAN_DEV_H */
> diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h
> index fc61cf4eff1c..c90ebbd3008c 100644
> --- a/include/linux/can/skb.h
> +++ b/include/linux/can/skb.h
> @@ -16,6 +16,19 @@
>  #include <linux/can.h>
>  #include <net/sock.h>
>
> +void can_flush_echo_skb(struct net_device *dev);
> +int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
> +                    unsigned int idx);
> +struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx,
> +                                  u8 *len_ptr);
> +unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
> +void can_free_echo_skb(struct net_device *dev, unsigned int idx);
> +struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
> +struct sk_buff *alloc_canfd_skb(struct net_device *dev,
> +                               struct canfd_frame **cfd);
> +struct sk_buff *alloc_can_err_skb(struct net_device *dev,
> +                                 struct can_frame **cf);
> +
>  /*
>   * The struct can_skb_priv is used to transport additional information along
>   * with the stored struct can(fd)_frame that can not be contained in existing
> @@ -74,4 +87,68 @@ static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb)
>         return nskb;
>  }
>
> +/* Check for outgoing skbs that have not been created by the CAN subsystem */
> +static inline bool can_skb_headroom_valid(struct net_device *dev,
> +                                         struct sk_buff *skb)
> +{
> +       /* af_packet creates a headroom of HH_DATA_MOD bytes which is fine */
> +       if (WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct can_skb_priv)))
> +               return false;
> +
> +       /* af_packet does not apply CAN skb specific settings */
> +       if (skb->ip_summed == CHECKSUM_NONE) {
> +               /* init headroom */
> +               can_skb_prv(skb)->ifindex = dev->ifindex;
> +               can_skb_prv(skb)->skbcnt = 0;
> +
> +               skb->ip_summed = CHECKSUM_UNNECESSARY;
> +
> +               /* perform proper loopback on capable devices */
> +               if (dev->flags & IFF_ECHO)
> +                       skb->pkt_type = PACKET_LOOPBACK;
> +               else
> +                       skb->pkt_type = PACKET_HOST;
> +
> +               skb_reset_mac_header(skb);
> +               skb_reset_network_header(skb);
> +               skb_reset_transport_header(skb);
> +       }
> +
> +       return true;
> +}
> +
> +/* Drop a given socketbuffer if it does not contain a valid CAN frame. */
> +static inline bool can_dropped_invalid_skb(struct net_device *dev,
> +                                         struct sk_buff *skb)
> +{
> +       const struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
> +
> +       if (skb->protocol == htons(ETH_P_CAN)) {
> +               if (unlikely(skb->len != CAN_MTU ||
> +                            cfd->len > CAN_MAX_DLEN))
> +                       goto inval_skb;
> +       } else if (skb->protocol == htons(ETH_P_CANFD)) {
> +               if (unlikely(skb->len != CANFD_MTU ||
> +                            cfd->len > CANFD_MAX_DLEN))
> +                       goto inval_skb;
> +       } else
> +               goto inval_skb;
> +
> +       if (!can_skb_headroom_valid(dev, skb))
> +               goto inval_skb;
> +
> +       return false;
> +
> +inval_skb:
> +       kfree_skb(skb);
> +       dev->stats.tx_dropped++;
> +       return true;
> +}
> +
> +static inline bool can_is_canfd_skb(const struct sk_buff *skb)
> +{
> +       /* the CAN specific type of skb is identified by its data length */
> +       return skb->len == CANFD_MTU;
> +}
> +
>  #endif /* !_CAN_SKB_H */
> --
> 2.29.2
>
>

Fails to build. I think you just forgot to include the changes on
drivers/net/can/dev/Makefile (c.f. below).

diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile
index 5c647951e06d..2c38bd532157 100644
--- a/drivers/net/can/dev/Makefile
+++ b/drivers/net/can/dev/Makefile
@@ -5,5 +5,6 @@ can-dev-y            += bittiming.o
 can-dev-y            += dev.o
 can-dev-y            += length.o
 can-dev-y            += rx-offload.o
+can-dev-y            += skb.o

 can-dev-$(CONFIG_CAN_LEDS)    += led.o



[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux