vxcan: remove sk reference in peer skb
PATCH 1/2 vxcan: remove sk reference in peer skb
With can_create_echo_skb() the skb which is forwarded to the peer CAN interface shares the sk pointer from the originating socket. This makes the CAN frame show up in the peer namespace as a TX packet.
With the use of skb_clone() analogue to the handling in gw.c the peer skb gets a new start in the peer namespace and correctly appears as a RX packet.
--- drivers/net/can/vxcan.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/net/can/vxcan.c +11 -6
@@ -31,32 +31,37 @@ MODULE_ALIAS_RTNL_LINK(DRV_NAME);struct vxcan_priv {struct net_device __rcu *peer; }; -static netdev_tx_t vxcan_xmit (struct sk_buff *skb,struct net_device *dev) +static netdev_tx_t vxcan_xmit (struct sk_buff *oskb,struct net_device *dev) {struct vxcan_priv *priv =netdev_priv (dev);struct net_device *peer; -struct canfd_frame *cfd = (struct canfd_frame *)skb->data; +struct canfd_frame *cfd = (struct canfd_frame *)oskb->data;struct net_device_stats *peerstats, *srcstats = &dev->stats; +struct sk_buff *skb;u8 len; -if (can_dropped_invalid_skb (dev, skb)) +if (can_dropped_invalid_skb (dev, oskb))return NETDEV_TX_OK ;rcu_read_lock (); peer =rcu_dereference (priv->peer);if (unlikely (!peer)) { -kfree_skb (skb); +kfree_skb (oskb); dev->stats.tx_dropped++; goto out_unlock; } - skb =can_create_echo_skb (skb); -if (!skb) + skb =skb_clone (oskb,GFP_ATOMIC ); +if (skb) { +consume_skb (oskb); + }else { +kfree (oskb); goto out_unlock; + }/* reset CAN GW hop counter */ skb->csum_start =0 ; skb->pkt_type =PACKET_BROADCAST ; skb->dev = peer;
Signature · 1 line
2.30.2
PATCH 2/2 vxcan: enable local echo for sent CAN frames
The vxcan driver provides a pair of virtual CAN interfaces to exchange CAN traffic between different namespaces - analogue to veth.
In opposite to the vcan driver the local sent CAN traffic on this interface is not echo'ed back but only sent to the remote peer. This is unusual and can be easily fixed by removing IFF_ECHO from the netdevice flags that are set for vxcan interfaces by default at startup.
Without IFF_ECHO set on driver level, the local sent CAN frames are echo'ed in af_can.c in can_send(). This patch makes vxcan interfaces adopt the same local echo behavior and procedures as known from the vcan interfaces.
--- drivers/net/can/vxcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/vxcan.c +1 -1
@@ -151,11 +151,11 @@ static void vxcan_setup(struct net_device *dev) dev->type =ARPHRD_CAN ; dev->mtu =CANFD_MTU ; dev->hard_header_len =0 ; dev->addr_len =0 ; dev->tx_queue_len =0 ; - dev->flags = (IFF_NOARP |IFF_ECHO ); + dev->flags =IFF_NOARP ; dev->netdev_ops = &vxcan_netdev_ops; dev->needs_free_netdev = true; can_ml =netdev_priv (dev) +ALIGN (sizeof (struct vxcan_priv ),NETDEV_ALIGN );can_set_ml_priv (dev, can_ml);
Signature · 1 line
2.30.2