From b00f74f7e4c6535b6157a934c7b51a0f97b19656 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Mon, 3 Nov 2025 07:49:03 +0100 Subject: [PATCH] demoexporter/bmp: switch to GoBGP v4 --- demoexporter/bmp/client.go | 82 +++++++++++++++++++++------------ demoexporter/bmp/client_test.go | 2 +- demoexporter/bmp/config.go | 2 +- go.mod | 3 +- go.sum | 6 +++ 5 files changed, 62 insertions(+), 33 deletions(-) diff --git a/demoexporter/bmp/client.go b/demoexporter/bmp/client.go index 9ef9adba..48af8d4f 100644 --- a/demoexporter/bmp/client.go +++ b/demoexporter/bmp/client.go @@ -9,11 +9,12 @@ import ( "errors" "io" "net" + "net/netip" "syscall" "time" - "github.com/osrg/gobgp/v3/pkg/packet/bgp" - "github.com/osrg/gobgp/v3/pkg/packet/bmp" + "github.com/osrg/gobgp/v4/pkg/packet/bgp" + "github.com/osrg/gobgp/v4/pkg/packet/bmp" ) // startBMPClient starts the BMP client @@ -31,9 +32,9 @@ func (c *Component) startBMPClient(ctx context.Context) { buf := bytes.NewBuffer([]byte{}) peerHeader := bmp.NewBMPPeerHeader( bmp.BMP_PEER_TYPE_GLOBAL, 0, 0, - c.config.PeerIP.Unmap().String(), + c.config.PeerIP, uint32(c.config.PeerASN), - "2.2.2.2", + netip.MustParseAddr("2.2.2.2"), 0) pkt, err := bmp.NewBMPInitiation([]bmp.BMPInfoTLVInterface{ bmp.NewBMPInfoTLVString(bmp.BMP_INIT_TLV_TYPE_SYS_DESCR, "Fake exporter"), @@ -43,23 +44,31 @@ func (c *Component) startBMPClient(ctx context.Context) { panic(err) } buf.Write(pkt) - pkt, err = bmp.NewBMPPeerUpNotification(*peerHeader, c.config.LocalIP.Unmap().String(), 179, 47647, - bgp.NewBGPOpenMessage(c.config.LocalASN, 30, "1.1.1.1", - []bgp.OptionParameterInterface{ - bgp.NewOptionParameterCapability([]bgp.ParameterCapabilityInterface{ - bgp.NewCapMultiProtocol(bgp.RF_IPv4_UC), - bgp.NewCapMultiProtocol(bgp.RF_IPv6_UC), - }), - }, - ), - bgp.NewBGPOpenMessage(c.config.PeerASN, 30, "2.2.2.2", - []bgp.OptionParameterInterface{ - bgp.NewOptionParameterCapability([]bgp.ParameterCapabilityInterface{ - bgp.NewCapMultiProtocol(bgp.RF_IPv4_UC), - bgp.NewCapMultiProtocol(bgp.RF_IPv6_UC), - }), - }, - ), + om1, err := bgp.NewBGPOpenMessage(c.config.LocalASN, 30, netip.MustParseAddr("1.1.1.1"), + []bgp.OptionParameterInterface{ + bgp.NewOptionParameterCapability([]bgp.ParameterCapabilityInterface{ + bgp.NewCapMultiProtocol(bgp.RF_IPv4_UC), + bgp.NewCapMultiProtocol(bgp.RF_IPv6_UC), + }), + }, + ) + if err != nil { + panic(err) + } + om2, err := bgp.NewBGPOpenMessage(c.config.PeerASN, 30, netip.MustParseAddr("2.2.2.2"), + []bgp.OptionParameterInterface{ + bgp.NewOptionParameterCapability([]bgp.ParameterCapabilityInterface{ + bgp.NewCapMultiProtocol(bgp.RF_IPv4_UC), + bgp.NewCapMultiProtocol(bgp.RF_IPv6_UC), + }), + }, + ) + if err != nil { + panic(err) + } + pkt, err = bmp.NewBMPPeerUpNotification(*peerHeader, c.config.LocalIP, 179, 47647, + om1, + om2, ).Serialize() if err != nil { panic(err) @@ -67,28 +76,41 @@ func (c *Component) startBMPClient(ctx context.Context) { buf.Write(pkt) // Send the routes - for _, af := range []bgp.RouteFamily{bgp.RF_IPv4_UC, bgp.RF_IPv6_UC} { + for _, af := range []bgp.Family{bgp.RF_IPv4_UC, bgp.RF_IPv6_UC} { + var nh netip.Addr + if af == bgp.RF_IPv4_UC { + nh = netip.MustParseAddr("192.0.2.1") + } else { + nh = netip.MustParseAddr("fe80::1") + } for _, route := range c.config.Routes { - prefixes := []bgp.AddrPrefixInterface{} + prefixes := []bgp.PathNLRI{} + for _, prefix := range route.Prefixes { - if af == bgp.RF_IPv4_UC && prefix.Addr().Is4() { - prefixes = append(prefixes, - bgp.NewIPAddrPrefix(uint8(prefix.Bits()), prefix.Addr().String())) - } else if af == bgp.RF_IPv6_UC && prefix.Addr().Is6() { - prefixes = append(prefixes, - bgp.NewIPv6AddrPrefix(uint8(prefix.Bits()), prefix.Addr().String())) + if af == bgp.RF_IPv4_UC && prefix.Addr().Is4() || af == bgp.RF_IPv6_UC && prefix.Addr().Is6() { + n, err := bgp.NewIPAddrPrefix(prefix) + if err != nil { + panic(err) + } + prefixes = append(prefixes, bgp.PathNLRI{ + NLRI: n, + }) } } if len(prefixes) == 0 { continue } + nlri, err := bgp.NewPathAttributeMpReachNLRI(af, prefixes, nh) + if err != nil { + panic(err) + } attrs := []bgp.PathAttributeInterface{ // bgp.NewPathAttributeNextHop("192.0.2.20"), bgp.NewPathAttributeOrigin(1), bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{ bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, route.ASPath), }), - bgp.NewPathAttributeMpReachNLRI("fe80::1", prefixes), + nlri, } if route.Communities != nil { comms := make([]uint32, len(route.Communities)) diff --git a/demoexporter/bmp/client_test.go b/demoexporter/bmp/client_test.go index 32a4215f..d25d49cc 100644 --- a/demoexporter/bmp/client_test.go +++ b/demoexporter/bmp/client_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - gobmp "github.com/osrg/gobgp/v3/pkg/packet/bmp" + gobmp "github.com/osrg/gobgp/v4/pkg/packet/bmp" "akvorado/common/daemon" "akvorado/common/helpers" diff --git a/demoexporter/bmp/config.go b/demoexporter/bmp/config.go index 8f6ad571..be84ab50 100644 --- a/demoexporter/bmp/config.go +++ b/demoexporter/bmp/config.go @@ -11,7 +11,7 @@ import ( "strings" "time" - "github.com/osrg/gobgp/v3/pkg/packet/bgp" + "github.com/osrg/gobgp/v4/pkg/packet/bgp" ) // Configuration describes the configuration for the BMP component. Only one peer is emulated. diff --git a/go.mod b/go.mod index 904ca769..baf60e4a 100644 --- a/go.mod +++ b/go.mod @@ -123,7 +123,7 @@ require ( github.com/jackc/pgx/v5 v5.6.0 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jellydator/ttlcache/v2 v2.11.1 // indirect - github.com/jessevdk/go-flags v1.5.0 // indirect + github.com/jessevdk/go-flags v1.6.1 // indirect github.com/jhump/protoreflect v1.17.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect @@ -146,6 +146,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openconfig/grpctunnel v0.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/osrg/gobgp/v4 v4.0.0 // indirect github.com/pascaldekloe/name v1.0.1 // indirect github.com/paulmach/orb v0.11.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect diff --git a/go.sum b/go.sum index ca400a03..bcab2fe7 100644 --- a/go.sum +++ b/go.sum @@ -159,6 +159,7 @@ github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqw github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= @@ -237,6 +238,8 @@ github.com/jellydator/ttlcache/v2 v2.11.1/go.mod h1:RtE5Snf0/57e+2cLWFYWCCsLas2H github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= +github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -338,6 +341,8 @@ github.com/oschwald/maxminddb-golang/v2 v2.0.0 h1:Gyljxck1kHbBxDgLM++NfDWBqvu1pW github.com/oschwald/maxminddb-golang/v2 v2.0.0/go.mod h1:gG4V88LsawPEqtbL1Veh1WRh+nVSYwXzJ1P5Fcn77g0= github.com/osrg/gobgp/v3 v3.37.0 h1:+ObuOdvj7G7nxrT0fKFta+EAupdWf/q1WzbXydr8IOY= github.com/osrg/gobgp/v3 v3.37.0/go.mod h1:kVHVFy1/fyZHJ8P32+ctvPeJogn9qKwa1YCeMRXXrP0= +github.com/osrg/gobgp/v4 v4.0.0 h1:DCL7iWUAPgL/DDBp1FSdkayQ0ptYYkucpuMkre+HGaI= +github.com/osrg/gobgp/v4 v4.0.0/go.mod h1:1a0YiXMuyRPqcCX+fkXZ2UUtcOnUxAWynFunUOSZepk= github.com/pascaldekloe/name v1.0.1 h1:9lnXOHeqeHHnWLbKfH6X98+4+ETVqFqxN09UXSjcMb0= github.com/pascaldekloe/name v1.0.1/go.mod h1:Z//MfYJnH4jVpQ9wkclwu2I2MkHmXTlT9wR5UZScttM= github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU= @@ -452,6 +457,7 @@ github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2W github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=