BGP peer


A BGP peer resource (BGPPeer) represents a remote BGP peer with which the node(s) in a Calico cluster will peer. Configuring BGP peers allows you to peer a Calico network with your datacenter fabric (e.g. ToR). For more information on cluster layouts, see Calico’s documentation on Calico over IP fabrics.

For calicoctl commands that specify a resource type on the CLI, the following aliases are supported (all case insensitive): bgppeer, bgppeers, bgpp, bgpps, bp, bps.

Sample YAML

kind: BGPPeer
  node: rack1-host1
  asNumber: 63400

BGP peer definition


Field Description Accepted Values Schema
name Unique name to describe this resource instance. Must be specified. Alphanumeric string with optional ., _, or -. string


Field Description Accepted Values Schema Default
node If specified, the scope is node level, otherwise the scope is global. The hostname of the node to which this peer applies. string  
peerIP The IP address of this peer and an optional port number. If port number is not set, and peer is Calico node with listenPort set, then listenPort is used. Valid IPv4 or IPv6 address. If port number is set use, IPv4:port or [IPv6]:port format. string  
asNumber The remote AS Number of the peer. A valid AS Number, may be specified in dotted notation. integer/string  
nodeSelector Selector for the nodes that should have this peering. When this is set, the node field must be empty.   selector  
peerSelector Selector for the remote nodes to peer with. When this is set, the peerIP and asNumber fields must be empty.   selector  
keepOriginalNextHop Maintain and forward the original next hop BGP route attribute to a specific Peer within a different AS.   boolean  
password BGP password for the peerings generated by this BGPPeer resource.   BGPPassword nil (no password)
sourceAddress Specifies whether and how to configure a source address for the peerings generated by this BGPPeer resource. Default value “UseNodeIP” means to configure the node IP as the source address. “None” means not to configure a source address. “UseNodeIP”, “None” string “UseNodeIP”
maxRestartTime Restart time that is announced by BIRD in the BGP graceful restart capability and that specifies how long the neighbor would wait for the BGP session to re-establish after a restart before deleting stale routes. Note: extra care should be taken when changing this configuration, as it may break networking in your cluster. When not specified, BIRD uses the default value of 120 seconds. 10s, 120s, 2m etc. Duration string nil (empty config, BIRD will use the default value of 120s)

Tip: the cluster-wide default local AS number used when speaking with a peer is controlled by the BGPConfiguration resource. That value can be overriden per-node by using the bgp field of the node resource.


Note: BGP passwords must be 80 characters or fewer. If a password longer than that is configured, the BGP sessions with that password will fail to be established.

Field Description Schema
secretKeyRef Get the password from a secret. KeyRef


KeyRef tells Calico where to get a BGP password. The referenced Kubernetes secret must be in the same namespace as the calico/node pod.

Field Description Schema
name The name of the secret string
key The key within the secret string

Peer scopes

BGP Peers can exist at either global or node-specific scope. A peer’s scope determines which calico/nodes will attempt to establish a BGP session with that peer. If calico/node has a listenPort set in BGPConfiguration, it will be used in peering.

Global peer

To assign a BGP peer a global scope, omit the node and nodeSelector fields. All nodes in the cluster will attempt to establish BGP connections with it

Node-specific peer

A BGP peer can also be node-specific. When the node field is included, only the specified node will peer with it. When the nodeSelector field is included, the nodes with labels that match that selector will peer with it.

Supported operations

Datastore type Create/Delete Update Get/List Notes
etcdv3 Yes Yes Yes  
Kubernetes API server Yes Yes Yes  


A label selector is an expression which either matches or does not match a resource based on its labels.

Calico label selectors support a number of operators, which can be combined into larger expressions using the boolean operators and parentheses.

Expression Meaning
Logical operators  
( <expression> ) Matches if and only if <expression> matches. (Parentheses are used for grouping expressions.)
! <expression> Matches if and only if <expression> does not match. Tip: ! is a special character at the start of a YAML string, if you need to use ! at the start of a YAML string, enclose the string in quotes.
<expression 1> && <expression 2> “And”: matches if and only if both <expression 1>, and, <expression 2> matches
<expression 1> || <expression 2> “Or”: matches if and only if either <expression 1>, or, <expression 2> matches.
Match operators  
all() Match all in-scope resources. To match no resources, combine this operator with ! to form !all().
global() Match all non-namespaced resources. Useful in a namespaceSelector to select global resources such as global network sets.
k == 'v' Matches resources with the label ‘k’ and value ‘v’.
k != 'v' Matches resources without label ‘k’ or with label ‘k’ and value not equal to v
has(k) Matches resources with label ‘k’, independent of value. To match pods that do not have label k, combine this operator with ! to form !has(k)
k in { 'v1', 'v2' } Matches resources with label ‘k’ and value in the given set
k not in { 'v1', 'v2' } Matches resources without label ‘k’ or with label ‘k’ and value not in the given set
k contains 's' Matches resources with label ‘k’ and value containing the substring ‘s’
k starts with 's' Matches resources with label ‘k’ and value starting with the substring ‘s’
k ends with 's' Matches resources with label ‘k’ and value ending with the substring ‘s’

Operators have the following precedence:

  • Highest: all the match operators
  • Parentheses ( ... )
  • Negation with !
  • Conjunction with &&
  • Lowest: Disjunction with ||

For example, the expression

! has(my-label) || my-label starts with 'prod' && role in {'frontend','business'}

Would be “bracketed” like this:

((!(has(my-label)) || ((my-label starts with 'prod') && (role in {'frontend','business'}))

It would match:

  • Any resource that did not have label “my-label”.
  • Any resource that both:
    • Has a value for my-label that starts with “prod”, and,
    • Has a role label with value either “frontend”, or “business”.