[can-next 5/5] can: gw: use new can_gw_hops variable instead of re-using csum_start
From: Oliver Hartkopp <socketcan@hartkopp.net>
Date: 2026-01-12 15:10:24
Also in:
linux-can
Subsystem:
can network layer, networking [general], the rest · Maintainers:
Oliver Hartkopp, Marc Kleine-Budde, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
As CAN skbs don't use IP checksums the skb->csum_start variable was used to store the can-gw CAN frame time-to-live counter together with skb->ip_summed set to CHECKSUM_UNNECESSARY. As we still have 16 bit left in the inner protocol space for ethernet/IP encapsulation the time-to-live counter is moved there to remove the 'hack' using the skb->csum_start variable. Patch 5/5 to remove the private CAN bus skb headroom infrastructure. Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> --- include/linux/skbuff.h | 2 ++ net/can/gw.c | 23 ++++++----------------- 2 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index eccd0b3898a0..7ef0b8e24a30 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h@@ -863,10 +863,11 @@ enum skb_tstamp_type { * @vlan_all: vlan fields (proto & tci) * @vlan_proto: vlan encapsulation protocol * @vlan_tci: vlan tag control information * @can_iif: ifindex of the first interface the CAN frame appeared on * @can_framelen: cached echo CAN frame length for bql + * @can_gw_hops: can-gw CAN frame time-to-live counter * @inner_protocol: Protocol (encapsulation) * @inner_ipproto: (aka @inner_protocol) stores ipproto when * skb->inner_protocol_type == ENCAP_TYPE_IPPROTO; * @inner_transport_header: Inner transport layer header (encapsulation) * @inner_network_header: Network layer header (encapsulation)
@@ -1085,10 +1086,11 @@ struct sk_buff { /* space for protocols without protocol/header encapsulation */ struct { int can_iif; __u16 can_framelen; + __u16 can_gw_hops; }; }; __be16 protocol; __u16 transport_header;
diff --git a/net/can/gw.c b/net/can/gw.c
index 74d771a3540c..fca0566963a2 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c@@ -68,12 +68,12 @@ MODULE_ALIAS(CAN_GW_NAME); #define CGW_MIN_HOPS 1 #define CGW_MAX_HOPS 6 #define CGW_DEFAULT_HOPS 1 -static unsigned int max_hops __read_mostly = CGW_DEFAULT_HOPS; -module_param(max_hops, uint, 0444); +static unsigned short max_hops __read_mostly = CGW_DEFAULT_HOPS; +module_param(max_hops, ushort, 0444); MODULE_PARM_DESC(max_hops, "maximum " CAN_GW_NAME " routing hops for CAN frames " "(valid values: " __stringify(CGW_MIN_HOPS) "-" __stringify(CGW_MAX_HOPS) " hops, " "default: " __stringify(CGW_DEFAULT_HOPS) ")");
@@ -472,23 +472,12 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) } /* Do not handle CAN frames routed more than 'max_hops' times. * In general we should never catch this delimiter which is intended * to cover a misconfiguration protection (e.g. circular CAN routes). - * - * The Controller Area Network controllers only accept CAN frames with - * correct CRCs - which are not visible in the controller registers. - * According to skbuff.h documentation the csum_start element for IP - * checksums is undefined/unused when ip_summed == CHECKSUM_UNNECESSARY. - * Only CAN skbs can be processed here which already have this property. */ - -#define cgw_hops(skb) ((skb)->csum_start) - - BUG_ON(skb->ip_summed != CHECKSUM_UNNECESSARY); - - if (cgw_hops(skb) >= max_hops) { + if (skb->can_gw_hops >= max_hops) { /* indicate deleted frames due to misconfiguration */ gwj->deleted_frames++; return; }
@@ -517,15 +506,15 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data) gwj->dropped_frames++; return; } /* put the incremented hop counter in the cloned skb */ - cgw_hops(nskb) = cgw_hops(skb) + 1; + nskb->can_gw_hops = skb->can_gw_hops + 1; /* first processing of this CAN frame -> adjust to private hop limit */ - if (gwj->limit_hops && cgw_hops(nskb) == 1) - cgw_hops(nskb) = max_hops - gwj->limit_hops + 1; + if (gwj->limit_hops && nskb->can_gw_hops == 1) + nskb->can_gw_hops = max_hops - gwj->limit_hops + 1; nskb->dev = gwj->dst.dev; /* pointer to modifiable CAN frame */ cf = (struct canfd_frame *)nskb->data;
--
2.47.3