Cloud Routers and routing
Fabric Cloud Router lifecycle, routing protocols on a connection, route filters, and route tables.
Cloud Router#
A Fabric Cloud Router (FCR) is a managed layer 3 router in one metro. A connection that starts on a Cloud Router has the type IP_VC and needs a DIRECT routing protocol for the link subnet and, for dynamic routing, a BGP routing protocol.
Packages#
The package sets the limits of a router, such as the number of connections and routes. The API returns the packages with their current limits.
import com.eqixiac.equinix.fabric.enums.CloudRouterPackageCode;
import com.eqixiac.equinix.fabric.model.CloudRouterPackage;
for (CloudRouterPackage p : fabric.cloudRouters().routerPackages()) {
System.out.println(p.getCode() + " " + p.getDescription());
}
CloudRouterPackage standard = fabric.cloudRouters().routerPackageByCode(CloudRouterPackageCode.STANDARD);The request-side enum GatewayPackageCode has LAB, BASIC, STANDARD, ADVANCED and PREMIUM. Live list prices in Ashburn on 2026-11-11 were USD 0, 1500 and 3000 per month for LAB, STANDARD and ADVANCED.
Create#
import com.eqixiac.equinix.fabric.enums.GatewayPackageCode;
import com.eqixiac.equinix.fabric.enums.NotificationType;
import com.eqixiac.equinix.fabric.model.CloudRouter;
CloudRouter router = fabric.cloudRouters().define()
.name("fcr-dc-prod")
.inMetro("DC")
.withPackage(GatewayPackageCode.STANDARD)
.accountNumber(123456L)
.projectId(projectId)
.notification(NotificationType.ALL, List.of("noc@example.com")) // Fabric requires at least one recipient
.create();dryRun() before create() validates the request. order(purchaseOrderNumber, termLength, customerReference) sets a term in months for term pricing.
Update#
CloudRouter existing = fabric.cloudRouters().getByUuid(routerUuid);
existing.update().name("fcr-dc-prod-01").save();
existing.update().changePackage(GatewayPackageCode.ADVANCED).save();Routing protocols#
A routing protocol is created on a connection. Fabric rejects a BGP protocol on a connection that has no DIRECT protocol, so the DIRECT protocol is created first.
import com.eqixiac.equinix.fabric.enums.RoutingProtocolType;
import com.eqixiac.equinix.fabric.model.RoutingProtocol;
// DIRECT: the Equinix-side interface address of the /30 link subnet
fabric.routingProtocols().define()
.ofType(RoutingProtocolType.DIRECT)
.withName("direct-fcr-dc-to-aws")
.withDirectIpv4("10.100.0.1/30")
.create(connectionUuid);
// BGP: customer peer, Equinix peer, enabled
RoutingProtocol bgp = fabric.routingProtocols().define()
.ofType(RoutingProtocolType.BGP)
.withName("bgp-fcr-dc-to-aws")
.withCustomerAsn(64512L)
.withBGPIpv4("10.100.0.2", "10.100.0.1", true)
.withBFD(true, 300) // interval in ms
.withBgpAuthKey("change-me")
.create(connectionUuid);
System.out.println("Equinix ASN " + bgp.getEquinixAsn());withBGPIpv4Options(outboundAsPrependCount, inboundMed, outboundMed, routesMax) sets the BGP path attributes and the route limit. The IPv6 methods take the same arguments as the IPv4 ones. Fabric assigns the Equinix ASN, and the 3.0.0 method withEquinixAsn(...) is removed because Fabric release 2025.5 removed the field from the request.
The BGP peer addresses and the ASN of the cloud side are set on the provider's object (the AWS virtual interface, the Azure peering configuration or the Google Cloud Router). The SDK does not read them from the provider, so the caller supplies them.
BGP actions#
import com.eqixiac.equinix.fabric.enums.BGPActionType;
String bgpUuid = "routing-protocol-uuid";
fabric.routingProtocols().createBgpAction(connectionUuid, bgpUuid, BGPActionType.CLEAR_BGPIPV4_INBOUND);
fabric.routingProtocols().getBgpActions(connectionUuid, bgpUuid);CLEAR_*_INBOUND is a soft clear. RESET_BGPIPV4 and RESET_BGPIPV6 tear the session down and interrupt traffic on that connection.
Route filters#
A route filter is an ordered set of prefix rules with a default action, attached to a connection for one direction.
import com.eqixiac.equinix.fabric.enums.Direction;
import com.eqixiac.equinix.fabric.enums.RouteFilterAction;
import com.eqixiac.equinix.fabric.enums.RouteFilterType;
import com.eqixiac.equinix.fabric.model.RouteFilter;
RouteFilter filter = fabric.routeFilters().define()
.ofType(RouteFilterType.BGP_IPv4_PREFIX_FILTER)
.name("accept-rfc1918-from-aws")
.description("Inbound from AWS: private space only")
.notMatchedRuleAction(RouteFilterAction.DENY)
.create();
fabric.routeFilterRules().define(filter.getUuid())
.name("ten-slash-eight")
.prefix("10.0.0.0/8")
.prefixMatch("orlonger")
.action(RouteFilterAction.PERMIT)
.create();
fabric.connections().attachRouteFilter(connectionUuid, filter.getUuid(), Direction.INBOUND);routeAggregations() and routeAggregationRules() follow the same shape for route aggregation, attached with connections().attachRouteAggregation(connectionUuid, aggregationUuid).
Route table#
import com.eqixiac.equinix.fabric.model.RouteTableEntry;
for (RouteTableEntry route : fabric.cloudRouters().searchRoutes(routerUuid).loadAll()) {
System.out.println(route.getPrefix() + " " + route.getProtocolType() + " next hop " + route.getNextHop()
+ " state " + route.getState());
}searchRoutes(routerUuid, filter, sort) narrows the result. Per-connection views are on connections().searchAdvertisedRoutes(...) and searchReceivedRoutes(...).
Commands and actions#
cloudRouters().defineCommand(routerUuid) runs a diagnostic command, such as a ping or traceroute, from the router. commands(routerUuid) and getCommand(...) read the results. getActions(routerUuid) lists router actions such as route-table refreshes.
Design notes#
- One Cloud Router per metro is the unit the Deployment Wizard plans. Two routers in one metro give router-level redundancy at twice the router fee.
- A Cloud Router filters routes by prefix and does not inspect traffic. Stateful inspection requires a firewall in the path, such as a Network Edge device (Network functions).
- Each connection needs its own /30. The wizard allocates them from
subnetBase(...), and two plans in one project need different bases.