Add support for per-Source Hidden Neighbors #143

Open
jof wants to merge 1 commits from jof/jof/hidden-neighbors into develop
jof commented 2024-02-19 08:38:24 +08:00 (Migrated from github.com)

Closes #142

As part of Route Server operations, it is sometimes necessary to configure some BGP Neighbors which are not appropriate for a public Looking Glass interface.
For example, an internal route server peer used to collect routes for flow analytics, but which is not a "normal" Route Server peer. Another example: an internal (route server)-to-(route server) peer used to scale a multi-instance route server.

This PR adds some support to Alice to enable configuring some Neighbors to be hidden on a per-source basis. This filtration could be based on IPs, CIDRs, or Regular Expressions. As BIRD(watcher) has some some NeighborStatus IDs which are potentially not IP addresses, it seemed important to enable filtering either IPs or Neighbor Protocol names.

Closes #142 As part of Route Server operations, it is sometimes necessary to configure some BGP Neighbors which are not appropriate for a public Looking Glass interface. For example, an internal route server peer used to collect routes for flow analytics, but which is not a "normal" Route Server peer. Another example: an internal (route server)-to-(route server) peer used to scale a multi-instance route server. This PR adds some support to Alice to enable configuring some Neighbors to be hidden on a per-source basis. This filtration could be based on IPs, CIDRs, or Regular Expressions. As BIRD(watcher) has some some NeighborStatus IDs which are potentially not IP addresses, it seemed important to enable filtering either IPs or Neighbor Protocol names.
annikahannig commented 2024-02-29 17:33:50 +08:00 (Migrated from github.com)

I'm currently reviewing this.

I'm currently reviewing this.
annikahannig (Migrated from github.com) requested changes 2024-02-29 18:26:47 +08:00
annikahannig (Migrated from github.com) left a comment

Hej! :)

Thanks again for the effort.
I added some notes how this could be improved and reuse already existing code. (To a degree)

Hej! :) Thanks again for the effort. I added some notes how this could be improved and reuse already existing code. (To a degree)
@ -38,0 +58,4 @@
}
return excludeCIDRs, excludeIPs, excludePatterns, nil
}
annikahannig (Migrated from github.com) commented 2024-02-29 17:51:29 +08:00

This function has too many return values.
Also I think it should be done during config parsing.

Also, maybe the already existing filtering infrastructure could be reused:

There is api.NeighborFilter which could be extended:

  • api.Filterable this should maybe be split into RouteFilterable and NeighborFilterable
  • NeighborFilter.Match should accept this interface, so this can be implemented for api.Neighbor and api.NeighborStatus
This function has too many return values. Also I think it should be done during config parsing. Also, maybe the already existing filtering infrastructure could be reused: There is `api.NeighborFilter` which could be extended: - `api.Filterable` this should maybe be split into `RouteFilterable` and `NeighborFilterable` - `NeighborFilter.Match` should accept this interface, so this can be implemented for `api.Neighbor` and `api.NeighborStatus`
annikahannig (Migrated from github.com) commented 2024-02-29 18:21:25 +08:00

The NeighborFilter could then include this list of CIDRs / IPs / RE patterns.

The NeighborFilterable then could maybe expect MatchAddress MatchASN, MatchDescription MatchPattern?

something like this :)

The `NeighborFilter` could then include this list of CIDRs / IPs / RE patterns. The NeighborFilterable then could maybe expect `MatchAddress` `MatchASN`, `MatchDescription` `MatchPattern?` something like this :)
@ -38,0 +68,4 @@
}
neighbors:
for _, neighbor := range neighbors {
neighborIP := net.ParseIP(neighbor.Address)
annikahannig (Migrated from github.com) commented 2024-02-29 18:24:04 +08:00

Another reason to do this at config parse time:
If there is a broken pattern in the config, this would fail when routes refresh starts or, if there is no global search enabled, on first request.

Another reason to do this at config parse time: If there is a broken pattern in the config, this would fail when routes refresh starts or, if there is no global search enabled, on first request.
@ -38,0 +78,4 @@
continue neighbors
}
}
for _, cidr := range excludeCIDRs {
annikahannig (Migrated from github.com) commented 2024-02-29 18:09:43 +08:00

If the hidden_members config option is parsed into a e.g. []*NeighborFilter / filterset something like

func (filters []*NeighborFilter) Exclude[T NeighborFilterable](n []T) ([]T, error) {
  for filters ... {
     if n.Match(...) skip
  }
}

Then the invocation in the source could be like

neighbors := make(api.Neighbors, 0)
... decode neighbors...
response.Neighbors, err = src.cfg.HiddenNeighbors.Exclude(neighbors)
	if err != nil {
		return nil, err
	}
If the `hidden_members` config option is parsed into a e.g. []*NeighborFilter / filterset something like ``` func (filters []*NeighborFilter) Exclude[T NeighborFilterable](n []T) ([]T, error) { for filters ... { if n.Match(...) skip } } ``` Then the invocation in the source could be like ``` neighbors := make(api.Neighbors, 0) ... decode neighbors... response.Neighbors, err = src.cfg.HiddenNeighbors.Exclude(neighbors) if err != nil { return nil, err } ```
@ -38,0 +111,4 @@
for _, ip := range excludeIPs {
if ip.Equal(neighborIDAsIP) {
continue neighbors
}
annikahannig (Migrated from github.com) commented 2024-02-29 18:05:13 +08:00

This should rather be an early return, to reduce nesting.

This should rather be an early return, to reduce nesting.
annikahannig (Migrated from github.com) commented 2024-02-29 18:13:15 +08:00

Also this duplicated code would not longer be required.

Additionally: These functions feel a bit out of place here; so this would also be resolved.

Also this duplicated code would not longer be required. Additionally: These functions feel a bit out of place here; so this would also be resolved.
@ -54,6 +54,7 @@ type NeighborsStoreBackend interface {
type NeighborsStore struct {
backend NeighborsStoreBackend
sources *SourcesStore
cfg *config.Config
annikahannig (Migrated from github.com) commented 2024-02-29 18:16:34 +08:00

I think this is an artifact?

I think this is an artifact?
annikahannig (Migrated from github.com) reviewed 2024-02-29 18:29:48 +08:00
@ -38,0 +78,4 @@
continue neighbors
}
}
for _, cidr := range excludeCIDRs {
annikahannig (Migrated from github.com) commented 2024-02-29 18:29:48 +08:00

Or: even better: before it is appended during decode:

if cfg.HiddenNeighbors.Match(...) {
  continue
 }
 response.Neighbors = append(...

Then the Exclude function would not even be required. :)

Or: even better: before it is appended during decode: ``` if cfg.HiddenNeighbors.Match(...) { continue } response.Neighbors = append(... ``` Then the Exclude function would not even be required. :)
jof (Migrated from github.com) reviewed 2024-03-01 04:26:20 +08:00
@ -54,6 +54,7 @@ type NeighborsStoreBackend interface {
type NeighborsStore struct {
backend NeighborsStoreBackend
sources *SourcesStore
cfg *config.Config
jof (Migrated from github.com) commented 2024-03-01 04:26:19 +08:00

Indeed, it was.

Indeed, it was.
jof commented 2024-03-09 14:13:57 +08:00 (Migrated from github.com)

I'm still thinking this through, but I understand the desire to have a common filtering interface.

I'll take me a little bit to get up to speed with the other filtering codepaths and interfaces.

I'm still thinking this through, but I understand the desire to have a common filtering interface. I'll take me a little bit to get up to speed with the other filtering codepaths and interfaces.
This pull request can be merged automatically.
You are not authorized to merge this pull request.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin jof/jof/hidden-neighbors:jof/jof/hidden-neighbors
git checkout jof/jof/hidden-neighbors
Sign in to join this conversation.
No description provided.