+++ /dev/null
-From 7d298976beff0cce310fb53a430f82b53f43a394 Mon Sep 17 00:00:00 2001
-From: Guy Harris <gharris@sonic.net>
-Date: Fri, 14 Feb 2025 19:12:24 -0800
-Subject: [PATCH 2/2] Linux: handle other DSA tags.
-
-Many of those entries need their own LINKTYPE_/DLT_? values, including
-tcpdump and Wireshark support for same, but at least this lets you see
-raw hex data from a capture.
-
-Fixes #1367.
-
-Supercedes #1451.
----
- pcap-linux.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 280 insertions(+), 4 deletions(-)
-
---- a/pcap-linux.c
-+++ b/pcap-linux.c
-@@ -5267,23 +5267,299 @@ iface_get_offload(pcap_t *handle _U_)
- }
- #endif /* SIOCETHTOOL */
-
-+/*
-+ * As per
-+ *
-+ * https://www.kernel.org/doc/html/latest/networking/dsa/dsa.html#switch-tagging-protocols
-+ *
-+ * Type 1 means that the tag is prepended to the Ethernet packet.
-+ * LINKTYPE_ETHERNET/DLT_EN10MB doesn't work, as it would try to
-+ * dissect the tag data as the Ethernet header. These should get
-+ * their own LINKTYPE_DLT_ values.
-+ *
-+ * Type 2 means that the tag is inserted into the Ethernet header
-+ * after the source address and before the type/length field.
-+ *
-+ * Type 3 means that tag is a packet trailer. LINKTYPE_ETHERNET/DLT_EN10MB
-+ * works, unless the next-layer protocol has no length field of its own,
-+ * so that the tag might be treated as part of the payload. These should
-+ * get their own LINKTYPE_/DLT_ values.
-+ *
-+ * If you get an "unsupported DSA tag" error, please add the tag to here,
-+ * complete with a full comment indicating whether it's type 1, 2, or 3,
-+ * and, for type 2, indicating whether it has an Ethertype and, if so
-+ * what that type is, and whether it's registered with the IEEE or is
-+ * self-assigned. Also, point to *something* that indicates the format
-+ * of the tag.
-+ */
- static struct dsa_proto {
- const char *name;
- bpf_u_int32 linktype;
- } dsa_protos[] = {
- /*
-- * None is special and indicates that the interface does not have
-- * any tagging protocol configured, and is therefore a standard
-- * Ethernet interface.
-+ * Type 1. See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ar9331.c
-+ */
-+ { "ar9331", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, without an Ethertype at the beginning,
-+ * assigned a LINKTYPE_/DLT_ value.
- */
-- { "none", DLT_EN10MB },
- { "brcm", DLT_DSA_TAG_BRCM },
-+
-+ /*
-+ * Type 2, with Ethertype 0x8874, assigned to Broadcom.
-+ *
-+ * This doies not require a LINKTYPE_/DLT_ value, it
-+ * just requires that Ethertype 0x8874 be dissected
-+ * properly.
-+ */
-+ { "brcm-legacy", DLT_EN10MB },
-+
-+ /*
-+ * Type 1.
-+ */
- { "brcm-prepend", DLT_DSA_TAG_BRCM_PREPEND },
-+
-+ /*
-+ * Type 2, without an Etherype at he beginning,
-+ * assigned a LINKTYPE_/DLT_ value.
-+ */
- { "dsa", DLT_DSA_TAG_DSA },
-+
-+ /*
-+ * Type 2, with an Ethertype field, but without
-+ * an assigned Ethertype value that can be relied
-+ * on; assigned a LINKTYPE_/DLT_ value.
-+ */
- { "edsa", DLT_DSA_TAG_EDSA },
-+
-+ /*
-+ * Type 1, with different transmit and receive headers,
-+ * so can't really be handled well with the current
-+ * libpcap API and with pcap files. Use DLT_LINUX_SLL,
-+ * to get the direction?
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_gswip.c
-+ */
-+ { "gswip", DLT_EN10MB },
-+
-+ /*
-+ * Type 3. See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_hellcreek.c
-+ */
-+ { "hellcreek", DLT_EN10MB },
-+
-+ /*
-+ * Type 3, with different transmit and receive headers,
-+ * so can't really be handled well with the current
-+ * libpcap API and with pcap files. Use DLT_LINUX_SLL,
-+ * to get the direction?
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L102
-+ */
-+ { "ksz8795", DLT_EN10MB },
-+
-+ /*
-+ * Type 3, with different transmit and receive headers,
-+ * so can't really be handled well with the current
-+ * libpcap API and with pcap files. Use DLT_LINUX_SLL,
-+ * to get the direction?
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L160
-+ */
-+ { "ksz9477", DLT_EN10MB },
-+
-+ /*
-+ * Type 3, with different transmit and receive headers,
-+ * so can't really be handled well with the current
-+ * libpcap API and with pcap files. Use DLT_LINUX_SLL,
-+ * to get the direction?
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L341
-+ */
-+ { "ksz9893", DLT_EN10MB },
-+
-+ /*
-+ * Type 3, with different transmit and receive headers,
-+ * so can't really be handled well with the current
-+ * libpcap API and with pcap files. Use DLT_LINUX_SLL,
-+ * to get the direction?
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ksz.c#L386
-+ */
-+ { "lan937x", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, with Ethertype 0x8100; the VID can be interpreted
-+ * as per
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_lan9303.c#L24
-+ *
-+ * so giving its own LINKTYPE_/DLT_ value would allow a
-+ * dissector to do so.
-+ */
-+ { "lan9303", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, without an Etherype at he beginning,
-+ * should be assigned a LINKTYPE_/DLT_ value.
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_mtk.c#L15
-+ */
-+ { "mtk", DLT_EN10MB },
-+
-+ /*
-+ * None is special and indicates that the interface does not have
-+ * any tagging protocol configured, and is therefore a standard
-+ * Ethernet interface.
-+ */
-+ { "none", DLT_EN10MB },
-+
-+ /*
-+ * Type 1.
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ocelot.c
-+ */
-+ { "ocelot", DLT_EN10MB },
-+
-+ /*
-+ * Type 1.
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_ocelot.c
-+ */
-+ { "seville", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, with Ethertype 0x8100; the VID can be interpreted
-+ * as per
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15
-+ *
-+ * so giving its own LINKTYPE_/DLT_ value would allow a
-+ * dissector to do so.
-+ */
-+ { "ocelot-8021q", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, without an Etherype at he beginning,
-+ * should be assigned a LINKTYPE_/DLT_ value.
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_qca.c
-+ */
-+ { "qca", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, with Ethertype 0x8899, assigned to Realtek;
-+ * they use it for several on-the-Ethernet protocols
-+ * as well, but there are fields that allow the two
-+ * tag formats, and all the protocols in question,
-+ * to be distinguiished from one another.
-+ *
-+ * This doies not require a LINKTYPE_/DLT_ value, it
-+ * just requires that Ethertype 0x8899 be dissected
-+ * properly.
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_rtl4_a.c
-+ *
-+ * http://realtek.info/pdf/rtl8306sd%28m%29_datasheet_1.1.pdf
-+ *
-+ * and various pages in tcpdump's print-realtek.c and Wireshark's
-+ * epan/dissectors/packet-realtek.c for the other protocols.
-+ */
- { "rtl4a", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, with Ethertype 0x8899, assigned to Realtek;
-+ * see above.
-+ */
- { "rtl8_4", DLT_EN10MB },
-+
-+ /*
-+ * Type 3, with the same tag format as rtl8_4.
-+ */
- { "rtl8_4t", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, with Ethertype 0xe001; that's probably
-+ * self-assigned, so this really should ahve its
-+ * own LINKTYPE_/DLT_ value.
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_rzn1_a5psw.c
-+ */
-+ { "a5psw", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, with Ethertype 0x8100 or the self-assigned
-+ * 0xdadb, so this really should ahve its own
-+ * LINKTYPE_/DLT_ value; that would also allow the
-+ * VID of the tag to be dissected as per
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15
-+ */
-+ { "sja1105", DLT_EN10MB },
-+
-+ /*
-+ * Type "none of the above", with both a header and trailer,
-+ * with different transmit and receive tags. Has
-+ * Ethertype 0xdadc, which is probably self-assigned.
-+ * This should really have its own LINKTYPE_/DLT_ value.
-+ */
-+ { "sja1110", DLT_EN10MB },
-+
-+ /*
-+ * Type 3, as the name suggests.
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_trailer.c
-+ */
-+ { "trailer", DLT_EN10MB },
-+
-+ /*
-+ * Type 2, with Ethertype 0x8100; the VID can be interpreted
-+ * as per
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_8021q.c#L15
-+ *
-+ * so giving its own LINKTYPE_/DLT_ value would allow a
-+ * dissector to do so.
-+ */
-+ { "vsc73xx-8021q", DLT_EN10MB },
-+
-+ /*
-+ * Type 3.
-+ *
-+ * See
-+ *
-+ * https://elixir.bootlin.com/linux/v6.13.2/source/net/dsa/tag_xrs700x.c
-+ */
-+ { "xrs700x", DLT_EN10MB },
- };
-
- static int
#endif
--- a/gencode.c
+++ b/gencode.c
-@@ -58,6 +58,8 @@
+@@ -51,6 +51,8 @@
#include "sunatmpos.h"
#include "pflog.h"
#include "ppp.h"
#include "pcap/sll.h"
#include "pcap/ipnet.h"
#include "arcnet.h"
-@@ -9704,6 +9706,168 @@ gen_geneve(compiler_state_t *cstate, bpf
+@@ -9846,6 +9848,168 @@ gen_geneve(compiler_state_t *cstate, bpf
return b1;
}
struct block *gen_atmtype_abbrev(compiler_state_t *, int);
--- a/grammar.y.in
+++ b/grammar.y.in
-@@ -383,6 +383,7 @@ DIAG_OFF_BISON_BYACC
+@@ -370,6 +370,7 @@ DIAG_OFF_BISON_BYACC
%type <i> mtp2type
%type <blk> mtp3field
%type <blk> mtp3fieldvalue mtp3value mtp3listvalue
%token DST SRC HOST GATEWAY
-@@ -401,7 +402,7 @@ DIAG_OFF_BISON_BYACC
+@@ -388,7 +389,7 @@ DIAG_OFF_BISON_BYACC
%token LEN
%token IPV6 ICMPV6 AH ESP
%token VLAN MPLS
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
%token STP
%token IPX
-@@ -698,11 +699,40 @@ other: pqual TK_BROADCAST { CHECK_PTR_
+@@ -685,11 +686,40 @@ other: pqual TK_BROADCAST { CHECK_PTR_
| PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }
| GENEVE pnum { CHECK_PTR_VAL(($$ = gen_geneve(cstate, $2, 1))); }
| GENEVE { CHECK_PTR_VAL(($$ = gen_geneve(cstate, 0, 0))); }
| PF_RNR NUM { CHECK_PTR_VAL(($$ = gen_pf_rnr(cstate, $2))); }
--- a/nametoaddr.c
+++ b/nametoaddr.c
-@@ -134,8 +134,12 @@
+@@ -109,8 +109,12 @@
#include "diag-control.h"
#include "nametoaddr.h"
#include "thread-local.h"
-@@ -597,6 +601,7 @@ PCAP_API_DEF struct eproto eproto_db[] =
+@@ -572,6 +576,7 @@ PCAP_API_DEF struct eproto eproto_db[] =
{ "moprc", ETHERTYPE_MOPRC },
{ "rarp", ETHERTYPE_REVARP },
{ "sca", ETHERTYPE_SCA },
{ (char *)0, 0 }
};
-@@ -631,6 +636,60 @@ pcap_nametollc(const char *s)
+@@ -606,6 +611,60 @@ pcap_nametollc(const char *s)
while (p->s != 0) {
if (strcmp(p->s, s) == 0)
* If a protocol is unknown, PROTO_UNDEF is returned.
--- a/scanner.l
+++ b/scanner.l
-@@ -365,6 +365,7 @@ mpls return MPLS;
+@@ -343,6 +343,7 @@ mpls return MPLS;
pppoed return PPPOED;
pppoes return PPPOES;
geneve return GENEVE;