Skip to content

Commit 1db83ad

Browse files
johanotmurali-reddy
authored andcommitted
Added support for custom BGP ports with 179 still being default (#492) (#493)
* Introduced new cmdline flag --bgp-port, which controls BGP Server listening port and remote port of in-cluster node peers * Introduced new cmdline flag --peer-router-ports, which controls remote BGP port for external peers * Introduced new node annotation kube-router.io/peer.ports with same effect as --peer-router-ports
1 parent 86ba784 commit 1db83ad

File tree

7 files changed

+98
-28
lines changed

7 files changed

+98
-28
lines changed

docs/user-guide.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Usage of kube-router:
3131
--advertise-loadbalancer-ip Add LoadbBalancer IP of service status as set by the LB provider to the RIB so that it gets advertised to the BGP peers.
3232
--advertise-pod-cidr Add Node's POD cidr to the RIB so that it gets advertised to the BGP peers. (default true)
3333
--bgp-graceful-restart Enables the BGP Graceful Restart capability so that routes are preserved on unexpected restarts
34+
--bgp-port uint16 The port open for incoming BGP connections and to use for connecting with other BGP peers. (default 179)
3435
--cache-sync-timeout duration The timeout for cache synchronization (e.g. '5s', '1m'). Must be greater than 0. (default 1m0s)
3536
--cleanup-config Cleanup iptables rules, ipvs, ipset configuration and exit.
3637
--cluster-asn uint ASN number under which cluster nodes will run iBGP.
@@ -58,6 +59,7 @@ Usage of kube-router:
5859
--peer-router-ips ipSlice The ip address of the external router to which all nodes will peer and advertise the cluster ip and pod cidr's. (default [])
5960
--peer-router-multihop-ttl uint8 Enable eBGP multihop supports -- sets multihop-ttl. (Relevant only if ttl >= 2)
6061
--peer-router-passwords strings Password for authenticating against the BGP peer defined with "--peer-router-ips".
62+
--peer-router-ports uints The remote port of the external BGP to which all nodes will peer. If not set, default BGP port (179) will be used. (default [])
6163
--routes-sync-period duration The delay between route updates and advertisements (e.g. '5s', '1m', '2h22m'). Must be greater than 0. (default 5m0s)
6264
--run-firewall Enables Network Policy -- sets up iptables to provide ingress firewall for pods. (default true)
6365
--run-router Enables Pod Networking -- Advertises and learns the routes to Pods via iBGP. (default true)

pkg/controllers/routing/bgp_peers.go

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"time"
1010

1111
"github.com/cloudnativelabs/kube-router/pkg/metrics"
12+
"github.com/cloudnativelabs/kube-router/pkg/options"
1213
"github.com/cloudnativelabs/kube-router/pkg/utils"
1314
"github.com/golang/glog"
1415
"github.com/osrg/gobgp/config"
@@ -90,6 +91,11 @@ func (nrc *NetworkRoutingController) syncInternalPeers() {
9091
NeighborAddress: nodeIP.String(),
9192
PeerAs: nrc.nodeAsnNumber,
9293
},
94+
Transport: config.Transport{
95+
Config: config.TransportConfig{
96+
RemotePort: nrc.bgpPort,
97+
},
98+
},
9399
}
94100

95101
if nrc.bgpGracefulRestart {
@@ -173,11 +179,8 @@ func (nrc *NetworkRoutingController) syncInternalPeers() {
173179
}
174180

175181
// connectToExternalBGPPeers adds all the configured eBGP peers (global or node specific) as neighbours
176-
func connectToExternalBGPPeers(server *gobgp.BgpServer, peerConfigs []*config.NeighborConfig, bgpGracefulRestart bool, peerMultihopTtl uint8) error {
177-
for _, peerConfig := range peerConfigs {
178-
n := &config.Neighbor{
179-
Config: *peerConfig,
180-
}
182+
func connectToExternalBGPPeers(server *gobgp.BgpServer, peerNeighbors []*config.Neighbor, bgpGracefulRestart bool, peerMultihopTtl uint8) error {
183+
for _, n := range peerNeighbors {
181184

182185
if bgpGracefulRestart {
183186
n.GracefulRestart = config.GracefulRestart{
@@ -216,6 +219,7 @@ func connectToExternalBGPPeers(server *gobgp.BgpServer, peerConfigs []*config.Ne
216219
}
217220
}
218221
err := server.AddNeighbor(n)
222+
peerConfig := n.Config
219223
if err != nil {
220224
return fmt.Errorf("Error peering with peer router "+
221225
"%q due to: %s", peerConfig.NeighborAddress, err)
@@ -227,9 +231,9 @@ func connectToExternalBGPPeers(server *gobgp.BgpServer, peerConfigs []*config.Ne
227231
}
228232

229233
// Does validation and returns neighbor configs
230-
func newGlobalPeers(ips []net.IP, asns []uint32, passwords []string) (
231-
[]*config.NeighborConfig, error) {
232-
peers := make([]*config.NeighborConfig, 0)
234+
func newGlobalPeers(ips []net.IP, ports []uint16, asns []uint32, passwords []string) (
235+
[]*config.Neighbor, error) {
236+
peers := make([]*config.Neighbor, 0)
233237

234238
// Validations
235239
if len(ips) != len(asns) {
@@ -244,20 +248,39 @@ func newGlobalPeers(ips []net.IP, asns []uint32, passwords []string) (
244248
"Example: \"pass,,pass\" OR [\"pass\",\"\",\"pass\"].")
245249
}
246250

251+
if len(ips) != len(ports) && len(ports) != 0 {
252+
return nil, errors.New("Invalid peer router config. " +
253+
"The number of ports should either be zero, or one per peer router." +
254+
" If blank items are used, it will default to standard BGP port, " +
255+
strconv.Itoa(options.DEFAULT_BGP_PORT) + "\n" +
256+
"Example: \"port,,port\" OR [\"port\",\"\",\"port\"].")
257+
}
258+
247259
for i := 0; i < len(ips); i++ {
248260
if !((asns[i] >= 64512 && asns[i] <= 65535) ||
249261
(asns[i] >= 4200000000 && asns[i] <= 4294967294)) {
250262
return nil, fmt.Errorf("Invalid ASN number \"%d\" for global BGP peer",
251263
asns[i])
252264
}
253265

254-
peer := &config.NeighborConfig{
255-
NeighborAddress: ips[i].String(),
256-
PeerAs: asns[i],
266+
peer := &config.Neighbor{
267+
Config: config.NeighborConfig{
268+
NeighborAddress: ips[i].String(),
269+
PeerAs: asns[i],
270+
},
271+
Transport: config.Transport{
272+
Config: config.TransportConfig{
273+
RemotePort: options.DEFAULT_BGP_PORT,
274+
},
275+
},
276+
}
277+
278+
if len(ports) != 0 {
279+
peer.Transport.Config.RemotePort = ports[i]
257280
}
258281

259282
if len(passwords) != 0 {
260-
peer.AuthPassword = passwords[i]
283+
peer.Config.AuthPassword = passwords[i]
261284
}
262285

263286
peers = append(peers, peer)

pkg/controllers/routing/export_policies.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
121121
externalBgpPeers := make([]string, 0)
122122
if len(nrc.globalPeerRouters) != 0 {
123123
for _, peer := range nrc.globalPeerRouters {
124-
externalBgpPeers = append(externalBgpPeers, peer.NeighborAddress)
124+
externalBgpPeers = append(externalBgpPeers, peer.Config.NeighborAddress)
125125
}
126126
}
127127
if len(nrc.nodePeerRouters) != 0 {

pkg/controllers/routing/network_routes_controller.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const (
4646
peerASNAnnotation = "kube-router.io/peer.asns"
4747
peerIPAnnotation = "kube-router.io/peer.ips"
4848
peerPasswordAnnotation = "kube-router.io/peer.passwords"
49+
peerPortAnnotation = "kube-router.io/peer.ports"
4950
rrClientAnnotation = "kube-router.io/rr.client"
5051
rrServerAnnotation = "kube-router.io/rr.server"
5152
svcLocalAnnotation = "kube-router.io/service.local"
@@ -73,7 +74,7 @@ type NetworkRoutingController struct {
7374
advertisePodCidr bool
7475
defaultNodeAsnNumber uint32
7576
nodeAsnNumber uint32
76-
globalPeerRouters []*config.NeighborConfig
77+
globalPeerRouters []*config.Neighbor
7778
nodePeerRouters []string
7879
enableCNI bool
7980
bgpFullMeshMode bool
@@ -84,6 +85,7 @@ type NetworkRoutingController struct {
8485
peerMultihopTTL uint8
8586
MetricsEnabled bool
8687
bgpServerStarted bool
88+
bgpPort uint16
8789
bgpRRClient bool
8890
bgpRRServer bool
8991
bgpClusterID uint32
@@ -661,6 +663,7 @@ func (nrc *NetworkRoutingController) startBgpServer() error {
661663
As: nodeAsnNumber,
662664
RouterId: nrc.nodeIP.String(),
663665
LocalAddressList: localAddressList,
666+
Port: int32(nrc.bgpPort),
664667
},
665668
}
666669

@@ -700,6 +703,19 @@ func (nrc *NetworkRoutingController) startBgpServer() error {
700703
return fmt.Errorf("Failed to parse node's Peer Addresses Annotation: %s", err)
701704
}
702705

706+
// Get Global Peer Router ASN configs
707+
nodeBgpPeerPortsAnnotation, ok := node.ObjectMeta.Annotations[peerPortAnnotation]
708+
// Default to default BGP port if port annotation is not found
709+
var peerPorts = make([]uint16, 0)
710+
if ok {
711+
portStrings := stringToSlice(nodeBgpPeerPortsAnnotation, ",")
712+
peerPorts, err = stringSliceToUInt16(portStrings)
713+
if err != nil {
714+
nrc.bgpServer.Stop()
715+
return fmt.Errorf("Failed to parse node's Peer Port Numbers Annotation: %s", err)
716+
}
717+
}
718+
703719
// Get Global Peer Router Password configs
704720
var peerPasswords []string
705721
nodeBGPPasswordsAnnotation, ok := node.ObjectMeta.Annotations[peerPasswordAnnotation]
@@ -715,7 +731,7 @@ func (nrc *NetworkRoutingController) startBgpServer() error {
715731
}
716732

717733
// Create and set Global Peer Router complete configs
718-
nrc.globalPeerRouters, err = newGlobalPeers(peerIPs, peerASNs, peerPasswords)
734+
nrc.globalPeerRouters, err = newGlobalPeers(peerIPs, peerPorts, peerASNs, peerPasswords)
719735
if err != nil {
720736
nrc.bgpServer.Stop()
721737
return fmt.Errorf("Failed to process Global Peer Router configs: %s", err)
@@ -820,12 +836,20 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
820836
nrc.advertisePodCidr = kubeRouterConfig.AdvertiseNodePodCidr
821837
nrc.enableOverlays = kubeRouterConfig.EnableOverlay
822838

839+
nrc.bgpPort = kubeRouterConfig.BGPPort
840+
823841
// Convert ints to uint32s
824842
peerASNs := make([]uint32, 0)
825843
for _, i := range kubeRouterConfig.PeerASNs {
826844
peerASNs = append(peerASNs, uint32(i))
827845
}
828846

847+
// Convert uints to uint16s
848+
peerPorts := make([]uint16, 0)
849+
for _, i := range kubeRouterConfig.PeerPorts {
850+
peerPorts = append(peerPorts, uint16(i))
851+
}
852+
829853
// Decode base64 passwords
830854
peerPasswords := make([]string, 0)
831855
if len(kubeRouterConfig.PeerPasswords) != 0 {
@@ -835,7 +859,7 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
835859
}
836860
}
837861

838-
nrc.globalPeerRouters, err = newGlobalPeers(kubeRouterConfig.PeerRouters,
862+
nrc.globalPeerRouters, err = newGlobalPeers(kubeRouterConfig.PeerRouters, peerPorts,
839863
peerASNs, peerPasswords)
840864
if err != nil {
841865
return nil, fmt.Errorf("Error processing Global Peer Router configs: %s", err)

pkg/controllers/routing/network_routes_controller_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,12 +1258,12 @@ func Test_addExportPolicies(t *testing.T) {
12581258
bgpEnableInternal: true,
12591259
bgpServer: gobgp.NewBgpServer(),
12601260
activeNodes: make(map[string]bool),
1261-
globalPeerRouters: []*config.NeighborConfig{
1261+
globalPeerRouters: []*config.Neighbor{
12621262
{
1263-
NeighborAddress: "10.10.0.1",
1263+
Config: config.NeighborConfig{NeighborAddress: "10.10.0.1"},
12641264
},
12651265
{
1266-
NeighborAddress: "10.10.0.2",
1266+
Config: config.NeighborConfig{NeighborAddress: "10.10.0.2"},
12671267
},
12681268
},
12691269
nodeAsnNumber: 100,
@@ -1393,12 +1393,12 @@ func Test_addExportPolicies(t *testing.T) {
13931393
bgpEnableInternal: false,
13941394
bgpServer: gobgp.NewBgpServer(),
13951395
activeNodes: make(map[string]bool),
1396-
globalPeerRouters: []*config.NeighborConfig{
1396+
globalPeerRouters: []*config.Neighbor{
13971397
{
1398-
NeighborAddress: "10.10.0.1",
1398+
Config: config.NeighborConfig{NeighborAddress: "10.10.0.1"},
13991399
},
14001400
{
1401-
NeighborAddress: "10.10.0.2",
1401+
Config: config.NeighborConfig{NeighborAddress: "10.10.0.2"},
14021402
},
14031403
},
14041404
nodeAsnNumber: 100,
@@ -1515,12 +1515,12 @@ func Test_addExportPolicies(t *testing.T) {
15151515
pathPrependAS: "65100",
15161516
bgpServer: gobgp.NewBgpServer(),
15171517
activeNodes: make(map[string]bool),
1518-
globalPeerRouters: []*config.NeighborConfig{
1518+
globalPeerRouters: []*config.Neighbor{
15191519
{
1520-
NeighborAddress: "10.10.0.1",
1520+
Config: config.NeighborConfig{NeighborAddress: "10.10.0.1"},
15211521
},
15221522
{
1523-
NeighborAddress: "10.10.0.2",
1523+
Config: config.NeighborConfig{NeighborAddress: "10.10.0.2"},
15241524
},
15251525
},
15261526
nodeAsnNumber: 100,
@@ -1658,12 +1658,12 @@ func Test_addExportPolicies(t *testing.T) {
16581658
pathPrependAS: "65100",
16591659
bgpServer: gobgp.NewBgpServer(),
16601660
activeNodes: make(map[string]bool),
1661-
globalPeerRouters: []*config.NeighborConfig{
1661+
globalPeerRouters: []*config.Neighbor{
16621662
{
1663-
NeighborAddress: "10.10.0.1",
1663+
Config: config.NeighborConfig{NeighborAddress: "10.10.0.1"},
16641664
},
16651665
{
1666-
NeighborAddress: "10.10.0.2",
1666+
Config: config.NeighborConfig{NeighborAddress: "10.10.0.2"},
16671667
},
16681668
},
16691669
nodeAsnNumber: 100,

pkg/controllers/routing/utils.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ func stringSliceToIPs(s []string) ([]net.IP, error) {
3535
return ips, nil
3636
}
3737

38+
func stringSliceToUInt16(s []string) ([]uint16, error) {
39+
ints := make([]uint16, 0)
40+
for _, intString := range s {
41+
newInt, err := strconv.ParseUint(intString, 0, 16)
42+
if err != nil {
43+
return nil, fmt.Errorf("Could not parse \"%s\" as an integer", intString)
44+
}
45+
ints = append(ints, uint16(newInt))
46+
}
47+
return ints, nil
48+
}
49+
3850
func stringSliceToUInt32(s []string) ([]uint32, error) {
3951
ints := make([]uint32, 0)
4052
for _, intString := range s {

pkg/options/options.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ import (
55
"time"
66

77
"github.com/spf13/pflag"
8+
"strconv"
89
)
910

11+
const DEFAULT_BGP_PORT = 179
12+
1013
type KubeRouterConfig struct {
1114
AdvertiseClusterIp bool
1215
AdvertiseExternalIp bool
1316
AdvertiseNodePodCidr bool
1417
AdvertiseLoadBalancerIp bool
1518
BGPGracefulRestart bool
19+
BGPPort uint16
1620
CacheSyncTimeout time.Duration
1721
CleanupConfig bool
1822
ClusterAsn uint
@@ -40,6 +44,7 @@ type KubeRouterConfig struct {
4044
PeerASNs []uint
4145
PeerMultihopTtl uint8
4246
PeerPasswords []string
47+
PeerPorts []uint
4348
PeerRouters []net.IP
4449
RoutesSyncPeriod time.Duration
4550
RunFirewall bool
@@ -101,6 +106,8 @@ func (s *KubeRouterConfig) AddFlags(fs *pflag.FlagSet) {
101106
"Add Node's POD cidr to the RIB so that it gets advertised to the BGP peers.")
102107
fs.IPSliceVar(&s.PeerRouters, "peer-router-ips", s.PeerRouters,
103108
"The ip address of the external router to which all nodes will peer and advertise the cluster ip and pod cidr's.")
109+
fs.UintSliceVar(&s.PeerPorts, "peer-router-ports", s.PeerPorts,
110+
"The remote port of the external BGP to which all nodes will peer. If not set, default BGP port ("+strconv.Itoa(DEFAULT_BGP_PORT)+") will be used.")
104111
fs.UintVar(&s.ClusterAsn, "cluster-asn", s.ClusterAsn,
105112
"ASN number under which cluster nodes will run iBGP.")
106113
fs.UintSliceVar(&s.PeerASNs, "peer-router-asns", s.PeerASNs,
@@ -111,6 +118,8 @@ func (s *KubeRouterConfig) AddFlags(fs *pflag.FlagSet) {
111118
"Each node in the cluster will setup BGP peering with rest of the nodes.")
112119
fs.BoolVar(&s.BGPGracefulRestart, "bgp-graceful-restart", false,
113120
"Enables the BGP Graceful Restart capability so that routes are preserved on unexpected restarts")
121+
fs.Uint16Var(&s.BGPPort, "bgp-port", DEFAULT_BGP_PORT,
122+
"The port open for incoming BGP connections and to use for connecting with other BGP peers.")
114123
fs.BoolVar(&s.EnableCNI, "enable-cni", true,
115124
"Enable CNI plugin. Disable if you want to use kube-router features alongside another CNI plugin.")
116125
fs.BoolVar(&s.EnableiBGP, "enable-ibgp", true,

0 commit comments

Comments
 (0)