From: Roman Khromenok <roma55592@yandex.ru>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
Thomas Monjalon <thomas@monjalon.net>,
Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Subject: [PATCH v3 3/6] ethdev: check module EEPROM length before decoding
Date: Tue, 29 Sep 2026 09:07:31 +0200 [thread overview]
Message-ID: <20260929070734.1106134-4-roma55592@yandex.ru> (raw)
In-Reply-To: <20260929070734.1106134-1-roma55592@yandex.ru>
The SFF-8079 and SFF-8472 decoders do not receive the buffer length
and assume it is large enough for the module type.
This holds for the telemetry command, which allocates the length
reported by the driver, but not for other callers.
Move the type dispatch into a common internal function which checks
the minimal length for each type before decoding:
- SFF-8079 and SFF-8436/8636 require at least 256 bytes,
- SFF-8472 requires 256 bytes for the base information,
and the diagnostics (page A2h) are decoded only if 512 bytes
are available.
Also decode the SFF-8636 thresholds and alarm flags when the data
is longer than 640 bytes, not only when it is exactly 640 bytes.
This is a preparation for exposing the decoders to applications.
Signed-off-by: Roman Khromenok <roma55592@yandex.ru>
---
v3: SFF-8636 fix moved to patch 1, decode thresholds for length >= 640
lib/ethdev/sff_8636.c | 2 +-
lib/ethdev/sff_common.c | 31 +++++++++++++++++++++++++++++++
lib/ethdev/sff_common.h | 8 ++++++++
lib/ethdev/sff_telemetry.c | 21 +++++----------------
4 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/lib/ethdev/sff_8636.c b/lib/ethdev/sff_8636.c
index bbd00cc0ca..40e5404caf 100644
--- a/lib/ethdev/sff_8636.c
+++ b/lib/ethdev/sff_8636.c
@@ -656,7 +656,7 @@ static void sff_8636_show_dom(const uint8_t *data, uint32_t eeprom_len, struct s
* If pagging support exists, then supports_alarms is marked as 1
*/
- if (eeprom_len == RTE_ETH_MODULE_SFF_8636_MAX_LEN) {
+ if (eeprom_len >= RTE_ETH_MODULE_SFF_8636_MAX_LEN) {
if (!(data[SFF_8636_STATUS_2_OFFSET] &
SFF_8636_STATUS_PAGE_3_PRESENT)) {
sd.supports_alarms = 1;
diff --git a/lib/ethdev/sff_common.c b/lib/ethdev/sff_common.c
index 1b48c0f6ea..a36bf83026 100644
--- a/lib/ethdev/sff_common.c
+++ b/lib/ethdev/sff_common.c
@@ -4,6 +4,7 @@
* common utilities for SFF-8436/8636 and SFF-8472/8079
*/
+#include <errno.h>
#include <math.h>
#include "sff_common.h"
@@ -14,6 +15,36 @@ void sff_output_field(struct sff_output *d, const char *name_str,
d->field_cb(name_str, value_str, d->arg);
}
+int sff_decode_module_eeprom(uint32_t type, const uint8_t *data, uint32_t length,
+ struct sff_output *d)
+{
+ switch (type) {
+ case RTE_ETH_MODULE_SFF_8079:
+ if (length < RTE_ETH_MODULE_SFF_8079_LEN)
+ return -EINVAL;
+ sff_8079_show_all(data, d);
+ break;
+ case RTE_ETH_MODULE_SFF_8472:
+ if (length < RTE_ETH_MODULE_SFF_8079_LEN)
+ return -EINVAL;
+ sff_8079_show_all(data, d);
+ /* diagnostics are in the second page (A2h) */
+ if (length >= RTE_ETH_MODULE_SFF_8472_LEN)
+ sff_8472_show_all(data, d);
+ break;
+ case RTE_ETH_MODULE_SFF_8436:
+ case RTE_ETH_MODULE_SFF_8636:
+ if (length < RTE_ETH_MODULE_SFF_8636_LEN)
+ return -EINVAL;
+ sff_8636_show_all(data, length, d);
+ break;
+ default:
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
double sff_convert_mw_to_dbm(double mw)
{
return (10. * log10(mw / 1000.)) + 30.;
diff --git a/lib/ethdev/sff_common.h b/lib/ethdev/sff_common.h
index 06f5a35e8e..6435f4d6f5 100644
--- a/lib/ethdev/sff_common.h
+++ b/lib/ethdev/sff_common.h
@@ -34,6 +34,14 @@ void sff_8472_show_all(const uint8_t *data, struct sff_output *d);
/* SFF-8636 Optics diagnostics */
void sff_8636_show_all(const uint8_t *data, uint32_t eeprom_len, struct sff_output *d);
+/*
+ * Decode module EEPROM of the given type (RTE_ETH_MODULE_SFF_*).
+ * Returns 0 on success, -EINVAL if the data is too short for the type,
+ * -ENOTSUP if the type is unknown.
+ */
+int sff_decode_module_eeprom(uint32_t type, const uint8_t *data, uint32_t length,
+ struct sff_output *d);
+
#define SFF_8024_ID_OFFSET 0x00
#define SFF_8024_ID_UNKNOWN 0x00
#define SFF_8024_ID_GBIC 0x01
diff --git a/lib/ethdev/sff_telemetry.c b/lib/ethdev/sff_telemetry.c
index 06a8122367..46533a9fc5 100644
--- a/lib/ethdev/sff_telemetry.c
+++ b/lib/ethdev/sff_telemetry.c
@@ -100,23 +100,12 @@ sff_port_module_eeprom_parse(uint16_t port_id, struct rte_tel_data *d)
return;
}
- switch (minfo.type) {
- /* parsing module EEPROM data base on different module type */
- case RTE_ETH_MODULE_SFF_8079:
- sff_8079_show_all(einfo.data, &out);
- break;
- case RTE_ETH_MODULE_SFF_8472:
- sff_8079_show_all(einfo.data, &out);
- sff_8472_show_all(einfo.data, &out);
- break;
- case RTE_ETH_MODULE_SFF_8436:
- case RTE_ETH_MODULE_SFF_8636:
- sff_8636_show_all(einfo.data, einfo.length, &out);
- break;
- default:
+ ret = sff_decode_module_eeprom(minfo.type, einfo.data, einfo.length, &out);
+ if (ret == -ENOTSUP)
RTE_ETHDEV_LOG_LINE(NOTICE, "Unsupported module type: %u", minfo.type);
- break;
- }
+ else if (ret != 0)
+ RTE_ETHDEV_LOG_LINE(ERR, "Port %u module EEPROM is too short: %u bytes",
+ port_id, einfo.length);
free(einfo.data);
}
--
2.47.3
next prev parent reply other threads:[~2026-09-29 7:08 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-27 11:20 [PATCH 0/4] ethdev: add API to decode module EEPROM Roman Khromenok
2026-09-27 11:20 ` [PATCH 1/4] ethdev: decouple SFF module EEPROM decoders from telemetry Roman Khromenok
2026-09-27 11:20 ` [PATCH 2/4] ethdev: check module EEPROM length before decoding Roman Khromenok
2026-09-27 11:20 ` [PATCH 3/4] ethdev: add API to decode module EEPROM Roman Khromenok
2026-09-27 11:20 ` [PATCH 4/4] test: add ethdev module EEPROM decoding tests Roman Khromenok
2026-09-28 8:47 ` [PATCH v2 0/4] ethdev: add API to decode module EEPROM Roman Khromenok
2026-09-28 8:47 ` [PATCH v2 1/4] ethdev: decouple SFF module EEPROM decoders from telemetry Roman Khromenok
2026-09-28 8:47 ` [PATCH v2 2/4] ethdev: check module EEPROM length before decoding Roman Khromenok
2026-09-28 8:47 ` [PATCH v2 3/4] ethdev: add API to decode module EEPROM Roman Khromenok
2026-09-28 8:47 ` [PATCH v2 4/4] test: add ethdev module EEPROM decoding tests Roman Khromenok
2026-09-28 18:11 ` [PATCH v2 0/4] ethdev: add API to decode module EEPROM Stephen Hemminger
2026-09-29 7:07 ` [PATCH v3 0/6] " Roman Khromenok
2026-09-29 7:07 ` [PATCH v3 1/6] ethdev: fix out-of-bounds read of SFF-8636 thresholds Roman Khromenok
2026-09-29 7:07 ` [PATCH v3 2/6] ethdev: decouple SFF module EEPROM decoders from telemetry Roman Khromenok
2026-09-29 7:07 ` Roman Khromenok [this message]
2026-09-29 7:07 ` [PATCH v3 4/6] ethdev: avoid unaligned access in SFF-8472 decoder Roman Khromenok
2026-09-29 7:07 ` [PATCH v3 5/6] ethdev: add API to decode module EEPROM Roman Khromenok
2026-09-29 7:07 ` [PATCH v3 6/6] test: add ethdev module EEPROM decoding tests Roman Khromenok
2026-09-29 16:02 ` [PATCH v3 0/6] ethdev: add API to decode module EEPROM Stephen Hemminger
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=20260929070734.1106134-4-roma55592@yandex.ru \
--to=roma55592@yandex.ru \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=dev@dpdk.org \
--cc=stephen@networkplumber.org \
--cc=thomas@monjalon.net \
/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