All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/4] net: hdlc_fr: Add support for any Ethertype
@ 2020-10-28 13:18 Xie He
  2020-10-28 13:18 ` [PATCH net-next v2 1/4] net: hdlc_fr: Simpify fr_rx by using "goto rx_drop" to drop frames Xie He
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Xie He @ 2020-10-28 13:18 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev, linux-kernel, Krzysztof Halasa
  Cc: Xie He

The main purpose of this series is the last patch. The previous 3 patches
are just code clean-ups so that the last patch will not make the code too
messy. The patches must be applied in sequence.

The receiving code of this driver doesn't support arbitrary Ethertype
values. It only recognizes a few known Ethertypes when receiving and drops
skbs with other Ethertypes.

However, the standard document RFC 2427 allows Frame Relay to support any
Ethertype values. This series adds support for this.

Change from v1:
Small fix to the commit message of the second patch

Xie He (4):
  net: hdlc_fr: Simpify fr_rx by using "goto rx_drop" to drop frames
  net: hdlc_fr: Change the use of "dev" in fr_rx to make the code
    cleaner
  net: hdlc_fr: Improve the initial check when we receive an skb
  net: hdlc_fr: Add support for any Ethertype

 drivers/net/wan/hdlc_fr.c | 119 +++++++++++++++++++++++---------------
 1 file changed, 73 insertions(+), 46 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 1/4] net: hdlc_fr: Simpify fr_rx by using "goto rx_drop" to drop frames
  2020-10-28 13:18 [PATCH net-next v2 0/4] net: hdlc_fr: Add support for any Ethertype Xie He
@ 2020-10-28 13:18 ` Xie He
  2020-10-28 13:18 ` [PATCH net-next v2 2/4] net: hdlc_fr: Change the use of "dev" in fr_rx to make the code cleaner Xie He
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Xie He @ 2020-10-28 13:18 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev, linux-kernel, Krzysztof Halasa
  Cc: Xie He

When the fr_rx function drops a received frame (because the protocol type
is not supported, or because the PVC virtual device that corresponds to
the DLCI number and the protocol type doesn't exist), the function frees
the skb and returns.

The code for freeing the skb and returning is repeated several times, this
patch uses "goto rx_drop" to replace them so that the code looks cleaner.

Also add code to increase the stats.rx_dropped count whenever we drop a
frame.

Cc: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: Xie He <xie.he.0141@gmail.com>
---
 drivers/net/wan/hdlc_fr.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 409e5a7ad8e2..c774eff44534 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -904,8 +904,7 @@ static int fr_rx(struct sk_buff *skb)
 		netdev_info(frad, "No PVC for received frame's DLCI %d\n",
 			    dlci);
 #endif
-		dev_kfree_skb_any(skb);
-		return NET_RX_DROP;
+		goto rx_drop;
 	}
 
 	if (pvc->state.fecn != fh->fecn) {
@@ -963,14 +962,12 @@ static int fr_rx(struct sk_buff *skb)
 		default:
 			netdev_info(frad, "Unsupported protocol, OUI=%x PID=%x\n",
 				    oui, pid);
-			dev_kfree_skb_any(skb);
-			return NET_RX_DROP;
+			goto rx_drop;
 		}
 	} else {
 		netdev_info(frad, "Unsupported protocol, NLPID=%x length=%i\n",
 			    data[3], skb->len);
-		dev_kfree_skb_any(skb);
-		return NET_RX_DROP;
+		goto rx_drop;
 	}
 
 	if (dev) {
@@ -982,12 +979,13 @@ static int fr_rx(struct sk_buff *skb)
 		netif_rx(skb);
 		return NET_RX_SUCCESS;
 	} else {
-		dev_kfree_skb_any(skb);
-		return NET_RX_DROP;
+		goto rx_drop;
 	}
 
- rx_error:
+rx_error:
 	frad->stats.rx_errors++; /* Mark error */
+rx_drop:
+	frad->stats.rx_dropped++;
 	dev_kfree_skb_any(skb);
 	return NET_RX_DROP;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 2/4] net: hdlc_fr: Change the use of "dev" in fr_rx to make the code cleaner
  2020-10-28 13:18 [PATCH net-next v2 0/4] net: hdlc_fr: Add support for any Ethertype Xie He
  2020-10-28 13:18 ` [PATCH net-next v2 1/4] net: hdlc_fr: Simpify fr_rx by using "goto rx_drop" to drop frames Xie He
@ 2020-10-28 13:18 ` Xie He
  2020-10-28 13:18 ` [PATCH net-next v2 3/4] net: hdlc_fr: Improve the initial check when we receive an skb Xie He
  2020-10-28 13:18 ` [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype Xie He
  3 siblings, 0 replies; 10+ messages in thread
From: Xie He @ 2020-10-28 13:18 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev, linux-kernel, Krzysztof Halasa
  Cc: Xie He

The eth_type_trans function is called when we receive frames carrying
Ethernet frames. This function expects a non-NULL pointer as a argument,
and assigns it directly to skb->dev.

However, the code handling other types of frames first assigns a pointer
to "dev", and then at the end checks whether the value is NULL, and if it
is not NULL, assigns it to skb->dev.

The two flows are different. Mixing them in this function makes the code
messy. It's better that we convert the second flow to align with how
eth_type_trans does things.

So this patch changes the code to: first make sure the pointer is not
NULL, then assign it directly to skb->dev. "dev" is no longer needed until
the end where we use it to update stats.

Cc: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: Xie He <xie.he.0141@gmail.com>
---
 drivers/net/wan/hdlc_fr.c | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index c774eff44534..ac65f5c435ef 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -880,7 +880,7 @@ static int fr_rx(struct sk_buff *skb)
 	u8 *data = skb->data;
 	u16 dlci;
 	struct pvc_device *pvc;
-	struct net_device *dev = NULL;
+	struct net_device *dev;
 
 	if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI)
 		goto rx_error;
@@ -930,13 +930,17 @@ static int fr_rx(struct sk_buff *skb)
 	}
 
 	if (data[3] == NLPID_IP) {
+		if (!pvc->main)
+			goto rx_drop;
 		skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
-		dev = pvc->main;
+		skb->dev = pvc->main;
 		skb->protocol = htons(ETH_P_IP);
 
 	} else if (data[3] == NLPID_IPV6) {
+		if (!pvc->main)
+			goto rx_drop;
 		skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
-		dev = pvc->main;
+		skb->dev = pvc->main;
 		skb->protocol = htons(ETH_P_IPV6);
 
 	} else if (skb->len > 10 && data[3] == FR_PAD &&
@@ -950,13 +954,16 @@ static int fr_rx(struct sk_buff *skb)
 		case ETH_P_IPX:
 		case ETH_P_IP:	/* a long variant */
 		case ETH_P_IPV6:
-			dev = pvc->main;
+			if (!pvc->main)
+				goto rx_drop;
+			skb->dev = pvc->main;
 			skb->protocol = htons(pid);
 			break;
 
 		case 0x80C20007: /* bridged Ethernet frame */
-			if ((dev = pvc->ether) != NULL)
-				skb->protocol = eth_type_trans(skb, dev);
+			if (!pvc->ether)
+				goto rx_drop;
+			skb->protocol = eth_type_trans(skb, pvc->ether);
 			break;
 
 		default:
@@ -970,17 +977,13 @@ static int fr_rx(struct sk_buff *skb)
 		goto rx_drop;
 	}
 
-	if (dev) {
-		dev->stats.rx_packets++; /* PVC traffic */
-		dev->stats.rx_bytes += skb->len;
-		if (pvc->state.becn)
-			dev->stats.rx_compressed++;
-		skb->dev = dev;
-		netif_rx(skb);
-		return NET_RX_SUCCESS;
-	} else {
-		goto rx_drop;
-	}
+	dev = skb->dev;
+	dev->stats.rx_packets++; /* PVC traffic */
+	dev->stats.rx_bytes += skb->len;
+	if (pvc->state.becn)
+		dev->stats.rx_compressed++;
+	netif_rx(skb);
+	return NET_RX_SUCCESS;
 
 rx_error:
 	frad->stats.rx_errors++; /* Mark error */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 3/4] net: hdlc_fr: Improve the initial check when we receive an skb
  2020-10-28 13:18 [PATCH net-next v2 0/4] net: hdlc_fr: Add support for any Ethertype Xie He
  2020-10-28 13:18 ` [PATCH net-next v2 1/4] net: hdlc_fr: Simpify fr_rx by using "goto rx_drop" to drop frames Xie He
  2020-10-28 13:18 ` [PATCH net-next v2 2/4] net: hdlc_fr: Change the use of "dev" in fr_rx to make the code cleaner Xie He
@ 2020-10-28 13:18 ` Xie He
  2020-10-28 13:18 ` [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype Xie He
  3 siblings, 0 replies; 10+ messages in thread
From: Xie He @ 2020-10-28 13:18 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev, linux-kernel, Krzysztof Halasa
  Cc: Xie He

1.
Change the skb->len check from "<= 4" to "< 4".
At first we only need to ensure a 4-byte header is present. We indeed
normally need the 5th byte, too, but it'd be more logical and cleaner
to check its existence when we actually need it.

2.
Add an fh->ea2 check to the initial checks in fr_fx. fh->ea2 == 1 means
the second address byte is the final address byte. We only support the
case where the address length is 2 bytes.

Cc: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: Xie He <xie.he.0141@gmail.com>
---
 drivers/net/wan/hdlc_fr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index ac65f5c435ef..3639c2bfb141 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -882,7 +882,7 @@ static int fr_rx(struct sk_buff *skb)
 	struct pvc_device *pvc;
 	struct net_device *dev;
 
-	if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI)
+	if (skb->len < 4 || fh->ea1 || !fh->ea2 || data[2] != FR_UI)
 		goto rx_error;
 
 	dlci = q922_to_dlci(skb->data);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype
  2020-10-28 13:18 [PATCH net-next v2 0/4] net: hdlc_fr: Add support for any Ethertype Xie He
                   ` (2 preceding siblings ...)
  2020-10-28 13:18 ` [PATCH net-next v2 3/4] net: hdlc_fr: Improve the initial check when we receive an skb Xie He
@ 2020-10-28 13:18 ` Xie He
  2020-10-29 17:23   ` Willem de Bruijn
  3 siblings, 1 reply; 10+ messages in thread
From: Xie He @ 2020-10-28 13:18 UTC (permalink / raw)
  To: Jakub Kicinski, David S. Miller, netdev, linux-kernel, Krzysztof Halasa
  Cc: Xie He

Change the fr_rx function to make this driver support any Ethertype
when receiving skbs on normal (non-Ethernet-emulating) PVC devices.
(This driver is already able to handle any Ethertype when sending.)

Originally in the fr_rx function, the code that parses the long (10-byte)
header only recognizes a few Ethertype values and drops frames with other
Ethertype values. This patch replaces this code to make fr_rx support
any Ethertype. This patch also creates a new function fr_snap_parse as
part of the new code.

Also add skb_reset_mac_header before we pass an skb (received on normal
PVC devices) to upper layers. Because we don't use header_ops for normal
PVC devices, we should hide the header from upper layer code in this case.

Cc: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: Xie He <xie.he.0141@gmail.com>
---
 drivers/net/wan/hdlc_fr.c | 76 ++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 3639c2bfb141..e95efc14bc97 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -871,6 +871,45 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
 	return 0;
 }
 
+static int fr_snap_parse(struct sk_buff *skb, struct pvc_device *pvc)
+{
+	/* OUI 00-00-00 indicates an Ethertype follows */
+	if (skb->data[0] == 0x00 &&
+	    skb->data[1] == 0x00 &&
+	    skb->data[2] == 0x00) {
+		if (!pvc->main)
+			return -1;
+		skb->dev = pvc->main;
+		skb->protocol = *(__be16 *)(skb->data + 3); /* Ethertype */
+		skb_pull(skb, 5);
+		skb_reset_mac_header(skb);
+		return 0;
+
+	/* OUI 00-80-C2 stands for the 802.1 organization */
+	} else if (skb->data[0] == 0x00 &&
+		   skb->data[1] == 0x80 &&
+		   skb->data[2] == 0xC2) {
+		/* PID 00-07 stands for Ethernet frames without FCS */
+		if (skb->data[3] == 0x00 &&
+		    skb->data[4] == 0x07) {
+			if (!pvc->ether)
+				return -1;
+			skb_pull(skb, 5);
+			if (skb->len < ETH_HLEN)
+				return -1;
+			skb->protocol = eth_type_trans(skb, pvc->ether);
+			return 0;
+
+		/* PID unsupported */
+		} else {
+			return -1;
+		}
+
+	/* OUI unsupported */
+	} else {
+		return -1;
+	}
+}
 
 static int fr_rx(struct sk_buff *skb)
 {
@@ -935,6 +974,7 @@ static int fr_rx(struct sk_buff *skb)
 		skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
 		skb->dev = pvc->main;
 		skb->protocol = htons(ETH_P_IP);
+		skb_reset_mac_header(skb);
 
 	} else if (data[3] == NLPID_IPV6) {
 		if (!pvc->main)
@@ -942,35 +982,21 @@ static int fr_rx(struct sk_buff *skb)
 		skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
 		skb->dev = pvc->main;
 		skb->protocol = htons(ETH_P_IPV6);
+		skb_reset_mac_header(skb);
 
-	} else if (skb->len > 10 && data[3] == FR_PAD &&
-		   data[4] == NLPID_SNAP && data[5] == FR_PAD) {
-		u16 oui = ntohs(*(__be16*)(data + 6));
-		u16 pid = ntohs(*(__be16*)(data + 8));
-		skb_pull(skb, 10);
-
-		switch ((((u32)oui) << 16) | pid) {
-		case ETH_P_ARP: /* routed frame with SNAP */
-		case ETH_P_IPX:
-		case ETH_P_IP:	/* a long variant */
-		case ETH_P_IPV6:
-			if (!pvc->main)
-				goto rx_drop;
-			skb->dev = pvc->main;
-			skb->protocol = htons(pid);
-			break;
-
-		case 0x80C20007: /* bridged Ethernet frame */
-			if (!pvc->ether)
+	} else if (data[3] == FR_PAD) {
+		if (skb->len < 5)
+			goto rx_error;
+		if (data[4] == NLPID_SNAP) { /* A SNAP header follows */
+			skb_pull(skb, 5);
+			if (skb->len < 5) /* Incomplete SNAP header */
+				goto rx_error;
+			if (fr_snap_parse(skb, pvc))
 				goto rx_drop;
-			skb->protocol = eth_type_trans(skb, pvc->ether);
-			break;
-
-		default:
-			netdev_info(frad, "Unsupported protocol, OUI=%x PID=%x\n",
-				    oui, pid);
+		} else {
 			goto rx_drop;
 		}
+
 	} else {
 		netdev_info(frad, "Unsupported protocol, NLPID=%x length=%i\n",
 			    data[3], skb->len);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype
  2020-10-28 13:18 ` [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype Xie He
@ 2020-10-29 17:23   ` Willem de Bruijn
  2020-10-29 23:53     ` Xie He
  0 siblings, 1 reply; 10+ messages in thread
From: Willem de Bruijn @ 2020-10-29 17:23 UTC (permalink / raw)
  To: Xie He
  Cc: Jakub Kicinski, David S. Miller, Network Development,
	linux-kernel, Krzysztof Halasa

On Wed, Oct 28, 2020 at 6:58 PM Xie He <xie.he.0141@gmail.com> wrote:
>
> Change the fr_rx function to make this driver support any Ethertype
> when receiving skbs on normal (non-Ethernet-emulating) PVC devices.
> (This driver is already able to handle any Ethertype when sending.)
>
> Originally in the fr_rx function, the code that parses the long (10-byte)
> header only recognizes a few Ethertype values and drops frames with other
> Ethertype values. This patch replaces this code to make fr_rx support
> any Ethertype. This patch also creates a new function fr_snap_parse as
> part of the new code.
>
> Also add skb_reset_mac_header before we pass an skb (received on normal
> PVC devices) to upper layers. Because we don't use header_ops for normal
> PVC devices, we should hide the header from upper layer code in this case.

This should probably be a separate commit

> Cc: Krzysztof Halasa <khc@pm.waw.pl>
> Signed-off-by: Xie He <xie.he.0141@gmail.com>
> ---
>  drivers/net/wan/hdlc_fr.c | 76 ++++++++++++++++++++++++++-------------
>  1 file changed, 51 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
> index 3639c2bfb141..e95efc14bc97 100644
> --- a/drivers/net/wan/hdlc_fr.c
> +++ b/drivers/net/wan/hdlc_fr.c
> @@ -871,6 +871,45 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
>         return 0;
>  }
>
> +static int fr_snap_parse(struct sk_buff *skb, struct pvc_device *pvc)
> +{
> +       /* OUI 00-00-00 indicates an Ethertype follows */
> +       if (skb->data[0] == 0x00 &&
> +           skb->data[1] == 0x00 &&
> +           skb->data[2] == 0x00) {
> +               if (!pvc->main)
> +                       return -1;
> +               skb->dev = pvc->main;
> +               skb->protocol = *(__be16 *)(skb->data + 3); /* Ethertype */

Does it make sense to define a struct snap_hdr instead of manually
casting all these bytes?

> +               skb_pull(skb, 5);
> +               skb_reset_mac_header(skb);
> +               return 0;
> +
> +       /* OUI 00-80-C2 stands for the 802.1 organization */
> +       } else if (skb->data[0] == 0x00 &&
> +                  skb->data[1] == 0x80 &&
> +                  skb->data[2] == 0xC2) {
> +               /* PID 00-07 stands for Ethernet frames without FCS */
> +               if (skb->data[3] == 0x00 &&
> +                   skb->data[4] == 0x07) {


And macros or constant integers to self document these kinds of fields.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype
  2020-10-29 17:23   ` Willem de Bruijn
@ 2020-10-29 23:53     ` Xie He
  2020-10-30  0:49       ` Xie He
  2020-10-30  0:50       ` Willem de Bruijn
  0 siblings, 2 replies; 10+ messages in thread
From: Xie He @ 2020-10-29 23:53 UTC (permalink / raw)
  To: Willem de Bruijn
  Cc: Jakub Kicinski, David S. Miller, Network Development,
	linux-kernel, Krzysztof Halasa

On Thu, Oct 29, 2020 at 10:24 AM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
>
> > Also add skb_reset_mac_header before we pass an skb (received on normal
> > PVC devices) to upper layers. Because we don't use header_ops for normal
> > PVC devices, we should hide the header from upper layer code in this case.
>
> This should probably be a separate commit

OK. I'll make it a separate commit in the next version of the series. Thanks!

> Does it make sense to define a struct snap_hdr instead of manually
> casting all these bytes?

> And macros or constant integers to self document these kinds of fields.

Yes, we can define a struct snap_hdr, like this:

struct snap_hdr {
        u8 oui[3];
        __be16 pid;
} __packed;

And then the fr_snap_parse function could be like this:

static int fr_snap_parse(struct sk_buff *skb, struct pvc_device *pvc)
{
       struct snap_hdr *hdr = (struct snap_hdr *)skb->data;

       if (hdr->oui[0] == OUI_ETHERTYPE_1 &&
           hdr->oui[1] == OUI_ETHERTYPE_2 &&
           hdr->oui[2] == OUI_ETHERTYPE_3) {
               if (!pvc->main)
                       return -1;
               skb->dev = pvc->main;
               skb->protocol = hdr->pid; /* Ethertype */
               skb_pull(skb, 5);
               skb_reset_mac_header(skb);
               return 0;

       } else if (hdr->oui[0] == OUI_802_1_1 &&
                  hdr->oui[1] == OUI_802_1_2 &&
                  hdr->oui[2] == OUI_802_1_3) {
               if (hdr->pid == htons(PID_ETHER_WO_FCS)) {

Would this look cleaner?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype
  2020-10-29 23:53     ` Xie He
@ 2020-10-30  0:49       ` Xie He
  2020-10-30  0:53         ` Willem de Bruijn
  2020-10-30  0:50       ` Willem de Bruijn
  1 sibling, 1 reply; 10+ messages in thread
From: Xie He @ 2020-10-30  0:49 UTC (permalink / raw)
  To: Willem de Bruijn
  Cc: Jakub Kicinski, David S. Miller, Network Development,
	linux-kernel, Krzysztof Halasa

On Thu, Oct 29, 2020 at 4:53 PM Xie He <xie.he.0141@gmail.com> wrote:
>
> > Does it make sense to define a struct snap_hdr instead of manually
> > casting all these bytes?
>
> > And macros or constant integers to self document these kinds of fields.
>
> Yes, we can define a struct snap_hdr, like this:
>
> struct snap_hdr {
>         u8 oui[3];
>         __be16 pid;
> } __packed;
>
> And then the fr_snap_parse function could be like this:
>
> static int fr_snap_parse(struct sk_buff *skb, struct pvc_device *pvc)
> {
>        struct snap_hdr *hdr = (struct snap_hdr *)skb->data;
>
>        if (hdr->oui[0] == OUI_ETHERTYPE_1 &&
>            hdr->oui[1] == OUI_ETHERTYPE_2 &&
>            hdr->oui[2] == OUI_ETHERTYPE_3) {
>                if (!pvc->main)
>                        return -1;
>                skb->dev = pvc->main;
>                skb->protocol = hdr->pid; /* Ethertype */
>                skb_pull(skb, 5);
>                skb_reset_mac_header(skb);
>                return 0;
>
>        } else if (hdr->oui[0] == OUI_802_1_1 &&
>                   hdr->oui[1] == OUI_802_1_2 &&
>                   hdr->oui[2] == OUI_802_1_3) {
>                if (hdr->pid == htons(PID_ETHER_WO_FCS)) {
>
> Would this look cleaner?

Actually I don't think this is significantly cleaner than the previous
version of code. A reader of this code may still wonder what are the
values of all these macros, and he/she may still want to look up the
values of them. The comment in the previous version of code has made
the meaning of these values very clear, and the reader of the code
would not need to go to another place of this file to find the values.

The struct snap_hdr eliminates a cast, but only one cast. So it might
not be very necessary, either. Introducing this struct also makes the
reader need to go to another place of this file to look up the
definition of this struct. So it does not significantly improve the
readability (IMHO).

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype
  2020-10-29 23:53     ` Xie He
  2020-10-30  0:49       ` Xie He
@ 2020-10-30  0:50       ` Willem de Bruijn
  1 sibling, 0 replies; 10+ messages in thread
From: Willem de Bruijn @ 2020-10-30  0:50 UTC (permalink / raw)
  To: Xie He
  Cc: Willem de Bruijn, Jakub Kicinski, David S. Miller,
	Network Development, linux-kernel, Krzysztof Halasa

On Thu, Oct 29, 2020 at 7:53 PM Xie He <xie.he.0141@gmail.com> wrote:
>
> On Thu, Oct 29, 2020 at 10:24 AM Willem de Bruijn
> <willemdebruijn.kernel@gmail.com> wrote:
> >
> > > Also add skb_reset_mac_header before we pass an skb (received on normal
> > > PVC devices) to upper layers. Because we don't use header_ops for normal
> > > PVC devices, we should hide the header from upper layer code in this case.
> >
> > This should probably be a separate commit
>
> OK. I'll make it a separate commit in the next version of the series. Thanks!
>
> > Does it make sense to define a struct snap_hdr instead of manually
> > casting all these bytes?
>
> > And macros or constant integers to self document these kinds of fields.
>
> Yes, we can define a struct snap_hdr, like this:
>
> struct snap_hdr {
>         u8 oui[3];
>         __be16 pid;
> } __packed;
>
> And then the fr_snap_parse function could be like this:
>
> static int fr_snap_parse(struct sk_buff *skb, struct pvc_device *pvc)
> {
>        struct snap_hdr *hdr = (struct snap_hdr *)skb->data;
>
>        if (hdr->oui[0] == OUI_ETHERTYPE_1 &&
>            hdr->oui[1] == OUI_ETHERTYPE_2 &&
>            hdr->oui[2] == OUI_ETHERTYPE_3) {
>                if (!pvc->main)
>                        return -1;
>                skb->dev = pvc->main;
>                skb->protocol = hdr->pid; /* Ethertype */
>                skb_pull(skb, 5);
>                skb_reset_mac_header(skb);
>                return 0;
>
>        } else if (hdr->oui[0] == OUI_802_1_1 &&
>                   hdr->oui[1] == OUI_802_1_2 &&
>                   hdr->oui[2] == OUI_802_1_3) {
>                if (hdr->pid == htons(PID_ETHER_WO_FCS)) {
>
> Would this look cleaner?

Oh, right. The OUI being 3 bytes introduces masking and endianness
issues if casting to a wider type. Similar to IPv6 flowlabel handling,
for instance.

There is a lot of OUI code, such as cea_db_is_hdmi_forum_vsdb. But no
standard way of going about this. Some does byte-by-byte, some memcmp,
some masks.

The existing is probably as concise and readable as anything, and we
don't really care about a few extra branches here. Never mind this
suggestion.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype
  2020-10-30  0:49       ` Xie He
@ 2020-10-30  0:53         ` Willem de Bruijn
  0 siblings, 0 replies; 10+ messages in thread
From: Willem de Bruijn @ 2020-10-30  0:53 UTC (permalink / raw)
  To: Xie He
  Cc: Willem de Bruijn, Jakub Kicinski, David S. Miller,
	Network Development, linux-kernel, Krzysztof Halasa

On Thu, Oct 29, 2020 at 8:49 PM Xie He <xie.he.0141@gmail.com> wrote:
>
> On Thu, Oct 29, 2020 at 4:53 PM Xie He <xie.he.0141@gmail.com> wrote:
> >
> > > Does it make sense to define a struct snap_hdr instead of manually
> > > casting all these bytes?
> >
> > > And macros or constant integers to self document these kinds of fields.
> >
> > Yes, we can define a struct snap_hdr, like this:
> >
> > struct snap_hdr {
> >         u8 oui[3];
> >         __be16 pid;
> > } __packed;
> >
> > And then the fr_snap_parse function could be like this:
> >
> > static int fr_snap_parse(struct sk_buff *skb, struct pvc_device *pvc)
> > {
> >        struct snap_hdr *hdr = (struct snap_hdr *)skb->data;
> >
> >        if (hdr->oui[0] == OUI_ETHERTYPE_1 &&
> >            hdr->oui[1] == OUI_ETHERTYPE_2 &&
> >            hdr->oui[2] == OUI_ETHERTYPE_3) {
> >                if (!pvc->main)
> >                        return -1;
> >                skb->dev = pvc->main;
> >                skb->protocol = hdr->pid; /* Ethertype */
> >                skb_pull(skb, 5);
> >                skb_reset_mac_header(skb);
> >                return 0;
> >
> >        } else if (hdr->oui[0] == OUI_802_1_1 &&
> >                   hdr->oui[1] == OUI_802_1_2 &&
> >                   hdr->oui[2] == OUI_802_1_3) {
> >                if (hdr->pid == htons(PID_ETHER_WO_FCS)) {
> >
> > Would this look cleaner?
>
> Actually I don't think this is significantly cleaner than the previous
> version of code. A reader of this code may still wonder what are the
> values of all these macros, and he/she may still want to look up the
> values of them. The comment in the previous version of code has made
> the meaning of these values very clear, and the reader of the code
> would not need to go to another place of this file to find the values.
>
> The struct snap_hdr eliminates a cast, but only one cast. So it might
> not be very necessary, either. Introducing this struct also makes the
> reader need to go to another place of this file to look up the
> definition of this struct. So it does not significantly improve the
> readability (IMHO).

Thanks for coding up an example. Yes, seeing the alternative, I agree.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-10-30  0:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-28 13:18 [PATCH net-next v2 0/4] net: hdlc_fr: Add support for any Ethertype Xie He
2020-10-28 13:18 ` [PATCH net-next v2 1/4] net: hdlc_fr: Simpify fr_rx by using "goto rx_drop" to drop frames Xie He
2020-10-28 13:18 ` [PATCH net-next v2 2/4] net: hdlc_fr: Change the use of "dev" in fr_rx to make the code cleaner Xie He
2020-10-28 13:18 ` [PATCH net-next v2 3/4] net: hdlc_fr: Improve the initial check when we receive an skb Xie He
2020-10-28 13:18 ` [PATCH net-next v2 4/4] net: hdlc_fr: Add support for any Ethertype Xie He
2020-10-29 17:23   ` Willem de Bruijn
2020-10-29 23:53     ` Xie He
2020-10-30  0:49       ` Xie He
2020-10-30  0:53         ` Willem de Bruijn
2020-10-30  0:50       ` Willem de Bruijn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.