Skip to content

Reachability analysis with the full OVN substrate view.

POST
/v1/admin/network/ovn/reachability-analyses
Code sample: Shell / cURL
curl --request POST \
--url https://stratum.example.com/v1/admin/network/ovn/reachability-analyses \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "source": { "kind": "instance-nic", "address": "example", "port": "example", "nicId": "example", "vpcId": "example", "id": "example" }, "destination": { "kind": "instance-nic", "address": "example", "port": "example", "nicId": "example", "vpcId": "example", "id": "example" }, "protocol": "tcp", "port": 1, "trace": false }'

The operator’s reachability analysis: the same pipeline model as the project-scoped endpoint, projected with nothing removed — OVN object names, ACL and routing-policy priorities, verbatim match expressions, NAT rows, and the platform transit carves.

Separate from the tenant endpoint rather than the same one with a verbosity flag, because the difference is not verbosity. This surface can ask questions the tenant surface must never be able to express: from a platform port (IMDS, the DNS recursor, a subnet probe, any tenant’s load-balancer data plane), between projects, or by raw OVN port name.

Endpoints are therefore given as fabric coordinates — an address, and optionally the logical switch port that carries it — rather than as project resources. Nothing here consults the database.

Answers 200 for every verdict including blocked: a closed path is a successful analysis. Install-scope admin (network:GetOvnTopology), the same read-only gate as the topology and doctor endpoints.

Media typeapplication/json
object
source
required

A fabric coordinate. address is what the pipeline is evaluated for; port names the OVN logical switch port directly when you already know it, otherwise nicId resolves it, otherwise it is resolved from the address.

object
kind

Advisory. Changes how the model treats a destination that legitimately leaves the fabric. Defaults to address.

string
Allowed values: instance-nic load-balancer floating-ip internet vpn-client-cidr peered-vpc service-endpoint address
address
required
string format: ipv4
port

OVN logical switch port name.

string
nicId
string
vpcId
string
id
string
destination
required

A fabric coordinate. address is what the pipeline is evaluated for; port names the OVN logical switch port directly when you already know it, otherwise nicId resolves it, otherwise it is resolved from the address.

object
kind

Advisory. Changes how the model treats a destination that legitimately leaves the fabric. Defaults to address.

string
Allowed values: instance-nic load-balancer floating-ip internet vpn-client-cidr peered-vpc service-endpoint address
address
required
string format: ipv4
port

OVN logical switch port name.

string
nicId
string
vpcId
string
id
string
protocol
required
string
Allowed values: tcp udp icmp
port
integer
>= 1 <= 65535
trace

Corroborate the verdict against the dataplane with ofproto/trace on the chassis hosting the ingress port. Shells out, so it is opt-in.

boolean

The analysis, with the substrate view.

Media typeapplication/json
object
query
required

The resolved question, with each endpoint’s address and OVN port filled in.

object
verdict
required

undetermined is not a soft form of either other value. A path the analyzer could not model, rendered as reachable, talks an operator out of investigating a real outage; rendered as blocked, it sends them hunting for a rule that does not exist.

string
Allowed values: reachable blocked undetermined
reason

The KIND of block, so a caller can branch without parsing prose. The specific offending object is on the blocking hop.

flow_log_capture is split from acl_deny because the repair differs: the priority-501 capture ACL is the only band matching an explicit port name rather than a port group, so on a port with no security group there is no default-deny beneath it and the capture becomes that port’s entire policy. Reporting it as a generic ACL denial sends an operator looking for a security-group rule on a port that has no security group at all.

no_return_route likewise: the forward path is open and the reply has nowhere to go. Per routes are required in BOTH VPCs.

string
Allowed values: acl_deny sg_default_deny flow_log_capture no_route no_return_route missing_nat port_unbound peering_inactive endpoint_unresolved
summary
required

The one sentence. An operator who reads nothing else should be able to act on it — it names the object, the rule that acted, and the precondition that made it act.

string
forward
required
object
direction
required
string
Allowed values: forward return
verdict
required

undetermined is not a soft form of either other value. A path the analyzer could not model, rendered as reachable, talks an operator out of investigating a real outage; rendered as blocked, it sends them hunting for a rule that does not exist.

string
Allowed values: reachable blocked undetermined
reason

The KIND of block, so a caller can branch without parsing prose. The specific offending object is on the blocking hop.

flow_log_capture is split from acl_deny because the repair differs: the priority-501 capture ACL is the only band matching an explicit port name rather than a port group, so on a port with no security group there is no default-deny beneath it and the capture becomes that port’s entire policy. Reporting it as a generic ACL denial sends an operator looking for a security-group rule on a port that has no security group at all.

no_return_route likewise: the forward path is open and the reply has nowhere to go. Per routes are required in BOTH VPCs.

string
Allowed values: acl_deny sg_default_deny flow_log_capture no_route no_return_route missing_nat port_unbound peering_inactive endpoint_unresolved
hops
required
Array<object>
object
sequence
required
integer
stage
required

The pipeline stage, in the order OVN runs them. switch-load-balancer runs BEFORE router-policy — a load balancer attached to a switch rewrites the destination before the router sees the packet, which is the ordering turned on.

string
Allowed values: source-port egress-acl switch-load-balancer router-policy router-route nat egress ingress-acl destination-port
component
required

The OVN object a hop passed through.

object
type
required

OVN kind — logical-switch-port, logical-router, acl, route-policy, static-route, nat, load-balancer, peering-link, localnet, external.

string
name

The OVN name, or the row uuid when the row is unnamed.

string
resource

The Stratum resource behind an OVN row, recovered from its external_ids. Absent when the row carries no stratum-* stamp, which means it is operator-managed or pre-Stratum OVN content rather than something with an owner to name.

object
type
required
string
id
required
string
name
string
priority

The rule’s priority for ACLs and routing policies, where it is the whole reason one rule won over another.

integer
match

The OVN match expression, verbatim, so it can be pasted into ovn-nbctl.

string
action
required
string
Allowed values: forward allow drop reroute dnat snat deliver
detail
required

One line explaining the hop, including why this rule won — a priority comparison, a longest-prefix match, or a precondition that did not hold.

string
blockingHop

Index into hops of the hop that dropped the packet.

integer
return

The reply’s path, evaluated whenever the forward path completed. Not optional analysis: a forward path that is open and a reply that cannot get home is not a reachable path, and reporting it as one is the most dangerous wrong answer this endpoint could give.

object
direction
required
string
Allowed values: forward return
verdict
required

undetermined is not a soft form of either other value. A path the analyzer could not model, rendered as reachable, talks an operator out of investigating a real outage; rendered as blocked, it sends them hunting for a rule that does not exist.

string
Allowed values: reachable blocked undetermined
reason

The KIND of block, so a caller can branch without parsing prose. The specific offending object is on the blocking hop.

flow_log_capture is split from acl_deny because the repair differs: the priority-501 capture ACL is the only band matching an explicit port name rather than a port group, so on a port with no security group there is no default-deny beneath it and the capture becomes that port’s entire policy. Reporting it as a generic ACL denial sends an operator looking for a security-group rule on a port that has no security group at all.

no_return_route likewise: the forward path is open and the reply has nowhere to go. Per routes are required in BOTH VPCs.

string
Allowed values: acl_deny sg_default_deny flow_log_capture no_route no_return_route missing_nat port_unbound peering_inactive endpoint_unresolved
hops
required
Array<object>
object
sequence
required
integer
stage
required

The pipeline stage, in the order OVN runs them. switch-load-balancer runs BEFORE router-policy — a load balancer attached to a switch rewrites the destination before the router sees the packet, which is the ordering turned on.

string
Allowed values: source-port egress-acl switch-load-balancer router-policy router-route nat egress ingress-acl destination-port
component
required

The OVN object a hop passed through.

object
type
required

OVN kind — logical-switch-port, logical-router, acl, route-policy, static-route, nat, load-balancer, peering-link, localnet, external.

string
name

The OVN name, or the row uuid when the row is unnamed.

string
resource

The Stratum resource behind an OVN row, recovered from its external_ids. Absent when the row carries no stratum-* stamp, which means it is operator-managed or pre-Stratum OVN content rather than something with an owner to name.

object
type
required
string
id
required
string
name
string
priority

The rule’s priority for ACLs and routing policies, where it is the whole reason one rule won over another.

integer
match

The OVN match expression, verbatim, so it can be pasted into ovn-nbctl.

string
action
required
string
Allowed values: forward allow drop reroute dnat snat deliver
detail
required

One line explaining the hop, including why this rule won — a priority comparison, a longest-prefix match, or a precondition that did not hold.

string
blockingHop

Index into hops of the hop that dropped the packet.

integer
caveats
Array<string>
Allowed values: dataplane_not_verified conntrack_not_modeled stateful_lb_not_modeled
corroboration

The dataplane’s second opinion on a modeled path, from ovs-appctl ofproto/trace on the chassis hosting the ingress port.

It never changes verdict. A configuration model and a flow table disagreeing is information, not an error to be resolved by preferring one source — and a disagreement is the finding, because it is the only signal that catches a fabric whose configuration is right and whose dataplane is not (’s chassis with zero geneve tunnels, ’s dead ovn-controller).

object
outcome
required

tunneled means this chassis forwarded the packet into a geneve tunnel, so only the SOURCE side is confirmed — the destination port’s policy is evaluated on the chassis hosting that port and this trace cannot see it. It is deliberately not delivered: reading it as delivery reports a confident disagreement against a model that is right, on every cross-node path whose destination policy drops the packet.

not-run carries the reason in detail — most often that another chassis owns the ingress port, since a trace run anywhere else reads a different flow table and returns something that looks exactly like an answer. inconclusive means the trace ran and its output could not be read; it is never collapsed into agreement.

string
Allowed values: delivered tunneled dropped inconclusive not-run
chassis

The chassis owning the ingress port — the only one that can answer for it.

string
localChassis

The chassis that served this request.

string
peerChassis

The chassis hosting the destination port, when it is a different one. On a tunneled outcome it names where the other half of the pipeline runs.

string
agrees

Present only when a trace produced a readable outcome. Absent means “not compared”, which is deliberately distinct from false.

boolean
detail
required
string
flow

The flow handed to ofproto/trace, so it can be rerun by hand.

string
raw

The trace output, whole. Truncating it is how the manual sessions behind this epic reached wrong conclusions.

string
undetermined

What could not be evaluated, and why. Each entry stands alone.

Array<string>

Example

{
"verdict": "reachable",
"reason": "acl_deny",
"summary": "Blocked: interface nic-abc at 192.0.2.11 -> load balancer lb-xyz over tcp/443 — dropped by flow-log capture ACL fl-yjgehorkyh (priority 501), because port lbdp-lb-xyz has no security group.",
"forward": {
"direction": "forward",
"verdict": "reachable",
"reason": "acl_deny",
"hops": [
{
"stage": "source-port",
"component": {
"resource": {
"type": "security-group",
"id": "sg-2hipbqkonx"
}
},
"action": "forward"
}
]
},
"return": {
"direction": "forward",
"verdict": "reachable",
"reason": "acl_deny",
"hops": [
{
"stage": "source-port",
"component": {
"resource": {
"type": "security-group",
"id": "sg-2hipbqkonx"
}
},
"action": "forward"
}
]
},
"caveats": [
"dataplane_not_verified"
],
"corroboration": {
"outcome": "delivered"
}
}

Bad request.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}

Authenticated but not authorized.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}