diff --git a/docs/antctl.md b/docs/antctl.md index 62073d87dc4..483aba04fd5 100644 --- a/docs/antctl.md +++ b/docs/antctl.md @@ -803,25 +803,29 @@ For more information about route advertisement, please refer to [Advertisements] # Get the list of all advertised bgp routes $ antctl get bgproutes -ROUTE -10.96.10.10/32 -192.168.77.100/32 -fec0::10:96:10:10/128 -fec0::192:168:77:100/128 +ROUTE TYPE +10.244.1.0/24 NodeIPAMPodCIDR +10.96.0.1/32 LoadBalancerIP +172.18.0.3/32 EgressIP +fd00:10:244:1::/64 NodeIPAMPodCIDR +fec0::10:96:10:10/128 LoadBalancerIP +fec0::192:168:77:100/128 EgressIP # Get the list of advertised IPv4 bgp routes $ antctl get bgproutes --ipv4-only -ROUTE -10.96.10.10/32 -192.168.77.100/32 +ROUTE TYPE +10.244.1.0/24 NodeIPAMPodCIDR +10.96.0.1/32 LoadBalancerIP +172.18.0.3/32 EgressIP # Get the list of advertised IPv6 bgp routes $ antctl get bgproutes --ipv6-only -ROUTE -fec0::10:96:10:10/128 -fec0::192:168:77:100/128 +ROUTE TYPE +fd00:10:244:1::/64 NodeIPAMPodCIDR +fec0::10:96:10:10/128 LoadBalancerIP +fec0::192:168:77:100/128 EgressIP ``` ### Upgrade existing objects of CRDs diff --git a/pkg/agent/apis/types.go b/pkg/agent/apis/types.go index 1b00c9d80b8..ebb5f5139a5 100644 --- a/pkg/agent/apis/types.go +++ b/pkg/agent/apis/types.go @@ -233,14 +233,15 @@ func (r BGPPeerResponse) SortRows() bool { // BGPRouteResponse describes the response struct of bgproutes command. type BGPRouteResponse struct { Route string `json:"route,omitempty"` + Type string `json:"type,omitempty"` } func (r BGPRouteResponse) GetTableHeader() []string { - return []string{"ROUTE"} + return []string{"ROUTE", "TYPE"} } func (r BGPRouteResponse) GetTableRow(_ int) []string { - return []string{r.Route} + return []string{r.Route, r.Type} } func (r BGPRouteResponse) SortRows() bool { diff --git a/pkg/agent/apiserver/handlers/bgproute/handler.go b/pkg/agent/apiserver/handlers/bgproute/handler.go index fbdd8006bcb..b01c902fff0 100644 --- a/pkg/agent/apiserver/handlers/bgproute/handler.go +++ b/pkg/agent/apiserver/handlers/bgproute/handler.go @@ -68,10 +68,13 @@ func HandleFunc(bq querier.AgentBGPPolicyInfoQuerier) http.HandlerFunc { } var bgpRoutesResp []apis.BGPRouteResponse - for _, bgpRoute := range bgpRoutes { - bgpRoutesResp = append(bgpRoutesResp, apis.BGPRouteResponse{ - Route: bgpRoute, - }) + for routeType := range bgpRoutes { + for _, bgpRoute := range bgpRoutes[routeType] { + bgpRoutesResp = append(bgpRoutesResp, apis.BGPRouteResponse{ + Route: bgpRoute, + Type: string(routeType), + }) + } } if err := json.NewEncoder(w).Encode(bgpRoutesResp); err != nil { diff --git a/pkg/agent/apiserver/handlers/bgproute/handler_test.go b/pkg/agent/apiserver/handlers/bgproute/handler_test.go index 69333f9e3df..b27de179556 100644 --- a/pkg/agent/apiserver/handlers/bgproute/handler_test.go +++ b/pkg/agent/apiserver/handlers/bgproute/handler_test.go @@ -50,18 +50,25 @@ func TestBGPRouteQuery(t *testing.T) { name: "get all advertised routes", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { mockBGPServer.EXPECT().GetBGPRoutes(ctx, true, true).Return( - []string{"192.168.1.0/24", "192.168.2.0/24", "fec0::10:96:10:10/128"}, nil) + map[bgp.AdvertisedRouteType][]string{ + bgp.ClusterIP: {"192.168.1.2/32"}, + bgp.NodeIPAMPodCIDR: {"192.168.2.0/24"}, + bgp.EgressIP: {"fec0::10:96:10:10/128"}, + }, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPRouteResponse{ { - Route: "192.168.1.0/24", + Route: "192.168.1.2/32", + Type: "ClusterIP", }, { Route: "192.168.2.0/24", + Type: "NodeIPAMPodCIDR", }, { Route: "fec0::10:96:10:10/128", + Type: "EgressIP", }, }, }, @@ -70,15 +77,20 @@ func TestBGPRouteQuery(t *testing.T) { url: "?ipv4-only", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { mockBGPServer.EXPECT().GetBGPRoutes(ctx, true, false).Return( - []string{"192.168.1.0/24", "192.168.2.0/24"}, nil) + map[bgp.AdvertisedRouteType][]string{ + bgp.ClusterIP: {"192.168.1.2/32"}, + bgp.NodeIPAMPodCIDR: {"192.168.2.0/24"}, + }, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPRouteResponse{ { - Route: "192.168.1.0/24", + Route: "192.168.1.2/32", + Type: "ClusterIP", }, { Route: "192.168.2.0/24", + Type: "NodeIPAMPodCIDR", }, }, }, @@ -87,15 +99,20 @@ func TestBGPRouteQuery(t *testing.T) { url: "?ipv6-only=", expectedCalls: func(mockBGPServer *queriertest.MockAgentBGPPolicyInfoQuerier) { mockBGPServer.EXPECT().GetBGPRoutes(ctx, false, true).Return( - []string{"fec0::192:168:77:150/128", "fec0::10:10:0:10/128"}, nil) + map[bgp.AdvertisedRouteType][]string{ + bgp.LoadBalancerIP: {"fec0::192:168:77:150/128"}, + bgp.EgressIP: {"fec0::10:10:0:10/128"}, + }, nil) }, expectedStatus: http.StatusOK, expectedResponse: []apis.BGPRouteResponse{ { Route: "fec0::192:168:77:150/128", + Type: "LoadBalancerIP", }, { Route: "fec0::10:10:0:10/128", + Type: "EgressIP", }, }, }, @@ -131,7 +148,7 @@ func TestBGPRouteQuery(t *testing.T) { var received []apis.BGPRouteResponse err = json.Unmarshal(recorder.Body.Bytes(), &received) require.NoError(t, err) - assert.Equal(t, tt.expectedResponse, received) + assert.ElementsMatch(t, tt.expectedResponse, received) } }) } diff --git a/pkg/agent/controller/bgp/controller.go b/pkg/agent/controller/bgp/controller.go index b10a0caf261..002896d1844 100644 --- a/pkg/agent/controller/bgp/controller.go +++ b/pkg/agent/controller/bgp/controller.go @@ -78,6 +78,16 @@ var ( ErrBGPPolicyNotFound = errors.New("BGPPolicy not found") ) +type AdvertisedRouteType string + +const ( + EgressIP AdvertisedRouteType = "EgressIP" + LoadBalancerIP AdvertisedRouteType = "LoadBalancerIP" + ExternalIP AdvertisedRouteType = "ExternalIP" + ClusterIP AdvertisedRouteType = "ClusterIP" + NodeIPAMPodCIDR AdvertisedRouteType = "NodeIPAMPodCIDR" +) + type bgpPolicyState struct { // The local BGP server. bgpServer bgp.Interface @@ -89,8 +99,8 @@ type bgpPolicyState struct { localASN int32 // The router ID used by the local BGP server. routerID string - // routes stores all BGP routers advertised to BGP peers. - routes sets.Set[bgp.Route] + // routes stores all BGP routes advertised to BGP peers. + routes map[AdvertisedRouteType]sets.Set[bgp.Route] // peerConfigs is a map that stores configurations of BGP peers. The map keys are the concatenated strings of BGP // peer IP address and ASN (e.g., "192.168.77.100-65000", "2001::1-65000"). peerConfigs map[string]bgp.PeerConfig @@ -387,7 +397,7 @@ func (c *Controller) syncBGPPolicy(ctx context.Context) error { routerID: routerID, listenPort: listenPort, localASN: localASN, - routes: make(sets.Set[bgp.Route]), + routes: make(map[AdvertisedRouteType]sets.Set[bgp.Route]), peerConfigs: make(map[string]bgp.PeerConfig), } } else if c.bgpPolicyState.bgpPolicyName != bgpPolicyName { @@ -457,21 +467,37 @@ func (c *Controller) reconcileBGPAdvertisements(ctx context.Context, bgpAdvertis return err } preRoutes := c.bgpPolicyState.routes - routesToAdvertise := curRoutes.Difference(preRoutes) - routesToWithdraw := preRoutes.Difference(curRoutes) - bgpServer := c.bgpPolicyState.bgpServer - for route := range routesToAdvertise { - if err := bgpServer.AdvertiseRoutes(ctx, []bgp.Route{route}); err != nil { - return err + + for routeType := range curRoutes { + routesToAdvertise := curRoutes[routeType] + if _, ok := preRoutes[routeType]; ok { + routesToAdvertise = curRoutes[routeType].Difference(preRoutes[routeType]) + } + for route := range routesToAdvertise { + if err := bgpServer.AdvertiseRoutes(ctx, []bgp.Route{route}); err != nil { + return err + } + if _, ok := c.bgpPolicyState.routes[routeType]; !ok { + c.bgpPolicyState.routes[routeType] = make(sets.Set[bgp.Route]) + } + c.bgpPolicyState.routes[routeType].Insert(route) } - c.bgpPolicyState.routes.Insert(route) } - for route := range routesToWithdraw { - if err := bgpServer.WithdrawRoutes(ctx, []bgp.Route{route}); err != nil { - return err + for routeType := range preRoutes { + routesToWithdraw := preRoutes[routeType] + if _, ok := curRoutes[routeType]; ok { + routesToWithdraw = preRoutes[routeType].Difference(curRoutes[routeType]) + } + for route := range routesToWithdraw { + if err := bgpServer.WithdrawRoutes(ctx, []bgp.Route{route}); err != nil { + return err + } + c.bgpPolicyState.routes[routeType].Delete(route) + } + if c.bgpPolicyState.routes[routeType].Len() == 0 { + delete(c.bgpPolicyState.routes, routeType) } - c.bgpPolicyState.routes.Delete(route) } return nil @@ -540,8 +566,8 @@ func (c *Controller) getRouterID() (string, error) { return routerID, nil } -func (c *Controller) getRoutes(advertisements v1alpha1.Advertisements) (sets.Set[bgp.Route], error) { - allRoutes := sets.New[bgp.Route]() +func (c *Controller) getRoutes(advertisements v1alpha1.Advertisements) (map[AdvertisedRouteType]sets.Set[bgp.Route], error) { + allRoutes := map[AdvertisedRouteType]sets.Set[bgp.Route]{} if advertisements.Service != nil { c.addServiceRoutes(advertisements.Service, allRoutes) @@ -556,11 +582,11 @@ func (c *Controller) getRoutes(advertisements v1alpha1.Advertisements) (sets.Set return allRoutes, nil } -func (c *Controller) addServiceRoutes(advertisement *v1alpha1.ServiceAdvertisement, allRoutes sets.Set[bgp.Route]) { +func (c *Controller) addServiceRoutes(advertisement *v1alpha1.ServiceAdvertisement, allRoutes map[AdvertisedRouteType]sets.Set[bgp.Route]) { ipTypes := sets.New(advertisement.IPTypes...) services, _ := c.serviceLister.List(labels.Everything()) - var serviceIPs []string + var clusterIPs, externalIPs, loadBalancerIPs []string for _, svc := range services { internalLocal := svc.Spec.InternalTrafficPolicy != nil && *svc.Spec.InternalTrafficPolicy == corev1.ServiceInternalTrafficPolicyLocal externalLocal := svc.Spec.ExternalTrafficPolicy == corev1.ServiceExternalTrafficPolicyLocal @@ -571,56 +597,87 @@ func (c *Controller) addServiceRoutes(advertisement *v1alpha1.ServiceAdvertiseme if ipTypes.Has(v1alpha1.ServiceIPTypeClusterIP) { if internalLocal && hasLocalEndpoints || !internalLocal { for _, clusterIP := range svc.Spec.ClusterIPs { - serviceIPs = append(serviceIPs, clusterIP) + clusterIPs = append(clusterIPs, clusterIP) } } } if ipTypes.Has(v1alpha1.ServiceIPTypeExternalIP) { if externalLocal && hasLocalEndpoints || !externalLocal { for _, externalIP := range svc.Spec.ExternalIPs { - serviceIPs = append(serviceIPs, externalIP) + externalIPs = append(externalIPs, externalIP) } } } if ipTypes.Has(v1alpha1.ServiceIPTypeLoadBalancerIP) && svc.Spec.Type == corev1.ServiceTypeLoadBalancer { if externalLocal && hasLocalEndpoints || !externalLocal { - serviceIPs = append(serviceIPs, getIngressIPs(svc)...) + loadBalancerIPs = append(loadBalancerIPs, getIngressIPs(svc)...) } } } - for _, ip := range serviceIPs { + for _, ip := range clusterIPs { + if _, ok := allRoutes[ClusterIP]; !ok { + allRoutes[ClusterIP] = sets.Set[bgp.Route]{} + } if c.enabledIPv4 && utilnet.IsIPv4String(ip) { - allRoutes.Insert(bgp.Route{Prefix: ip + ipv4Suffix}) + allRoutes[ClusterIP].Insert(bgp.Route{Prefix: ip + ipv4Suffix}) } if c.enabledIPv6 && utilnet.IsIPv6String(ip) { - allRoutes.Insert(bgp.Route{Prefix: ip + ipv6Suffix}) + allRoutes[ClusterIP].Insert(bgp.Route{Prefix: ip + ipv6Suffix}) + } + } + for _, ip := range externalIPs { + if _, ok := allRoutes[ExternalIP]; !ok { + allRoutes[ExternalIP] = sets.Set[bgp.Route]{} + } + if c.enabledIPv4 && utilnet.IsIPv4String(ip) { + allRoutes[ExternalIP].Insert(bgp.Route{Prefix: ip + ipv4Suffix}) + } + if c.enabledIPv6 && utilnet.IsIPv6String(ip) { + allRoutes[ExternalIP].Insert(bgp.Route{Prefix: ip + ipv6Suffix}) + } + } + for _, ip := range loadBalancerIPs { + if _, ok := allRoutes[LoadBalancerIP]; !ok { + allRoutes[LoadBalancerIP] = sets.Set[bgp.Route]{} + } + if c.enabledIPv4 && utilnet.IsIPv4String(ip) { + allRoutes[LoadBalancerIP].Insert(bgp.Route{Prefix: ip + ipv4Suffix}) + } + if c.enabledIPv6 && utilnet.IsIPv6String(ip) { + allRoutes[LoadBalancerIP].Insert(bgp.Route{Prefix: ip + ipv6Suffix}) } } } -func (c *Controller) addEgressRoutes(allRoutes sets.Set[bgp.Route]) { +func (c *Controller) addEgressRoutes(allRoutes map[AdvertisedRouteType]sets.Set[bgp.Route]) { egresses, _ := c.egressLister.List(labels.Everything()) for _, eg := range egresses { if eg.Status.EgressNode != c.nodeName { continue } ip := eg.Status.EgressIP + if _, ok := allRoutes[EgressIP]; !ok { + allRoutes[EgressIP] = sets.Set[bgp.Route]{} + } if c.enabledIPv4 && utilnet.IsIPv4String(ip) { - allRoutes.Insert(bgp.Route{Prefix: ip + ipv4Suffix}) + allRoutes[EgressIP].Insert(bgp.Route{Prefix: ip + ipv4Suffix}) } if c.enabledIPv6 && utilnet.IsIPv6String(ip) { - allRoutes.Insert(bgp.Route{Prefix: ip + ipv6Suffix}) + allRoutes[EgressIP].Insert(bgp.Route{Prefix: ip + ipv6Suffix}) } } } -func (c *Controller) addPodRoutes(allRoutes sets.Set[bgp.Route]) { +func (c *Controller) addPodRoutes(allRoutes map[AdvertisedRouteType]sets.Set[bgp.Route]) { + if _, ok := allRoutes[NodeIPAMPodCIDR]; !ok { + allRoutes[NodeIPAMPodCIDR] = sets.Set[bgp.Route]{} + } if c.enabledIPv4 { - allRoutes.Insert(bgp.Route{Prefix: c.podIPv4CIDR}) + allRoutes[NodeIPAMPodCIDR].Insert(bgp.Route{Prefix: c.podIPv4CIDR}) } if c.enabledIPv6 { - allRoutes.Insert(bgp.Route{Prefix: c.podIPv6CIDR}) + allRoutes[NodeIPAMPodCIDR].Insert(bgp.Route{Prefix: c.podIPv6CIDR}) } } @@ -1009,8 +1066,8 @@ func (c *Controller) GetBGPPeerStatus(ctx context.Context, ipv4Peers, ipv6Peers } // GetBGPRoutes returns the advertised BGP routes. -func (c *Controller) GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) ([]string, error) { - getBgpRoutesAdvertised := func() sets.Set[bgp.Route] { +func (c *Controller) GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) (map[AdvertisedRouteType][]string, error) { + getBgpRoutesAdvertised := func() map[AdvertisedRouteType]sets.Set[bgp.Route] { c.bgpPolicyStateMutex.RLock() defer c.bgpPolicyStateMutex.RUnlock() if c.bgpPolicyState == nil { @@ -1024,18 +1081,22 @@ func (c *Controller) GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bo return nil, ErrBGPPolicyNotFound } - bgpRoutes := make([]string, 0, bgpRoutesAdvertised.Len()) + bgpRoutes := map[AdvertisedRouteType][]string{} if ipv4Routes { // insert IPv4 advertised routes - for route := range bgpRoutesAdvertised { - if utilnet.IsIPv4CIDRString(route.Prefix) { - bgpRoutes = append(bgpRoutes, route.Prefix) + for routeSourceType := range bgpRoutesAdvertised { + for route := range bgpRoutesAdvertised[routeSourceType] { + if utilnet.IsIPv4CIDRString(route.Prefix) { + bgpRoutes[routeSourceType] = append(bgpRoutes[routeSourceType], route.Prefix) + } } } } if ipv6Routes { // insert IPv6 advertised routes - for route := range bgpRoutesAdvertised { - if utilnet.IsIPv6CIDRString(route.Prefix) { - bgpRoutes = append(bgpRoutes, route.Prefix) + for routeSourceType := range bgpRoutesAdvertised { + for route := range bgpRoutesAdvertised[routeSourceType] { + if utilnet.IsIPv6CIDRString(route.Prefix) { + bgpRoutes[routeSourceType] = append(bgpRoutes[routeSourceType], route.Prefix) + } } } } diff --git a/pkg/agent/controller/bgp/controller_test.go b/pkg/agent/controller/bgp/controller_test.go index bb1cc2d4327..d05133cfd3e 100644 --- a/pkg/agent/controller/bgp/controller_test.go +++ b/pkg/agent/controller/bgp/controller_test.go @@ -287,7 +287,7 @@ func TestBGPPolicyAdd(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(clusterIPv4)}, + map[AdvertisedRouteType][]string{ClusterIP: {ipStrToPrefix(clusterIPv4)}}, []bgp.PeerConfig{ipv4Peer1Config}, ), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { @@ -319,7 +319,7 @@ func TestBGPPolicyAdd(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(externalIPv6)}, + map[AdvertisedRouteType][]string{ExternalIP: {ipStrToPrefix(externalIPv6)}}, []bgp.PeerConfig{ipv6Peer1Config}, ), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { @@ -354,7 +354,7 @@ func TestBGPPolicyAdd(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(loadBalancerIPv4), ipStrToPrefix(loadBalancerIPv6)}, + map[AdvertisedRouteType][]string{LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4), ipStrToPrefix(loadBalancerIPv6)}}, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config}, ), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { @@ -388,7 +388,7 @@ func TestBGPPolicyAdd(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(ipv4EgressIP1)}, + map[AdvertisedRouteType][]string{EgressIP: {ipStrToPrefix(ipv4EgressIP1)}}, []bgp.PeerConfig{ipv4Peer1Config}, ), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { @@ -416,7 +416,7 @@ func TestBGPPolicyAdd(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv6Peer1Config}, ), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { @@ -490,14 +490,14 @@ func TestBGPPolicyAdd(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(clusterIPv4)}, + map[AdvertisedRouteType][]string{ClusterIP: {ipStrToPrefix(clusterIPv4)}}, []bgp.PeerConfig{ipv4Peer1Config}, ), expectedState: generateBGPPolicyState(bgpPolicyName2, 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(clusterIPv4)}, + map[AdvertisedRouteType][]string{ClusterIP: {ipStrToPrefix(clusterIPv4)}}, []bgp.PeerConfig{ipv4Peer1Config}, ), }, @@ -555,12 +555,10 @@ func TestBGPPolicyUpdate(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(clusterIPv4), - ipStrToPrefix(clusterIPv6), - ipStrToPrefix(loadBalancerIPv4), - ipStrToPrefix(loadBalancerIPv6), - podIPv4CIDR.String(), - podIPv6CIDR.String(), + map[AdvertisedRouteType][]string{ + ClusterIP: {ipStrToPrefix(clusterIPv4), ipStrToPrefix(clusterIPv6)}, + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4), ipStrToPrefix(loadBalancerIPv6)}, + NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}, }, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config, @@ -660,12 +658,10 @@ func TestBGPPolicyUpdate(t *testing.T) { 1179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(clusterIPv4), - ipStrToPrefix(clusterIPv6), - ipStrToPrefix(loadBalancerIPv4), - ipStrToPrefix(loadBalancerIPv6), - podIPv4CIDR.String(), - podIPv6CIDR.String(), + map[AdvertisedRouteType][]string{ + ClusterIP: {ipStrToPrefix(clusterIPv4), ipStrToPrefix(clusterIPv6)}, + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4), ipStrToPrefix(loadBalancerIPv6)}, + NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}, }, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config, @@ -718,10 +714,9 @@ func TestBGPPolicyUpdate(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(externalIPv4), - ipStrToPrefix(externalIPv6), - ipStrToPrefix(ipv4EgressIP1), - ipStrToPrefix(ipv6EgressIP1), + map[AdvertisedRouteType][]string{ + ExternalIP: {ipStrToPrefix(externalIPv4), ipStrToPrefix(externalIPv6)}, + EgressIP: {ipStrToPrefix(ipv4EgressIP1), ipStrToPrefix(ipv6EgressIP1)}, }, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config, @@ -764,10 +759,9 @@ func TestBGPPolicyUpdate(t *testing.T) { 179, 65001, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(externalIPv4), - ipStrToPrefix(externalIPv6), - ipStrToPrefix(ipv4EgressIP1), - ipStrToPrefix(ipv6EgressIP1), + map[AdvertisedRouteType][]string{ + ExternalIP: {ipStrToPrefix(externalIPv4), ipStrToPrefix(externalIPv6)}, + EgressIP: {ipStrToPrefix(ipv4EgressIP1), ipStrToPrefix(ipv6EgressIP1)}, }, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config, @@ -809,12 +803,10 @@ func TestBGPPolicyUpdate(t *testing.T) { 1179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(clusterIPv4), - ipStrToPrefix(clusterIPv6), - ipStrToPrefix(loadBalancerIPv4), - ipStrToPrefix(loadBalancerIPv6), - podIPv4CIDR.String(), - podIPv6CIDR.String(), + map[AdvertisedRouteType][]string{ + ClusterIP: {ipStrToPrefix(clusterIPv4), ipStrToPrefix(clusterIPv6)}, + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4), ipStrToPrefix(loadBalancerIPv6)}, + NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}, }, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config, @@ -857,12 +849,10 @@ func TestBGPPolicyUpdate(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(clusterIPv4), - ipStrToPrefix(clusterIPv6), - ipStrToPrefix(loadBalancerIPv4), - ipStrToPrefix(loadBalancerIPv6), - podIPv4CIDR.String(), - podIPv6CIDR.String(), + map[AdvertisedRouteType][]string{ + ClusterIP: {ipStrToPrefix(clusterIPv4), ipStrToPrefix(clusterIPv6)}, + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4), ipStrToPrefix(loadBalancerIPv6)}, + NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}, }, []bgp.PeerConfig{updatedIPv4Peer2Config, updatedIPv6Peer2Config, @@ -981,9 +971,9 @@ func TestBGPPolicyDelete(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ - ipStrToPrefix(loadBalancerIPv4), - ipStrToPrefix(loadBalancerIPv6), + map[AdvertisedRouteType][]string{ + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4), + ipStrToPrefix(loadBalancerIPv6)}, }, []bgp.PeerConfig{ ipv4Peer1Config, @@ -1008,9 +998,9 @@ func TestBGPPolicyDelete(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ - ipStrToPrefix(externalIPv4), - ipStrToPrefix(externalIPv6), + map[AdvertisedRouteType][]string{ + ExternalIP: {ipStrToPrefix(externalIPv4), + ipStrToPrefix(externalIPv6)}, }, []bgp.PeerConfig{ ipv4Peer2Config, @@ -1034,9 +1024,9 @@ func TestBGPPolicyDelete(t *testing.T) { 1179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ - ipStrToPrefix(externalIPv4), - ipStrToPrefix(externalIPv6), + map[AdvertisedRouteType][]string{ + ExternalIP: {ipStrToPrefix(externalIPv4), + ipStrToPrefix(externalIPv6)}, }, []bgp.PeerConfig{ ipv4Peer2Config, @@ -1158,7 +1148,7 @@ func TestNodeUpdate(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{podIPv4CIDR.String(), podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config}) policy2 := generateBGPPolicy(bgpPolicyName2, creationTimestampAdd1s, @@ -1175,7 +1165,7 @@ func TestNodeUpdate(t *testing.T) { 1179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{podIPv4CIDR.String(), podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config}) policy3 := generateBGPPolicy(bgpPolicyName3, creationTimestampAdd2s, @@ -1260,7 +1250,7 @@ func TestNodeUpdate(t *testing.T) { 179, 65000, nodeAnnotations2[types.NodeBGPRouterIDAnnotationKey], - []string{podIPv4CIDR.String(), podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config}), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { mockBGPServer.Start(gomock.Any()) @@ -1282,7 +1272,7 @@ func TestNodeUpdate(t *testing.T) { 179, 65000, nodeIPv4Addr.IP.String(), - []string{podIPv4CIDR.String(), podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv4Peer1Config, ipv6Peer1Config}), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { mockBGPServer.Start(gomock.Any()) @@ -1302,13 +1292,13 @@ func TestNodeUpdate(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv6Peer1Config}), expectedState: generateBGPPolicyState(bgpPolicyName1, 179, 65000, nodeAnnotations2[types.NodeBGPRouterIDAnnotationKey], - []string{podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv6Peer1Config}), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { mockBGPServer.Start(gomock.Any()) @@ -1326,13 +1316,13 @@ func TestNodeUpdate(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv6Peer1Config}), expectedState: generateBGPPolicyState(bgpPolicyName1, 179, 65000, "156.67.103.8", - []string{podIPv6CIDR.String()}, + map[AdvertisedRouteType][]string{NodeIPAMPodCIDR: {podIPv6CIDR.String()}}, []bgp.PeerConfig{ipv6Peer1Config}), expectedCalls: func(mockBGPServer *bgptest.MockInterfaceMockRecorder) { mockBGPServer.Start(gomock.Any()) @@ -1776,7 +1766,7 @@ func TestSyncBGPPolicyFailures(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(loadBalancerIPv4)}, + map[AdvertisedRouteType][]string{LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4)}}, []bgp.PeerConfig{ipv4Peer2Config}), c.bgpPolicyState) @@ -1793,7 +1783,7 @@ func TestSyncBGPPolicyFailures(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(loadBalancerIPv4)}, + map[AdvertisedRouteType][]string{LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4)}}, []bgp.PeerConfig{ipv4Peer2Config}), c.bgpPolicyState) @@ -1811,7 +1801,7 @@ func TestSyncBGPPolicyFailures(t *testing.T) { 1179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{}, + map[AdvertisedRouteType][]string{}, []bgp.PeerConfig{}), c.bgpPolicyState) @@ -1825,7 +1815,7 @@ func TestSyncBGPPolicyFailures(t *testing.T) { 1179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{}, + map[AdvertisedRouteType][]string{}, []bgp.PeerConfig{ipv4Peer1Config}), c.bgpPolicyState) @@ -1844,7 +1834,7 @@ func TestSyncBGPPolicyFailures(t *testing.T) { 1179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(externalIPv4)}, + map[AdvertisedRouteType][]string{ExternalIP: {ipStrToPrefix(externalIPv4)}}, []bgp.PeerConfig{ipv4Peer2Config}), c.bgpPolicyState) @@ -1863,7 +1853,7 @@ func TestSyncBGPPolicyFailures(t *testing.T) { 1179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(loadBalancerIPv4)}, + map[AdvertisedRouteType][]string{LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4)}}, []bgp.PeerConfig{updatedIPv4Peer2Config}), c.bgpPolicyState) } @@ -1872,12 +1862,15 @@ func generateBGPPolicyState(bgpPolicyName string, listenPort int32, localASN int32, routerID string, - prefixes []string, + prefixes map[AdvertisedRouteType][]string, peerConfigs []bgp.PeerConfig) *bgpPolicyState { - routes := sets.New[bgp.Route]() + routes := map[AdvertisedRouteType]sets.Set[bgp.Route]{} peerConfigMap := make(map[string]bgp.PeerConfig) - for _, prefix := range prefixes { - routes.Insert(bgp.Route{Prefix: prefix}) + for sourceType := range prefixes { + routes[sourceType] = make(sets.Set[bgp.Route]) + for _, prefix := range prefixes[sourceType] { + routes[sourceType].Insert(bgp.Route{Prefix: prefix}) + } } for _, peerConfig := range peerConfigs { peerKey := generateBGPPeerKey(peerConfig.Address, peerConfig.ASN) @@ -1899,13 +1892,17 @@ func deepCopyBGPPolicyState(in *bgpPolicyState) *bgpPolicyState { peerKey := generateBGPPeerKey(peerConfig.Address, peerConfig.ASN) peerConfigMap[peerKey] = peerConfig } + routes := make(map[AdvertisedRouteType]sets.Set[bgp.Route]) + for routeType := range in.routes { + routes[routeType] = in.routes[routeType].Union(nil) + } return &bgpPolicyState{ bgpPolicyName: in.bgpPolicyName, listenPort: in.listenPort, localASN: in.localASN, routerID: in.routerID, - routes: in.routes.Union(nil), + routes: routes, peerConfigs: peerConfigMap, } } @@ -2259,12 +2256,10 @@ func TestGetBGPRoutes(t *testing.T) { 179, 65000, nodeAnnotations1[types.NodeBGPRouterIDAnnotationKey], - []string{ipStrToPrefix(clusterIPv4), - ipStrToPrefix(loadBalancerIPv4), - podIPv4CIDR.String(), - ipStrToPrefix(clusterIPv6), - ipStrToPrefix(loadBalancerIPv6), - podIPv6CIDR.String(), + map[AdvertisedRouteType][]string{ + ClusterIP: {ipStrToPrefix(clusterIPv4), ipStrToPrefix(clusterIPv6)}, + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4), ipStrToPrefix(loadBalancerIPv6)}, + NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}, }, []bgp.PeerConfig{}, ) @@ -2274,7 +2269,7 @@ func TestGetBGPRoutes(t *testing.T) { ipv4Routes bool ipv6Routes bool existingState *bgpPolicyState - expectedBgpRoutes []string + expectedBgpRoutes map[AdvertisedRouteType][]string expectedErr string }{ { @@ -2282,33 +2277,30 @@ func TestGetBGPRoutes(t *testing.T) { ipv4Routes: true, ipv6Routes: true, existingState: effectivePolicyState, - expectedBgpRoutes: []string{ - ipStrToPrefix(clusterIPv4), - ipStrToPrefix(loadBalancerIPv4), - podIPv4CIDR.String(), - ipStrToPrefix(clusterIPv6), - ipStrToPrefix(loadBalancerIPv6), - podIPv6CIDR.String(), + expectedBgpRoutes: map[AdvertisedRouteType][]string{ + ClusterIP: {ipStrToPrefix(clusterIPv4), ipStrToPrefix(clusterIPv6)}, + NodeIPAMPodCIDR: {podIPv4CIDR.String(), podIPv6CIDR.String()}, + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4), ipStrToPrefix(loadBalancerIPv6)}, }, }, { name: "get advertised ipv4 routes only", ipv4Routes: true, existingState: effectivePolicyState, - expectedBgpRoutes: []string{ - ipStrToPrefix(clusterIPv4), - ipStrToPrefix(loadBalancerIPv4), - podIPv4CIDR.String(), + expectedBgpRoutes: map[AdvertisedRouteType][]string{ + ClusterIP: {ipStrToPrefix(clusterIPv4)}, + NodeIPAMPodCIDR: {podIPv4CIDR.String()}, + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv4)}, }, }, { name: "get advertised ipv6 routes only", ipv6Routes: true, existingState: effectivePolicyState, - expectedBgpRoutes: []string{ - ipStrToPrefix(clusterIPv6), - ipStrToPrefix(loadBalancerIPv6), - podIPv6CIDR.String(), + expectedBgpRoutes: map[AdvertisedRouteType][]string{ + ClusterIP: {ipStrToPrefix(clusterIPv6)}, + NodeIPAMPodCIDR: {podIPv6CIDR.String()}, + LoadBalancerIP: {ipStrToPrefix(loadBalancerIPv6)}, }, }, { @@ -2329,7 +2321,7 @@ func TestGetBGPRoutes(t *testing.T) { assert.EqualError(t, err, tt.expectedErr) } else { require.NoError(t, err) - assert.ElementsMatch(t, tt.expectedBgpRoutes, actualBgpRoutes) + assert.Equal(t, tt.expectedBgpRoutes, actualBgpRoutes) } }) } diff --git a/pkg/querier/querier.go b/pkg/querier/querier.go index f3153d65d90..8a3b7c649ba 100644 --- a/pkg/querier/querier.go +++ b/pkg/querier/querier.go @@ -23,6 +23,7 @@ import ( "antrea.io/antrea/pkg/agent/apis" "antrea.io/antrea/pkg/agent/bgp" + bgpcontroller "antrea.io/antrea/pkg/agent/controller/bgp" "antrea.io/antrea/pkg/agent/interfacestore" "antrea.io/antrea/pkg/agent/multicast" "antrea.io/antrea/pkg/agent/types" @@ -148,5 +149,5 @@ type AgentBGPPolicyInfoQuerier interface { // GetBGPPeerStatus returns current status of BGP Peers of effective BGP Policy applied on the Node. GetBGPPeerStatus(ctx context.Context, ipv4Peers, ipv6Peers bool) ([]bgp.PeerStatus, error) // GetBGPRoutes returns the advertised BGP routes. - GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) ([]string, error) + GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) (map[bgpcontroller.AdvertisedRouteType][]string, error) } diff --git a/pkg/querier/testing/mock_querier.go b/pkg/querier/testing/mock_querier.go index 7ce0fa0d8e2..3537c58a442 100644 --- a/pkg/querier/testing/mock_querier.go +++ b/pkg/querier/testing/mock_querier.go @@ -29,6 +29,7 @@ import ( reflect "reflect" bgp "antrea.io/antrea/pkg/agent/bgp" + bgp0 "antrea.io/antrea/pkg/agent/controller/bgp" interfacestore "antrea.io/antrea/pkg/agent/interfacestore" multicast "antrea.io/antrea/pkg/agent/multicast" types "antrea.io/antrea/pkg/agent/types" @@ -396,10 +397,10 @@ func (mr *MockAgentBGPPolicyInfoQuerierMockRecorder) GetBGPPolicyInfo() *gomock. } // GetBGPRoutes mocks base method. -func (m *MockAgentBGPPolicyInfoQuerier) GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) ([]string, error) { +func (m *MockAgentBGPPolicyInfoQuerier) GetBGPRoutes(ctx context.Context, ipv4Routes, ipv6Routes bool) (map[bgp0.AdvertisedRouteType][]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBGPRoutes", ctx, ipv4Routes, ipv6Routes) - ret0, _ := ret[0].([]string) + ret0, _ := ret[0].(map[bgp0.AdvertisedRouteType][]string) ret1, _ := ret[1].(error) return ret0, ret1 }