Skip to content

Commit 8fe9f70

Browse files
aaurenmurali-reddy
authored andcommitted
Add Import Policy for Service VIPs (#721)
* rename export policies to make it direction independent * split creating neighborsets and prefixsets from applying export policy * add bgp import policy to deny service VIPs * add tests for addition of import policy
1 parent 4be51ba commit 8fe9f70

File tree

5 files changed

+301
-127
lines changed

5 files changed

+301
-127
lines changed

pkg/controllers/routing/bgp_peers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,9 @@ func (nrc *NetworkRoutingController) OnNodeUpdate(obj interface{}) {
350350
}
351351

352352
// update export policies so that NeighborSet gets updated with new set of nodes
353-
err := nrc.addExportPolicies()
353+
err := nrc.AddPolicies()
354354
if err != nil {
355-
glog.Errorf("Error adding BGP export policies: %s", err.Error())
355+
glog.Errorf("Error adding BGP policies: %s", err.Error())
356356
}
357357

358358
if nrc.bgpEnableInternal {

pkg/controllers/routing/export_policies.go renamed to pkg/controllers/routing/bgp_policies.go

Lines changed: 153 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,10 @@ import (
1010
v1core "k8s.io/api/core/v1"
1111
)
1212

13-
// BGP export policies are added so that following conditions are met
14-
//
15-
// - by default export of all routes from the RIB to the neighbour's is denied, and explicity statements are added i
16-
// to permit the desired routes to be exported
17-
// - each node is allowed to advertise its assigned pod CIDR's to all of its iBGP peer neighbours with same ASN if --enable-ibgp=true
18-
// - each node is allowed to advertise its assigned pod CIDR's to all of its external BGP peer neighbours
19-
// only if --advertise-pod-cidr flag is set to true
20-
// - each node is NOT allowed to advertise its assigned pod CIDR's to all of its external BGP peer neighbours
21-
// only if --advertise-pod-cidr flag is set to false
22-
// - each node is allowed to advertise service VIP's (cluster ip, load balancer ip, external IP) ONLY to external
23-
// BGP peers
24-
// - each node is NOT allowed to advertise service VIP's (cluster ip, load balancer ip, external IP) to
25-
// iBGP peers
26-
// - an option to allow overriding the next-hop-address with the outgoing ip for external bgp peers
27-
func (nrc *NetworkRoutingController) addExportPolicies() error {
28-
13+
// First create all prefix and neighbor sets
14+
// Then apply export policies
15+
// Then apply import policies
16+
func (nrc *NetworkRoutingController) AddPolicies() error {
2917
// we are rr server do not add export policies
3018
if nrc.bgpRRServer {
3119
return nil
@@ -51,30 +39,18 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
5139
}
5240

5341
// creates prefix set to represent all the advertisable IP associated with the services
54-
advIpPrefixList := make([]config.Prefix, 0)
42+
advIPPrefixList := make([]config.Prefix, 0)
5543
advIps, _, _ := nrc.getAllVIPs()
5644
for _, ip := range advIps {
57-
advIpPrefixList = append(advIpPrefixList, config.Prefix{IpPrefix: ip + "/32"})
45+
advIPPrefixList = append(advIPPrefixList, config.Prefix{IpPrefix: ip + "/32"})
5846
}
59-
clusterIpPrefixSet, err := table.NewPrefixSet(config.PrefixSet{
47+
clusterIPPrefixSet, err := table.NewPrefixSet(config.PrefixSet{
6048
PrefixSetName: "clusteripprefixset",
61-
PrefixList: advIpPrefixList,
49+
PrefixList: advIPPrefixList,
6250
})
63-
err = nrc.bgpServer.ReplaceDefinedSet(clusterIpPrefixSet)
51+
err = nrc.bgpServer.ReplaceDefinedSet(clusterIPPrefixSet)
6452
if err != nil {
65-
nrc.bgpServer.AddDefinedSet(clusterIpPrefixSet)
66-
}
67-
68-
statements := make([]config.Statement, 0)
69-
70-
var bgpActions config.BgpActions
71-
if nrc.pathPrepend {
72-
bgpActions = config.BgpActions{
73-
SetAsPathPrepend: config.SetAsPathPrepend{
74-
As: nrc.pathPrependAS,
75-
RepeatN: nrc.pathPrependCount,
76-
},
77-
}
53+
nrc.bgpServer.AddDefinedSet(clusterIPPrefixSet)
7854
}
7955

8056
if nrc.bgpEnableInternal {
@@ -93,10 +69,75 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
9369
NeighborSetName: "iBGPpeerset",
9470
NeighborInfoList: iBGPPeers,
9571
})
96-
err = nrc.bgpServer.ReplaceDefinedSet(iBGPPeerNS)
72+
err := nrc.bgpServer.ReplaceDefinedSet(iBGPPeerNS)
9773
if err != nil {
9874
nrc.bgpServer.AddDefinedSet(iBGPPeerNS)
9975
}
76+
}
77+
78+
externalBgpPeers := make([]string, 0)
79+
if len(nrc.globalPeerRouters) > 0 {
80+
for _, peer := range nrc.globalPeerRouters {
81+
externalBgpPeers = append(externalBgpPeers, peer.Config.NeighborAddress)
82+
}
83+
}
84+
if len(nrc.nodePeerRouters) > 0 {
85+
for _, peer := range nrc.nodePeerRouters {
86+
externalBgpPeers = append(externalBgpPeers, peer)
87+
}
88+
}
89+
if len(externalBgpPeers) > 0 {
90+
ns, _ := table.NewNeighborSet(config.NeighborSet{
91+
NeighborSetName: "externalpeerset",
92+
NeighborInfoList: externalBgpPeers,
93+
})
94+
err := nrc.bgpServer.ReplaceDefinedSet(ns)
95+
if err != nil {
96+
nrc.bgpServer.AddDefinedSet(ns)
97+
}
98+
}
99+
100+
err = nrc.addExportPolicies()
101+
if err != nil {
102+
return err
103+
}
104+
105+
err = nrc.addImportPolicies()
106+
if err != nil {
107+
return err
108+
}
109+
110+
return nil
111+
}
112+
113+
// BGP export policies are added so that following conditions are met:
114+
//
115+
// - by default export of all routes from the RIB to the neighbour's is denied, and explicity statements are added i
116+
// to permit the desired routes to be exported
117+
// - each node is allowed to advertise its assigned pod CIDR's to all of its iBGP peer neighbours with same ASN if --enable-ibgp=true
118+
// - each node is allowed to advertise its assigned pod CIDR's to all of its external BGP peer neighbours
119+
// only if --advertise-pod-cidr flag is set to true
120+
// - each node is NOT allowed to advertise its assigned pod CIDR's to all of its external BGP peer neighbours
121+
// only if --advertise-pod-cidr flag is set to false
122+
// - each node is allowed to advertise service VIP's (cluster ip, load balancer ip, external IP) ONLY to external
123+
// BGP peers
124+
// - each node is NOT allowed to advertise service VIP's (cluster ip, load balancer ip, external IP) to
125+
// iBGP peers
126+
// - an option to allow overriding the next-hop-address with the outgoing ip for external bgp peers
127+
func (nrc *NetworkRoutingController) addExportPolicies() error {
128+
statements := make([]config.Statement, 0)
129+
130+
var bgpActions config.BgpActions
131+
if nrc.pathPrepend {
132+
bgpActions = config.BgpActions{
133+
SetAsPathPrepend: config.SetAsPathPrepend{
134+
As: nrc.pathPrependAS,
135+
RepeatN: nrc.pathPrependCount,
136+
},
137+
}
138+
}
139+
140+
if nrc.bgpEnableInternal {
100141
actions := config.Actions{
101142
RouteDisposition: config.ROUTE_DISPOSITION_ACCEPT_ROUTE,
102143
}
@@ -118,26 +159,7 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
118159
})
119160
}
120161

121-
externalBgpPeers := make([]string, 0)
122-
if len(nrc.globalPeerRouters) != 0 {
123-
for _, peer := range nrc.globalPeerRouters {
124-
externalBgpPeers = append(externalBgpPeers, peer.Config.NeighborAddress)
125-
}
126-
}
127-
if len(nrc.nodePeerRouters) != 0 {
128-
for _, peer := range nrc.nodePeerRouters {
129-
externalBgpPeers = append(externalBgpPeers, peer)
130-
}
131-
}
132-
if len(externalBgpPeers) > 0 {
133-
ns, _ := table.NewNeighborSet(config.NeighborSet{
134-
NeighborSetName: "externalpeerset",
135-
NeighborInfoList: externalBgpPeers,
136-
})
137-
err = nrc.bgpServer.ReplaceDefinedSet(ns)
138-
if err != nil {
139-
nrc.bgpServer.AddDefinedSet(ns)
140-
}
162+
if len(nrc.globalPeerRouters) > 0 || len(nrc.nodePeerRouters) > 0 {
141163
if nrc.overrideNextHop {
142164
bgpActions.SetNextHop = "self"
143165
}
@@ -179,7 +201,7 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
179201
}
180202

181203
definition := config.PolicyDefinition{
182-
Name: "kube_router",
204+
Name: "kube_router_export",
183205
Statements: statements,
184206
}
185207

@@ -191,7 +213,7 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
191213
policyAlreadyExists := false
192214
policyList := nrc.bgpServer.GetPolicy()
193215
for _, existingPolicy := range policyList {
194-
if existingPolicy.Name == "kube_router" {
216+
if existingPolicy.Name == "kube_router_export" {
195217
policyAlreadyExists = true
196218
}
197219
}
@@ -207,7 +229,7 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
207229
_, existingPolicyAssignments, err := nrc.bgpServer.GetPolicyAssignment("", table.POLICY_DIRECTION_EXPORT)
208230
if err == nil {
209231
for _, existingPolicyAssignment := range existingPolicyAssignments {
210-
if existingPolicyAssignment.Name == "kube_router" {
232+
if existingPolicyAssignment.Name == "kube_router_export" {
211233
policyAssignmentExists = true
212234
}
213235
}
@@ -234,3 +256,76 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
234256

235257
return nil
236258
}
259+
260+
// BGP import policies are added so that the following conditions are met:
261+
// - do not import Service VIPs at all, instead traffic to service VIPs should be sent to the gateway and ECMPed from there
262+
func (nrc *NetworkRoutingController) addImportPolicies() error {
263+
statements := make([]config.Statement, 0)
264+
265+
statements = append(statements, config.Statement{
266+
Conditions: config.Conditions{
267+
MatchPrefixSet: config.MatchPrefixSet{
268+
PrefixSet: "clusteripprefixset",
269+
},
270+
},
271+
Actions: config.Actions{
272+
RouteDisposition: config.ROUTE_DISPOSITION_REJECT_ROUTE,
273+
},
274+
})
275+
276+
definition := config.PolicyDefinition{
277+
Name: "kube_router_import",
278+
Statements: statements,
279+
}
280+
281+
policy, err := table.NewPolicy(definition)
282+
if err != nil {
283+
return errors.New("Failed to create new policy: " + err.Error())
284+
}
285+
286+
policyAlreadyExists := false
287+
policyList := nrc.bgpServer.GetPolicy()
288+
for _, existingPolicy := range policyList {
289+
if existingPolicy.Name == "kube_router_import" {
290+
policyAlreadyExists = true
291+
}
292+
}
293+
294+
if !policyAlreadyExists {
295+
err = nrc.bgpServer.AddPolicy(policy, false)
296+
if err != nil {
297+
return errors.New("Failed to add policy: " + err.Error())
298+
}
299+
}
300+
301+
policyAssignmentExists := false
302+
_, existingPolicyAssignments, err := nrc.bgpServer.GetPolicyAssignment("", table.POLICY_DIRECTION_IMPORT)
303+
if err == nil {
304+
for _, existingPolicyAssignment := range existingPolicyAssignments {
305+
if existingPolicyAssignment.Name == "kube_router_import" {
306+
policyAssignmentExists = true
307+
}
308+
}
309+
}
310+
311+
// Default policy is to accept
312+
if !policyAssignmentExists {
313+
err = nrc.bgpServer.AddPolicyAssignment("",
314+
table.POLICY_DIRECTION_IMPORT,
315+
[]*config.PolicyDefinition{&definition},
316+
table.ROUTE_TYPE_ACCEPT)
317+
if err != nil {
318+
return errors.New("Failed to add policy assignment: " + err.Error())
319+
}
320+
} else {
321+
err = nrc.bgpServer.ReplacePolicyAssignment("",
322+
table.POLICY_DIRECTION_IMPORT,
323+
[]*config.PolicyDefinition{&definition},
324+
table.ROUTE_TYPE_ACCEPT)
325+
if err != nil {
326+
return errors.New("Failed to replace policy assignment: " + err.Error())
327+
}
328+
}
329+
330+
return nil
331+
}

pkg/controllers/routing/ecmp_vip.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ func (nrc *NetworkRoutingController) handleServiceUpdate(svc *v1core.Service) {
9494
}
9595

9696
// update export policies so that new VIP's gets addedd to clusteripprefixsit and vip gets advertised to peers
97-
err = nrc.addExportPolicies()
97+
err = nrc.AddPolicies()
9898
if err != nil {
99-
glog.Errorf("Error adding BGP export policies: %s", err.Error())
99+
glog.Errorf("Error adding BGP policies: %s", err.Error())
100100
}
101101

102102
nrc.advertiseVIPs(toAdvertise)
@@ -162,7 +162,7 @@ func (nrc *NetworkRoutingController) newEndpointsEventHandler() cache.ResourceEv
162162

163163
// OnEndpointsAdd handles endpoint add events from apiserver
164164
// This method calls OnEndpointsUpdate with the addition of updating BGP export policies
165-
// Calling addExportPolicies here covers the edge case where addExportPolicies fails in
165+
// Calling AddPolicies here covers the edge case where AddPolicies fails in
166166
// OnServiceUpdate because the corresponding Endpoint resource for the
167167
// Service was not created yet.
168168
func (nrc *NetworkRoutingController) OnEndpointsAdd(obj interface{}) {
@@ -171,9 +171,9 @@ func (nrc *NetworkRoutingController) OnEndpointsAdd(obj interface{}) {
171171
return
172172
}
173173

174-
err := nrc.addExportPolicies()
174+
err := nrc.AddPolicies()
175175
if err != nil {
176-
glog.Errorf("error adding BGP export policies: %s", err)
176+
glog.Errorf("error adding BGP policies: %s", err)
177177
}
178178

179179
nrc.OnEndpointsUpdate(obj)

pkg/controllers/routing/network_routes_controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,9 @@ func (nrc *NetworkRoutingController) Run(healthChan chan<- *healthcheck.Controll
286286
glog.Errorf("Error advertising route: %s", err.Error())
287287
}
288288

289-
err = nrc.addExportPolicies()
289+
err = nrc.AddPolicies()
290290
if err != nil {
291-
glog.Errorf("Error adding BGP export policies: %s", err.Error())
291+
glog.Errorf("Error adding BGP policies: %s", err.Error())
292292
}
293293

294294
if nrc.bgpEnableInternal {

0 commit comments

Comments
 (0)