diff --git a/.github/ISSUE_TEMPLATE/release-template.md b/.github/ISSUE_TEMPLATE/release-template.md
index 1487cfb0a..2ce829fb1 100644
--- a/.github/ISSUE_TEMPLATE/release-template.md
+++ b/.github/ISSUE_TEMPLATE/release-template.md
@@ -67,7 +67,7 @@ bin/harvest generate metrics --poller POLLERNAME
### The day of the release
-- [ ] Create a new build from [Jenkins](http://harvest-jenkins.rtp.openenglab.netapp.com:8080/job/harvest2_0/job/BuildHarvestArtifacts/) ([details](https://github.com/NetApp/harvest-private/wiki/Release-Checklist#jenkins))
+- [ ] Create a new build from [Jenkins](http://harvest-ci.rtp.openenglab.netapp.com:8080/job/harvest2_0/job/BuildHarvestArtifacts/) ([details](https://github.com/NetApp/harvest-private/wiki/Release-Checklist#jenkins))
- [ ] Click `Build with Parameters` and fill in the appropriate fields. Here's an example, where `RELEASE=23.02.0`
| Field | Value |
diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml
index 99a5fc8e7..93a8bb735 100644
--- a/.github/workflows/zizmor.yml
+++ b/.github/workflows/zizmor.yml
@@ -22,7 +22,7 @@ jobs:
persist-credentials: false
- name: Install the latest version of uv
- uses: astral-sh/setup-uv@0d20755a2389f8ddbd3ad4f8a536309a4db22de9
+ uses: astral-sh/setup-uv@b49dc9e8821aa6e5df06b85779f66761402a1787
- name: Run zizmor 🌈
run: uvx zizmor --format sarif . > results.sarif
diff --git a/.harvest.env b/.harvest.env
index 6cb6cc90b..0bf7ccd71 100644
--- a/.harvest.env
+++ b/.harvest.env
@@ -1 +1 @@
-GO_VERSION=1.25.3
\ No newline at end of file
+GO_VERSION=1.25.4
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9655682fb..423caaf70 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,205 @@
# Change Log
## [Releases](https://github.com/NetApp/harvest/releases)
-## 25.11.0 / 2025-11- Release
-Volume performance metrics changes: https://github.com/NetApp/harvest/discussions/3900
+## 25.11.0 / 2025-11-10 Release
+:pushpin: Highlights of this major release include:
+## :star: New Features
+
+- :medal_sports: We've created a [Harvest Model Context Protocol](https://netapp.github.io/harvest/latest/mcp/overview/) (MCP) server. The Harvest MCP server provides MCP clients like GitHub Copilot, Claude Desktop, and other large language models (LLMs) access to your infrastructure monitoring data collected by Harvest from ONTAP, StorageGRID, and Cisco systems.
+
+- :fire: Harvest supports monitoring NetApp AFX clusters with this release. Performance metrics with the API name KeyPerf or StatPerf in the [ONTAP metrics documentation](https://netapp.github.io/harvest/latest/ontap-metrics/) are supported in AFX systems. As a result, some panels in the dashboards may be missing information.
+
+- :gem: New dashboards and additional panels:
+ - Harvest includes an ASAr2 dashboard with storage units and SAN initiator group panels.
+ - Harvest includes a StorageGRID S3 dashboard. Thanks to @ofu48167 for raising!
+ - Harvest includes a Hosts dashboard with SAN initiator groups. Thanks to @CJLvU for raising!
+ - Harvest collects FlexCache metrics from FSx.
+ - The StorageGRID Tenants dashboard includes tenant descriptions and bucket versioning. Thanks to @jowanw for raising!
+ - The Volume dashboard includes an autosize table panel. Thanks to @roybatty2019 for raising!
+ - The Network dashboard shows all ethernet port errors. Thanks to RobertWatson for raising!
+ - The Datacenter dashboard includes a System Manager panel with links to ONTAP System Manager. Thanks to Ed Barron for raising!
+ - The Data Protection dashboard includes a Snapshot Policy Violations panel that shows the number of snapshots outside the defined policy scope. Thanks to Lora NeyMan for raising!
+ - The Volume dashboard includes panels on hot and cold data. Thanks to prime_kiwi_05259 for raising!
+ - The Snapmirror Destination dashboard includes a "TopN Destination Volumes by Average Throughput" panel. Thanks to @roybatty2019 for raising!
+ - The Volume dashboard includes a Snaplock panel. Thanks to @BrendonA667 for raising!
+ - The MetroCluster dashboard includes IWarp and NVM mirror metrics. Thanks to @mamoep for raising!
+ - The Security dashboard includes an anti-ransomware snapshots table. Thanks to @ybizeul for raising!
+ - The Workload dashboard includes min IOPs and workload size in the adaptive QoS workload table. Thanks to Paqui for raising!
+ - The LUN dashboard includes a LUN's block size in the LUN table. Thanks to Venumadhu for raising!
+
+- :ear_of_rice: `harvest grafana import` includes a new command-line interface option (`show-datasource`) to show the datasource variable dropdown in dashboards, useful for multi-datasource setups. Thanks to @RockSolidScripts for raising!
+
+- `harvest grafana import` includes a new command-line interface option (`add-cluster-label`) to rewrite all panel expressions to add the specified cluster label and variable. Thanks to @RockSolidScripts for raising!
+
+- :closed_book: Documentation additions:
+ - Added a tutorial for how to include StorageGRID-supplied dashboards into Harvest. Thanks to @ofu48167 for raising!
+ - Included [ONTAP permissions](https://netapp.github.io/harvest/latest/prepare-cdot-clusters/#statperf-least-privilege-role) required for the [StatPerf collector](https://netapp.github.io/harvest/latest/configure-statperf/).
+ - Clarified which APIs are used to collect each metric.
+ - Clarified that the StatPerf collector does not work for FSx clusters due to ONTAP limitations.
+
+- Harvest reports node-scoped metrics even when some nodes are down.
+
+- Harvest's poller includes a `/health` endpoint for liveness checks. Thanks to @RockSolidScripts for raising!
+
+- The FcpPort and NicCommon templates work with the StatPerf collector. This means the Network dashboard works with AFX and ASAr2 clusters.
+
+## Announcements
+
+:bangbang: **IMPORTANT** We've made changes to how volume performance metrics are collected. These changes are automatic and require no action from you unless you've customized Harvest's default `volume.yaml` templates. Continue reading for more details on the reasons behind this change and how to accommodate it.
+
+By default, Harvest will now use the `KeyPerf` collector for volume performance metrics. This better aligns with ONTAP's recommendations and what System Manager shows.
+
+The `default.yaml` files for `ZapiPerf` and `RestPerf` now include a `KeyPerf:` prefix for the volume template (e.g., `KeyPerf:volume.yaml`). This instructs Harvest to use the `KeyPerf` collector for volumes. More details are available at: #3900
+
+:bangbang: **IMPORTANT** If you are using Docker Compose and want to keep your historical Prometheus data, please
+read [how to migrate your Prometheus volume](https://github.com/NetApp/harvest/blob/main/docs/MigratePrometheusDocker.md).
+
+:bulb: **IMPORTANT** After upgrading, don't forget to re-import your dashboards to get all the new enhancements and fixes. You can import them via the `bin/harvest grafana import` CLI, from the Grafana UI, or from the 'Maintenance > Reset Harvest Dashboards' button in NAbox3. For NAbox4, this step is not needed.
+
+## Known Issues
+
+- #3941 disabled the `restperf/volume_node.yaml` and `zapiperf/volume_node.yaml` templates because ONTAP provided incomplete metrics for them. The `node_vol` prefixed metrics are not used in any Harvest dashboard. If you still need these metrics, you can re-enable the templates in their corresponding `default.yaml`. See #3900 for details.
+
+## Thanks to all the awesome contributors
+:metal: Thanks to all the people who've opened issues, asked questions on Discord, and contributed code or dashboards for this release:
+
+@BrendonA667, @CJLvU, @Falcon667, @RockSolidScripts, @jowanw, @mamoep, @ofu48167, @roybatty2019, @ybizeul
+
+:seedling: This release includes 34 features, 20 bug fixes, 17 documentation, 1 testing, 8 refactoring, 21 miscellaneous, and 14 ci pull requests.
+
+
+Expand for full list of pull requests
+### :rocket: Features
+- Allow Partial Aggregation For Node Scoped Objects ([#3811](https://github.com/NetApp/harvest/pull/3811))
+- Grafana Import Should Include Option To Show Datasource Var ([#3830](https://github.com/NetApp/harvest/pull/3830))
+- Adding Description And Versioning Enable In Tenant Dashboard ([#3833](https://github.com/NetApp/harvest/pull/3833))
+- Adding Volume Autosize Details In Volume Dashboard ([#3851](https://github.com/NetApp/harvest/pull/3851))
+- Network Dashboard Ethernet Port Errors Should Show All Errors ([#3852](https://github.com/NetApp/harvest/pull/3852))
+- Datacenter Dashboard Should Include Links To System Manager ([#3853](https://github.com/NetApp/harvest/pull/3853))
+- Monitor Snapshot Policy Compliance ([#3857](https://github.com/NetApp/harvest/pull/3857))
+- Display Hot/Cold Data Of Volumes ([#3858](https://github.com/NetApp/harvest/pull/3858))
+- Adding Storage-Units Rest Call In Asar2 ([#3867](https://github.com/NetApp/harvest/pull/3867))
+- Adding Availability-Zones Rest Call In Asar2 ([#3870](https://github.com/NetApp/harvest/pull/3870))
+- Harvest Should Load Asar2 Templates When Monitoring Asar2 Clusters ([#3871](https://github.com/NetApp/harvest/pull/3871))
+- Add Health Endpoint To Harvest Poller ([#3879](https://github.com/NetApp/harvest/pull/3879))
+- Adding Total Throughput Panel Of Destination Volume Of Sm-Sv ([#3880](https://github.com/NetApp/harvest/pull/3880))
+- Collect Volume Snaplock Information ([#3883](https://github.com/NetApp/harvest/pull/3883))
+- Adding Nvm_mirror Zapiperf Object And Removed Read_ops And Ops From Iwarp ([#3884](https://github.com/NetApp/harvest/pull/3884))
+- Honour Volume Filter In Top Client/File In Volume ([#3888](https://github.com/NetApp/harvest/pull/3888))
+- Harvest Mcp ([#3895](https://github.com/NetApp/harvest/pull/3895))
+- Asar2 Storage Unit Dashboard ([#3898](https://github.com/NetApp/harvest/pull/3898))
+- Use Keyperf Collector For Volume Performance Metrics ([#3909](https://github.com/NetApp/harvest/pull/3909))
+- Include Node Model In Aggregate Dashboard ([#3929](https://github.com/NetApp/harvest/pull/3929))
+- Arw Snapshot Template With Private Cli ([#3933](https://github.com/NetApp/harvest/pull/3933))
+- Adding Static Counter File For Keyperf Asar2 Folder ([#3934](https://github.com/NetApp/harvest/pull/3934))
+- Adding Min Iops And Workload Size In Adaptive Qos ([#3937](https://github.com/NetApp/harvest/pull/3937))
+- Storagegrid S3 Dashboard ([#3940](https://github.com/NetApp/harvest/pull/3940))
+- Disable Volumenode Metrics ([#3941](https://github.com/NetApp/harvest/pull/3941))
+- Adding Unique Type Field In Metroclustercheck ([#3948](https://github.com/NetApp/harvest/pull/3948))
+- Add Mcp Tool Details ([#3950](https://github.com/NetApp/harvest/pull/3950))
+- Cluster-Label Flag Adds New Cluster Var/Label And Update All Panels ([#3955](https://github.com/NetApp/harvest/pull/3955))
+- Add Plugins For Statperf Collector ([#3969](https://github.com/NetApp/harvest/pull/3969))
+- Root Volume Enable/Disable Handled In Template ([#3975](https://github.com/NetApp/harvest/pull/3975))
+- Include Tiering_minimum_cooling_days In Volume Template ([#3977](https://github.com/NetApp/harvest/pull/3977))
+- Adding Block_size In Lun Perf ([#3982](https://github.com/NetApp/harvest/pull/3982))
+- Add Nic And Fcp Port Support In Statperf ([#3989](https://github.com/NetApp/harvest/pull/3989))
+- Hosts Dashboard ([#3994](https://github.com/NetApp/harvest/pull/3994))
+
+### :bug: Bug Fixes
+- Check Asup For All Pollers In Docker-Ci ([#3836](https://github.com/NetApp/harvest/pull/3836))
+- Don't Fail Poller Startup When Zapi Is Disabled ([#3839](https://github.com/NetApp/harvest/pull/3839))
+- Handle Ha Alerts For Non Ha Nodes ([#3881](https://github.com/NetApp/harvest/pull/3881))
+- Cluster Label Rewriting Should Not Modify Metrics That Contain T… ([#3896](https://github.com/NetApp/harvest/pull/3896))
+- Ignore Empty Templates ([#3911](https://github.com/NetApp/harvest/pull/3911))
+- Indent Aggregate Json ([#3932](https://github.com/NetApp/harvest/pull/3932))
+- Remove Cdot Tags From Storagegrid Fabricpool Dashboard ([#3938](https://github.com/NetApp/harvest/pull/3938))
+- Include User And Group Columns In Quota Dashboard ([#3944](https://github.com/NetApp/harvest/pull/3944))
+- Update Flexgroup Latency To 0 In Case Of No Ops ([#3952](https://github.com/NetApp/harvest/pull/3952))
+- Handle Workload Filter Batch And Instance Removal ([#3958](https://github.com/NetApp/harvest/pull/3958))
+- Handle Afx Ha Error ([#3960](https://github.com/NetApp/harvest/pull/3960))
+- Disable `Latency_io_reqd` ([#3963](https://github.com/NetApp/harvest/pull/3963))
+- Join With Group_left And Adding Workload Field ([#3968](https://github.com/NetApp/harvest/pull/3968))
+- Auditlog Dashboard Duplicate Count In Victoriametrics ([#3973](https://github.com/NetApp/harvest/pull/3973))
+- Fix Versioning Mapping In Dashboard ([#4000](https://github.com/NetApp/harvest/pull/4000))
+- Correct Query With Group_left ([#4001](https://github.com/NetApp/harvest/pull/4001))
+- Harvest Target File Should Use Soft Dependency ([#4002](https://github.com/NetApp/harvest/pull/4002))
+- Cisco Lldp Should Handle Instances With The Same Chassisid ([#4004](https://github.com/NetApp/harvest/pull/4004))
+- Storagegrid Cached Credential Script Tokens Not Expired On 401 ([#4010](https://github.com/NetApp/harvest/pull/4010))
+- Statperf Multi Line Handling ([#4017](https://github.com/NetApp/harvest/pull/4017))
+
+### :closed_book: Documentation
+- Remove Invalid Api Url From Permissions ([#3835](https://github.com/NetApp/harvest/pull/3835))
+- Fix Asar2 Spelling ([#3906](https://github.com/NetApp/harvest/pull/3906))
+- Mcp Documentation ([#3916](https://github.com/NetApp/harvest/pull/3916))
+- Update Readme To Mention Mcp ([#3923](https://github.com/NetApp/harvest/pull/3923))
+- Use Consistent Role Name In Documentation ([#3928](https://github.com/NetApp/harvest/pull/3928))
+- Add Configuration Link For Mcp ([#3931](https://github.com/NetApp/harvest/pull/3931))
+- Update Statperf Permissions ([#3949](https://github.com/NetApp/harvest/pull/3949))
+- Update Volume Metric Doc ([#3954](https://github.com/NetApp/harvest/pull/3954))
+- Update Ontap Metrics With Actual Api ([#3956](https://github.com/NetApp/harvest/pull/3956))
+- Tutorial To Add Storagegrid Supplied Dashboards Into Harvest ([#3957](https://github.com/NetApp/harvest/pull/3957))
+- Add Afx Testing In Release Checklist ([#3961](https://github.com/NetApp/harvest/pull/3961))
+- Build From Source Instructions For Mcp ([#3964](https://github.com/NetApp/harvest/pull/3964))
+- Add Nabox4 Config Collection ([#3978](https://github.com/NetApp/harvest/pull/3978))
+- Remove Statperf For Fsx ([#3981](https://github.com/NetApp/harvest/pull/3981))
+- Add Log File Location Change Steps To Quickstart ([#3993](https://github.com/NetApp/harvest/pull/3993))
+- Add Flexcache As Supported With Fsx ([#4005](https://github.com/NetApp/harvest/pull/4005))
+- Update Metric Docs ([#4014](https://github.com/NetApp/harvest/pull/4014))
+
+### :wrench: Testing
+- Use Asserts In Tests ([#3863](https://github.com/NetApp/harvest/pull/3863))
+
+### Refactoring
+- Rename Tag Mapper Part 1 ([#3864](https://github.com/NetApp/harvest/pull/3864))
+- Rename Tag Mapper Part 2 ([#3865](https://github.com/NetApp/harvest/pull/3865))
+- Rename Asar2 Dashboard To Overview ([#3920](https://github.com/NetApp/harvest/pull/3920))
+- Only Check If Zapis Exist When A Zapi Collector Is Desired ([#3921](https://github.com/NetApp/harvest/pull/3921))
+- Only Check If Zapis Exist When A Zapi Collector Is Desired ([#3924](https://github.com/NetApp/harvest/pull/3924))
+- Add Debug Logging For Rest Href ([#3943](https://github.com/NetApp/harvest/pull/3943))
+- Remove Checksum Generation Since Github Provides Digests Now ([#3983](https://github.com/NetApp/harvest/pull/3983))
+- Use Strings.builder To Improve Performance ([#3984](https://github.com/NetApp/harvest/pull/3984))
+
+### Miscellaneous
+- Merge Release/25.08.0 To Main ([#3831](https://github.com/NetApp/harvest/pull/3831))
+- Update All Dependencies ([#3841](https://github.com/NetApp/harvest/pull/3841))
+- Merge Release/25.08.1 To Main ([#3848](https://github.com/NetApp/harvest/pull/3848))
+- Update All Dependencies ([#3856](https://github.com/NetApp/harvest/pull/3856))
+- Track Upstream Gopsutil Changes ([#3872](https://github.com/NetApp/harvest/pull/3872))
+- Go Bump ([#3873](https://github.com/NetApp/harvest/pull/3873))
+- Update All Dependencies ([#3876](https://github.com/NetApp/harvest/pull/3876))
+- Update Astral-Sh/Setup-Uv Digest To B75a909 ([#3887](https://github.com/NetApp/harvest/pull/3887))
+- Update Astral-Sh/Setup-Uv Digest To 208B0c0 ([#3903](https://github.com/NetApp/harvest/pull/3903))
+- Update All Dependencies ([#3918](https://github.com/NetApp/harvest/pull/3918))
+- Track Upstream Gopsutil Changes ([#3922](https://github.com/NetApp/harvest/pull/3922))
+- Update All Dependencies ([#3930](https://github.com/NetApp/harvest/pull/3930))
+- Bump Go ([#3936](https://github.com/NetApp/harvest/pull/3936))
+- Update All Dependencies ([#3945](https://github.com/NetApp/harvest/pull/3945))
+- Update All Dependencies ([#3965](https://github.com/NetApp/harvest/pull/3965))
+- Update All Dependencies ([#3971](https://github.com/NetApp/harvest/pull/3971))
+- Bump Modelcontextprotocol/Go-Sdk ([#3987](https://github.com/NetApp/harvest/pull/3987))
+- Update All Dependencies ([#3991](https://github.com/NetApp/harvest/pull/3991))
+- Bump Modelcontextprotocol/Go-Sdk ([#3996](https://github.com/NetApp/harvest/pull/3996))
+- Track Upstream Gopsutil Changes ([#3997](https://github.com/NetApp/harvest/pull/3997))
+- Update Jenkins Href To New Server ([#4015](https://github.com/NetApp/harvest/pull/4015))
+
+### :hammer: CI
+- Update Integration Dependency ([#3818](https://github.com/NetApp/harvest/pull/3818))
+- Bump Go ([#3834](https://github.com/NetApp/harvest/pull/3834))
+- Disable Fips Check For Clusters That Don't Support Fips ([#3837](https://github.com/NetApp/harvest/pull/3837))
+- Update Makefile Go Version ([#3850](https://github.com/NetApp/harvest/pull/3850))
+- Fix Ci Issues ([#3877](https://github.com/NetApp/harvest/pull/3877))
+- Enable The Gopls Modernize Analyzer ([#3890](https://github.com/NetApp/harvest/pull/3890))
+- Update Mcp Version ([#3913](https://github.com/NetApp/harvest/pull/3913))
+- Mcp Container Publish ([#3914](https://github.com/NetApp/harvest/pull/3914))
+- Bump Go ([#3951](https://github.com/NetApp/harvest/pull/3951))
+- Reduce Nightly Build Time ([#3953](https://github.com/NetApp/harvest/pull/3953))
+- Add Sha File To Nightly Builds ([#3980](https://github.com/NetApp/harvest/pull/3980))
+- Update Ci Machine ([#3985](https://github.com/NetApp/harvest/pull/3985))
+- Bump Go ([#4008](https://github.com/NetApp/harvest/pull/4008))
+- Handle Renovate[Bot] Pull Requests In Changelog ([#4012](https://github.com/NetApp/harvest/pull/4012))
+
+---
## 25.08.1 / 2025-08-18 Release
:pushpin: This release is the same as version 25.08.0, with a fix for an issue where the ONTAP REST collector fails to start if ZAPIs are disabled on the cluster.
diff --git a/cmd/collectors/cisco/plugins/lldp/lldp.go b/cmd/collectors/cisco/plugins/lldp/lldp.go
index a280f2e9f..867d65bc4 100644
--- a/cmd/collectors/cisco/plugins/lldp/lldp.go
+++ b/cmd/collectors/cisco/plugins/lldp/lldp.go
@@ -7,6 +7,7 @@ import (
"github.com/netapp/harvest/v2/pkg/collector"
"github.com/netapp/harvest/v2/pkg/conf"
"github.com/netapp/harvest/v2/pkg/matrix"
+ "github.com/netapp/harvest/v2/pkg/slogx"
"github.com/netapp/harvest/v2/third_party/tidwall/gjson"
"log/slog"
"slices"
@@ -23,6 +24,7 @@ type LLDP struct {
matrix *matrix.Matrix
client *rest.Client
templateObject string // object name from the template
+ RemoteSerial string
}
func New(p *plugin.AbstractPlugin) plugin.Plugin {
@@ -50,6 +52,7 @@ func (l *LLDP) Init(remote conf.Remote) error {
}
l.client = client
+ l.RemoteSerial = client.Remote().Serial
l.templateObject = l.ParentParams.GetChildContentS("object")
l.matrix = matrix.New(l.Parent+".LLDP", l.templateObject, l.templateObject)
@@ -118,10 +121,10 @@ func (l *LLDP) parseLLDP(output gjson.Result, mat *matrix.Matrix) {
})
for _, model := range models {
- instanceKey := model.ChassisID
+ instanceKey := model.ChassisID + "-" + model.LocalPort
instance, err := mat.NewInstance(instanceKey)
if err != nil {
- l.SLogger.Warn("Failed to create lldp instance", slog.String("key", instanceKey))
+ l.SLogger.Warn("Failed to create lldp instance", slog.String("key", instanceKey), slogx.Err(err))
continue
}
@@ -131,7 +134,7 @@ func (l *LLDP) parseLLDP(output gjson.Result, mat *matrix.Matrix) {
instance.SetLabel("local_port", model.LocalPort)
instance.SetLabel("remote_port", model.RemotePort)
instance.SetLabel("capabilities", strings.Join(model.Capabilities, ","))
- instance.SetLabel("local_platform", l.client.Remote().Serial)
+ instance.SetLabel("local_platform", l.RemoteSerial)
mat.GetMetric(labels).SetValueFloat64(instance, 1.0)
}
diff --git a/cmd/collectors/cisco/plugins/lldp/lldp_test.go b/cmd/collectors/cisco/plugins/lldp/lldp_test.go
index 99be29aac..8676a0b7f 100644
--- a/cmd/collectors/cisco/plugins/lldp/lldp_test.go
+++ b/cmd/collectors/cisco/plugins/lldp/lldp_test.go
@@ -3,7 +3,10 @@ package lldp
import (
"github.com/google/go-cmp/cmp"
"github.com/netapp/harvest/v2/assert"
+ "github.com/netapp/harvest/v2/cmd/poller/plugin"
+ "github.com/netapp/harvest/v2/pkg/matrix"
"github.com/netapp/harvest/v2/third_party/tidwall/gjson"
+ "log/slog"
"os"
"testing"
)
@@ -43,3 +46,20 @@ func TestNewLLDPModel(t *testing.T) {
})
}
}
+
+func TestParse(t *testing.T) {
+ // Read the file from the testdata directory
+ filename := "testdata/lldp2.json"
+ data, err := os.ReadFile(filename)
+ assert.Nil(t, err)
+
+ result := gjson.ParseBytes(data)
+ output := result.Get("ins_api.outputs")
+ l := New(&plugin.AbstractPlugin{SLogger: slog.Default()}).(*LLDP)
+
+ m := matrix.New("lldp", "lldp", "lldp")
+ _, _ = m.NewMetricFloat64("labels")
+ l.parseLLDP(output, m)
+
+ assert.Equal(t, len(m.GetInstances()), 13)
+}
diff --git a/cmd/collectors/cisco/plugins/lldp/testdata/lldp2.json b/cmd/collectors/cisco/plugins/lldp/testdata/lldp2.json
new file mode 100644
index 000000000..0c0e3e59e
--- /dev/null
+++ b/cmd/collectors/cisco/plugins/lldp/testdata/lldp2.json
@@ -0,0 +1,323 @@
+{
+ "ins_api": {
+ "type": "cli_show_array",
+ "version": "1.0",
+ "sid": "eoc",
+ "outputs": {
+ "output": {
+ "input": "show lldp neighbors detail",
+ "msg": "Success",
+ "code": "200",
+ "body": {
+ "neigh_hdr": "neigh_hdr",
+ "TABLE_nbor_detail": {
+ "ROW_nbor_detail": [
+ {
+ "chassis_type": "Mac Address",
+ "chassis_id": "10b3.d566.3bd3",
+ "port_type": "Interface Name",
+ "port_id": "Ethernet1/44",
+ "l_port_id": "mgmt0",
+ "port_desc": "Ethernet1/44",
+ "sys_name": "sa-tme-flexpod-3048TP-gg28-01",
+ "sys_desc": "Cisco Nexus Operating System (NX-OS) Software 9.3(7)\nTAC support: http://www.cisco.com/tac\nCopyright (c) 2002-2021, Cisco Systems, Inc. All rights reserved.",
+ "ttl": 101,
+ "system_capability": "B, R",
+ "enabled_capability": "B, R",
+ "mgmt_addr_type": "IPV4",
+ "mgmt_addr": "10.192.116.11",
+ "mgmt_addr_ipv6_type": "802",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "817",
+ "max_framesize": "not advertised",
+ "vlan_name": "not advertised",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Mac Address",
+ "chassis_id": "d039.ea53.77ed",
+ "port_type": "Interface Name",
+ "port_id": "e4b",
+ "l_port_id": "Eth1/1",
+ "port_desc": "null",
+ "sys_name": "sa-tme-flexpod-afx-c1-01",
+ "sys_desc": "AFX-A900, NetApp Release R9.18.1xN_251015_0400: Wed Oct 15 06:48:40 EDT 2025 ",
+ "ttl": 93,
+ "system_capability": "S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "Address not advertised",
+ "mgmt_addr": "not advertised",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "not advertised",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Mac Address",
+ "chassis_id": "d039.ea48.2f19",
+ "port_type": "Interface Name",
+ "port_id": "e2b",
+ "l_port_id": "Eth1/2",
+ "port_desc": "null",
+ "sys_name": "sa-tme-flexpod-afx-c2-01",
+ "sys_desc": "AFX-A900, NetApp Release R9.18.1xN_251015_0400: Wed Oct 15 06:48:40 EDT 2025 ",
+ "ttl": 93,
+ "system_capability": "S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "Address not advertised",
+ "mgmt_addr": "not advertised",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "not advertised",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Mac Address",
+ "chassis_id": "d039.ea48.2f19",
+ "port_type": "Interface Name",
+ "port_id": "e10b",
+ "l_port_id": "Eth1/18",
+ "port_desc": "null",
+ "sys_name": "sa-tme-flexpod-afx-c2-01",
+ "sys_desc": "AFX-A900, NetApp Release R9.18.1xN_251015_0400: Wed Oct 15 06:48:40 EDT 2025 ",
+ "ttl": 93,
+ "system_capability": "S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "Address not advertised",
+ "mgmt_addr": "not advertised",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "not advertised",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Locally Assigned",
+ "chassis_id": "localhost.localdomain",
+ "port_type": "Interface Name",
+ "port_id": "e0b",
+ "l_port_id": "Eth1/21",
+ "port_desc": "d0:39:ea:b2:ab:dc",
+ "sys_name": "021918000242",
+ "sys_desc": "NetApp NS224.NSM100.SH10.A (v.E715)",
+ "ttl": 99,
+ "system_capability": "B, W, R, S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "IPV4",
+ "mgmt_addr": "0.0.0.0",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "30: vlan30",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Locally Assigned",
+ "chassis_id": "localhost.localdomain",
+ "port_type": "Interface Name",
+ "port_id": "e0b",
+ "l_port_id": "Eth1/22",
+ "port_desc": "d0:39:ea:b6:cf:e0",
+ "sys_name": "021918000242",
+ "sys_desc": "NetApp NS224.NSM100.SH10.B (v.E715)",
+ "ttl": 98,
+ "system_capability": "B, W, R, S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "IPV4",
+ "mgmt_addr": "0.0.0.0",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "30: vlan30",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Locally Assigned",
+ "chassis_id": "localhost.localdomain",
+ "port_type": "Interface Name",
+ "port_id": "e0b",
+ "l_port_id": "Eth1/24",
+ "port_desc": "00:a0:98:fa:89:89",
+ "sys_name": "SHFFG1906000236",
+ "sys_desc": "NetApp NS224.NSM100.SH13.A (v.E715)",
+ "ttl": 119,
+ "system_capability": "B, W, R, S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "IPV4",
+ "mgmt_addr": "0.0.0.0",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "30: vlan30",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Locally Assigned",
+ "chassis_id": "localhost.localdomain",
+ "port_type": "Interface Name",
+ "port_id": "e0b",
+ "l_port_id": "Eth1/25",
+ "port_desc": "d0:39:ea:25:ba:83",
+ "sys_name": "042017000925",
+ "sys_desc": "NetApp NS224.NSM100.SH04.A (v.E715)",
+ "ttl": 108,
+ "system_capability": "B, W, R, S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "IPV4",
+ "mgmt_addr": "0.0.0.0",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "30: vlan30",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Locally Assigned",
+ "chassis_id": "localhost.localdomain",
+ "port_type": "Interface Name",
+ "port_id": "e0b",
+ "l_port_id": "Eth1/26",
+ "port_desc": "d0:39:ea:25:8f:9e",
+ "sys_name": "042017000925",
+ "sys_desc": "NetApp NS224.NSM100.SH04.B (v.E715)",
+ "ttl": 97,
+ "system_capability": "B, W, R, S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "IPV4",
+ "mgmt_addr": "0.0.0.0",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "30: vlan30",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Mac Address",
+ "chassis_id": "d039.ea48.2f19",
+ "port_type": "Interface Name",
+ "port_id": "e4b",
+ "l_port_id": "Eth1/27",
+ "port_desc": "null",
+ "sys_name": "sa-tme-flexpod-afx-c2-01",
+ "sys_desc": "AFX-A900, NetApp Release R9.18.1xN_251015_0400: Wed Oct 15 06:48:40 EDT 2025 ",
+ "ttl": 93,
+ "system_capability": "S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "Address not advertised",
+ "mgmt_addr": "not advertised",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "not advertised",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Mac Address",
+ "chassis_id": "d039.ea48.2f19",
+ "port_type": "Interface Name",
+ "port_id": "e4a",
+ "l_port_id": "Eth1/28",
+ "port_desc": "null",
+ "sys_name": "sa-tme-flexpod-afx-c2-01",
+ "sys_desc": "AFX-A900, NetApp Release R9.18.1xN_251015_0400: Wed Oct 15 06:48:40 EDT 2025 ",
+ "ttl": 93,
+ "system_capability": "S",
+ "enabled_capability": "S",
+ "mgmt_addr_type": "Address not advertised",
+ "mgmt_addr": "not advertised",
+ "mgmt_addr_ipv6_type": "Address not advertised",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "not advertised",
+ "max_framesize": "not advertised",
+ "vlan_name": "not advertised",
+ "link_agg_capability": "not advertised",
+ "link_agg_status": "not advertised",
+ "link_agg_id": 0
+ },
+ {
+ "chassis_type": "Mac Address",
+ "chassis_id": "d4c9.3cc0.790a",
+ "port_type": "Interface Name",
+ "port_id": "Ethernet1/35",
+ "l_port_id": "Eth1/35",
+ "port_desc": "LOCAL_ISL Switch 100G Port",
+ "sys_name": "sa-tme-flexpod-9336-fx2-gg28-02",
+ "sys_desc": "Cisco Nexus Operating System (NX-OS) Software 10.3(4a)\nTAC support: http://www.cisco.com/tac\nCopyright (c) 2002-2023, Cisco Systems, Inc. All rights reserved.",
+ "ttl": 98,
+ "system_capability": "B, R",
+ "enabled_capability": "B, R",
+ "mgmt_addr_type": "IPV4",
+ "mgmt_addr": "10.192.116.26",
+ "mgmt_addr_ipv6_type": "802",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "1",
+ "max_framesize": "1500",
+ "vlan_name": "1: default, 17: VLAN0017, 18: VLAN0018, 30: VLAN0030, 40: VLAN0040",
+ "link_agg_capability": "enabled",
+ "link_agg_status": "aggregated",
+ "link_agg_id": 1,
+ "dc_uuid": "FDO22451KY5"
+ },
+ {
+ "chassis_type": "Mac Address",
+ "chassis_id": "d4c9.3cc0.790e",
+ "port_type": "Interface Name",
+ "port_id": "Ethernet1/36",
+ "l_port_id": "Eth1/36",
+ "port_desc": "LOCAL_ISL Switch 100G Port",
+ "sys_name": "sa-tme-flexpod-9336-fx2-gg28-02",
+ "sys_desc": "Cisco Nexus Operating System (NX-OS) Software 10.3(4a)\nTAC support: http://www.cisco.com/tac\nCopyright (c) 2002-2023, Cisco Systems, Inc. All rights reserved.",
+ "ttl": 98,
+ "system_capability": "B, R",
+ "enabled_capability": "B, R",
+ "mgmt_addr_type": "IPV4",
+ "mgmt_addr": "10.192.116.26",
+ "mgmt_addr_ipv6_type": "802",
+ "mgmt_addr_ipv6": "not advertised",
+ "vlan_id": "1",
+ "max_framesize": "1500",
+ "vlan_name": "1: default, 17: VLAN0017, 18: VLAN0018, 30: VLAN0030, 40: VLAN0040",
+ "link_agg_capability": "enabled",
+ "link_agg_status": "aggregated",
+ "link_agg_id": 1,
+ "dc_uuid": "FDO22451KY5"
+ }
+ ]
+ },
+ "neigh_count": 13
+ }
+ }
+ }
+ }
+}
diff --git a/cmd/collectors/statperf/parser.go b/cmd/collectors/statperf/parser.go
index cc4586bfa..78b060550 100644
--- a/cmd/collectors/statperf/parser.go
+++ b/cmd/collectors/statperf/parser.go
@@ -324,21 +324,66 @@ func (s *StatPerf) parseRows(input string) ([]map[string]any, error) {
}
// Check for continuation lines.
+ // For single-token lines: use indent to determine counter vs value continuation
+ // For multi-token lines: check if merging with counter creates a valid counter name
var cb strings.Builder
cb.WriteString(counter)
for i+1 < len(tableLines) {
nextLineRaw := tableLines[i+1]
nextTokens := strings.Fields(nextLineRaw)
- if len(nextTokens) != 1 {
+ if len(nextTokens) == 0 || strings.Contains(nextLineRaw, "entries were displayed") {
break
}
+
indent := getIndent(nextLineRaw)
- if dividerWidth > 0 && indent < dividerWidth {
- cb.WriteString(nextTokens[0])
+
+ if len(nextTokens) == 1 {
+ // Single token: use indent to determine counter vs value continuation
+ if dividerWidth > 0 && indent < dividerWidth {
+ cb.WriteString(nextTokens[0])
+ } else {
+ valueBuilder.WriteString(nextTokens[0])
+ }
+ i++
} else {
- valueBuilder.WriteString(nextTokens[0])
+ // Multiple tokens: could be new row or continuation
+ leftPart := ""
+ if dividerWidth > 0 && len(nextLineRaw) > dividerWidth {
+ leftPart = strings.TrimSpace(nextLineRaw[:dividerWidth])
+ } else if indent < dividerWidth {
+ leftPart = nextTokens[0]
+ }
+
+ if leftPart != "" {
+ // Check if this would create a valid counter
+ potentialCounter := cb.String() + leftPart
+ if s.perfProp != nil && s.perfProp.counterInfo != nil {
+ // Check if left part + current counter forms a valid counter name
+ if _, exists := s.perfProp.counterInfo[potentialCounter]; exists {
+ // Valid counter continuation
+ cb.WriteString(leftPart)
+ // If there's also right part, add to value
+ if dividerWidth > 0 && len(nextLineRaw) > dividerWidth {
+ rightPart := strings.TrimSpace(nextLineRaw[dividerWidth:])
+ if rightPart != "" {
+ valueBuilder.WriteString(rightPart)
+ }
+ }
+ i++
+ continue
+ }
+ }
+ }
+
+ // Not a counter continuation - check if it's a value continuation
+ if dividerWidth > 0 && indent >= dividerWidth {
+ valueBuilder.WriteString(strings.TrimSpace(nextLineRaw))
+ i++
+ } else {
+ // Must be a new row - stop
+ break
+ }
}
- i++
}
counter = cb.String()
value := valueBuilder.String()
diff --git a/cmd/collectors/statperf/parser_test.go b/cmd/collectors/statperf/parser_test.go
index 5070a1a4a..378d2ba99 100644
--- a/cmd/collectors/statperf/parser_test.go
+++ b/cmd/collectors/statperf/parser_test.go
@@ -7,6 +7,7 @@ import (
"log/slog"
"os"
"slices"
+ "strings"
"testing"
)
@@ -362,3 +363,224 @@ flexcache_per_volume·Test·blocks_requested_from_client·637069129383·`,
})
}
}
+
+func TestParseRows_MultiLineContinuations(t *testing.T) {
+ tests := []struct {
+ name string
+ input string
+ expectedGroups int
+ expectedCounter string
+ expectedCounterValue string
+ expectedInstanceValue string
+ }{
+ {
+ name: "single_token_value_continuation",
+ input: `Object: volume
+Instance: test_volume
+Start-time: 11/7/2025 10:00:00
+End-time: 11/7/2025 10:00:00
+Scope: cluster-01
+
+ Counter Value
+ -------------------------------- --------------------------------
+ instance_name trident_pvc_12d750da_fd62_4f3a_
+ a711_70688b3844cb
+ read_data 104KB
+3 entries were displayed.`,
+ expectedGroups: 1,
+ expectedCounter: "instance_name",
+ expectedInstanceValue: "trident_pvc_12d750da_fd62_4f3a_a711_70688b3844cb",
+ },
+ {
+ name: "multi_token_value_continuation",
+ input: `Object: nvm_mirror
+Instance: NVM Mirror
+Start-time: 11/7/2025 12:16:52
+End-time: 11/7/2025 12:16:52
+Scope: sa-tme-flexpod-a800-rdma-01
+
+ Counter Value
+ -------------------------------- --------------------------------
+ instance_name NVM Mirror
+ instance_uuid sa-tme-flexpod-a800-rdma-01:
+ kernel:NVM Mirror
+ node_name sa-tme-flexpod-a800-rdma-01
+4 entries were displayed.`,
+ expectedGroups: 1,
+ expectedCounter: "instance_uuid",
+ expectedInstanceValue: "sa-tme-flexpod-a800-rdma-01:kernel:NVM Mirror",
+ },
+ {
+ name: "single_token_counter_continuation",
+ input: `Object: volume
+Instance: test_volume
+Start-time: 11/7/2025 10:00:00
+End-time: 11/7/2025 10:00:00
+Scope: cluster-01
+
+ Counter Value
+ -------------------------------- --------------------------------
+ instance_name test_volume
+ wvblk_saved_fsinfo_private_inos_ 1638
+ reserve
+3 entries were displayed.`,
+ expectedGroups: 1,
+ expectedCounter: "wvblk_saved_fsinfo_private_inos_reserve",
+ expectedCounterValue: "1638",
+ },
+ {
+ name: "multiple_instances_with_continuations",
+ input: `Object: nvm_mirror
+Instance: NVM Mirror
+Start-time: 11/7/2025 12:16:52
+End-time: 11/7/2025 12:16:52
+Scope: sa-tme-flexpod-a800-rdma-01
+
+ Counter Value
+ -------------------------------- --------------------------------
+ instance_name NVM Mirror
+ instance_uuid sa-tme-flexpod-a800-rdma-01:
+ kernel:NVM Mirror
+ write_throughput 13847639326958
+
+Object: nvm_mirror
+Instance: NVM Mirror
+Start-time: 11/7/2025 12:16:52
+End-time: 11/7/2025 12:16:52
+Scope: sa-tme-flexpod-a800-rdma-02
+
+ Counter Value
+ -------------------------------- --------------------------------
+ instance_name NVM Mirror
+ instance_uuid sa-tme-flexpod-a800-rdma-02:
+ kernel:NVM Mirror
+ write_throughput 629627001678
+8 entries were displayed.`,
+ expectedGroups: 2,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ s := &StatPerf{
+ Rest: &rest2.Rest{
+ AbstractCollector: &collector.AbstractCollector{},
+ },
+ }
+ s.Logger = slog.Default()
+ s.perfProp = &perfProp{
+ counterInfo: map[string]*counter{
+ "instance_name": {name: "instance_name"},
+ "instance_uuid": {name: "instance_uuid"},
+ "node_name": {name: "node_name"},
+ "write_throughput": {name: "write_throughput"},
+ "read_data": {name: "read_data"},
+ "wvblk_saved_fsinfo_private_inos_reserve": {name: "wvblk_saved_fsinfo_private_inos_reserve"},
+ },
+ }
+
+ groups, err := s.parseRows(tc.input)
+ assert.Nil(t, err)
+ assert.Equal(t, len(groups), tc.expectedGroups)
+
+ if tc.expectedCounter != "" {
+ found := false
+ for _, group := range groups {
+ val, ok := group[tc.expectedCounter]
+ if !ok {
+ continue
+ }
+ found = true
+ valStr, _ := val.(string)
+ if tc.expectedCounterValue != "" {
+ assert.Equal(t, valStr, tc.expectedCounterValue)
+ }
+ if tc.expectedInstanceValue != "" {
+ assert.Equal(t, valStr, tc.expectedInstanceValue)
+ }
+ break
+ }
+ assert.True(t, found)
+ }
+ })
+ }
+}
+
+func TestParseRows_BothCounterAndValueContinuation(t *testing.T) {
+ // Test case where a continuation line has content in both columns
+ input := `Object: volume
+Instance: test_volume
+Start-time: 11/7/2025 10:00:00
+End-time: 11/7/2025 10:00:00
+Scope: cluster-01
+
+ Counter Value
+ -------------------------------- --------------------------------
+ very_long_counter_name_that_sp some_very_long_v
+ ans_multiple_lines alue_text_here
+ normal_counter 12345
+3 entries were displayed.`
+
+ s := &StatPerf{
+ Rest: &rest2.Rest{
+ AbstractCollector: &collector.AbstractCollector{},
+ },
+ }
+ s.Logger = slog.Default()
+ s.perfProp = &perfProp{
+ counterInfo: map[string]*counter{
+ "very_long_counter_name_that_spans_multiple_lines": {name: "very_long_counter_name_that_spans_multiple_lines"},
+ "normal_counter": {name: "normal_counter"},
+ },
+ }
+
+ groups, err := s.parseRows(input)
+ assert.Nil(t, err)
+ assert.Equal(t, len(groups), 1)
+
+ val1, ok1 := groups[0]["very_long_counter_name_that_spans_multiple_lines"]
+ assert.True(t, ok1)
+ assert.Equal(t, val1, "some_very_long_value_text_here")
+
+ val2, ok2 := groups[0]["normal_counter"]
+ assert.True(t, ok2)
+ assert.Equal(t, val2, "12345")
+}
+
+func TestParseRows_EntriesDisplayedLine(t *testing.T) {
+ input := `Object: volume
+Instance: test_volume
+Start-time: 11/7/2025 10:00:00
+End-time: 11/7/2025 10:00:00
+Scope: cluster-01
+
+ Counter Value
+ -------------------------------- --------------------------------
+ instance_name test_volume
+ read_data 104KB
+2 entries were displayed.`
+
+ s := &StatPerf{
+ Rest: &rest2.Rest{
+ AbstractCollector: &collector.AbstractCollector{},
+ },
+ }
+ s.Logger = slog.Default()
+ s.perfProp = &perfProp{
+ counterInfo: map[string]*counter{
+ "instance_name": {name: "instance_name"},
+ "read_data": {name: "read_data"},
+ },
+ }
+
+ groups, err := s.parseRows(input)
+ assert.Nil(t, err)
+ assert.Equal(t, len(groups), 1)
+
+ val, ok := groups[0]["read_data"]
+ assert.True(t, ok)
+ assert.Equal(t, val, "104KB")
+ valStr, isString := val.(string)
+ assert.True(t, isString)
+ assert.False(t, strings.Contains(valStr, "entries"))
+}
diff --git a/cmd/collectors/statperf/statperf_test.go b/cmd/collectors/statperf/statperf_test.go
index 67e8a7940..a97c46815 100644
--- a/cmd/collectors/statperf/statperf_test.go
+++ b/cmd/collectors/statperf/statperf_test.go
@@ -278,3 +278,24 @@ func processAndCookCounters(s *StatPerf, pollData []gjson.Result, prevMat *matri
got, err := s.cookCounters(curMat, prevMat)
return got, metricCount, err
}
+
+func TestParseRows_MultiLineInstanceUUID(t *testing.T) {
+ s := newStatPerf("nvm_mirror", "nvm_mirror.yaml")
+
+ content, err := os.ReadFile("testdata/nvm_mirror_data.txt")
+ assert.Nil(t, err)
+
+ groups, err := s.parseRows(string(content))
+ assert.Nil(t, err)
+ assert.Equal(t, len(groups), 2)
+
+ assert.Equal(t, groups[0]["instance_name"], "NVM Mirror")
+ assert.Equal(t, groups[0]["instance_uuid"], "sa-tme-flexpod-a800-rdma-01:kernel:NVM Mirror")
+ assert.Equal(t, groups[0]["node_name"], "sa-tme-flexpod-a800-rdma-01")
+ assert.Equal(t, groups[0]["write_throughput"], "13847639326958")
+
+ assert.Equal(t, groups[1]["instance_name"], "NVM Mirror")
+ assert.Equal(t, groups[1]["instance_uuid"], "sa-tme-flexpod-a800-rdma-02:kernel:NVM Mirror")
+ assert.Equal(t, groups[1]["node_name"], "sa-tme-flexpod-a800-rdma-02")
+ assert.Equal(t, groups[1]["write_throughput"], "629627001678")
+}
diff --git a/cmd/collectors/statperf/testdata/nvm_mirror_data.txt b/cmd/collectors/statperf/testdata/nvm_mirror_data.txt
new file mode 100644
index 000000000..4e28f1116
--- /dev/null
+++ b/cmd/collectors/statperf/testdata/nvm_mirror_data.txt
@@ -0,0 +1,33 @@
+Last login time: 11/7/2025 10:37:26
+
+
+
+
+Object: nvm_mirror
+Instance: NVM Mirror
+Start-time: 11/7/2025 12:16:52
+End-time: 11/7/2025 12:16:52
+Scope: sa-tme-flexpod-a800-rdma-01
+
+ Counter Value
+ -------------------------------- --------------------------------
+ instance_name NVM Mirror
+ instance_uuid sa-tme-flexpod-a800-rdma-01:
+ kernel:NVM Mirror
+ node_name sa-tme-flexpod-a800-rdma-01
+ write_throughput 13847639326958
+
+Object: nvm_mirror
+Instance: NVM Mirror
+Start-time: 11/7/2025 12:16:52
+End-time: 11/7/2025 12:16:52
+Scope: sa-tme-flexpod-a800-rdma-02
+
+ Counter Value
+ -------------------------------- --------------------------------
+ instance_name NVM Mirror
+ instance_uuid sa-tme-flexpod-a800-rdma-02:
+ kernel:NVM Mirror
+ node_name sa-tme-flexpod-a800-rdma-02
+ write_throughput 629627001678
+8 entries were displayed.
diff --git a/cmd/collectors/storagegrid/rest/client.go b/cmd/collectors/storagegrid/rest/client.go
index 297cc98cd..158789674 100644
--- a/cmd/collectors/storagegrid/rest/client.go
+++ b/cmd/collectors/storagegrid/rest/client.go
@@ -209,6 +209,17 @@ func (c *Client) invoke() ([]byte, error) {
var storageGridErr errs.StorageGridError
if errors.As(err, &storageGridErr) {
if storageGridErr.IsAuthErr() {
+ // If using authToken from credential script, expire cache before retry
+ // so fetchTokenWithAuthRetry gets fresh token instead of cached expired one
+ pollerAuth, authErr := c.auth.GetPollerAuth()
+ if authErr != nil {
+ return nil, authErr
+ }
+ if pollerAuth.HasCredentialScript && pollerAuth.AuthToken != "" {
+ c.Logger.Debug("Expiring cached credential script token after 401 response")
+ c.auth.Expire()
+ }
+
err2 := c.fetchTokenWithAuthRetry()
if err2 != nil {
return nil, err2
diff --git a/docs/cisco-switch-metrics.md b/docs/cisco-switch-metrics.md
index c0cbbf480..46ec15a86 100644
--- a/docs/cisco-switch-metrics.md
+++ b/docs/cisco-switch-metrics.md
@@ -5,7 +5,7 @@ These can be generated on demand by running `bin/harvest grafana metrics`. See
[#1577](https://github.com/NetApp/harvest/issues/1577#issue-1471478260) for details.
```
-Creation Date : 2025-Nov-03
+Creation Date : 2025-Nov-06
NX-OS Version: 9.3.12
```
diff --git a/docs/ontap-metrics.md b/docs/ontap-metrics.md
index 4c70d8a9a..6e25795e3 100644
--- a/docs/ontap-metrics.md
+++ b/docs/ontap-metrics.md
@@ -7,7 +7,7 @@ These can be generated on demand by running `bin/harvest grafana metrics`. See
- More information about ONTAP REST performance counters can be found [here](https://docs.netapp.com/us-en/ontap-pcmap-9121/index.html).
```
-Creation Date : 2025-Nov-03
+Creation Date : 2025-Nov-06
ONTAP Version: 9.16.1
```
diff --git a/docs/prepare-fsx-clusters.md b/docs/prepare-fsx-clusters.md
index 454886309..873a5493e 100644
--- a/docs/prepare-fsx-clusters.md
+++ b/docs/prepare-fsx-clusters.md
@@ -18,6 +18,7 @@ The dashboards that work with FSx are tagged with `fsx` and listed below:
* ONTAP: Cluster
* ONTAP: Data Protection
* ONTAP: Datacenter
+* ONTAP: FlexCache
* ONTAP: FlexGroup
* ONTAP: FPolicy
* ONTAP: LUN
diff --git a/docs/storagegrid-metrics.md b/docs/storagegrid-metrics.md
index 74fe347d9..e7e2160dc 100644
--- a/docs/storagegrid-metrics.md
+++ b/docs/storagegrid-metrics.md
@@ -5,7 +5,7 @@ These can be generated on demand by running `bin/harvest grafana metrics`. See
[#1577](https://github.com/NetApp/harvest/issues/1577#issue-1471478260) for details.
```
-Creation Date : 2025-Nov-03
+Creation Date : 2025-Nov-06
StorageGrid Version: 11.6.0
```
diff --git a/go.mod b/go.mod
index 6851c740c..4da1e8ef9 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
github.com/rivo/uniseg v0.4.7
github.com/spf13/cobra v1.10.1
github.com/zekroTJA/timedmap/v2 v2.0.0
- golang.org/x/sys v0.37.0
+ golang.org/x/sys v0.38.0
golang.org/x/term v0.36.0
golang.org/x/text v0.30.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
diff --git a/go.sum b/go.sum
index 246efd061..bfb7db3fe 100644
--- a/go.sum
+++ b/go.sum
@@ -25,6 +25,8 @@ github.com/zekroTJA/timedmap/v2 v2.0.0 h1:Bo9oq8AExd0GuDFbcPXm3xoidUAtrnNsZN1d1H
github.com/zekroTJA/timedmap/v2 v2.0.0/go.mod h1:xHDLg687zASqLBJqoysF+WORHxL/kYNphVD36CRJxhM=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
+golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
diff --git a/grafana/dashboards/cmode/flexcache.json b/grafana/dashboards/cmode/flexcache.json
index fa2944c58..7aba533bb 100644
--- a/grafana/dashboards/cmode/flexcache.json
+++ b/grafana/dashboards/cmode/flexcache.json
@@ -2033,7 +2033,8 @@
"tags": [
"harvest",
"ontap",
- "cdot"
+ "cdot",
+ "fsx"
],
"templating": {
"list": [
diff --git a/grafana/dashboards/cmode/snapmirror_destinations.json b/grafana/dashboards/cmode/snapmirror_destinations.json
index c04c916f0..d0d28cb97 100644
--- a/grafana/dashboards/cmode/snapmirror_destinations.json
+++ b/grafana/dashboards/cmode/snapmirror_destinations.json
@@ -1233,7 +1233,7 @@
"targets": [
{
"exemplar": false,
- "expr": "volume_total_data{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",style!=\"flexgroup_constituent\",svm=~\"$SVM\",volume=~\"$Volume\"}\nand on (datacenter, cluster, svm, volume)\n topk(\n $TopResources,\n (\n avg_over_time(\n volume_total_data{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",style!=\"flexgroup_constituent\",svm=~\"$SVM\",volume=~\"$Volume\"}[3h] @ end()\n )\n * on (datacenter, cluster, svm, volume)\n label_replace(\n label_replace(\n snapmirror_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",derived_relationship_type!=\"load_sharing\",destination_volume=~\"$Volume\",destination_vserver=~\"$SVM\",relationship_id!=\"\"},\n \"volume\",\n \"$1\",\n \"destination_volume\",\n \"(.*)\"\n ),\n \"svm\",\n \"$1\",\n \"destination_vserver\",\n \"(.*)\"\n )\n )\n )",
+ "expr": "volume_total_data{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",style!=\"flexgroup_constituent\",svm=~\"$SVM\",volume=~\"$Volume\"}\nand on (datacenter, cluster, svm, volume)\n topk(\n $TopResources,\n (\n avg_over_time(\n volume_total_data{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",style!=\"flexgroup_constituent\",svm=~\"$SVM\",volume=~\"$Volume\"}[3h] @ end()\n )\n * on (datacenter, cluster, svm, volume) group_left ()\n label_replace(\n label_replace(\n snapmirror_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",derived_relationship_type!=\"load_sharing\",destination_volume=~\"$Volume\",destination_vserver=~\"$SVM\",relationship_id!=\"\"},\n \"volume\",\n \"$1\",\n \"destination_volume\",\n \"(.*)\"\n ),\n \"svm\",\n \"$1\",\n \"destination_vserver\",\n \"(.*)\"\n )\n )\n )",
"interval": "",
"legendFormat": "{{svm}} - {{volume}}",
"refId": "A"
diff --git a/grafana/dashboards/storagegrid/tenant.json b/grafana/dashboards/storagegrid/tenant.json
index 60299d6c0..b2b4e1cf6 100644
--- a/grafana/dashboards/storagegrid/tenant.json
+++ b/grafana/dashboards/storagegrid/tenant.json
@@ -808,11 +808,11 @@
"options": {
"false": {
"index": 1,
- "text": "False"
+ "text": "No"
},
"true": {
"index": 0,
- "text": "True"
+ "text": "Yes"
}
},
"type": "value"
diff --git a/mcp/go.mod b/mcp/go.mod
index 1ac7ae7c4..8b77f5e02 100644
--- a/mcp/go.mod
+++ b/mcp/go.mod
@@ -7,7 +7,7 @@ replace github.com/netapp/harvest/v2 => ../
require (
github.com/goccy/go-yaml v1.18.0
github.com/modelcontextprotocol/go-sdk v1.1.0
- github.com/netapp/harvest/v2 v2.0.0-20251031171647-f283c2f7940c
+ github.com/netapp/harvest/v2 v2.0.0-20251106124425-91a28125a7a8
github.com/spf13/cobra v1.10.1
)
diff --git a/mcp/vendor/modules.txt b/mcp/vendor/modules.txt
index abfce55e6..490972fbc 100644
--- a/mcp/vendor/modules.txt
+++ b/mcp/vendor/modules.txt
@@ -23,7 +23,7 @@ github.com/modelcontextprotocol/go-sdk/internal/util
github.com/modelcontextprotocol/go-sdk/internal/xcontext
github.com/modelcontextprotocol/go-sdk/jsonrpc
github.com/modelcontextprotocol/go-sdk/mcp
-# github.com/netapp/harvest/v2 v2.0.0-20251031171647-f283c2f7940c => ../
+# github.com/netapp/harvest/v2 v2.0.0-20251106124425-91a28125a7a8 => ../
## explicit; go 1.24.0
github.com/netapp/harvest/v2/pkg/slogx
# github.com/spf13/cobra v1.10.1
diff --git a/pkg/changelog/main.go b/pkg/changelog/main.go
index fab1cf5e8..d43ff13bf 100644
--- a/pkg/changelog/main.go
+++ b/pkg/changelog/main.go
@@ -165,7 +165,7 @@ func (c pr) linkToIssue() string {
}
// * docs: improve security panel info for ONTAP 9.10+ by @foo in https://github.com/NetApp/harvest/pull/1238
-var prRegex = regexp.MustCompile(`\* (.*?): (.*?) by @(\w+) in (https://.*)$`)
+var prRegex = regexp.MustCompile(`\* (.*?): (.*?) by @(.*?) in (https://.*)$`)
func (c *cli) readPrs(notes []byte) {
scanner := bufio.NewScanner(bytes.NewReader(notes))
diff --git a/service/contrib/target.tmpl b/service/contrib/target.tmpl
index a3fb5e418..955ce5bfa 100644
--- a/service/contrib/target.tmpl
+++ b/service/contrib/target.tmpl
@@ -1,6 +1,6 @@
[Unit]
Description="NetApp Harvest Meta Service"
-Requires={{- .Admin -}}{{range .PollersOrdered}}poller@{{.}}.service {{end}}
+Wants={{- .Admin -}}{{range .PollersOrdered}}poller@{{.}}.service {{end}}
[Install]
WantedBy=multi-user.target
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index d1c8b2640..42517077c 100644
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -226,6 +226,7 @@ struct ltchars {
#include
#include
#include
+#include
#include
#include
#include
@@ -529,6 +530,7 @@ ccflags="$@"
$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
+ $2 ~ /^(DT|EI|ELF|EV|NN|NT|PF|SHF|SHN|SHT|STB|STT|VER)_/ ||
$2 ~ /^O?XTABS$/ ||
$2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ ||
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 9439af961..06c0eea6f 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -2643,3 +2643,9 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) {
//sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error)
//sys Mseal(b []byte, flags uint) (err error)
+
+//sys setMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY
+
+func SetMemPolicy(mode int, mask *CPUSet) error {
+ return setMemPolicy(mode, mask, _CPU_SETSIZE)
+}
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go
index b6db27d93..d0a75da57 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -853,20 +853,86 @@ const (
DM_VERSION_MAJOR = 0x4
DM_VERSION_MINOR = 0x32
DM_VERSION_PATCHLEVEL = 0x0
+ DT_ADDRRNGHI = 0x6ffffeff
+ DT_ADDRRNGLO = 0x6ffffe00
DT_BLK = 0x6
DT_CHR = 0x2
+ DT_DEBUG = 0x15
DT_DIR = 0x4
+ DT_ENCODING = 0x20
DT_FIFO = 0x1
+ DT_FINI = 0xd
+ DT_FLAGS_1 = 0x6ffffffb
+ DT_GNU_HASH = 0x6ffffef5
+ DT_HASH = 0x4
+ DT_HIOS = 0x6ffff000
+ DT_HIPROC = 0x7fffffff
+ DT_INIT = 0xc
+ DT_JMPREL = 0x17
DT_LNK = 0xa
+ DT_LOOS = 0x6000000d
+ DT_LOPROC = 0x70000000
+ DT_NEEDED = 0x1
+ DT_NULL = 0x0
+ DT_PLTGOT = 0x3
+ DT_PLTREL = 0x14
+ DT_PLTRELSZ = 0x2
DT_REG = 0x8
+ DT_REL = 0x11
+ DT_RELA = 0x7
+ DT_RELACOUNT = 0x6ffffff9
+ DT_RELAENT = 0x9
+ DT_RELASZ = 0x8
+ DT_RELCOUNT = 0x6ffffffa
+ DT_RELENT = 0x13
+ DT_RELSZ = 0x12
+ DT_RPATH = 0xf
DT_SOCK = 0xc
+ DT_SONAME = 0xe
+ DT_STRSZ = 0xa
+ DT_STRTAB = 0x5
+ DT_SYMBOLIC = 0x10
+ DT_SYMENT = 0xb
+ DT_SYMTAB = 0x6
+ DT_TEXTREL = 0x16
DT_UNKNOWN = 0x0
+ DT_VALRNGHI = 0x6ffffdff
+ DT_VALRNGLO = 0x6ffffd00
+ DT_VERDEF = 0x6ffffffc
+ DT_VERDEFNUM = 0x6ffffffd
+ DT_VERNEED = 0x6ffffffe
+ DT_VERNEEDNUM = 0x6fffffff
+ DT_VERSYM = 0x6ffffff0
DT_WHT = 0xe
ECHO = 0x8
ECRYPTFS_SUPER_MAGIC = 0xf15f
EFD_SEMAPHORE = 0x1
EFIVARFS_MAGIC = 0xde5e81e4
EFS_SUPER_MAGIC = 0x414a53
+ EI_CLASS = 0x4
+ EI_DATA = 0x5
+ EI_MAG0 = 0x0
+ EI_MAG1 = 0x1
+ EI_MAG2 = 0x2
+ EI_MAG3 = 0x3
+ EI_NIDENT = 0x10
+ EI_OSABI = 0x7
+ EI_PAD = 0x8
+ EI_VERSION = 0x6
+ ELFCLASS32 = 0x1
+ ELFCLASS64 = 0x2
+ ELFCLASSNONE = 0x0
+ ELFCLASSNUM = 0x3
+ ELFDATA2LSB = 0x1
+ ELFDATA2MSB = 0x2
+ ELFDATANONE = 0x0
+ ELFMAG = "\177ELF"
+ ELFMAG0 = 0x7f
+ ELFMAG1 = 'E'
+ ELFMAG2 = 'L'
+ ELFMAG3 = 'F'
+ ELFOSABI_LINUX = 0x3
+ ELFOSABI_NONE = 0x0
EM_386 = 0x3
EM_486 = 0x6
EM_68K = 0x4
@@ -1152,14 +1218,24 @@ const (
ETH_P_WCCP = 0x883e
ETH_P_X25 = 0x805
ETH_P_XDSA = 0xf8
+ ET_CORE = 0x4
+ ET_DYN = 0x3
+ ET_EXEC = 0x2
+ ET_HIPROC = 0xffff
+ ET_LOPROC = 0xff00
+ ET_NONE = 0x0
+ ET_REL = 0x1
EV_ABS = 0x3
EV_CNT = 0x20
+ EV_CURRENT = 0x1
EV_FF = 0x15
EV_FF_STATUS = 0x17
EV_KEY = 0x1
EV_LED = 0x11
EV_MAX = 0x1f
EV_MSC = 0x4
+ EV_NONE = 0x0
+ EV_NUM = 0x2
EV_PWR = 0x16
EV_REL = 0x2
EV_REP = 0x14
@@ -2276,7 +2352,167 @@ const (
NLM_F_REPLACE = 0x100
NLM_F_REQUEST = 0x1
NLM_F_ROOT = 0x100
+ NN_386_IOPERM = "LINUX"
+ NN_386_TLS = "LINUX"
+ NN_ARC_V2 = "LINUX"
+ NN_ARM_FPMR = "LINUX"
+ NN_ARM_GCS = "LINUX"
+ NN_ARM_HW_BREAK = "LINUX"
+ NN_ARM_HW_WATCH = "LINUX"
+ NN_ARM_PACA_KEYS = "LINUX"
+ NN_ARM_PACG_KEYS = "LINUX"
+ NN_ARM_PAC_ENABLED_KEYS = "LINUX"
+ NN_ARM_PAC_MASK = "LINUX"
+ NN_ARM_POE = "LINUX"
+ NN_ARM_SSVE = "LINUX"
+ NN_ARM_SVE = "LINUX"
+ NN_ARM_SYSTEM_CALL = "LINUX"
+ NN_ARM_TAGGED_ADDR_CTRL = "LINUX"
+ NN_ARM_TLS = "LINUX"
+ NN_ARM_VFP = "LINUX"
+ NN_ARM_ZA = "LINUX"
+ NN_ARM_ZT = "LINUX"
+ NN_AUXV = "CORE"
+ NN_FILE = "CORE"
+ NN_GNU_PROPERTY_TYPE_0 = "GNU"
+ NN_LOONGARCH_CPUCFG = "LINUX"
+ NN_LOONGARCH_CSR = "LINUX"
+ NN_LOONGARCH_HW_BREAK = "LINUX"
+ NN_LOONGARCH_HW_WATCH = "LINUX"
+ NN_LOONGARCH_LASX = "LINUX"
+ NN_LOONGARCH_LBT = "LINUX"
+ NN_LOONGARCH_LSX = "LINUX"
+ NN_MIPS_DSP = "LINUX"
+ NN_MIPS_FP_MODE = "LINUX"
+ NN_MIPS_MSA = "LINUX"
+ NN_PPC_DEXCR = "LINUX"
+ NN_PPC_DSCR = "LINUX"
+ NN_PPC_EBB = "LINUX"
+ NN_PPC_HASHKEYR = "LINUX"
+ NN_PPC_PKEY = "LINUX"
+ NN_PPC_PMU = "LINUX"
+ NN_PPC_PPR = "LINUX"
+ NN_PPC_SPE = "LINUX"
+ NN_PPC_TAR = "LINUX"
+ NN_PPC_TM_CDSCR = "LINUX"
+ NN_PPC_TM_CFPR = "LINUX"
+ NN_PPC_TM_CGPR = "LINUX"
+ NN_PPC_TM_CPPR = "LINUX"
+ NN_PPC_TM_CTAR = "LINUX"
+ NN_PPC_TM_CVMX = "LINUX"
+ NN_PPC_TM_CVSX = "LINUX"
+ NN_PPC_TM_SPR = "LINUX"
+ NN_PPC_VMX = "LINUX"
+ NN_PPC_VSX = "LINUX"
+ NN_PRFPREG = "CORE"
+ NN_PRPSINFO = "CORE"
+ NN_PRSTATUS = "CORE"
+ NN_PRXFPREG = "LINUX"
+ NN_RISCV_CSR = "LINUX"
+ NN_RISCV_TAGGED_ADDR_CTRL = "LINUX"
+ NN_RISCV_VECTOR = "LINUX"
+ NN_S390_CTRS = "LINUX"
+ NN_S390_GS_BC = "LINUX"
+ NN_S390_GS_CB = "LINUX"
+ NN_S390_HIGH_GPRS = "LINUX"
+ NN_S390_LAST_BREAK = "LINUX"
+ NN_S390_PREFIX = "LINUX"
+ NN_S390_PV_CPU_DATA = "LINUX"
+ NN_S390_RI_CB = "LINUX"
+ NN_S390_SYSTEM_CALL = "LINUX"
+ NN_S390_TDB = "LINUX"
+ NN_S390_TIMER = "LINUX"
+ NN_S390_TODCMP = "LINUX"
+ NN_S390_TODPREG = "LINUX"
+ NN_S390_VXRS_HIGH = "LINUX"
+ NN_S390_VXRS_LOW = "LINUX"
+ NN_SIGINFO = "CORE"
+ NN_TASKSTRUCT = "CORE"
+ NN_VMCOREDD = "LINUX"
+ NN_X86_SHSTK = "LINUX"
+ NN_X86_XSAVE_LAYOUT = "LINUX"
+ NN_X86_XSTATE = "LINUX"
NSFS_MAGIC = 0x6e736673
+ NT_386_IOPERM = 0x201
+ NT_386_TLS = 0x200
+ NT_ARC_V2 = 0x600
+ NT_ARM_FPMR = 0x40e
+ NT_ARM_GCS = 0x410
+ NT_ARM_HW_BREAK = 0x402
+ NT_ARM_HW_WATCH = 0x403
+ NT_ARM_PACA_KEYS = 0x407
+ NT_ARM_PACG_KEYS = 0x408
+ NT_ARM_PAC_ENABLED_KEYS = 0x40a
+ NT_ARM_PAC_MASK = 0x406
+ NT_ARM_POE = 0x40f
+ NT_ARM_SSVE = 0x40b
+ NT_ARM_SVE = 0x405
+ NT_ARM_SYSTEM_CALL = 0x404
+ NT_ARM_TAGGED_ADDR_CTRL = 0x409
+ NT_ARM_TLS = 0x401
+ NT_ARM_VFP = 0x400
+ NT_ARM_ZA = 0x40c
+ NT_ARM_ZT = 0x40d
+ NT_AUXV = 0x6
+ NT_FILE = 0x46494c45
+ NT_GNU_PROPERTY_TYPE_0 = 0x5
+ NT_LOONGARCH_CPUCFG = 0xa00
+ NT_LOONGARCH_CSR = 0xa01
+ NT_LOONGARCH_HW_BREAK = 0xa05
+ NT_LOONGARCH_HW_WATCH = 0xa06
+ NT_LOONGARCH_LASX = 0xa03
+ NT_LOONGARCH_LBT = 0xa04
+ NT_LOONGARCH_LSX = 0xa02
+ NT_MIPS_DSP = 0x800
+ NT_MIPS_FP_MODE = 0x801
+ NT_MIPS_MSA = 0x802
+ NT_PPC_DEXCR = 0x111
+ NT_PPC_DSCR = 0x105
+ NT_PPC_EBB = 0x106
+ NT_PPC_HASHKEYR = 0x112
+ NT_PPC_PKEY = 0x110
+ NT_PPC_PMU = 0x107
+ NT_PPC_PPR = 0x104
+ NT_PPC_SPE = 0x101
+ NT_PPC_TAR = 0x103
+ NT_PPC_TM_CDSCR = 0x10f
+ NT_PPC_TM_CFPR = 0x109
+ NT_PPC_TM_CGPR = 0x108
+ NT_PPC_TM_CPPR = 0x10e
+ NT_PPC_TM_CTAR = 0x10d
+ NT_PPC_TM_CVMX = 0x10a
+ NT_PPC_TM_CVSX = 0x10b
+ NT_PPC_TM_SPR = 0x10c
+ NT_PPC_VMX = 0x100
+ NT_PPC_VSX = 0x102
+ NT_PRFPREG = 0x2
+ NT_PRPSINFO = 0x3
+ NT_PRSTATUS = 0x1
+ NT_PRXFPREG = 0x46e62b7f
+ NT_RISCV_CSR = 0x900
+ NT_RISCV_TAGGED_ADDR_CTRL = 0x902
+ NT_RISCV_VECTOR = 0x901
+ NT_S390_CTRS = 0x304
+ NT_S390_GS_BC = 0x30c
+ NT_S390_GS_CB = 0x30b
+ NT_S390_HIGH_GPRS = 0x300
+ NT_S390_LAST_BREAK = 0x306
+ NT_S390_PREFIX = 0x305
+ NT_S390_PV_CPU_DATA = 0x30e
+ NT_S390_RI_CB = 0x30d
+ NT_S390_SYSTEM_CALL = 0x307
+ NT_S390_TDB = 0x308
+ NT_S390_TIMER = 0x301
+ NT_S390_TODCMP = 0x302
+ NT_S390_TODPREG = 0x303
+ NT_S390_VXRS_HIGH = 0x30a
+ NT_S390_VXRS_LOW = 0x309
+ NT_SIGINFO = 0x53494749
+ NT_TASKSTRUCT = 0x4
+ NT_VMCOREDD = 0x700
+ NT_X86_SHSTK = 0x204
+ NT_X86_XSAVE_LAYOUT = 0x205
+ NT_X86_XSTATE = 0x202
OCFS2_SUPER_MAGIC = 0x7461636f
OCRNL = 0x8
OFDEL = 0x80
@@ -2463,6 +2699,59 @@ const (
PERF_RECORD_MISC_USER = 0x2
PERF_SAMPLE_BRANCH_PLM_ALL = 0x7
PERF_SAMPLE_WEIGHT_TYPE = 0x1004000
+ PF_ALG = 0x26
+ PF_APPLETALK = 0x5
+ PF_ASH = 0x12
+ PF_ATMPVC = 0x8
+ PF_ATMSVC = 0x14
+ PF_AX25 = 0x3
+ PF_BLUETOOTH = 0x1f
+ PF_BRIDGE = 0x7
+ PF_CAIF = 0x25
+ PF_CAN = 0x1d
+ PF_DECnet = 0xc
+ PF_ECONET = 0x13
+ PF_FILE = 0x1
+ PF_IB = 0x1b
+ PF_IEEE802154 = 0x24
+ PF_INET = 0x2
+ PF_INET6 = 0xa
+ PF_IPX = 0x4
+ PF_IRDA = 0x17
+ PF_ISDN = 0x22
+ PF_IUCV = 0x20
+ PF_KCM = 0x29
+ PF_KEY = 0xf
+ PF_LLC = 0x1a
+ PF_LOCAL = 0x1
+ PF_MAX = 0x2e
+ PF_MCTP = 0x2d
+ PF_MPLS = 0x1c
+ PF_NETBEUI = 0xd
+ PF_NETLINK = 0x10
+ PF_NETROM = 0x6
+ PF_NFC = 0x27
+ PF_PACKET = 0x11
+ PF_PHONET = 0x23
+ PF_PPPOX = 0x18
+ PF_QIPCRTR = 0x2a
+ PF_R = 0x4
+ PF_RDS = 0x15
+ PF_ROSE = 0xb
+ PF_ROUTE = 0x10
+ PF_RXRPC = 0x21
+ PF_SECURITY = 0xe
+ PF_SMC = 0x2b
+ PF_SNA = 0x16
+ PF_TIPC = 0x1e
+ PF_UNIX = 0x1
+ PF_UNSPEC = 0x0
+ PF_VSOCK = 0x28
+ PF_W = 0x2
+ PF_WANPIPE = 0x19
+ PF_X = 0x1
+ PF_X25 = 0x9
+ PF_XDP = 0x2c
PID_FS_MAGIC = 0x50494446
PIPEFS_MAGIC = 0x50495045
PPPIOCGNPMODE = 0xc008744c
@@ -2758,6 +3047,23 @@ const (
PTRACE_SYSCALL_INFO_NONE = 0x0
PTRACE_SYSCALL_INFO_SECCOMP = 0x3
PTRACE_TRACEME = 0x0
+ PT_AARCH64_MEMTAG_MTE = 0x70000002
+ PT_DYNAMIC = 0x2
+ PT_GNU_EH_FRAME = 0x6474e550
+ PT_GNU_PROPERTY = 0x6474e553
+ PT_GNU_RELRO = 0x6474e552
+ PT_GNU_STACK = 0x6474e551
+ PT_HIOS = 0x6fffffff
+ PT_HIPROC = 0x7fffffff
+ PT_INTERP = 0x3
+ PT_LOAD = 0x1
+ PT_LOOS = 0x60000000
+ PT_LOPROC = 0x70000000
+ PT_NOTE = 0x4
+ PT_NULL = 0x0
+ PT_PHDR = 0x6
+ PT_SHLIB = 0x5
+ PT_TLS = 0x7
P_ALL = 0x0
P_PGID = 0x2
P_PID = 0x1
@@ -3091,6 +3397,47 @@ const (
SEEK_MAX = 0x4
SEEK_SET = 0x0
SELINUX_MAGIC = 0xf97cff8c
+ SHF_ALLOC = 0x2
+ SHF_EXCLUDE = 0x8000000
+ SHF_EXECINSTR = 0x4
+ SHF_GROUP = 0x200
+ SHF_INFO_LINK = 0x40
+ SHF_LINK_ORDER = 0x80
+ SHF_MASKOS = 0xff00000
+ SHF_MASKPROC = 0xf0000000
+ SHF_MERGE = 0x10
+ SHF_ORDERED = 0x4000000
+ SHF_OS_NONCONFORMING = 0x100
+ SHF_RELA_LIVEPATCH = 0x100000
+ SHF_RO_AFTER_INIT = 0x200000
+ SHF_STRINGS = 0x20
+ SHF_TLS = 0x400
+ SHF_WRITE = 0x1
+ SHN_ABS = 0xfff1
+ SHN_COMMON = 0xfff2
+ SHN_HIPROC = 0xff1f
+ SHN_HIRESERVE = 0xffff
+ SHN_LIVEPATCH = 0xff20
+ SHN_LOPROC = 0xff00
+ SHN_LORESERVE = 0xff00
+ SHN_UNDEF = 0x0
+ SHT_DYNAMIC = 0x6
+ SHT_DYNSYM = 0xb
+ SHT_HASH = 0x5
+ SHT_HIPROC = 0x7fffffff
+ SHT_HIUSER = 0xffffffff
+ SHT_LOPROC = 0x70000000
+ SHT_LOUSER = 0x80000000
+ SHT_NOBITS = 0x8
+ SHT_NOTE = 0x7
+ SHT_NULL = 0x0
+ SHT_NUM = 0xc
+ SHT_PROGBITS = 0x1
+ SHT_REL = 0x9
+ SHT_RELA = 0x4
+ SHT_SHLIB = 0xa
+ SHT_STRTAB = 0x3
+ SHT_SYMTAB = 0x2
SHUT_RD = 0x0
SHUT_RDWR = 0x2
SHUT_WR = 0x1
@@ -3317,6 +3664,16 @@ const (
STATX_UID = 0x8
STATX_WRITE_ATOMIC = 0x10000
STATX__RESERVED = 0x80000000
+ STB_GLOBAL = 0x1
+ STB_LOCAL = 0x0
+ STB_WEAK = 0x2
+ STT_COMMON = 0x5
+ STT_FILE = 0x4
+ STT_FUNC = 0x2
+ STT_NOTYPE = 0x0
+ STT_OBJECT = 0x1
+ STT_SECTION = 0x3
+ STT_TLS = 0x6
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
SYNC_FILE_RANGE_WRITE = 0x2
@@ -3553,6 +3910,8 @@ const (
UTIME_OMIT = 0x3ffffffe
V9FS_MAGIC = 0x1021997
VERASE = 0x2
+ VER_FLG_BASE = 0x1
+ VER_FLG_WEAK = 0x2
VINTR = 0x0
VKILL = 0x3
VLNEXT = 0xf
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
index 5cc1e8eb2..8935d10a3 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
@@ -2238,3 +2238,13 @@ func Mseal(b []byte, flags uint) (err error) {
}
return
}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setMemPolicy(mode int, mask *CPUSet, size int) (err error) {
+ _, _, e1 := Syscall(SYS_SET_MEMPOLICY, uintptr(mode), uintptr(unsafe.Pointer(mask)), uintptr(size))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go
index 944e75a11..c1a467017 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -3590,6 +3590,8 @@ type Nhmsg struct {
Flags uint32
}
+const SizeofNhmsg = 0x8
+
type NexthopGrp struct {
Id uint32
Weight uint8
@@ -3597,6 +3599,8 @@ type NexthopGrp struct {
Resvd2 uint16
}
+const SizeofNexthopGrp = 0x8
+
const (
NHA_UNSPEC = 0x0
NHA_ID = 0x1
@@ -6332,3 +6336,30 @@ type SockDiagReq struct {
}
const RTM_NEWNVLAN = 0x70
+
+const (
+ MPOL_BIND = 0x2
+ MPOL_DEFAULT = 0x0
+ MPOL_F_ADDR = 0x2
+ MPOL_F_MEMS_ALLOWED = 0x4
+ MPOL_F_MOF = 0x8
+ MPOL_F_MORON = 0x10
+ MPOL_F_NODE = 0x1
+ MPOL_F_NUMA_BALANCING = 0x2000
+ MPOL_F_RELATIVE_NODES = 0x4000
+ MPOL_F_SHARED = 0x1
+ MPOL_F_STATIC_NODES = 0x8000
+ MPOL_INTERLEAVE = 0x3
+ MPOL_LOCAL = 0x4
+ MPOL_MAX = 0x7
+ MPOL_MF_INTERNAL = 0x10
+ MPOL_MF_LAZY = 0x8
+ MPOL_MF_MOVE_ALL = 0x4
+ MPOL_MF_MOVE = 0x2
+ MPOL_MF_STRICT = 0x1
+ MPOL_MF_VALID = 0x7
+ MPOL_MODE_FLAGS = 0xe000
+ MPOL_PREFERRED = 0x1
+ MPOL_PREFERRED_MANY = 0x5
+ MPOL_WEIGHTED_INTERLEAVE = 0x6
+)
diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go
index bd5133730..69439df2a 100644
--- a/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -892,8 +892,12 @@ const socket_error = uintptr(^uint32(0))
//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
//sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx
//sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex
+//sys GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) = iphlpapi.GetIpForwardEntry2
+//sys GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) = iphlpapi.GetIpForwardTable2
//sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry
+//sys FreeMibTable(memory unsafe.Pointer) = iphlpapi.FreeMibTable
//sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange
+//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2
//sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange
//sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2
@@ -916,6 +920,17 @@ type RawSockaddrInet6 struct {
Scope_id uint32
}
+// RawSockaddrInet is a union that contains an IPv4, an IPv6 address, or an address family. See
+// https://learn.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet.
+//
+// A [*RawSockaddrInet] may be converted to a [*RawSockaddrInet4] or [*RawSockaddrInet6] using
+// unsafe, depending on the address family.
+type RawSockaddrInet struct {
+ Family uint16
+ Port uint16
+ Data [6]uint32
+}
+
type RawSockaddr struct {
Family uint16
Data [14]int8
diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go
index 358be3c7f..6e4f50eb4 100644
--- a/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/vendor/golang.org/x/sys/windows/types_windows.go
@@ -2320,6 +2320,82 @@ type MibIfRow2 struct {
OutQLen uint64
}
+// IP_ADDRESS_PREFIX stores an IP address prefix. See
+// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-ip_address_prefix.
+type IpAddressPrefix struct {
+ Prefix RawSockaddrInet
+ PrefixLength uint8
+}
+
+// NL_ROUTE_ORIGIN enumeration from nldef.h or
+// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_origin.
+const (
+ NlroManual = 0
+ NlroWellKnown = 1
+ NlroDHCP = 2
+ NlroRouterAdvertisement = 3
+ Nlro6to4 = 4
+)
+
+// NL_ROUTE_ORIGIN enumeration from nldef.h or
+// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_protocol.
+const (
+ MIB_IPPROTO_OTHER = 1
+ MIB_IPPROTO_LOCAL = 2
+ MIB_IPPROTO_NETMGMT = 3
+ MIB_IPPROTO_ICMP = 4
+ MIB_IPPROTO_EGP = 5
+ MIB_IPPROTO_GGP = 6
+ MIB_IPPROTO_HELLO = 7
+ MIB_IPPROTO_RIP = 8
+ MIB_IPPROTO_IS_IS = 9
+ MIB_IPPROTO_ES_IS = 10
+ MIB_IPPROTO_CISCO = 11
+ MIB_IPPROTO_BBN = 12
+ MIB_IPPROTO_OSPF = 13
+ MIB_IPPROTO_BGP = 14
+ MIB_IPPROTO_IDPR = 15
+ MIB_IPPROTO_EIGRP = 16
+ MIB_IPPROTO_DVMRP = 17
+ MIB_IPPROTO_RPL = 18
+ MIB_IPPROTO_DHCP = 19
+ MIB_IPPROTO_NT_AUTOSTATIC = 10002
+ MIB_IPPROTO_NT_STATIC = 10006
+ MIB_IPPROTO_NT_STATIC_NON_DOD = 10007
+)
+
+// MIB_IPFORWARD_ROW2 stores information about an IP route entry. See
+// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_row2.
+type MibIpForwardRow2 struct {
+ InterfaceLuid uint64
+ InterfaceIndex uint32
+ DestinationPrefix IpAddressPrefix
+ NextHop RawSockaddrInet
+ SitePrefixLength uint8
+ ValidLifetime uint32
+ PreferredLifetime uint32
+ Metric uint32
+ Protocol uint32
+ Loopback uint8
+ AutoconfigureAddress uint8
+ Publish uint8
+ Immortal uint8
+ Age uint32
+ Origin uint32
+}
+
+// MIB_IPFORWARD_TABLE2 contains a table of IP route entries. See
+// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_table2.
+type MibIpForwardTable2 struct {
+ NumEntries uint32
+ Table [1]MibIpForwardRow2
+}
+
+// Rows returns the IP route entries in the table.
+func (t *MibIpForwardTable2) Rows() []MibIpForwardRow2 {
+ return unsafe.Slice(&t.Table[0], t.NumEntries)
+}
+
// MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row.
type MibUnicastIpAddressRow struct {
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index 426151a01..f25b7308a 100644
--- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -182,13 +182,17 @@ var (
procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute")
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2")
+ procFreeMibTable = modiphlpapi.NewProc("FreeMibTable")
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx")
procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex")
+ procGetIpForwardEntry2 = modiphlpapi.NewProc("GetIpForwardEntry2")
+ procGetIpForwardTable2 = modiphlpapi.NewProc("GetIpForwardTable2")
procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry")
procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange")
+ procNotifyRouteChange2 = modiphlpapi.NewProc("NotifyRouteChange2")
procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange")
procAddDllDirectory = modkernel32.NewProc("AddDllDirectory")
procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject")
@@ -1624,6 +1628,11 @@ func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) {
return
}
+func FreeMibTable(memory unsafe.Pointer) {
+ syscall.SyscallN(procFreeMibTable.Addr(), uintptr(memory))
+ return
+}
+
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
r0, _, _ := syscall.SyscallN(procGetAdaptersAddresses.Addr(), uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)))
if r0 != 0 {
@@ -1664,6 +1673,22 @@ func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) {
return
}
+func GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) {
+ r0, _, _ := syscall.SyscallN(procGetIpForwardEntry2.Addr(), uintptr(unsafe.Pointer(row)))
+ if r0 != 0 {
+ errcode = syscall.Errno(r0)
+ }
+ return
+}
+
+func GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) {
+ r0, _, _ := syscall.SyscallN(procGetIpForwardTable2.Addr(), uintptr(family), uintptr(unsafe.Pointer(table)))
+ if r0 != 0 {
+ errcode = syscall.Errno(r0)
+ }
+ return
+}
+
func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) {
r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressEntry.Addr(), uintptr(unsafe.Pointer(row)))
if r0 != 0 {
@@ -1684,6 +1709,18 @@ func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsa
return
}
+func NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) {
+ var _p0 uint32
+ if initialNotification {
+ _p0 = 1
+ }
+ r0, _, _ := syscall.SyscallN(procNotifyRouteChange2.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)))
+ if r0 != 0 {
+ errcode = syscall.Errno(r0)
+ }
+ return
+}
+
func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) {
var _p0 uint32
if initialNotification {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c3be0b343..0af495ba0 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -32,7 +32,7 @@ github.com/spf13/pflag
# github.com/zekroTJA/timedmap/v2 v2.0.0
## explicit; go 1.19
github.com/zekroTJA/timedmap/v2
-# golang.org/x/sys v0.37.0
+# golang.org/x/sys v0.38.0
## explicit; go 1.24.0
golang.org/x/sys/plan9
golang.org/x/sys/unix