0001
0002
0003
0004
0005
0006
0007 #include <linux/can/dev.h>
0008 #include <linux/can/netlink.h>
0009 #include <linux/module.h>
0010
0011 #define MOD_DESC "CAN device driver interface"
0012
0013 MODULE_DESCRIPTION(MOD_DESC);
0014 MODULE_LICENSE("GPL v2");
0015 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 void can_flush_echo_skb(struct net_device *dev)
0027 {
0028 struct can_priv *priv = netdev_priv(dev);
0029 struct net_device_stats *stats = &dev->stats;
0030 int i;
0031
0032 for (i = 0; i < priv->echo_skb_max; i++) {
0033 if (priv->echo_skb[i]) {
0034 kfree_skb(priv->echo_skb[i]);
0035 priv->echo_skb[i] = NULL;
0036 stats->tx_dropped++;
0037 stats->tx_aborted_errors++;
0038 }
0039 }
0040 }
0041
0042
0043
0044
0045
0046
0047
0048 int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
0049 unsigned int idx, unsigned int frame_len)
0050 {
0051 struct can_priv *priv = netdev_priv(dev);
0052
0053 BUG_ON(idx >= priv->echo_skb_max);
0054
0055
0056 if (!(dev->flags & IFF_ECHO) ||
0057 (skb->protocol != htons(ETH_P_CAN) &&
0058 skb->protocol != htons(ETH_P_CANFD))) {
0059 kfree_skb(skb);
0060 return 0;
0061 }
0062
0063 if (!priv->echo_skb[idx]) {
0064 skb = can_create_echo_skb(skb);
0065 if (!skb)
0066 return -ENOMEM;
0067
0068
0069 skb->ip_summed = CHECKSUM_UNNECESSARY;
0070 skb->dev = dev;
0071
0072
0073 can_skb_prv(skb)->frame_len = frame_len;
0074
0075 if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
0076 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
0077
0078 skb_tx_timestamp(skb);
0079
0080
0081 priv->echo_skb[idx] = skb;
0082 } else {
0083
0084 netdev_err(dev, "%s: BUG! echo_skb %d is occupied!\n", __func__, idx);
0085 kfree_skb(skb);
0086 return -EBUSY;
0087 }
0088
0089 return 0;
0090 }
0091 EXPORT_SYMBOL_GPL(can_put_echo_skb);
0092
0093 struct sk_buff *
0094 __can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr,
0095 unsigned int *frame_len_ptr)
0096 {
0097 struct can_priv *priv = netdev_priv(dev);
0098
0099 if (idx >= priv->echo_skb_max) {
0100 netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
0101 __func__, idx, priv->echo_skb_max);
0102 return NULL;
0103 }
0104
0105 if (priv->echo_skb[idx]) {
0106
0107
0108
0109 struct sk_buff *skb = priv->echo_skb[idx];
0110 struct can_skb_priv *can_skb_priv = can_skb_prv(skb);
0111 struct canfd_frame *cf = (struct canfd_frame *)skb->data;
0112
0113 if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)
0114 skb_tstamp_tx(skb, skb_hwtstamps(skb));
0115
0116
0117 if (cf->can_id & CAN_RTR_FLAG)
0118 *len_ptr = 0;
0119 else
0120 *len_ptr = cf->len;
0121
0122 if (frame_len_ptr)
0123 *frame_len_ptr = can_skb_priv->frame_len;
0124
0125 priv->echo_skb[idx] = NULL;
0126
0127 if (skb->pkt_type == PACKET_LOOPBACK) {
0128 skb->pkt_type = PACKET_BROADCAST;
0129 } else {
0130 dev_consume_skb_any(skb);
0131 return NULL;
0132 }
0133
0134 return skb;
0135 }
0136
0137 return NULL;
0138 }
0139
0140
0141
0142
0143
0144
0145
0146 unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx,
0147 unsigned int *frame_len_ptr)
0148 {
0149 struct sk_buff *skb;
0150 u8 len;
0151
0152 skb = __can_get_echo_skb(dev, idx, &len, frame_len_ptr);
0153 if (!skb)
0154 return 0;
0155
0156 skb_get(skb);
0157 if (netif_rx(skb) == NET_RX_SUCCESS)
0158 dev_consume_skb_any(skb);
0159 else
0160 dev_kfree_skb_any(skb);
0161
0162 return len;
0163 }
0164 EXPORT_SYMBOL_GPL(can_get_echo_skb);
0165
0166
0167
0168
0169
0170 void can_free_echo_skb(struct net_device *dev, unsigned int idx,
0171 unsigned int *frame_len_ptr)
0172 {
0173 struct can_priv *priv = netdev_priv(dev);
0174
0175 if (idx >= priv->echo_skb_max) {
0176 netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
0177 __func__, idx, priv->echo_skb_max);
0178 return;
0179 }
0180
0181 if (priv->echo_skb[idx]) {
0182 struct sk_buff *skb = priv->echo_skb[idx];
0183 struct can_skb_priv *can_skb_priv = can_skb_prv(skb);
0184
0185 if (frame_len_ptr)
0186 *frame_len_ptr = can_skb_priv->frame_len;
0187
0188 dev_kfree_skb_any(skb);
0189 priv->echo_skb[idx] = NULL;
0190 }
0191 }
0192 EXPORT_SYMBOL_GPL(can_free_echo_skb);
0193
0194 struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
0195 {
0196 struct sk_buff *skb;
0197
0198 skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
0199 sizeof(struct can_frame));
0200 if (unlikely(!skb)) {
0201 *cf = NULL;
0202
0203 return NULL;
0204 }
0205
0206 skb->protocol = htons(ETH_P_CAN);
0207 skb->pkt_type = PACKET_BROADCAST;
0208 skb->ip_summed = CHECKSUM_UNNECESSARY;
0209
0210 skb_reset_mac_header(skb);
0211 skb_reset_network_header(skb);
0212 skb_reset_transport_header(skb);
0213
0214 can_skb_reserve(skb);
0215 can_skb_prv(skb)->ifindex = dev->ifindex;
0216 can_skb_prv(skb)->skbcnt = 0;
0217
0218 *cf = skb_put_zero(skb, sizeof(struct can_frame));
0219
0220 return skb;
0221 }
0222 EXPORT_SYMBOL_GPL(alloc_can_skb);
0223
0224 struct sk_buff *alloc_canfd_skb(struct net_device *dev,
0225 struct canfd_frame **cfd)
0226 {
0227 struct sk_buff *skb;
0228
0229 skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
0230 sizeof(struct canfd_frame));
0231 if (unlikely(!skb)) {
0232 *cfd = NULL;
0233
0234 return NULL;
0235 }
0236
0237 skb->protocol = htons(ETH_P_CANFD);
0238 skb->pkt_type = PACKET_BROADCAST;
0239 skb->ip_summed = CHECKSUM_UNNECESSARY;
0240
0241 skb_reset_mac_header(skb);
0242 skb_reset_network_header(skb);
0243 skb_reset_transport_header(skb);
0244
0245 can_skb_reserve(skb);
0246 can_skb_prv(skb)->ifindex = dev->ifindex;
0247 can_skb_prv(skb)->skbcnt = 0;
0248
0249 *cfd = skb_put_zero(skb, sizeof(struct canfd_frame));
0250
0251 return skb;
0252 }
0253 EXPORT_SYMBOL_GPL(alloc_canfd_skb);
0254
0255 struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
0256 {
0257 struct sk_buff *skb;
0258
0259 skb = alloc_can_skb(dev, cf);
0260 if (unlikely(!skb))
0261 return NULL;
0262
0263 (*cf)->can_id = CAN_ERR_FLAG;
0264 (*cf)->len = CAN_ERR_DLC;
0265
0266 return skb;
0267 }
0268 EXPORT_SYMBOL_GPL(alloc_can_err_skb);
0269
0270
0271 static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb)
0272 {
0273
0274 if (WARN_ON_ONCE(skb_headroom(skb) < sizeof(struct can_skb_priv)))
0275 return false;
0276
0277
0278 if (skb->ip_summed == CHECKSUM_NONE) {
0279
0280 can_skb_prv(skb)->ifindex = dev->ifindex;
0281 can_skb_prv(skb)->skbcnt = 0;
0282
0283 skb->ip_summed = CHECKSUM_UNNECESSARY;
0284
0285
0286 if (dev->flags & IFF_ECHO)
0287 skb->pkt_type = PACKET_LOOPBACK;
0288 else
0289 skb->pkt_type = PACKET_HOST;
0290
0291 skb_reset_mac_header(skb);
0292 skb_reset_network_header(skb);
0293 skb_reset_transport_header(skb);
0294 }
0295
0296 return true;
0297 }
0298
0299
0300 bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
0301 {
0302 const struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
0303 struct can_priv *priv = netdev_priv(dev);
0304
0305 if (skb->protocol == htons(ETH_P_CAN)) {
0306 if (unlikely(skb->len != CAN_MTU ||
0307 cfd->len > CAN_MAX_DLEN))
0308 goto inval_skb;
0309 } else if (skb->protocol == htons(ETH_P_CANFD)) {
0310 if (unlikely(skb->len != CANFD_MTU ||
0311 cfd->len > CANFD_MAX_DLEN))
0312 goto inval_skb;
0313 } else {
0314 goto inval_skb;
0315 }
0316
0317 if (!can_skb_headroom_valid(dev, skb)) {
0318 goto inval_skb;
0319 } else if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) {
0320 netdev_info_once(dev,
0321 "interface in listen only mode, dropping skb\n");
0322 goto inval_skb;
0323 }
0324
0325 return false;
0326
0327 inval_skb:
0328 kfree_skb(skb);
0329 dev->stats.tx_dropped++;
0330 return true;
0331 }
0332 EXPORT_SYMBOL_GPL(can_dropped_invalid_skb);