public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Oltean <olteanv@gmail.com>
To: George McCollister <george.mccollister@gmail.com>
Cc: Jakub Kicinski <kuba@kernel.org>, Andrew Lunn <andrew@lunn.ch>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Jonathan Corbet <corbet@lwn.net>,
	netdev@vger.kernel.org
Subject: Re: [RESEND PATCH net-next 1/4] net: hsr: generate supervision frame without HSR tag
Date: Mon, 1 Feb 2021 16:59:43 +0200	[thread overview]
Message-ID: <20210201145943.ajxecwnhsjslr2uf@skbuf> (raw)
In-Reply-To: <20210201140503.130625-2-george.mccollister@gmail.com>

On Mon, Feb 01, 2021 at 08:05:00AM -0600, George McCollister wrote:
> Generate supervision frame without HSR/PRP tag and rely on existing
> code which inserts it later.
> This will allow HSR/PRP tag insertions to be offloaded in the future.
> 
> Signed-off-by: George McCollister <george.mccollister@gmail.com>
> ---

I'm not sure I understand why this change is correct, you'll have to
write a more convincing commit message, and if that takes up too much
space (I hope it will), you'll have to break this up into multiple
trivial changes.

Just so we're on the same page, here is the call path:

hsr_announce
-> hsr->proto_ops->send_sv_frame
   -> hsr_init_skb
   -> hsr_forward_skb
      -> fill_frame_info
         -> hsr->proto_ops->fill_frame_info
      -> hsr_forward_do
         -> hsr_handle_sup_frame
         -> hsr->proto_ops->create_tagged_frame
         -> hsr_xmit

>  net/hsr/hsr_device.c  | 32 ++++----------------------------
>  net/hsr/hsr_forward.c | 10 +++++++---
>  2 files changed, 11 insertions(+), 31 deletions(-)
> 
> diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
> index ab953a1a0d6c..161b8da6a21d 100644
> --- a/net/hsr/hsr_device.c
> +++ b/net/hsr/hsr_device.c
> @@ -242,8 +242,7 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master, u16 proto)
>  	 * being, for PRP it is a trailer and for HSR it is a
>  	 * header
>  	 */
> -	skb = dev_alloc_skb(sizeof(struct hsr_tag) +
> -			    sizeof(struct hsr_sup_tag) +
> +	skb = dev_alloc_skb(sizeof(struct hsr_sup_tag) +
>  			    sizeof(struct hsr_sup_payload) + hlen + tlen);

Question 1: why are you no longer allocating struct hsr_tag (or struct prp_rct,
which has the same size)?

In hsr->proto_ops->fill_frame_info in the call path above, the skb is
still put either into frame->skb_hsr or into frame->skb_prp, but not
into frame->skb_std, even if it does not contain a struct hsr_tag.

Also, which code exactly will insert the hsr_tag later? I assume
hsr_fill_tag via hsr->proto_ops->create_tagged_frame?

But I don't think that's how it works, unless I'm misunderstanding
something.. The code path in hsr_create_tagged_frame is:

	if (frame->skb_hsr) {   <- it will take this branch
		struct hsr_ethhdr *hsr_ethhdr =
			(struct hsr_ethhdr *)skb_mac_header(frame->skb_hsr);

		/* set the lane id properly */
		hsr_set_path_id(hsr_ethhdr, port);
		return skb_clone(frame->skb_hsr, GFP_ATOMIC);
	}

	not this one
	|
	v

	/* Create the new skb with enough headroom to fit the HSR tag */
	skb = __pskb_copy(frame->skb_std,
			  skb_headroom(frame->skb_std) + HSR_HLEN, GFP_ATOMIC);
	if (!skb)
		return NULL;
	skb_reset_mac_header(skb);

	if (skb->ip_summed == CHECKSUM_PARTIAL)
		skb->csum_start += HSR_HLEN;

	movelen = ETH_HLEN;
	if (frame->is_vlan)
		movelen += VLAN_HLEN;

	src = skb_mac_header(skb);
	dst = skb_push(skb, HSR_HLEN);
	memmove(dst, src, movelen);
	skb_reset_mac_header(skb);

	/* skb_put_padto free skb on error and hsr_fill_tag returns NULL in
	 * that case
	 */
	return hsr_fill_tag(skb, frame, port, port->hsr->prot_version);

Otherwise said, it assumes that a frame->skb_hsr already has a struct
hsr_tag, no? Where does hsr_set_path_id() write?

>  
>  	if (!skb)
> @@ -275,12 +274,10 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
>  {
>  	struct hsr_priv *hsr = master->hsr;
>  	__u8 type = HSR_TLV_LIFE_CHECK;
> -	struct hsr_tag *hsr_tag = NULL;
>  	struct hsr_sup_payload *hsr_sp;
>  	struct hsr_sup_tag *hsr_stag;
>  	unsigned long irqflags;
>  	struct sk_buff *skb;
> -	u16 proto;
>  
>  	*interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL);
>  	if (hsr->announce_count < 3 && hsr->prot_version == 0) {
> @@ -289,23 +286,12 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
>  		hsr->announce_count++;
>  	}
>  
> -	if (!hsr->prot_version)
> -		proto = ETH_P_PRP;
> -	else
> -		proto = ETH_P_HSR;
> -
> -	skb = hsr_init_skb(master, proto);
> +	skb = hsr_init_skb(master, ETH_P_PRP);

Question 2: why is this correct, setting skb->protocol to ETH_P_PRP
(HSR v0) regardless of prot_version? Also, why is the change necessary?

Why is it such a big deal if supervision frames have HSR/PRP tag or not?

>  	if (!skb) {
>  		WARN_ONCE(1, "HSR: Could not send supervision frame\n");
>  		return;
>  	}
>  
> -	if (hsr->prot_version > 0) {
> -		hsr_tag = skb_put(skb, sizeof(struct hsr_tag));
> -		hsr_tag->encap_proto = htons(ETH_P_PRP);
> -		set_hsr_tag_LSDU_size(hsr_tag, HSR_V1_SUP_LSDUSIZE);
> -	}
> -
>  	hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag));
>  	set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf));
>  	set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
> @@ -315,8 +301,6 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
>  	if (hsr->prot_version > 0) {
>  		hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
>  		hsr->sup_sequence_nr++;
> -		hsr_tag->sequence_nr = htons(hsr->sequence_nr);
> -		hsr->sequence_nr++;
>  	} else {
>  		hsr_stag->sequence_nr = htons(hsr->sequence_nr);
>  		hsr->sequence_nr++;
> @@ -332,7 +316,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
>  	hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
>  	ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
>  
> -	if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN))
> +	if (skb_put_padto(skb, ETH_ZLEN))
>  		return;
>  
>  	hsr_forward_skb(skb, master);
> @@ -348,8 +332,6 @@ static void send_prp_supervision_frame(struct hsr_port *master,
>  	struct hsr_sup_tag *hsr_stag;
>  	unsigned long irqflags;
>  	struct sk_buff *skb;
> -	struct prp_rct *rct;
> -	u8 *tail;
>  
>  	skb = hsr_init_skb(master, ETH_P_PRP);
>  	if (!skb) {
> @@ -373,17 +355,11 @@ static void send_prp_supervision_frame(struct hsr_port *master,
>  	hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
>  	ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
>  
> -	if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) {
> +	if (skb_put_padto(skb, ETH_ZLEN)) {
>  		spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
>  		return;
>  	}
>  
> -	tail = skb_tail_pointer(skb) - HSR_HLEN;
> -	rct = (struct prp_rct *)tail;
> -	rct->PRP_suffix = htons(ETH_P_PRP);
> -	set_prp_LSDU_size(rct, HSR_V1_SUP_LSDUSIZE);
> -	rct->sequence_nr = htons(hsr->sequence_nr);
> -	hsr->sequence_nr++;
>  	spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
>  
>  	hsr_forward_skb(skb, master);
> diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
> index cadfccd7876e..a5566b2245a0 100644
> --- a/net/hsr/hsr_forward.c
> +++ b/net/hsr/hsr_forward.c
> @@ -454,8 +454,10 @@ static void handle_std_frame(struct sk_buff *skb,
>  void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb,
>  			 struct hsr_frame_info *frame)
>  {
> -	if (proto == htons(ETH_P_PRP) ||
> -	    proto == htons(ETH_P_HSR)) {
> +	struct hsr_port *port = frame->port_rcv;
> +
> +	if (port->type != HSR_PT_MASTER &&
> +	    (proto == htons(ETH_P_PRP) || proto == htons(ETH_P_HSR))) {

Why is this change necessary? Are you trying to force fill_frame_info to
call handle_std_frame for supervision frames, which will fix up the
kludge I asked about earlier? And why does checking for HSR_PT_MASTER
fixing it?

>  		/* HSR tagged frame :- Data or Supervision */
>  		frame->skb_std = NULL;
>  		frame->skb_prp = NULL;
> @@ -473,8 +475,10 @@ void prp_fill_frame_info(__be16 proto, struct sk_buff *skb,
>  {
>  	/* Supervision frame */
>  	struct prp_rct *rct = skb_get_PRP_rct(skb);
> +	struct hsr_port *port = frame->port_rcv;
>  
> -	if (rct &&
> +	if (port->type != HSR_PT_MASTER &&
> +	    rct &&
>  	    prp_check_lsdu_size(skb, rct, frame->is_supervision)) {
>  		frame->skb_hsr = NULL;
>  		frame->skb_std = NULL;
> -- 
> 2.11.0
> 

  reply	other threads:[~2021-02-01 15:02 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-01 14:04 [RESEND PATCH net-next 0/4] add HSR offloading support for DSA switches George McCollister
2021-02-01 14:05 ` [RESEND PATCH net-next 1/4] net: hsr: generate supervision frame without HSR tag George McCollister
2021-02-01 14:59   ` Vladimir Oltean [this message]
2021-02-01 19:43     ` George McCollister
2021-02-02  0:37       ` Vladimir Oltean
2021-02-02 14:49         ` George McCollister
2021-02-03 21:16           ` Vladimir Oltean
2021-02-06 23:43           ` Vladimir Oltean
2021-02-08 15:26             ` George McCollister
2021-02-01 14:05 ` [RESEND PATCH net-next 2/4] net: hsr: add offloading support George McCollister
2021-02-01 15:23   ` Vladimir Oltean
2021-02-01 20:15     ` George McCollister
2021-02-03 20:43     ` George McCollister
2021-02-01 14:05 ` [RESEND PATCH net-next 3/4] net: dsa: add support for offloading HSR George McCollister
2021-02-01 14:05 ` [RESEND PATCH net-next 4/4] net: dsa: xrs700x: add HSR offloading support George McCollister
2021-02-01 15:29   ` Vladimir Oltean
2021-02-01 21:25     ` George McCollister

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210201145943.ajxecwnhsjslr2uf@skbuf \
    --to=olteanv@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=corbet@lwn.net \
    --cc=f.fainelli@gmail.com \
    --cc=george.mccollister@gmail.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=vivien.didelot@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox