Skip to content

[code sync] Merge code from sonic-net/sonic-buildimage:master to master - #3071

Open
mssonicbld wants to merge 90 commits into
Azure:masterfrom
mssonicbld:sonicbld/master-merge
Open

mssonicbld wants to merge 90 commits into
Azure:masterfrom
mssonicbld:sonicbld/master-merge

Conversation

@mssonicbld

Copy link
Copy Markdown
Collaborator
* c1359b01f - (head/master) snmp: prevent newline injection in generated config (#29319) (2026-09-08) [jithinv86]
* 0326efa0b - Add inode real time usage in monit script (#29276) (2026-09-08) [Feng-msft]
* c252843da - [Mellanox] Increase TC3 DWRR weight to 26 for SN6600_LD SPC6 SKUs (#29255) (2026-09-08) [Jianyue Wu]
* 9297b9879 - [submodule] Update submodule sonic-platform-modules-arista to the latest HEAD (#29213) (2026-09-08) [Justin Wong]
* c25c59661 - [marvell] Formalize create_only_config_db_buffers (2026-09-08) [Matt Hoffman]
* 50cccb059 - [submodule] Update submodule sonic-platform-common to the latest HEAD automatically (#29399) (2026-09-08) [mssonicbld]
* 29e54dde4 - [submodule] Update submodule dhcpmon to the latest HEAD automatically (#29398) (2026-09-08) [mssonicbld]<br>```

mssonicbld and others added 7 commits September 8, 2026 20:13
… (#29398)

#### Why I did it
src/dhcpmon
```
* ecebfe4 - (HEAD -> master, origin/master, origin/HEAD) [dhcpmon] Validate downstream DHCPv4 reply fan-out (Azure#107) (21 hours ago) [Xichen96]
```
#### How I did it
#### How to verify it
#### Description for the changelog
… automatically (#29399)

#### Why I did it
src/sonic-platform-common
```
* 34d7720 - (HEAD -> master, origin/master, origin/HEAD) [eeprom] Use swsscommon instead of redis-py in eeprom_tlvinfo. (Azure#748) (11 hours ago) [Jianyue Wu]
```
#### How I did it
#### How to verify it
#### Description for the changelog
[marvell] Formalize create_only_config_db_buffers
…est HEAD (#29213)

Update the following submodules to the latest head:
- aspeed/sonic-platform-modules-arista
- broadcom/sonic-platform-modules-arista

Signed-off-by: Justin Wong <jvwong@arista.com>
…9255)

[Mellanox] Increase TC3 DWRR weight to 26 for SN6600_LD SPC6 SKUs
Add inode real time usage in monit script
Why I did it
SNMP_USER values and SNMP_COMMUNITY keys were rendered directly into whitespace-delimited snmpd.conf directives. Values containing LF, CR, CRLF, spaces, tabs, vertical tabs, or form feeds could create additional directives or alter directive arguments when ConfigDB/YANG validation was bypassed through a direct Redis write.

Work item tracking
Microsoft ADO (number only): 39463594
How I did it
Added leaf-specific YANG patterns rejecting carriage returns, line feeds, and tabs in SNMP user names, authentication passwords, encryption passwords, and community names.
Kept the validation changes local to the affected leaves; no shared typedef was broadened or changed.
Removed Net-SNMP whitespace separators (space, tab, vertical tab, form feed, CR, and LF) from every rendered SNMP_USER value at the snmpd.conf.j2 sink.
Applied the same sink protection to community keys used by rocommunity, rocommunity6, rwcommunity, and rwcommunity6.
Protected both RO and RW paths and retained valid clean rendering behavior.
Added YANG negative cases for LF, CR, CRLF, and tabs in all affected free-form fields.
Added real sonic-cfggen coverage for same-line argument injection and newline configuration injection.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@mssonicbld

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

brcarr-nv and others added 12 commits September 8, 2026 20:20
… MCTP (#29044)

Switch-BMC images on the NVIDIA AST2700 platform need a supported path to update the BMC firmware from the running SONiC image. Operators expect to use the existing fwutil workflow (fwutil install … fw / fwutil update … fw) rather than a separate out-of-band tool.

This PR adds platform integration so fwutil can drive BMC firmware updates over PLDM for Firmware Update (DSP0267) on MCTP, targeting the Aspeed IRoT link (mctpirot0).

---------

Signed-off-by: Brian Carr <brcarr@nvidia.com>
What: Adds installer/efi_sbatlevel.py and updates installer/default_platform.conf to compare installed vs incoming shim SBAT levels before replacing the UEFI Secure Boot component set (shim, grub, MokManager).
Why: Prevent shim SBAT downgrades; prerequisite for safe SONiC-to-SONiC downgrade on Secure Boot systems (relates to #28739).
How: On install, compares SBAT timestamps; preserves the complete installed bundle on downgrade or comparison failure, and repairs an unreadable installed shim with the incoming bundle. Errors out if it can't preserve an incomplete installed set.
Testing: CI green (CLEAN/MERGEABLE), APPROVED. Manual test script included in PR; additional Secure Boot test cases in progress in sonic-mgmt.

Signed-off-by: Ely Barnea <elybarnea@microsoft.com>
What: Replaces the platform-specific Watchdog class in platform/aspeed/sonic-platform-modules-nokia/h6-128 with the common BMCWatchdog from sonic-platform-common; deletes the old watchdog.py and wires chassis.py to BMCWatchdog via the hw-watchdog-mgrd UPIC socket.
Why: The aspeed BMC watchdog moved to a daemon (hw-watchdog-mgrd) exposing a UPIC socket, and a common BMCWatchdog class was added to avoid client-side duplication. Nokia's h6-128 was never updated and retained the original bug.
How: Import BMCWatchdog and initialize it with SOCKET_PATH /run/hw-watchdog-mgrd/hw-watchdog-mgrd.sock, removing the legacy ioctl/sysfs watchdog implementation.
Testing: CI green (CLEAN/MERGEABLE), APPROVED.

Signed-off-by: Chandrasekaran Swaminathan <chander@nexthop.ai>
…omatically (#29414)

#### Why I did it
platform/alpinevs
```
* ed558c8 - (HEAD -> master, origin/master, origin/HEAD) [AVS-lite] Alpine start order and config files fixed (Azure#47) (11 hours ago) [Sree Iyer]
```
#### How I did it
#### How to verify it
#### Description for the changelog
…automatically (#29417)

#### Why I did it
src/sonic-mgmt-framework
```
* c08cc7b - (HEAD -> master, origin/master, origin/HEAD) [CLI] Require explicit CA for remote Python REST connections (Azure#166) (8 hours ago) [Ashutosh Agrawal]
```
#### How I did it
#### How to verify it
#### Description for the changelog
… automatically (#29418)

#### Why I did it
src/sonic-platform-common
```
* 7ff32c1 - (HEAD -> master, origin/master, origin/HEAD) Add SFF-8024 Rev 4.14 LRO (RTLR) AppSel host electrical interface codes (Azure#749) (5 hours ago) [Bobby McGonigle]
```
#### How I did it
#### How to verify it
#### Description for the changelog
…omatically (#29421)

#### Why I did it
src/sonic-swss-common
```
* 42f5152 - (HEAD -> master, origin/master, origin/HEAD) [common]: Add shared VRF name validation (Azure#1242) (8 hours ago) [Ashutosh Agrawal]
```
#### How I did it
#### How to verify it
#### Description for the changelog
- Why I did it
Support CLI command: 'show interfaces label-port status' for sn6810_ld

For all supported platforms, platform.json should be extended with:

label_port_lanes_mapping (object):
a. Key: Label-port identifiers (strings, e.g., "1", "2").
b. Values: list of lane numbers (strings, e.g., ["1", "2", "3", "4"] ).
For multi-ASIC platforms only - number_of_lanes_per_asic (stringified integer) - Used to compute global lane offsets on multi-ASIC systems: global_lane = local_lane + (asic_index × number_of_lanes_per_asic).
Example:

platform.json

// Single-ASIC

"label_port_lanes_mapping": {
   "1": ["0", "1", "2", "3"],
   "2": ["4", "5", "6", "7"],
   ...
   "127": ["504", "505", "506", "507"],
   "128": ["508", "509", "510", "511"]
}
// Multi-ASIC

"number_of_lanes_per_asic": "512",
"label_port_lanes_mapping": {
   "1": ["0", "512", "1024", "1536"],
   "2": ["1", "513", "1025", "1537"],
   ...
   "511": ["510", "1022", "1534", "2046"],
   "512": ["511", "1023", "1535", "2047"]
}

- How I did it
Validate it on a simulation

- How to verify it
Run the following command: 'show interfaces label-port status'

Example output:

Single-ASIC ( 2 x 4x)

>> show interfaces label-port status
Label-port | Lane 1        | Lane 2        | Lane 3        | Lane 4
-----------|---------------|---------------|---------------|---------------
1          | Ethernet0(UP) | Ethernet0(UP) | Ethernet0(UP) | Ethernet0(UP)
2          | Ethernet4(UP) | Ethernet4(UP) | Ethernet4(UP) | Ethernet4(UP)
3          | Ethernet8(UP) | Ethernet8(UP) | Ethernet8(UP) | Ethernet8(UP)
...
128        | Ethernet508(UP) | Ethernet508(UP) | Ethernet508(DN) | Ethernet508(UP)
Single-ASIC ( 4 x 2x)

>> show interfaces label-port status
Label-port | Lane 1        | Lane 2        | Lane 3        | Lane 4
-----------|---------------|---------------|---------------|---------------
1          | Ethernet0(UP) | Ethernet0(UP) | Ethernet2(UP) | Ethernet2(UP)
2          | Ethernet4(UP) | Ethernet4(UP) | Ethernet6(UP) | Ethernet6(UP)
3          | Ethernet8(UP) | Ethernet8(UP) | Ethernet10(UP) | Ethernet10(UP)
...
128        | Ethernet508(UP) | Ethernet508(UP) | Ethernet510(DN) | Ethernet510(UP)
Multi-ASIC

>> show interfaces label-port status
Label-port | Lane 1              | Lane 2              | Lane 3              | Lane 4
-----------|---------------------|---------------------|---------------------|---------------------
1          | Ethernet0/asic0(UP) | Ethernet512/asic1(UP) | Ethernet1024/asic2(UP) | Ethernet1536/asic3(UP)
2          | Ethernet1/asic0(UP) | Ethernet513/asic1(UP) | Ethernet1025/asic2(UP) | Ethernet1537/asic3(UP)
3          | Ethernet2/asic0(UP) | Ethernet514/asic1(UP) | Ethernet1026/asic2(UP) | Ethernet1538/asic3(UP)
...
512        | Ethernet511/asic0(UP) | Ethernet1023/asic1(UP) | Ethernet1535/asic2(DN) | Ethernet2047/asic3(UP)

Signed-off-by: Zili Bombach <zbombach@nvidia.com>
- Why I did it
To add fast-reboot support for multi-asic devices, according to this HLD - sonic-net/SONiC#2306

- How I did it
Enhanced services startup scripts to support fast reboot on multiple ASICs

- How to verify it
by running fast-reboot on a multi-asic device and verifying that all services start with the fast-reboot path.

Signed-off-by: Yair Raviv <yraviv@nvidia.com>
… what patches fix (#29237)

#### Why I did it

Eight things the SBOM and its vulnerability report got wrong, all in the `ENABLE_SBOM=y` path.

| Problem | Consequence |
|---|---|
| A patch that fixes a CVE doesn't record which one | SONiC patches rather than rebasing, so the SBOM honestly reports the older upstream version — a scanner then reports issues we already fixed, with no way to tell which |
| VEX-suppressed findings are dropped from the report entirely | Package, version and history unchanged, finding just gone — indistinguishable from a scan that failed |
| An SBOM carries no identifier of its own | The vulnerability report can only reference it by filename, which breaks as soon as either file is copied |
| syft catalogues every file on the image | **57,332 of 65,870 components, 24.8 MB of 54 MB.** No purl, version or CPE, so no feed can match one; the CycloneDX encoder drops syft's file-ownership links, so nothing says which package owns a file; and they aren't attested — the SLSA provenance names one subject, the `.bin` |
| The dependency graph has no root | Nothing descends from the image, all 37 containers appear in no edge, **7,569 of 8,538 packages have no edge at all**. So the SBOM can say a package is vulnerable but not which container ships it — the first question anyone triaging asks. `README.sbom.md` already claimed this nesting existed |
| One package is described as two components | **156 packages of 7,689**, each listed twice under a different package URL namespace — `pkg:deb/sonic/openssl` beside `pkg:deb/debian/openssl`, `pkg:deb/sonic/bash` beside `pkg:deb/bash`. Every finding against them is counted twice, and a consumer asking what is affected gets two answers for one thing |
| A dependency read from a lockfile is not attributed to anything | A Go module is compiled into a program, and the program is what its `go.sum` sits beside. Of **952 such dependencies, 900 appear in no edge at all** and 16 hang off the image, which says the image depends on a Go module. So the SBOM can say a module is vulnerable but not which of our programs it was built into |
| Code compiled into a program is attributed to the filesystem it sits in | syft records which executable a Go module was linked into and nothing reversed that, so `stdlib` was a direct child of the host filesystem when what it actually is is the runtime inside `/usr/bin/containerd` |

##### Work item tracking
- Microsoft ADO **(number only)**: N/A

#### How I did it

| Change | How |
|---|---|
| Patches record what they fix | A CVE in a patch's filename, `Fixes:` or `Subject:` header goes into `pedigree.patches[].resolves[]`. Only those — a CVE mentioned in passing isn't a claim to fix it. Parsing moves from `sbom_extract_vex_from_patches.py` into a shared `scripts/sbom_cve_refs.py`, so the SBOM and the VEX statements can't disagree |
| Suppressed findings stay in the report | Each carries an `analysis` block saying what the VEX statement claimed; "already fixed" is reported as fixed, not "does not apply". `--fail-on` still ignores them, so nothing newly fails |
| Each SBOM gets a serial number | Derived from its own contents, not random — `README.sbom.md` promises identical builds produce identical SBOMs. The vulnerability report records it, so the two match by identity |
| `affects[].ref` points at a component reference | It was a package URL. In our own SBOMs those are the same text, which is why it went unnoticed |
| Files are no longer catalogued | syft runs with `file.metadata.selection=none` — stopped at the source, which also skips digesting every file. Output is filtered for `type: file` regardless, since trivy has its own defaults. The scanner cache is versioned: the input didn't change, only our reading of it |
| One package is one component | `merge_components` already keyed on `(name, version)` so the three producers collapse into one record. The key also carried architecture, and only recipe-emit and observation fragments set the `sonic:arch` property it read — so all 5,826 syft components compared as architecture `""` and never matched the recipe fragment describing the same `.deb`. Architecture leaves the key: the recipe takes it from the `.deb` filename, which says `amd64` for a `symcrypt-openssl` whose control file says `all`; the observation stamps `CONFIGURED_ARCH` on everything, which says `amd64` for `Architecture: all` packages like `ifupdown2`; only syft reads dpkg. One document describes one image built for one architecture, and dpkg will not install one name at one version twice within it |
| The winner keeps what only the filesystem knew | Merging costs the loser's record, and the loser is the only one that read a real filesystem. For 65 packages it held the only note of which Debian release they were installed on — syft's `distro=` qualifier, which grype uses to select an OS advisory feed. For 535 it held `upstream=`, the Debian **source** package a binary package was built from: libssl3 from openssl, apt-utils from apt. Debian publishes advisories against the source package, so a binary package without it cannot be matched to the advisory that covers it. Both move to the winner, the same reasoning that already moves the CPE. Named as a list of what only a real filesystem can know, rather than as a rule about `distro` that happens to be applied once — the first version of this promotion carried `distro` alone, and a full rebuild showed it had silently cost all 535 packages their source package |
| A lockfile dependency says which program it was built into | Two causes, both fixed at the source. `scope_from_tarball_path` returned the tarball path when it could not derive a scope, so every tarball under `target/versions/build/log-*/` — which every build produces, and which `parse_lockfiles` collects because it walks all of `versions/` — gave its components a scope of `target/versions/build/log-.../lockfiles.tar.gz`. Nothing treats that as a scope, so 900 were placed nowhere; it now yields nothing, which is true rather than merely useless. And a lockfile's scope says which filesystem it was harvested from, not that the image depends on what it lists, so those no longer attach to the image. What was needed to do better is now kept: the parser records each lockfile's own path instead of discarding it, recipes record the source tree they were built from, and a dependency whose lockfile sits under a recipe's source tree is attached to what that recipe built — longest path first, so a vendored tree wins over the tree above it. Where the two do not line up nothing is emitted and the dependency stays unrooted, which is the rule the containment pass already holds to |
| Package URLs are escaped once, in one place | Both producers built the string by interpolation, so one version reached the document as `3.5.6-1~deb13u2+fips` from the recipe and `3.5.6-1~deb13u2%2Bfips` from syft — one package, two spellings, because `+` is reserved and only one of them escaped it. A new `scripts/sbom_purl.py` assembles and escapes for both, so the two cannot disagree again |
| The dependency graph is rooted | `run_scanner` stamps `sonic:scope` (`host-image` / `dockers/<name>`) on what it returns, after the cache so a cached archive stays reusable. `merge_components` carries scopes across the dedupe — the recipe-emit winner outranks the observation, but only the observation knows where it ended up. `sonic:scope` becomes multi-valued, since a shared library is in twenty containers. `build_dependency_graph` gains a containment class: image → the host filesystem and the containers it installs, and each of those → the packages it holds. The host filesystem gets a component of its own (`sonic:host-image`, type `operating-system`) so packages installed outside a container hang off a place rather than off the image |
| Code compiled into a program hangs off the program | The same defect as the lockfile row above, arriving by the other route: that one comes from a lockfile in a source tree we built, this one from scanning a filesystem we assembled, and nothing was reversing the second attribution. Scanning names the program but emits no component for it, so one `type: application` component is synthesized per program per scope and the modules hang off it: `host-image -> /usr/bin/containerd -> stdlib`. The pairing is made at scan time rather than after `merge_components`, because syft emits one record per (module, program) and they all share a package URL — the dedupe unions every record's scope but keeps only one record's location, so pairing afterwards hands that one path every scope the merge unioned in. A location under `/var/lib/docker/overlay2/` is a container's own file reached through the host filesystem; the per-container scan sees it at its real path, so no program is named after the overlay directory (whose name changes every build) and the module is not attached to the host filesystem either |

Two notes:

- **Nothing new is collected.** syft already ran once per container and once over the host rootfs, so it always knew which filesystem each result described — that knowledge just stops being discarded. A component that still can't be placed is left unrooted rather than attached to the image on the assumption it must be somewhere.
- **Dropping the file components removed two faults that only ever affected them:** the host and per-container scans shared one flat path namespace, so 10,921 paths were listed twice and 322 resolved to two different digests; and seven files were emitted with no digest at all, silently, because the scanner couldn't read them (`/etc/sudoers`, `/etc/pam_radius_auth.conf`, `chrony.keys`).

#### How to verify it

Run against a real build tree and a real 18 MB image SBOM — dropping the file inventory is what shrank it.

**Files dropped, packages untouched** — one container, syft 1.44.0:

| | default | `selection=none` |
|---|---:|---:|
| `type: file` components | 6,804 | **0** |
| package components | 220 | **220** (identical bom-refs) |
| dependency edges | 173 | **173** |
| output size | 2,485,196 B | **606,726 B** |

**Graph rooted** — builder run over a real broadcom SBOM's components. These are the
graph builder's own before/after over the pre-branch document, so the totals are that
document's, not the count a build at this branch's head produces:

| | before | after |
|---|---:|---:|
| `dependencies[]` entries | 176 | **194** |
| edges | 1,235 | **7,818** |
| components reachable through `dependencies[]` | 969 of 8,538 (11%) | **7,420 of 8,539 (87%)** |
| containers under the image root | 0 of 37 | **37 of 37** |
| image component present in the graph | no | **yes** |
| components left deliberately unplaced | 7,569 | **1,119** |

The after column includes the `sonic:host-image` node: one extra `dependencies[]` entry, one extra edge from the image, and one extra component in the document — which is why the reachable denominator moves by one too. The image's direct children are the containers it installs plus the host filesystem; the host packages that used to hang off the image directly now hang off that.

**Compiled-in code hangs off the program** — the builder run twice over one build
tree, identical inputs, only the attribution code differing:

| | before | after |
|---|---:|---:|
| program components | 17 | **21** |
| ...named after a `/var/lib/docker/overlay2/` path | 9 | **0** |
| `dependencies[]` entries | 179 | **183** |
| components reachable from the image root | 6,782 | **6,800** |
| host filesystem's direct children | 5,346 | **5,346** |
| Go modules hanging off the host filesystem | 0 | **0** |
| dangling references | 0 | **0** |
| non-program components added or removed | — | **0 / 0** |

The nine overlay2-named programs are the reason the pairing moved to scan time. A module
seen through the directory docker unpacked a container into would otherwise name a program
after a directory whose name changes every build, and the same collapse put
`/usr/bin/containerd`, `/usr/bin/dockerd` and `/usr/bin/runc` inside `docker-sonic-otel`,
which ships none of them, while nine of `docker-sonic-gnmi`'s own programs went unrecorded
and `/usr/sbin/rest_server` was credited with 1 of its 40 modules. The host filesystem's
direct children are unchanged because a module only ever seen inside a container layer is
left to the per-container scan rather than attached to the filesystem that layer sits in.

**One package, one component** — `merge_components` replayed over a real 8,374-component
image SBOM's own components, fed back in the priority order `main()` uses. Again a replay
over the pre-branch document: `7,680` is what that input merges to, not the component
count of a document built at this branch's head.

| | before | after |
|---|---:|---:|
| deb packages carrying more than one namespace | 156 | **0** |
| merged components | 8,374 | **7,680** |
| recipe-emit winners inheriting a `distro=` qualifier | 0 | **65** |
| components carrying a `distro=` qualifier | 587 | **587** |
| components carrying an `upstream=` qualifier | 535 | **535** |
| components carrying a `publisher` | 587 | **587** |
| packages whose stated version is not the one installed | 9 | **0** |
| lockfile dependencies attributed to what was built beside them | 0 | **60** |
| a crate and the .deb built from it merged into one component | 2 | **0** |
| components asserted to be in the image that are the build toolchain | 658 | **0** |
| vulnerabilities reported against that toolchain | 216 | **0** |
| `cyclonedx validate --input-version v1_6` | **rejected** | **valid** |

Re-running the *old* merge over that input returns it unchanged (8,374 → 8,374), which is the check that the harness reproduces the real merge: the input is that merge's own output.

**The build environment is described in `formulation`, not in `components`.** A lockfile harvested from `versions/build/log-*/lockfiles.tar.gz` comes from the container that *compiles* SONiC, and it holds two unrelated things: paths under `sonic/` are our own source trees, whose dependencies really are linked into the binaries we ship, and everything else is the toolchain. `usr/share/go-1.19/src/go.sum` is the Go compiler's own source tree, and a real broadcom image ships no golang package at all — no shipped scope's harvest contains a single `usr/` path. Left in `components` they are asserted to be image contents, because CycloneDX reads a component with no `scope` as `required`; that is 658 components and 216 vulnerabilities reported against a compiler nobody runs, conspicuous because nothing pulls them in.

`scope: "excluded"` does not fix that, and this was measured rather than assumed: against **grype 0.112.0 and 0.118.0**, one component reports the same 20 matches whether it is marked `excluded`, `optional`, `required`, or nothing at all. In `formulation` — the section CycloneDX 1.5 added for how an artifact was built — grype reports **0**. Nothing is discarded, so a build-chain compromise (xz-utils was introduced through a build system, not through source) stays answerable from the same document.

**The build now checks its own document, and `SBOM_STRICT=1` makes a failure fatal.** That is the actual fix; the one below is the bug it would have caught. It runs at both write sites using the cyclonedx-cli already provisioned for the SPDX export, and it passes `--fail-on-errors` — without that flag cyclonedx-cli prints "BOM is not valid." and **exits 0**, so the obvious spelling of the check passes on a document the same command has just rejected.

**The document validates now, and did not before.** `cyclonedx validate --input-version v1_6` rejected every SBOM this produced: `pedigree.patches[].diff` carries `url` and `text` and nothing else, and this emitted a `hashes` array beside them — 530 components carry one, so a single unschema'd field invalidated the whole file. Nothing in the build runs the validator, so the failure was silent and the tools we happened to use were lenient enough not to care. The digest moves to a `sonic:patch_sha256` property, which keeps *which* patch was applied, and the change-detection signature reads it from there — still reading the old spelling too, so a comparison against an older document does not read as every patch having changed.

Those last four came out of a self-review done before rebuilding, by replaying the merge over the previous document — the previous merge's own output, so a real 8,374-component input — and comparing every field, property and qualifier either side of it. Three of the four were introduced by the dedupe in this branch, and the fourth was inert rather than wrong: attributing a lockfile dependency to what was built beside it matched 0 of 952, because harvested paths are rooted at the source tree and the source trees recipes record are repository-relative. Nothing reported it, because "nothing matched" and "nothing to match" produce the same empty result.

The replay is the check worth keeping: a merge that drops a field states nothing about having dropped it, and every one of these was found by counting a property either side rather than by reading the diff.

The merged count above was later confirmed by a full rebuild, which produced 7,680 components and no duplicate package URLs. That rebuild also caught the `upstream=` loss: it is the qualifier count in the table that made a regression visible which nothing else would have reported, since a package quietly losing its source package still scans, still resolves and still looks right.

Of the 694 records absorbed, 686 are a syft observation of a package a recipe fragment or a post-versions observation already described, and every one carries the same name and version as the record it merged into. Ten do not, and all ten are the epoch drift `_normalize_version` was written for — `openssh-server 1:10.0p1-7+fips` into `openssh-server 10.0p1-7`, `fancontrol 1:3.6.0-7.1` into `3.6.0-7.1`. Two Rust crates absorb the `.deb` built from them (`syslog-counter`, `sonic-supervisord-utilities-rs`); eleven SONiC submodule packages absorb the `.deb` built from them, which is `build_purl` choosing the `pkg:github` identity as primary and is the intended behaviour. No two different upstream versions merge, and every `bom-ref` in the result is still unique.

**A dependency knows which program it is in** — the graph builder over the same 8,374-component image:

| | before | after |
|---|---:|---:|
| lockfile dependencies in no edge at all | 900 of 952 | **0 once the producer records the lockfile** |
| lockfile dependencies hanging off the image | 16 | **0** |
| edges over an *existing* document, lockfile attribution only | 25,128 | **25,128** (none added, none removed) |

The last row is about the lockfile attribution specifically: it rests on facts the producer did not record before, so for that class an already-built SBOM is byte-identical and the improvement arrives with the next build. Hanging compiled-in code off the program is the deliberate exception — it reads `syft:package:foundBy` and `syft:location:0:path`, which syft has always emitted, so re-running the builder over an already-built document does move it. The scope derivation is checked against the real strings — `target/versions/build/log-20260830011338/lockfiles.tar.gz` now yields no scope, while `versions/dockers/docker-fpm-frr/post-versions/` and `versions/host-image/post-versions/` still yield theirs. Attribution is exercised directly: a module beside `sonic-gnmi`'s `go.sum` attaches to sonic-gnmi, a vendored tree inside it wins over the tree above and does not also attach to the outer one, a lockfile under nothing we built stays unrooted, and a `host-image` lockfile is not attached to the image.

The lockfile path shape is taken from a real harvest: `collect_version_files` harvests from `/sonic`, which `Makefile.work` mounts as `$(PWD)`, so a harvested path is `sonic/<repo-relative path>` and the `sonic/` prefix the matcher strips is not a guess. The failure mode if a given build disagrees is that the dependency stays unrooted — the same place it is today, and never a wrong edge.

No regression, same input: with no `root_ref` the builder reproduces the previous graph exactly (all 1,235 edges); with one, every one of those edges survives; no self-edges; every `dependsOn` target resolves to a component in the document or the root. Scanning one archive twice under two scopes returns 220 components each time carrying the scope asked for, while the cached entry stays unscoped and reusable.

The 1,119 still unplaced are 932 lockfile-derived transitive deps (scope is the lockfile, not a filesystem) and 187 recipe-emit fragments the scanner didn't also see. Placing them needs build-side data not captured today.

Other checks:

- **VEX output unchanged** by the shared patch reader — `sbom_extract_vex_from_patches.py` before and after over the same `src/`: 17 statements, identical content and logs (0 of 17 differ, ignoring the generation timestamp).
- **Patches resolve correctly.** `src/thrift_0_14_1/thrift.patch` has five patches, one CVE-named — only `0002-cve-2017-1000487.patch` gets a `resolves[]` entry, lower-case identifier normalised.
- **Suppressed findings carry their reason** — `state: not_affected`, `justification: code_not_present`, statement namespace and reason in `detail`.
- **`affects[].ref`** resolves to the component reference against an SBOM where it deliberately differs from the package URL.

**Covered by a full build:** broadcom, broadcom-dnx and broadcom-legacy-th were built with `ENABLE_SBOM=y` at this branch's head, each producing a document that passes `cyclonedx validate --input-version v1_6 --fail-on-errors`, carries a deterministic serial number, has no `type: file` component and no duplicate package URL, and whose dependency graph the checker reports no problems on. **Not covered:** the non-broadcom platform legs. Builds without `ENABLE_SBOM` are unaffected — the path is skipped at the make level.

#### Which release branch to backport (provide reason below if selected)

- [ ] 202305
- [ ] 202311
- [ ] 202405
- [ ] 202411
- [ ] 202505
- [ ] 202511
- [ ] 202512
- [x] 202605
- [ ] 202608

Only 202605, and only the `sbom: emit a document that validates` change. That branch
carries `scripts/sbom_fragment.py` with a `hashes` array inside
`pedigree.patches[].diff`, which CycloneDX's schema does not allow, so every SBOM it
produces is rejected by `cyclonedx validate --input-version v1_6`. That is a defect in a
shipped release rather than an improvement. 202305 through 202512 do not carry the
commit and need nothing. The rest of this PR improves an opt-in feature and should not
be backported.

Tracking issue/work item for backport/cherry-pick request (GitHub issue or Microsoft ADO): N/A
Failure type: N/A

#### Tested branch

- [x] master
- [ ] N/A

#### Test result

master: verified against a locally built `sonic-broadcom.bin.cdx.json` (18 MB) and the `src/` tree it was built from, as described above.

#### Description for the changelog

sbom: record in the SBOM which vulnerabilities a carried patch fixes, keep VEX-suppressed findings in the vulnerability report, give each SBOM a serial number, stop cataloguing individual files, root the dependency graph so the image, the host filesystem, the containers it installs and their packages form one tree, stop describing one package as two components under two package URL namespaces, attribute a dependency read from a lockfile to the program it was built into, hang code compiled into a program off that program rather than off the filesystem it sits in, move the build toolchain out of the image's component list into `formulation` so the document stops asserting the image contains its own compiler, and move each patch's digest from an unschema'd `hashes` array into a `sonic:patch_sha256` property so the document validates as CycloneDX 1.6

#### Link to config_db schema for YANG module changes

N/A — no YANG changes.
Retain the upstream image names expected by Kubernetes after pulling images through the configured default registry.

Signed-off-by: losha228 <46000205+losha228@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* consolidate hwsku-level pmon_daemon_control.json for SN5640,SN5610N,SN4280,SN5600,SN4700

Signed-off-by: Matt Hoffman <matthoffman@microsoft.com>
@mssonicbld
mssonicbld force-pushed the sonicbld/master-merge branch from cc8cde5 to a96ade1 Compare September 10, 2026 03:05
@mssonicbld
mssonicbld requested a review from xumia as a code owner September 10, 2026 03:05
@mssonicbld

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

…28990)

Support for this feature was recently added to sonic-linux-kernel.
For more details, see sonic-net/sonic-linux-kernel#589

Signed-off-by: Yury Murashka <yurypm@arista.com>
…omatically (#29450)

#### Why I did it
platform/alpinevs
```
* 7a620dc - (HEAD -> master, origin/master, origin/HEAD) [AVS-lite] Moved config_db as a config option (Azure#48) (12 hours ago) [Sree Iyer]
```
#### How I did it
#### How to verify it
#### Description for the changelog
mssonicbld and others added 15 commits September 17, 2026 19:12
…tically (#29419)

#### Why I did it
src/sonic-sairedis
```
* be4e39da - (HEAD -> master, origin/master, origin/HEAD) [syncd] Do not abort syncd when a FlexCounter poll cycle fails (Azure#2057) (2 days ago) [Liping Xu]
* 32f40190 - [vpp][acl] raise the ACL entry attribute cap and report a missing priority (Azure#2073) (6 days ago) [Longxiang Lyu]
* 320250ad - vpp: interface registry to consolidate scattered interface maps (Azure#2067) (6 days ago) [yue-fred-gao]
```
#### How I did it
#### How to verify it
#### Description for the changelog
Removing `--privileged` from BlueField syncd exposes three missing permissions: DOCA device access, write access to the host hugepage configuration, and permission to lock the memory region.

##### Work item tracking
- Microsoft ADO **(number only)**:

#### How I did it
- Mount InfiniBand and VFIO devices at runtime with narrow cgroup rules.
- Mount `/sys/kernel/mm/hugepages` read-write for the existing hugepage setup.
- Add `IPC_LOCK` and unlimited memlock for the approximately 1.28 GiB NASA mbuf memory region.

This PR remains the prerequisite for separately removing the inherited `--privileged` flag from BlueField syncd.

#### How to verify it
On all four DPUs of a BlueField test setup, an image that had the device and hugepage fixes but where syncd had no `IPC_LOCK` and an 8 MiB memlock limit reproduced the following on every DPU:

```
mlx5_common: Failed to create an MR ... (1378975744 bytes)
mlx5_net: port 0 Rx queue allocation failed: Invalid argument
rte_eth_dev_start:err=-22, port=0
Failed to initialize NASA application - server is down
```

DOCA enumeration succeeds before this failure, confirming that the remaining failure is the RDMA memory-registration permission.

Signed-off-by: Gagan Ellath <gpunathilell@nvidia.com>
…est HEAD (#29474)

* Bump arista-drivers submodule

Signed-off-by: Justin Wong <jvwong@arista.com>
… ConfigDB input injection (#29519)

Why I did it
[Security] Remediate F080 — ConfigDB input injection in remote logging configuration (ADO 39463608).

files/image_config/rsyslog/rsyslog.conf.j2 renders DEVICE_METADATA|localhost.hostname
(passed in as the hostname variable) directly into three $template directives
(SONiCFileFormat, SONiCForwardFormat, SONiCForwardFormatWithOsVersion) with no
escaping, unlike every other ConfigDB-derived string used in this file (source, proto,
vrf, severity, regex, fw_name, server/Target), all of which already strip
newline/carriage-return/quote/backslash/percent characters before use.

The stypes:hostname YANG typedef (sonic-yang-models/yang-models/sonic-types.yang) only
enforces a 1–63 character length restriction — it places no restriction on which characters
are allowed. As a result, a hostname value containing a double-quote followed by a newline can
break out of the double-quoted $template string and inject an arbitrary rsyslog config
directive on its own line (e.g. an action(type="omprog" ...) directive, which rsyslog would
execute as an external program).

os_version sits directly next to hostname in the same unescaped $template line and shares
the identical rendering gap, so it was hardened with the same fix for consistency, even though
it is populated from /etc/sonic/sonic_version.yml at install time rather than being directly
ConfigDB-writable by an operator.
…500)

Description
Fixes a default-value gap in the telemetry/gNMI docker startup scripts. user_auth is read from the GNMI CONFIG_DB entry via extract_field. When the entry or field is missing, this returns an empty string rather than the literal string "null", so the existing check (== "null") did not catch it, USER_AUTH stayed empty, and --client_auth was never passed to the server binary.

Motivation and Context
Ensures the startup scripts always fail closed (default to cert auth) instead of silently omitting the auth flag when user_auth is unset in CONFIG_DB.

How Has This Been Tested?
bash -n syntax check passed on both modified scripts. No functional change when user_auth is explicitly configured.
…#28687)

* [bgpcfgd] Fix TSA route leak to confed-external peers in CONFED BGP

In BGP confederation (e.g. UT2), FRR treats confed-internal neighbors
(the local member ASN and confederation peers, e.g. LT2) as *internal*
and confed-external neighbors (e.g. T3) as *external*. The general
templates put every neighbor into PEER_V4/PEER_V6, but FRR rejects
mixing internal and external members in one peer-group
('Peer-group members must be all internal or all external'). As a
result the confed-external (T3) neighbors end up with NO peer-group,
hence no outbound route-map, so TSA (which rewrites the peer-group
out route-map) cannot stop advertising routes to them -> TSA leaks
routes to T3 on confed UT2 devices.

Fix: add a second peer-group PEER_EXTERNAL_V4/PEER_EXTERNAL_V6 that is
rendered only when confederation is configured and reuses the SAME
in/out route-maps (FROM_BGP_PEER_V4/TO_BGP_PEER_V4 ...). Confed-external
neighbors (ASN != local member ASN and not in the confederation peers
list) are assigned to it. Because the out route-map name is shared,
TSA needs no change - it already rewrites TO_BGP_PEER_V4/V6 which now
also applies to the external peer-group. Non-confed devices render
exactly as before (everything stays in PEER_V4/V6).

To let the templates read the confederation peers, DeviceGlobalCfgMgr
now stores the BGP_DEVICE_GLOBAL|CONFED row in the Directory (it was
previously dropped), and bgpcfgd passes CONFIG_DB__BGP_DEVICE_GLOBAL to
the peer templates. If it is unavailable the templates fall back to
PEER_V4/V6 (current behaviour), so there is no regression risk.

Fixes sonic-net/sonic-buildimage#28551

Signed-off-by: Yatish Koul <yatishkoul@microsoft.com>

* Address review: dedup table-map, prime CONFED at init, add tests

- peer-group.conf.j2: drop the table-map SELECTIVE_ROUTE_DOWNLOAD_V4/V6 lines
  from the PEER_EXTERNAL block. table-map is an address-family-level command
  (not per-peer-group), so it is already applied once by the PEER_V4/V6 block;
  emitting it again for PEER_EXTERNAL was a duplicate (review comment).
- managers_device_global.py: prime the CONFED row from CONFIG_DB in
  DeviceGlobalCfgMgr.__init__ so the peer templates can classify confed-external
  neighbors on the first render. bgpcfgd may process BGP_NEIGHBOR before the
  CONFED update arrives, and a neighbor that renders successfully is not
  re-rendered on a later CONFED change, which would otherwise leave
  confed-external neighbors in PEER_V4 (and leaking during TSA). No-op on
  non-confed devices.
- tests: add general peer-group.conf CONFED golden case (param_confed/result_confed)
  proving confed-external gets PEER_EXTERNAL_V4/V6 reusing TO_BGP_PEER_V4/V6 and
  that table-map is NOT duplicated; add DeviceGlobalCfgMgr unit tests for CONFED
  set_handler (stores in Directory, no TSA push) and del_handler (removes it).

Signed-off-by: Yatish Koul <yatishkoul@microsoft.com>

* [bgpcfgd] Future-proof CONFED handling + add confed test data

- DeviceGlobalCfgMgr: use fail-closed allowlist guard (if key != "STATE":
  return True) in set_handler/del_handler instead of the CONFED denylist, so
  any non-STATE key (e.g. CONFED) can never fall through to configure_tsa()
  and push a spurious TSB (#28515). CONFED is stored in / removed from the
  Directory inside the guard. Guard hunk matches the internal branch to keep
  code-sync clean.
- tests: add negative-key case (unknown key must not reach configure_tsa) and
  general/instance.conf confed fixtures (confed-external T3 -> PEER_EXTERNAL_V4/V6,
  confed-internal peer -> PEER_V4).
- constants: register PEER_EXTERNAL_V4/V6 under bgp.peers.general.bbr so BBR
  toggles allowas-in on them like PEER_V4/V6 (no-op on non-confed devices).

* Address review comments: coalesce get_table, distinct fixture ASNs, prime tests

- managers_device_global.prime_confed_from_config_db: coalesce get_table() to {}
  so a None return (missing table / transient read failure without an exception)
  cannot raise TypeError and break bgpcfgd startup (Copilot review).
- general/instance.conf confed fixtures: set bgp_asn distinct from CONFED.asn
  (64512 vs 65100) so the tests pin that the template compares bgp_session asn
  against bgp_asn (correct) rather than CONFED asn. Golden outputs unchanged
  (bgp_asn is only used in template predicates) (review).
- test_device_global: add success-path and None-table coverage for
  prime_confed_from_config_db by patching swsscommon.ConfigDBConnector, so the
  directory.put path is exercised under pytest (review).

Unit tests: 24 passed (test_device_global), 18 passed (test_templates).

* Add confed iBGP classification fixture

* [bgpcfgd] Extend confed-external classification to unnumbered peers

Unnumbered (interface) peers merged after this PR added a PEER_UNNUMBERED
peer-group. On a confederation device a confed-external unnumbered peer would
land in PEER_UNNUMBERED alongside confed-internal members, hitting the same
FRR internal/external peer-group conflict (#28551) and leaking routes during
TSA. Add a confed-only PEER_EXTERNAL_UNNUMBERED peer-group reusing the
TSA-managed PEER_UNNUMBERED in/out route-maps and route confed-external
interface peers to it. Adds the confed_external_unnumbered instance fixture.

---------

Signed-off-by: Yatish Koul <yatishkoul@microsoft.com>
Co-authored-by: Yatish Koul <yatishkoul@microsoft.com>
Co-authored-by: Yatish Koul <yatishkoul@gmail.com>
SONiC builds FRR with ENABLE_FRR_TCMALLOC=y, which passes
--enable-gperf-tcmalloc. gcc on Debian links with --as-needed by default, and
it keeps a DT_NEEDED entry for a library when the binary's own objects
reference a symbol that library defines. FRR daemons allocate through lib/'s
XMALLOC/XFREE macros, so the malloc-family references sit in libfrr, and the
linker drops libtcmalloc from most daemons including zebra.

libfrr.so.0 still lists libtcmalloc, so ldd and /proc/<pid>/maps both show it
present. The global symbol scope is searched breadth-first from the executable,
so libc.so.6 sits at depth 1 and serves malloc for every caller, libfrr
included. zebra therefore runs on glibc malloc while reporting tcmalloc
enabled, and it holds the RIB.

Carry the upstream fix, which wraps both tcmalloc libraries in a
--no-as-needed region scoped by --push-state/--pop-state.

Upstream: FRRouting/frr#23359
Fixes: sonic-net/sonic-buildimage#29443

Signed-off-by: Deepak Singhal <deepsinghal@microsoft.com>
Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.10.1 to 1.11.1.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](tokio-rs/bytes@v1.10.1...v1.11.1)

---
updated-dependencies:
- dependency-name: bytes
  dependency-version: 1.11.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* add w5000

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* Revert "update"

This reverts commit 12fedb6c542549cb09ff2f1974a6637793f45335.

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update

Signed-off-by: jackson <jackson@micasnetworks.com>

* update device

Signed-off-by: jackson-micas <jackson@micasnetworks.com>

* update micas-vs

Signed-off-by: jackson-micas <jackson@micasnetworks.com>

* update

Signed-off-by: jackson-micas <jackson@micasnetworks.com>

* change file CRLF TO LF

Signed-off-by: jackson-micas <jackson@micasnetworks.com>

---------

Signed-off-by: jackson <jackson@micasnetworks.com>
Signed-off-by: jackson-micas <jackson@micasnetworks.com>
* [config-engine] Validate interface table keys in pfx_filter

Reject malformed interface table keys consistently before template rendering.

Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>

* [config-engine] Use shared interface name validator

Apply the common interface identifier policy in both pfx_filter implementations.

Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>

* tests: cover IPv4-mapped IPv6 interface addresses

Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>

* tests: preserve pfx_filter output newline

Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>

---------

Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>
Why I did it
AdvertiseRouteMgr processes the VRF and prefix components of advertised-route
keys without first validating their format. Invalid keys can therefore produce
malformed configuration and inconsistent cached state.

Work item tracking
Microsoft ADO (number only):
How I did it
Validate routing VRF names with the shared isVrfNameValid() helper and
validate prefixes before processing set and delete operations.
Validate accepted IPv4 and IPv6 prefixes with ipaddress.ip_network while
preserving raw keys for exact set/delete identity.
Reject scoped IPv6, whitespace, control, non-ASCII, and malformed prefix
forms before command generation.
Reject invalid keys before updating cached state or generating configuration.
Add unit coverage for raw-key preservation and rejected key formats.
The shared VRF helper is provided by
sonic-swss-common#1242.

How to verify it
pytest -q src/sonic-bgpcfgd/tests/test_advertise_rt.py
Result: 6 passed.
Why I did it
StaticRouteMgr renders the VRF and prefix parsed from STATIC_ROUTE keys into
FRR configuration. These key components were not validated consistently, so
malformed input could change the structure of the generated routing commands.
The same validation is needed for CONFIG_DB and APPL_DB keys and for both SET
and DELETE events.

Work item tracking
Microsoft ADO (number only):
How I did it
Validate route and nexthop VRF names with the shared helper from
sonic-swss-common#1242.
Validate nexthop interface names with isInterfaceNameValid(), including
PortChannels carried in either ifname or the existing nexthop field,
strengthened by sonic-swss-common#1240.
Validate IPv4 and IPv6 prefixes with ipaddress while preserving the original database key text.
Log and ignore malformed keys before generating FRR configuration, rejecting the entire route when any ECMP identifier is unsafe and preserving the last-known-good route on an invalid replacement.
Add focused tests for valid legacy forms, raw prefix identity and CONFIG_DB lookups,
malformed SET and DELETE events, invalid nexthop identifiers, mixed ECMP rows, and last-known-good state preservation.
This PR carries the sonic-swss-common submodule commit from Azure#1242. It should be
merged after the common-library dependency.
Why I did it
Several Python components need to apply the same validation when processing BGP ASNs. Keeping those checks in each component makes it easy for their behavior to drift.

Work item tracking
Microsoft ADO (number only):
How I did it
Added a common validate_asn() helper to sonic-py-common.

The helper accepts decimal strings and integer values, rejects booleans and other representations, and checks the 32-bit BGP ASN range. Handling of missing values or component-specific sentinel values remains with the caller.

Added unit coverage for accepted values, range boundaries, invalid types, and invalid decimal representations.

Current consumers being updated to use this helper:

bgpcfgd: Validate DEVICE_METADATA BGP ASN #29226 validates the DEVICE_METADATA BGP ASN before caching it.
frr: Strictly validate isolate BGP ASN #29227 uses it as the sonic-cfggen filter for BGP isolation templates.
frrcfgd: Validate BGP table key components #29230 uses it for BGP ASN fields processed by frrcfgd.
How to verify it
Run:

PYTHONPATH=src/sonic-py-common pytest -q --noconftest src/sonic-py-common/tests/test_bgp.py

Result: 22 passed.
Why I did it
arp_update builds a few ping and neighbor commands as strings and evaluates them. The interface and address values are already available separately, so these commands can be called directly.

Keeping the values as individual arguments makes the command handling clearer and avoids parsing them a second time as shell input.

Work item tracking
Microsoft ADO (number only):
How I did it
Added helpers that invoke IPv6 multicast ping and neighbor commands with quoted arguments.
Replaced the generated DualToR flush and replace commands with direct loops over the neighbor rows.
Quoted the related interface, address, and database-key arguments.
Added focused tests for the new helpers.
How to verify it
bash -n files/scripts/arp_update files/scripts/tests/test_arp_update.sh
bash files/scripts/tests/test_arp_update.sh
The helper tests cover shell-metacharacter handling for timeout, arping, ndisc6, ip, and sonic-db-cli arguments.
Why I did it
Ensure BGP peer table keys are validated and interpreted consistently before generating FRR configuration.

Work item tracking
Microsoft ADO (number only): N/A
How I did it
Validate ordinary peer-table VRF names using the shared swsscommon validator.
Parse and normalize IP neighbor addresses.
Accept VNET names up to 255 characters for dynamic peer ranges while requiring command-safe routing-instance and peer-group tokens.
Apply the same validation to SET and DELETE operations.
Add unit coverage for accepted and rejected keys.
Update sonic-swss-common to include [common]: Add shared VRF name validation sonic-swss-common#1242.
How to verify it
Run the bgpcfgd BGP manager unit tests.
@mssonicbld
mssonicbld force-pushed the sonicbld/master-merge branch from 7655a72 to eaeba89 Compare September 18, 2026 03:03
@mssonicbld

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

mssonicbld and others added 9 commits September 18, 2026 19:12
Validated submodule pipeline runs for buildimage commit `61d862a88d29d09ef1e3ecfd32cae9870469d58f` on master `d06e04c7`:

```
buildimage_vs=61d862a88d29d09ef1e3ecfd32cae9870469d58f
common_libs=61d862a88d29d09ef1e3ecfd32cae9870469d58f
src/sonic-dash-api=2ce7ce648ee77a76fcf567191eb4b9ed6cfeed38
platform/vpp=a38dedf1eb7b855a9dbd7ff75df8112e37af9757
src/sonic-dbsyncd=d030540bca61cb32eda24699f6f83ece867860f8
src/sonic-host-services=0cc46258e1ab5f38eac5b5e4df44429b5d9c99d7
src/sonic-mgmt-common=50ba3bd4a238cb156247a22eb9d53efe694a880e
src/sonic-mgmt-framework=29b5acc965c7d761a82bd083c5f1f27117966b0e
src/sonic-platform-common=c0af37dace2b73416bfb7970cee6c15f64da96cd
src/sonic-platform-daemons=3a685f733966f1de5bd55c5941c54e1376f5ac20
src/sonic-snmpagent=e09fd3805de3bd67f39a3797a5a1a79f8323dbb3
src/sonic-swss-common=10d14ae58ae73899a52a2447d1e791a2b7bd1a34
src/dhcpmon=ecebfe4c88e3c68dd5bbd78fa46c2a6b9ad47f87
src/dhcprelay=633c8e1736854fca52553255a9abb9d0f704ce0e
src/linkmgrd=eb7fd014d3ed799e44f1976099c90b57ed6424e0
src/sonic-bmp=12e8c3958f6dfb6482509adee2718db8ea40ace6
src/sonic-dash-ha=6d8b81e968a7f0460199b3e8a9a9ed31a31c981a
src/sonic-gnmi=a2a21baf590ab988d547a80c73c4c5b5f3d3b55f
src/sonic-sairedis=5da475bc9ccf6da23f112cf8c849942b3d1466c5
src/sonic-stp=b803a4ce45113c96a7626563df0b235a81e74729
src/sonic-utilities=2fe754a5df70cd43db66854c23b04e059a9132a5
src/wpasupplicant/sonic-wpa-supplicant=6ca19c73b9c868782b59a0d7adc6ff34de5bbdba
src/sonic-swss=bb6c96decdebdf9d2c75d52c126719f316d53d11
docker_slave_bookworm=61d862a88d29d09ef1e3ecfd32cae9870469d58f
docker_slave_trixie=61d862a88d29d09ef1e3ecfd32cae9870469d58f
sonic_buildimage_ubuntu22_04=61d862a88d29d09ef1e3ecfd32cae9870469d58f

```
[Mellanox] Update buffer pool size calculation for SN6810_LD SKUs
[YANG] Fix QoS scheduler validation for PIR-only configurations
…dm calls (#29599)

kube_commands.py builds kubectl/kubeadm argv lists using the device hostname and CONFIG_DB-derived label values directly.

Added DNS-1123 hostname validation and Kubernetes label-key/value grammar checks before these values are placed into argv, and use '--' to separate options from positional arguments in the kubectl invocations that take the node name. If the hostname fails validation, the calling operation is skipped rather than passing an unvalidated value to kubectl/kubeadm.

No functional change for well-formed hostnames/labels.

Verify:
cd src/sonic-ctrmgrd
python3 -m pytest tests/kube_commands_test.py -v
python3 -m compileall -q ctrmgr
Signed-off-by: dygodwin <179140848+dgodwin-nokia@users.noreply.github.com>
Co-authored-by: dygodwin <179140848+dgodwin-nokia@users.noreply.github.com>
Why I did it
The dhclient exit hook currently inserts DHCP option 224 directly into a sed program. Since the option comes from the DHCP response, characters in the value can change what sed does instead of remaining part of the SNMP community string.

Work item tracking
Microsoft ADO (number only): N/A
How I did it
Validate the supplied value using the same length and character restrictions as the SNMP_COMMUNITY YANG key.
Write the community as a quoted YAML value using printf, without placing it in a shell or sed program.
Replace snmp.yml through a temporary file and preserve the existing file ownership and permissions.
Add regression coverage for valid punctuation, malformed values, replacement, append, and new-file cases.
…rate variable

[aspeed] Console baud rate: single applied source via the U-Boot baudrate variable
[nvidia-bmc] add watchdog platform API for ast2700
@mssonicbld
mssonicbld force-pushed the sonicbld/master-merge branch from eaeba89 to 0b44770 Compare September 19, 2026 03:05
@mssonicbld

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.