Skip to content

Commit

Permalink
bgpv2: use peer asn and address in the key
Browse files Browse the repository at this point in the history
On updating peer ASN and address, we need to remove old peer and readd
it again. This change adds ASN and address in the key of peer along with
the name.

Secondly, order of changing peer is now delete, update and add. This is
done because adding before deleting old peer is going to fail when
changing ASN.

This change also allows setting local peer port to 0 (random port
selection from kernel)

Signed-off-by: harsimran pabla <hpabla@isovalent.com>
  • Loading branch information
harsimran-pabla committed Jun 19, 2024
1 parent 6aa4fa8 commit 192e50a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 21 deletions.
5 changes: 2 additions & 3 deletions pkg/bgpv1/gobgp/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,8 @@ func (g *GoBGPServer) setPeerTransport(peer, existingPeer *gobgp.Peer, peerAddr
peer.Transport = &gobgp.Transport{}
}

if localPort > 0 {
peer.Transport.LocalPort = localPort
}
// update local port, 0 is fine as well. In which case, linux will assign a random port.
peer.Transport.LocalPort = localPort

if peerPort > 0 {
peer.Transport.RemotePort = peerPort
Expand Down
51 changes: 33 additions & 18 deletions pkg/bgpv1/manager/reconcilerv2/neighbor.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,19 @@ func (r *NeighborReconciler) Reconcile(ctx context.Context, p ReconcileParams) e
nset := map[string]*member{}

for i, n := range newNeigh {
// validate that peer has ASN and address. In current implementation these fields are
// mandatory for a peer. Eventually we will relax this restriction with implementation
// of BGP unnumbered.
if n.PeerASN == nil {
return fmt.Errorf("peer %s does not have a PeerASN", n.Name)
}

if n.PeerAddress == nil {
return fmt.Errorf("peer %s does not have a PeerAddress", n.Name)
}

var (
key = n.Name
key = r.neighborID(&n)
h *member
ok bool
)
Expand Down Expand Up @@ -210,7 +221,7 @@ func (r *NeighborReconciler) Reconcile(ctx context.Context, p ReconcileParams) e

for i, n := range curNeigh {
var (
key = n.Peer.Name
key = r.neighborID(n.Peer)
h *member
ok bool
)
Expand Down Expand Up @@ -247,19 +258,17 @@ func (r *NeighborReconciler) Reconcile(ctx context.Context, p ReconcileParams) e
l.Debug("No peer changes necessary")
}

// create new neighbors
for _, n := range toCreate {
l.WithField(types.PeerLogField, n.Peer.Name).Info("Adding peer")
// remove neighbors
for _, n := range toRemove {
l.WithField(types.PeerLogField, n.Peer.Name).Info("Removing peer")

if err := p.BGPInstance.Router.AddNeighbor(ctx, types.NeighborRequest{
Peer: n.Peer,
PeerConfig: n.Config,
Password: n.Password,
if err := p.BGPInstance.Router.RemoveNeighbor(ctx, types.NeighborRequest{
Peer: n.Peer,
}); err != nil {
return fmt.Errorf("failed to add neigbhor %s in instance %s: %w", n.Peer.Name, p.DesiredConfig.Name, err)
return fmt.Errorf("failed to remove neigbhor %s from instance %s: %w", n.Peer.Name, p.DesiredConfig.Name, err)
}
// update metadata
r.upsertMetadata(p.BGPInstance, p.DesiredConfig.Name, n)
r.deleteMetadata(p.BGPInstance, p.DesiredConfig.Name, n)
}

// update neighbors
Expand All @@ -277,17 +286,19 @@ func (r *NeighborReconciler) Reconcile(ctx context.Context, p ReconcileParams) e
r.upsertMetadata(p.BGPInstance, p.DesiredConfig.Name, n)
}

// remove neighbors
for _, n := range toRemove {
l.WithField(types.PeerLogField, n.Peer.Name).Info("Removing peer")
// create new neighbors
for _, n := range toCreate {
l.WithField(types.PeerLogField, n.Peer.Name).Info("Adding peer")

if err := p.BGPInstance.Router.RemoveNeighbor(ctx, types.NeighborRequest{
Peer: n.Peer,
if err := p.BGPInstance.Router.AddNeighbor(ctx, types.NeighborRequest{
Peer: n.Peer,
PeerConfig: n.Config,
Password: n.Password,
}); err != nil {
return fmt.Errorf("failed to remove neigbhor %s from instance %s: %w", n.Peer.Name, p.DesiredConfig.Name, err)
return fmt.Errorf("failed to add neigbhor %s in instance %s: %w", n.Peer.Name, p.DesiredConfig.Name, err)
}
// update metadata
r.deleteMetadata(p.BGPInstance, p.DesiredConfig.Name, n)
r.upsertMetadata(p.BGPInstance, p.DesiredConfig.Name, n)
}

l.Debug("Done reconciling peers")
Expand Down Expand Up @@ -375,3 +386,7 @@ func GetPeerAddressFromConfig(conf *v2alpha1.CiliumBGPNodeInstance, peerName str
}
return netip.Addr{}, fmt.Errorf("peer %s not found in instance %s", peerName, conf.Name)
}

func (r *NeighborReconciler) neighborID(n *v2alpha1.CiliumBGPNodePeer) string {
return fmt.Sprintf("%s%s%d", n.Name, *n.PeerAddress, *n.PeerASN)
}
17 changes: 17 additions & 0 deletions pkg/bgpv1/manager/reconcilerv2/neighbor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ var (
},
}

peer2UpdatedASN = func() PeerData {
peer2Copy := PeerData{
Peer: peer2.Peer.DeepCopy(),
Config: peer2.Config.DeepCopy(),
Password: peer2.Password,
}

peer2Copy.Peer.PeerASN = ptr.To[int64](64125)
return peer2Copy
}()

peer2UpdatedTimers = func() PeerData {
peer2Copy := PeerData{
Peer: peer2.Peer.DeepCopy(),
Expand Down Expand Up @@ -172,6 +183,12 @@ func TestNeighborReconciler(t *testing.T) {
newNeighbors: []PeerData{peer1},
err: nil,
},
{
name: "update config : ASN",
neighbors: []PeerData{peer1, peer2},
newNeighbors: []PeerData{peer1, peer2UpdatedASN},
err: nil,
},
{
name: "update config : timers",
neighbors: []PeerData{peer1, peer2},
Expand Down

0 comments on commit 192e50a

Please sign in to comment.