Reference
Resources
The declarative object model: the COSI namespaces and the resources you apply to shape the dataplane.
SiHA is configured with resources — typed objects grouped into namespaces,
one namespace per concern. You author them as YAML and apply them with
sihactl config apply. Each resource has an id; for interfaces, ACL bindings
and NAT modes the id matches the network id (ext, int, …).
Run sihactl get rd on a node to list every resource type it serves.
| Namespace | Resources |
|---|---|
link | Interface, InterfaceRXMode |
acl | ACL, ACLBinding |
nat | NATPool, NATStaticMapping, NATIdentityMapping, NATInterfaceMode |
routing | VRF, Route |
bgp | BGPConfig, BGPPeer (+ read-only BGPLearnedRoute) |
lb | NATLB, LBVIP, LBPluginConfig |
dataplane | DataplaneConfig (singleton) |
Interfaces
An Interface is any dataplane port. It has eight kinds —
pmd (a DPDK physical port), host-interface, loopback, tap, bond,
vlan, qinq, and vxlan — each with its own attributes. PMD interfaces are
adopted (VPP instantiates them at startup); the rest are created on demand.
# a physical port with an address
apiVersion: link.siha/v1
kind: Interface
metadata: { id: ext }
spec:
kind: pmd
addresses: ["203.0.113.1/24"]
---
# an 802.1Q sub-interface on that port
apiVersion: link.siha/v1
kind: Interface
metadata: { id: vlan10 }
spec:
kind: vlan
parent: ext
vlanId: 10
addresses: ["10.10.0.1/24"]
A VXLAN L3VNI interface must set
peerAddr— without it VPP has no way to resolve the tunnel peer and the connected route would black-hole.
ACLs
An ACL is an ordered rule list with a default action; an ACLBinding attaches
it to an interface in a direction. accept_stateful opens the reverse flow
automatically.
apiVersion: acl.siha/v1
kind: ACL
metadata: { id: edge-in }
spec:
family: ipv4
defaultAction: drop
rules:
- { action: accept, protocol: icmp, destinationCidr: 10.0.1.0/24 }
- { action: accept, protocol: tcp, destinationCidr: 10.0.1.0/24,
destinationPortFirst: 80, destinationPortLast: 80 }
- { action: accept_stateful, protocol: tcp, sourceCidr: 10.0.2.10/32,
destinationPortFirst: 22, destinationPortLast: 22 }
---
apiVersion: acl.siha/v1
kind: ACLBinding
metadata: { id: edge-in }
spec: { acl: edge-in, interface: ext, direction: input }
NAT
NATPool declares translation addresses; NATInterfaceMode marks interfaces
inside / outside; static and identity mappings pin specific translations.
For masquerade egress, the pool is the node’s own outside address.
apiVersion: nat.siha/v1
kind: NATPool
metadata: { id: egress }
spec: { addresses: ["203.0.113.1"] }
---
apiVersion: nat.siha/v1
kind: NATInterfaceMode
metadata: { id: int }
spec: { mode: inside }
Routing & BGP
VRF creates an isolated FIB table; Route adds a static route. BGP runs
per-tenant inside VRFs from a single embedded server: one BGPConfig per VRF
(id default = table 0), and BGPPeers bound to a VRF whose learned best-paths
are programmed into that VRF’s FIB.
apiVersion: routing.siha/v1
kind: VRF
metadata: { id: tenant-a }
spec: { table: 100, family: dual, description: "tenant A" }
---
apiVersion: bgp.siha/v1
kind: BGPConfig
metadata: { id: default }
spec: { localAsn: 65011 }
---
apiVersion: bgp.siha/v1
kind: BGPPeer
metadata: { id: uplink }
spec:
peerAsn: 65000
peerAddress: 10.42.0.10
localAddress: 10.42.0.1
Load balancing
A NATLB maps a VIP to health-checked backends; combined with BGP it gives
active-active anycast across nodes.
apiVersion: lb.siha/v1
kind: NATLB
metadata: { id: web }
spec:
vip: "10.40.0.100"
port: 80
backends: ["10.41.0.10", "10.41.0.11"]
healthCheck: { type: tcp, port: 80 }
Dataplane
The DataplaneConfig singleton (id: default) owns VPP’s startup.conf.
Changing it re-renders the file and restarts VPP through the health-checked,
last-known-good two-phase apply described in the architecture.
apiVersion: dataplane.siha/v1
kind: DataplaneConfig
metadata: { id: default }
spec:
workers: 2
requiredPlugins: ["dpdk_plugin", "acl_plugin", "nat44_ed_plugin"]
The manifests above are illustrative — apply your own with
sihactl config apply -f <dir>/and inspect the result withsihactl get.