mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
123 lines
3.7 KiB
Go
123 lines
3.7 KiB
Go
// SPDX-FileCopyrightText: 2022 Free Mobile
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
package bmp
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/netip"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/osrg/gobgp/v4/pkg/packet/bgp"
|
|
)
|
|
|
|
// Configuration describes the configuration for the BMP component. Only one peer is emulated.
|
|
type Configuration struct {
|
|
// Target specify the IP address and port to generate BMP routes to. Empty if this component is disabled.
|
|
Target string `validate:"isdefault|hostname_port"`
|
|
// Routes is the set of routes to announce to the collector using BMP.
|
|
Routes []RouteConfiguration `validate:"dive"`
|
|
// LocalASN is the local AS number
|
|
LocalASN uint16 `validate:"required,min=1"`
|
|
// PeerASN is the peer AS number
|
|
PeerASN uint16 `validate:"required,min=1"`
|
|
// LocalIP is the local IP address.
|
|
LocalIP netip.Addr `validate:"required"`
|
|
// PeerIP is the peer IP address.
|
|
PeerIP netip.Addr `validate:"required"`
|
|
// RetryAfter tells how much time to wait before retrying
|
|
RetryAfter time.Duration `validate:"min=0s"`
|
|
// StatsDelay tells how much time to wait between two BMP stats message (to check connection liveness)
|
|
StatsDelay time.Duration `validate:"min=0s"`
|
|
}
|
|
|
|
// RouteConfiguration describes a route to be generated with BMP.
|
|
type RouteConfiguration struct {
|
|
// Prefix is the set of prefixes to announce.
|
|
Prefixes []netip.Prefix `validate:"min=1"`
|
|
// ASPath is the AS path to associate with the prefixes.
|
|
ASPath []uint32 `validate:"min=1"`
|
|
// Communities are the set of standard communities to associate with the prefixes.
|
|
Communities []Community
|
|
// LargeCommunities are the set of large communities to associate with the prefixes.
|
|
LargeCommunities []LargeCommunity
|
|
}
|
|
|
|
// DefaultConfiguration represents the default configuration for the BMP component.
|
|
func DefaultConfiguration() Configuration {
|
|
return Configuration{
|
|
LocalASN: 64496,
|
|
PeerASN: 64497,
|
|
LocalIP: netip.MustParseAddr("2001:db8::1"),
|
|
PeerIP: netip.MustParseAddr("2001:db8::2"),
|
|
RetryAfter: time.Duration(5 * time.Second),
|
|
StatsDelay: time.Duration(time.Minute),
|
|
}
|
|
}
|
|
|
|
// Community is a standard community.
|
|
type Community uint32
|
|
|
|
// UnmarshalText parses a standard community.
|
|
func (comm *Community) UnmarshalText(input []byte) error {
|
|
text := string(input)
|
|
elems := strings.Split(text, ":")
|
|
if len(elems) != 2 {
|
|
return errors.New("community should be ASN:XX")
|
|
}
|
|
asn, err := strconv.ParseUint(elems[0], 10, 16)
|
|
if err != nil {
|
|
return errors.New("community should be ASN2:XX")
|
|
}
|
|
local, err := strconv.ParseUint(elems[1], 10, 16)
|
|
if err != nil {
|
|
return errors.New("community should be ASN:XX2")
|
|
}
|
|
*comm = Community((asn << 16) + local)
|
|
return nil
|
|
}
|
|
|
|
// String turns a community to a string.
|
|
func (comm Community) String() string {
|
|
return fmt.Sprintf("%d:%d", comm>>16, comm&0xffff)
|
|
}
|
|
|
|
// LargeCommunity represents a large community.
|
|
type LargeCommunity bgp.LargeCommunity
|
|
|
|
// UnmarshalText parses a large community
|
|
func (comm *LargeCommunity) UnmarshalText(input []byte) error {
|
|
text := string(input)
|
|
elems := strings.Split(text, ":")
|
|
if len(elems) != 3 {
|
|
return errors.New("community should be ASN:XX:YY")
|
|
}
|
|
asn, err := strconv.ParseUint(elems[0], 10, 32)
|
|
if err != nil {
|
|
return errors.New("community should be ASN4:XX:YY")
|
|
}
|
|
local1, err := strconv.ParseUint(elems[1], 10, 32)
|
|
if err != nil {
|
|
return errors.New("community should be ASN:XX4:YY")
|
|
}
|
|
local2, err := strconv.ParseUint(elems[2], 10, 32)
|
|
if err != nil {
|
|
return errors.New("community should be ASN:XX:YY4")
|
|
}
|
|
*comm = LargeCommunity{
|
|
ASN: uint32(asn),
|
|
LocalData1: uint32(local1),
|
|
LocalData2: uint32(local2),
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// String turns a large community to a string.
|
|
func (comm LargeCommunity) String() string {
|
|
b := bgp.LargeCommunity(comm)
|
|
return b.String()
|
|
}
|