saiserver: default switch_id on neighbor/route entries when omitted #2300
Conversation
Signed-off-by: Nicholas Ching <nicholaslching@gmail.com>
Signed-off-by: Nicholas Ching <nicholaslching@gmail.com>
|
Commenter does not have sufficient privileges for PR 2300 in repo opencomputeproject/SAI |
|
@tjchadaga please run azure pipeline when possible; this PR is needed for an upstream feature at Cisco ASAP, thanks! |
| } | ||
|
|
||
| void sai_thrift_parse_neighbor_entry(const sai_thrift_neighbor_entry_t &thrift_neighbor_entry, sai_neighbor_entry_t *neighbor_entry) { | ||
| neighbor_entry->switch_id = gSwitchId; |
There was a problem hiding this comment.
I don't quite understand about this change. From my reading of the code, saiserver stores switch_id in gSwitchId (
SAI/test/saithrift/src/saiserver.cpp
Line 438 in c0203c0
There was a problem hiding this comment.
Yes, that is correct; for v1, gSwitchId is always valid so the change is not needed here. I made it to maintain feature parity w/saithriftv2.
Edits to saithriftv2 were needed because gSwitchId in saiserver.cpp is only declared and not assigned on the RPC path.
SAI/test/saithriftv2/src/saiserver.cpp
Line 43 in 9e90412
Instead, sai_thrift_create_switch() stores the OID in the RPC-global switch_id.
So when tests created a neighbor or route over RPC, and did not send switch_id, saithriftv2 would pass switch_id=0 to SAI, resulting in switch id is NULL error (-5). The change to saithriftv2 adds a fallback for when switch_id is not passed in (0): first to the RPC path switch_id set by create_switch (which resolves the -5), then to gSwitchId as backup.
Should I keep this change for feature parity or remove to avoid touching v1?
There was a problem hiding this comment.
I see. Didn't know there are 2 versions of saithrift. I think we can undo the change. Leave v1 as is
| struct sai_thrift_neighbor_entry_t { | ||
| 1: sai_thrift_object_id_t rif_id; | ||
| 2: sai_thrift_ip_address_t ip_address; | ||
| 1: sai_thrift_object_id_t switch_id; |
There was a problem hiding this comment.
I think this is not needed. We should keep the original design. let sai rpc server assign switch_id use the stored RPC scoped switch_id variable. Then the changes in route_configer.py are also not needed.
There was a problem hiding this comment.
I agree, since issue was fixed by RPC-scoped switch_id fallback, no need for tests to pass in switch_id
| } else if (switch_id != SAI_NULL_OBJECT_ID) { | ||
| neighbor_entry->switch_id = switch_id; | ||
| } else if (gSwitchId != SAI_NULL_OBJECT_ID) { | ||
| neighbor_entry->switch_id = gSwitchId; |
There was a problem hiding this comment.
same as above, we probably can remove this line.
| [%- ######################################################################## -%] | ||
|
|
||
| [%- BLOCK special_helper_functions -%] | ||
| extern sai_object_id_t gSwitchId; |
There was a problem hiding this comment.
In thrift v2, gSwitchId is never set, right? We probably can remove this line.
There was a problem hiding this comment.
Yes, that is correct; gSwitchId is never set in v2. I will remove the line.
| } | ||
|
|
||
| void sai_thrift_parse_neighbor_entry(const sai_thrift_neighbor_entry_t &thrift_neighbor_entry, sai_neighbor_entry_t *neighbor_entry) { | ||
| neighbor_entry->switch_id = gSwitchId; |
There was a problem hiding this comment.
I see. Didn't know there are 2 versions of saithrift. I think we can undo the change. Leave v1 as is
Signed-off-by: Nicholas Ching <nicholaslching@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Hi @yue-fred-gao! I've made the requested changes on latest; now only fallback to RPC-scoped switch_id. Changes for this PR are much cleaner now, only touching 1 file; thanks! |
|
|
||
| // OCP sai_test often omits switch_id on neighbor_entry; fall back to the | ||
| // RPC-global switch_id set by sai_thrift_create_switch. | ||
| if (thrift_neighbor_entry.switch_id != 0) { |
There was a problem hiding this comment.
does sai_thrift_neighbor_entry_t have switch_id?
There was a problem hiding this comment.
Yes, thesai_thrift_neighbor_entry_t in thriftv2 is generated from the SAI header sai_neighbor_entry_t, of which switch_id is a member.
Lines 185 to 192 in c0203c0
There was a problem hiding this comment.
I see. The previous change to sai_thrift_neighbor_entry_t is actually for v1. v2 always generate sai thrift from SAI headers.
|
@kcudnik, could you please invoke azure pipelines to run checks, please. I do not have the permissions to do so. |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Hi @kcudnik, the changes in this PR have been reviewed by @yue-fred-gao and are passing checks. When you have a chance, could you please take a quick look and help us merge into master for upstream feature in |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…tdevs for standalone benches (#2316) Context / motivation Part of the SAIVPP unit-test framework (see the sonic-sairedis docker-sai-test-vpp harness). When the OCP sai_test T0 suite runs against a SAI backend on a standalone bench with no SONiC control plane, there is no teamd to create PortChannel netdevs and no IntfMgr to assign LAG/SVI interface IPs — which some backends (e.g. the VPP virtual switch) rely on for LAG bring-up and routed-to-LAG/SVI forwarding. This adds an opt-in way for the test setup to emulate that. What this change does test/sai_test/config/simulate_sonic.py (new). Opt-in helper, active only when SIMULATE_SONIC=1; every entry point is a no-op otherwise. test/sai_test/config/lag_configer.py — create_lag(). When enabled, create the PortChannel<N> netdev teamd would provide, before the SAI LAG create. test/sai_test/config/route_configer.py — create_router_interface(). When enabled, assign the connected IPs IntfMgr would set on a LAG or VLAN(SVI) router interface. Vendor-neutral by construction. PortChannel netdevs use generic Linux ip … type bond; LAG RIF IPs use ip addr add. A VLAN SVI has no host-interface netdev to mirror from, so its address is programmed via command templates supplied by the caller (SVI_RIF_SET_IP_CMD / SVI_RIF_PROBE_CMD, with {ifname}/{addr} placeholders) — no backend-specific tooling is hardcoded in sai_test. All interface-name prefixes and address patterns are env-overridable. Scope / risk 3 files (one new module + two setUp-path hooks) — test-config helpers only; no change to SAI/backend code or packet semantics. Fully opt-in with default-off: with SIMULATE_SONIC unset, all entry points no-op, so real-HW and other OCP consumers are unchanged unless they opt in. Dependencies None. Independent of #2299 / #2300 / #2301 (edits different functions); targets master.
…ix v4/v6 NHG port-list aliasing (#2301) Context / motivation Part of the SAIVPP unit-test framework (see PR 1 / our docker-sai-test-vpp/devdocs/, esp. the 6-19 entry). Three independent correctness/robustness fixes in the OCP sai_test config helpers that the suite needs when run against the VPP SAI backend. What this change does test/sai_test/config/port_configer.py — drop bridge_id on create_bridge_port. Passing bridge_id to sai_thrift_create_bridge_port caused a create failure in our backend; the default 1Q bridge is used, so the argument is redundant. Removing it lets bridge-port creation succeed. test/sai_test/config/port_configer.py — env-gated, bounded port bring-up wait. turn_up_and_get_checked_ports() waited per port, serially (retries × sleep) for oper-status UP. On a 32-port topology where oper-status is slow to settle, this is ~60s+ of dead time per common-config build. The wait is now tunable via env (SAI_PORT_UP_RETRIES, SAI_PORT_UP_POLL_INTERVAL, SAI_PORT_UP_SHARED_WAIT) and can poll all ports together in one bounded window. Defaults preserve the original behavior (per-port wait), so real-HW/other OCP consumers are unchanged unless they opt in; only our harness sets the fast values. test/sai_test/config/route_configer.py — give v4/v6 NHGs independent member_port_indexs. create_nexthop_group_by_nexthops() constructed the v4 and v6 NexthopGroup objects sharing one Python list object for member_port_indexs. A mutation on one group (member remove/re-add tests) then corrupted the other's port list (ValueError: list.remove(x): x not in list). Each group now gets its own list(...) copy. (Latent aliasing bug, independent of any harness specifics.) Scope / risk 2 files, +64/−25 — test-config helpers only; no change to SAI/backend code or packet semantics. The port-up change is opt-in via env with original defaults, so it does not alter timing for existing consumers. The bridge_id removal relies on the default 1Q bridge (already how these tests are used). Dependencies None. Related to #2299 and #2300, however, their edits are isolated and each target master.
Context / motivation
Part of the SAIVPP unit-test framework (see PR 1 / our
docker-sai-test-vpp/devdocs/). When running the OCPsai_testsuite against the VPP SAI backend, neighbor- and route-create tests failed at create time withSAI_STATUS_INVALID_PARAMETER (-5):Root cause
sai_thrift_neighbor_entry_t/sai_thrift_route_entry_tcarry aswitch_id, but many OCP tests build these entries with onlyrif_id(+ip_address/destination) and omitswitch_id. The saithriftv2 RPC server copied the thriftswitch_idstraight through, so meta validation receivedswitch_id == 0and rejected the create. (Tests that pass through the common-config path, which setsswitch_idexplicitly, succeeded — only entries that omit it failed.)What this change does
meta/templates/sai_rpc_server_helper_functions.tt— customsai_thrift_parse_neighbor_entry()/sai_thrift_parse_route_entry()that, when the thriftswitch_idis0, fall back to the RPC-globalswitch_id(the OID returned bysai_thrift_create_switch) and thengSwitchId. (The auto-generated struct copies for these two entry types are skipped in favor of these.)test/saithrift/src/switch_sai.thrift,switch_sai_rpc_server.cpp— the sameswitch_idfield + fallback in the legacy v1 thrift server, for parity.test/sai_test/config/route_configer.py— passswitch_id=self.dut.switch_idexplicitly on the route entries the common config builds, so the persisted T0 config is consistent regardless of the fallback.This mirrors how a real ASIC SAI shim behaves (the switch is unambiguous), and unblocks the neighbor/route-create-on-RIF tests.
Scope / risk
switch_idin the test common config.switch_id— the fallback only triggers when it is0/omitted.Dependencies
None. Related to #2299, however, their edits are isolated and each target
master.