Home / OCI

OCITroubleshootingAdvanced

OCI DRG routes missing or wrong in hub-and-spoke: DRG route tables, import distributions and transit routing through a hub firewall

Spokes can't reach each other or on-premises, or traffic skips the hub firewall. Trace the DRG attachment's route table, its import distribution and the hub VCN's ingress route table, then fix them step by step.

Deepak Bhardwaj5 min read

Applies toOCI Dynamic Routing Gateway (upgraded DRG), VCN attachments, FastConnect/IPSec attachments, remote peering, hub VCN with OCI Network Firewall or third-party appliances

Symptoms

  • A new spoke VCN can't reach on-premises, or on-premises can't reach it.
  • Spoke-to-spoke traffic works but bypasses the hub firewall (or is dropped by it).
  • Routes appear in one DRG route table but not another.

How DRG routing works

Every DRG attachment (VCN, virtual circuit, IPSec tunnel, remote peering) is associated with one DRG route table. That table decides where traffic arriving from that attachment goes.

A DRG route table gets its routes from:

  • Static rules you add.
  • Dynamic routes imported through an import route distribution: a list of statements like "import routes from all VCN attachments" or "from attachment X".

The default setup is simple and permissive: VCN attachments use one auto-generated table and other attachments another, each importing from the other side. Hub-and-spoke designs replace this with custom tables and distributions.

Traffic from attachment A  ──►  DRG route table of A  ──►  route to attachment B
                                (static rules + routes imported via its import distribution)

Step 1: list attachments and their tables

DRG=ocid1.drg.oc1.eu-frankfurt-1.aaaa...

oci network drg-attachment list --drg-id $DRG --all \
  --query 'data[].{name:"display-name",type:"network-details".type,id:id,drgRt:"drg-route-table-id"}' --output table

oci network drg-route-table list --drg-id $DRG --all \
  --query 'data[].{name:"display-name",id:id,importDist:"import-drg-route-distribution-id",ecmp:"is-ecmp-enabled"}' --output table

Write down, for the failing flow, the source attachment, its DRG route table and that table's import distribution.

Step 2: look at the routes in that table

oci network drg-route-table list-drg-route-rules --drg-route-table-id <drg-rt-ocid> --all \
  --query 'data[].{dest:destination,type:"route-type",nextHop:"next-hop-drg-attachment-id",conflict:"is-conflict",blackhole:"is-blackhole"}' \
  --output table
  • Destination missing → nothing imported it, and no static rule.
  • Next hop is the spoke itself, not the hub → traffic skips the firewall.
  • is-conflict true → several sources offer the same prefix; check which one won.

Step 3: check the import distribution

oci network drg-route-distribution-statement list --route-distribution-id <dist-ocid> --all \
  --query 'data[].{prio:priority,action:action,match:"match-criteria"}'

Statements match by attachment type (VCN, VIRTUAL_CIRCUIT, IPSEC_TUNNEL, REMOTE_PEERING_CONNECTION), a specific attachment ID, or "match all". A new spoke isn't covered if the statement lists attachment IDs explicitly.

Add a statement:

oci network drg-route-distribution-statement add --route-distribution-id <dist-ocid> \
  --statements '[{"action":"ACCEPT","priority":20,
                  "matchCriteria":[{"matchType":"DRG_ATTACHMENT_ID","drgAttachmentId":"<new-spoke-attachment>"}]}]'

Generate a JSON template with oci network drg-route-distribution-statement add --generate-param-json-input statements if the field names differ in your CLI version. Lower priority numbers are evaluated first.

Step 4: transit routing through the hub firewall

For "all traffic between spokes and on-premises goes through the hub firewall":

  1. Spoke attachments use a DRG route table with a static 0.0.0.0/0 (or your summary prefixes) → hub VCN attachment. They should not import other spokes' routes directly.
  2. Hub VCN attachment uses a DRG route table that imports routes from spokes and on-prem attachments, so traffic coming back from the firewall can reach everyone.
  3. On-prem attachments (virtual circuit, IPSec) use a table with static routes for spoke prefixes → hub VCN attachment.
  4. In the hub VCN, the VCN attachment has an ingress route table (a VCN route table set on the DRG attachment) that sends arriving traffic to the firewall's private IP.
  5. The firewall subnet's route table sends traffic for spokes and on-prem back to the DRG.

Set the hub's ingress route table on the attachment:

oci network drg-attachment update --drg-attachment-id <hub-attachment> \
  --network-details '{"type":"VCN","routeTableId":"<hub-ingress-vcn-rt>"}'

And in that VCN route table:

oci network route-table update --rt-id <hub-ingress-vcn-rt> --force --route-rules '[
  {"destination":"0.0.0.0/0","destinationType":"CIDR_BLOCK","networkEntityId":"<firewall-private-ip-ocid>"}
]'

Warning

Changing which DRG route table an attachment uses, or adding a default route, takes effect immediately for all traffic through that attachment. Change one spoke first, test, then roll out.

Step 5: check the VCN side too

Each spoke subnet's VCN route table needs routes for on-prem and other spokes pointing to the DRG. A perfect DRG configuration does nothing if the subnet sends traffic to a NAT gateway or has no route.

oci network route-table get --rt-id <spoke-subnet-rt> \
  --query 'data."route-rules"[].{dest:destination,target:"network-entity-id"}' --output table

Decision table

Symptom Likely cause Fix
New spoke unreachable from on-prem Not in the on-prem attachment's table (no import / no static) Add import statement or static route
Spoke-to-spoke skips firewall Spoke tables import each other's routes Use static default to hub; remove spoke imports
Traffic reaches firewall, replies lost Firewall subnet route table lacks routes back to DRG Add routes
Works for one prefix, not another Conflict; a more specific route elsewhere Check is-conflict and prefixes
On-prem learns nothing about new spoke Export to virtual circuit/IPSec not covering it Check export distribution and on-prem BGP

Prevent it next time

  • Draw the DRG design: each attachment, its DRG route table, its import distribution, and the hub ingress route table.
  • Use attachment-type matching for spokes where possible, so new spokes are covered automatically.
  • Manage DRG route tables and distributions in Terraform.
  • Add a connectivity test (spoke ↔ spoke, spoke ↔ on-prem, via firewall logs) to every new spoke onboarding.