corebgp

package module
v0.8.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 23, 2024 License: MIT Imports: 15 Imported by: 0

README

CoreBGP

GoDev

CoreBGP is a BGP library written in Go that implements the BGP FSM with an event-driven, pluggable model. It exposes an API that empowers the user to:

  • send and validate OPEN message capabilities
  • handle "important" state transitions
  • handle incoming UPDATE messages
  • send outgoing UPDATE messages

CoreBGP provides optional, composable UPDATE message decoding facilities via UpdateDecoder. CoreBGP does not manage a routing table or send its own UPDATE messages. Those responsibilities are passed down to the user. Therefore, the intended user is someone who wants that responsibility.

See this blog post for the background and reasoning behind the development of CoreBGP.

Plugin

The primary building block of CoreBGP is a Plugin, defined by the following interface:

// Plugin is a BGP peer plugin.
type Plugin interface {
	// GetCapabilities is fired when a peer's FSM is in the Connect state prior
	// to sending an Open message. The returned capabilities are included in the
	// Open message sent to the peer.
	//
	// The four-octet AS number space capability will be implicitly handled,
	// Plugin implementations are not required to return it.
	GetCapabilities(peer PeerConfig) []Capability

	// OnOpenMessage is fired when an Open message is received from a peer
	// during the OpenSent state. Returning a non-nil Notification will cause it
	// to be sent to the peer and the FSM will transition to the Idle state.
	//
	// Remote peers MUST include the four-octet AS number space capability in
	// their open message. corebgp will return a Notification message if a
	// remote peer does not support said capability, and will not invoke
	// OnOpenMessage.
	//
	// Per RFC5492 a BGP speaker should only send a Notification if a required
	// capability is missing; unknown or unsupported capabilities should be
	// ignored.
	OnOpenMessage(peer PeerConfig, routerID netip.Addr, capabilities []Capability) *Notification

	// OnEstablished is fired when a peer's FSM transitions to the Established
	// state. The returned UpdateMessageHandler will be fired when an Update
	// message is received from the peer.
	//
	// The provided writer can be used to send Update messages to the peer for
	// the lifetime of the FSM's current, established state. It should be
	// discarded once OnClose() fires.
	OnEstablished(peer PeerConfig, writer UpdateMessageWriter) UpdateMessageHandler

	// OnClose is fired when a peer's FSM transitions out of the Established
	// state.
	OnClose(peer PeerConfig)
}

Here's an example Plugin that logs when a peer enters/leaves an established state and when an UPDATE message is received:

type plugin struct{}

func (p *plugin) GetCapabilities(c corebgp.PeerConfig) []corebgp.Capability {
	caps := make([]corebgp.Capability, 0)
	return caps
}

func (p *plugin) OnOpenMessage(peer corebgp.PeerConfig, routerID netip.Addr, capabilities []corebgp.Capability) *corebgp.Notification {
	return nil
}

func (p *plugin) OnEstablished(peer corebgp.PeerConfig, writer corebgp.UpdateMessageWriter) corebgp.UpdateMessageHandler {
	log.Println("peer established")
	// send End-of-Rib
	writer.WriteUpdate([]byte{0, 0, 0, 0})
	return p.handleUpdate
}

func (p *plugin) OnClose(peer corebgp.PeerConfig) {
	log.Println("peer closed")
}

func (p *plugin) handleUpdate(peer corebgp.PeerConfig, u []byte) *corebgp.Notification {
	log.Printf("got update message of len: %d", len(u))
	return nil
}

Plugins are attached to peers when they are added to the Server, which manages their lifetime:

routerID := netip.MustParseAddr("192.0.2.1")
srv, err := corebgp.NewServer(routerID)
if err != nil {
    log.Fatalf("error constructing server: %v", err)
}
p := &plugin{}
err = srv.AddPeer(corebgp.PeerConfig{
    RemoteAddress: netip.MustParseAddr("198.51.100.10"),
    LocalAS:       65001,
    RemoteAS:      65010,
}, p, corebgp.WithLocalAddress(routerID))
if err != nil {
    log.Fatalf("error adding peer: %v", err)
}

For more examples check out the examples directory and pkg.go.dev for the complete API.

Versioning

CoreBGP follows semver as closely as it can. Seeing as we are still major version zero (0.y.z), the public API should not be considered stable. You are encouraged to pin CoreBGP's version with your dependency management solution of choice.

Documentation

Index

Examples

Constants

View Source
const (
	CAP_MP_EXTENSIONS              uint8 = 1  // Multiprotocol Extensions for BGP-4
	CAP_ROUTE_REFRESH              uint8 = 2  // Route Refresh Capability for BGP-4
	CAP_OUTBOUND_ROUTE_FILTERING   uint8 = 3  // Outbound Route Filtering Capability
	CAP_EXTENDED_NEXT_HOP_ENCODING uint8 = 5  // Extended Next Hop Encoding
	CAP_EXTENDED_MESSSAGE          uint8 = 6  // BGP Extended Message
	CAP_BGPSEC                     uint8 = 7  // BGPsec Capability
	CAP_MULTIPLE_LABELS            uint8 = 8  // Multiple Labels Capability
	CAP_ROLE                       uint8 = 9  // BGP Role
	CAP_GRACEFUL_RESTART           uint8 = 64 // Graceful Restart Capability
	CAP_FOUR_OCTET_AS              uint8 = 65 // Support for 4-octet AS number capability
	CAP_DYNAMIC                    uint8 = 67 // Support for Dynamic Capability (capability specific)
	CAP_MULTISESSION               uint8 = 68 // Multisession BGP Capability
	CAP_ADD_PATH                   uint8 = 69 // ADD-PATH Capability
	CAP_ENHANCED_ROUTE_REFRESH     uint8 = 70 // Enhanced Route Refresh Capability
	CAP_LLGR                       uint8 = 71 // Long-Lived Graceful Restart (LLGR) Capability
	CAP_ROUTING_POLICY_DIST        uint8 = 72 // Routing Policy Distribution
	CAP_FQDN                       uint8 = 73 // FQDN Capability
	CAP_BFD                        uint8 = 74 // BFD Capability
	CAP_SOFTWARE_VERSION           uint8 = 75 // Software Version Capability
)

Capability Codes, Updated: 2023-01-23

View Source
const (
	AFI_IPV4                           uint16 = 1     // IP (IP version 4)
	AFI_IPV6                           uint16 = 2     // IP6 (IP version 6)
	AFI_NSAP                           uint16 = 3     // NSAP
	AFI_HDLC                           uint16 = 4     // HDLC (8-bit multidrop)
	AFI_BBN_1822                       uint16 = 5     // BBN 1822
	AFI_802                            uint16 = 6     // 802 (includes all 802 media plus Ethernet "canonical format")
	AFI_E163                           uint16 = 7     // E.163
	AFI_E164                           uint16 = 8     // E.164 (SMDS, Frame Relay, ATM)
	AFI_F69                            uint16 = 9     // F.69 (Telex)
	AFI_X121                           uint16 = 10    // X.121 (X.25, Frame Relay)
	AFI_IPX                            uint16 = 11    // IPX
	AFI_APPLETALK                      uint16 = 12    // Appletalk
	AFI_DECNET_IV                      uint16 = 13    // Decnet IV
	AFI_BANYAN_VINES                   uint16 = 14    // Banyan Vines
	AFI_E164_WITH_NSAP_SUBADDR         uint16 = 15    // E.164 with NSAP format subaddress
	AFI_DNS                            uint16 = 16    // DNS (Domain Name System)
	AFI_DISTINGUISHED_NAME             uint16 = 17    // Distinguished Name
	AFI_AS_NUMBER                      uint16 = 18    // AS Number
	AFI_XTP_OVER_IPV4                  uint16 = 19    // XTP over IP version 4
	AFI_XTP_OVER_IPV6                  uint16 = 20    // XTP over IP version 6
	AFI_XTP_NATIVE                     uint16 = 21    // XTP native mode XTP
	AFI_FIBRE_CHANNEL_WWPN             uint16 = 22    // Fibre Channel World-Wide Port Name
	AFI_FIBRE_CHANNEL_WWNN             uint16 = 23    // Fibre Channel World-Wide Node Name
	AFI_GWID                           uint16 = 24    // GWID
	AFI_L2VPN_INFO                     uint16 = 25    // AFI for L2VPN information
	AFI_MPLS_TP_SECTION_ENDPOINT_ID    uint16 = 26    // MPLS-TP Section Endpoint Identifier
	AFI_MPLS_TP_LSP_ENDPOINT_ID        uint16 = 27    // MPLS-TP LSP Endpoint Identifier
	AFI_MPLS_TP_PSEUDOWIRE_ENDPOINT_ID uint16 = 28    // MPLS-TP Pseudowire Endpoint Identifier
	AFI_MT_IPV4                        uint16 = 29    // MT IP: Multi-Topology IP version 4
	AFI_MT_IPV6                        uint16 = 30    // MT IPv6: Multi-Topology IP version 6
	AFI_BGP_SFC                        uint16 = 31    // BGP SFC
	AFI_EIGRP_COMMON_SERVICE_FAMILY    uint16 = 16384 // EIGRP Common Service Family
	AFI_EIGRP_IPV4_SERVICE_FAMILY      uint16 = 16385 // EIGRP IPv4 Service Family
	AFI_EIGRP_IPV6_SERVICE_FAMILY      uint16 = 16386 // EIGRP IPv6 Service Family
	AFI_LCAF                           uint16 = 16387 // LISP Canonical Address Format (LCAF)
	AFI_BGP_LS                         uint16 = 16388 // BGP-LS
	AFI_48_BIT_MAC                     uint16 = 16389 // 48-bit MAC
	AFI_64_BIT_MAC                     uint16 = 16390 // 64-bit MAC
	AFI_OUI                            uint16 = 16391 // OUI
	AFI_MAC_FINAL_24_BITS              uint16 = 16392 // MAC/24
	AFI_MAC_FINAL_40_BITS              uint16 = 16393 // MAC/40
	AFI_IPV6_INITIAL_64_BITS           uint16 = 16394 // IPv6/64
	AFI_RBRIDGE_PORT_ID                uint16 = 16395 // RBridge Port ID
	AFI_TRILL_NICKNAME                 uint16 = 16396 // TRILL Nickname
	AFI_UUID                           uint16 = 16397 // Universally Unique Identifier (UUID)
	AFI_ROUTING_POLICY                 uint16 = 16398 // Routing Policy AFI
	AFI_MPLS_NAMESPACES                uint16 = 16399 // MPLS Namespaces
)

Address Family Numbers, Updated: 2021-10-19

View Source
const (
	SAFI_UNICAST                               uint8 = 1   // Network Layer Reachability Information used for unicast forwarding
	SAFI_MULTICAST                             uint8 = 2   // Network Layer Reachability Information used for multicast forwarding
	SAFI_MPLS                                  uint8 = 4   // Network Layer Reachability Information (NLRI) with MPLS Labels
	SAFI_MCAST_VPN                             uint8 = 5   // MCAST-VPN
	SAFI_DYN_PLACEMENT_MULTI_SEGMENT_PW        uint8 = 6   // Network Layer Reachability Information used for Dynamic Placement of Multi-Segment Pseudowires
	SAFI_MCAST_VPLS                            uint8 = 8   // MCAST-VPLS
	SAFI_BGP_SFC                               uint8 = 9   // BGP SFC
	SAFI_TUNNEL                                uint8 = 64  // Tunnel SAFI
	SAFI_VPLS                                  uint8 = 65  // Virtual Private LAN Service (VPLS)
	SAFI_BGP_MDT                               uint8 = 66  // BGP MDT SAFI
	SAFI_BGP_4OVER6                            uint8 = 67  // BGP 4over6 SAFI
	SAFI_BGP_6OVER4                            uint8 = 68  // BGP 6over4 SAFI
	SAFI_LAYER_1_VPN_AUTO_DISCOVERY_INFO       uint8 = 69  // Layer-1 VPN auto-discovery information
	SAFI_BGP_EVPNS                             uint8 = 70  // BGP EVPNs
	SAFI_BGP_LS                                uint8 = 71  // BGP-LS
	SAFI_BGP_LS_VPN                            uint8 = 72  // BGP-LS-VPN
	SAFI_SR_TE_POLICY                          uint8 = 73  // SR TE Policy SAFI
	SAFI_SD_WAN_CAPABILITIES                   uint8 = 74  // SD-WAN Capabilities
	SAFI_ROUTING_POLICY                        uint8 = 75  // Routing Policy SAFI
	SAFI_CLASSFUL_TRANSPORT                    uint8 = 76  // Classful-Transport SAFI
	SAFI_TUNNELED_TRAFFIC_FLOWSPEC             uint8 = 77  // Tunneled Traffic Flowspec
	SAFI_MCAST_TREE                            uint8 = 78  // MCAST-TREE
	SAFI_BGP_DPS                               uint8 = 79  // BGP-DPS (Dynamic Path Selection)
	SAFI_BGP_LS_SPF                            uint8 = 80  // BGP-LS-SPF
	SAFI_BGP_CAR                               uint8 = 83  // BGP CAR
	SAFI_BGP_VPN_CAR                           uint8 = 84  // BGP VPN CAR
	SAFI_BGP_MUP                               uint8 = 85  // BGP-MUP SAFI
	SAFI_MPLS_LABELED_VPN_ADDR                 uint8 = 128 // MPLS-labeled VPN address
	SAFI_MULTICAST_BGP_MPLS_IP_VPNS            uint8 = 129 // Multicast for BGP/MPLS IP Virtual Private Networks (VPNs)
	SAFI_ROUTE_TARGET_CONSTRAINS               uint8 = 132 // Route Target constrains
	SAFI_DISSEMINATION_OF_FLOWSPEC_RULES       uint8 = 133 // Dissemination of Flow Specification rules
	SAFI_L3VPN_DISSEMINATION_OF_FLOWSPEC_RULES uint8 = 134 // L3VPN Dissemination of Flow Specification rules
	SAFI_VPN_AUTO_DISCOVERY                    uint8 = 140 // VPN auto-discovery
)

Subsequent Address Family Identifiers (SAFI) Parameters, Updated: 2022-08-19

View Source
const (
	PATH_ATTR_ORIGIN                                uint8 = 1   // ORIGIN
	PATH_ATTR_AS_PATH                               uint8 = 2   // AS_PATH
	PATH_ATTR_NEXT_HOP                              uint8 = 3   // NEXT_HOP
	PATH_ATTR_MED                                   uint8 = 4   // MULTI_EXIT_DISC
	PATH_ATTR_LOCAL_PREF                            uint8 = 5   // LOCAL_PREF
	PATH_ATTR_ATOMIC_AGGREGATE                      uint8 = 6   // ATOMIC_AGGREGATE
	PATH_ATTR_AGGREGATOR                            uint8 = 7   // AGGREGATOR
	PATH_ATTR_COMMUNITY                             uint8 = 8   // COMMUNITY
	PATH_ATTR_ORIGINATOR_ID                         uint8 = 9   // ORIGINATOR_ID
	PATH_ATTR_CLUSTER_LIST                          uint8 = 10  // CLUSTER_LIST
	PATH_ATTR_MP_REACH_NLRI                         uint8 = 14  // MP_REACH_NLRI
	PATH_ATTR_MP_UNREACH_NLRI                       uint8 = 15  // MP_UNREACH_NLRI
	PATH_ATTR_EXTENDED_COMMUNITIES                  uint8 = 16  // EXTENDED COMMUNITIES
	PATH_ATTR_AS4_PATH                              uint8 = 17  // AS4_PATH
	PATH_ATTR_AS4_AGGREGATOR                        uint8 = 18  // AS4_AGGREGATOR
	PATH_ATTR_PMSI_TUNNEL                           uint8 = 22  // PMSI_TUNNEL
	PATH_ATTR_TUNNEL_ENCAPSULATION                  uint8 = 23  // Tunnel Encapsulation
	PATH_ATTR_TRAFFIC_ENGINEERING                   uint8 = 24  // Traffic Engineering
	PATH_ATTR_IPV6_ADDR_SPECIFIC_EXTENDED_COMMUNITY uint8 = 25  // IPv6 Address Specific Extended Community
	PATH_ATTR_AIGP                                  uint8 = 26  // AIGP
	PATH_ATTR_PE_DISTINGUISHER_LABELS               uint8 = 27  // PE Distinguisher Labels
	PATH_ATTR_BGP_LS                                uint8 = 29  // BGP-LS Attribute
	PATH_ATTR_LARGE_COMMUNITY                       uint8 = 32  // LARGE_COMMUNITY
	PATH_ATTR_BGPSEC_PATH                           uint8 = 33  // BGPsec_Path
	PATH_ATTR_OTC                                   uint8 = 35  // Only to Customer (OTC)
	PATH_ATTR_SFP_ATTR                              uint8 = 37  // SFP attribute
	PATH_ATTR_BFD_DISCRIMINATOR                     uint8 = 38  // BFD Discriminator
	PATH_ATTR_BGP_PREFIX_SID                        uint8 = 40  // BGP Prefix-SID
	PATH_ATTR_ATTR_SET                              uint8 = 128 // ATTR_SET
)

BGP Path Attributes, Updated: 2023-01-18

View Source
const (
	NOTIF_CODE_MESSAGE_HEADER_ERR        uint8 = 1 // Message Header Error
	NOTIF_CODE_OPEN_MESSAGE_ERR          uint8 = 2 // OPEN Message Error
	NOTIF_CODE_UPDATE_MESSAGE_ERR        uint8 = 3 // UPDATE Message Error
	NOTIF_CODE_HOLD_TIMER_EXPIRED        uint8 = 4 // Hold Timer Expired
	NOTIF_CODE_FSM_ERR                   uint8 = 5 // Finite State Machine Error
	NOTIF_CODE_CEASE                     uint8 = 6 // Cease
	NOTIF_CODE_ROUTE_REFRESH_MESSAGE_ERR uint8 = 7 // ROUTE-REFRESH Message Error
)

BGP Error (Notification) Codes, Updated: 2023-01-18

View Source
const (
	NOTIF_SUBCODE_CONN_NOT_SYNCHRONIZED uint8 = 1 // Connection Not Synchronized
	NOTIF_SUBCODE_BAD_MESSAGE_LEN       uint8 = 2 // Bad Message Length
	NOTIF_SUBCODE_BAD_MESSAGE_TYPE      uint8 = 3 // Bad Message Type
)

Message Header Error subcodes, Updated: 2023-01-18

View Source
const (
	NOTIF_SUBCODE_UNSUPPORTED_VERSION_NUM    uint8 = 1  // Unsupported Version Number
	NOTIF_SUBCODE_BAD_PEER_AS                uint8 = 2  // Bad Peer AS
	NOTIF_SUBCODE_BAD_BGP_ID                 uint8 = 3  // Bad BGP Identifier
	NOTIF_SUBCODE_UNSUPPORTED_OPTIONAL_PARAM uint8 = 4  // Unsupported Optional Parameter
	NOTIF_SUBCODE_UNACCEPTABLE_HOLD_TIME     uint8 = 6  // Unacceptable Hold Time
	NOTIF_SUBCODE_UNSUPPORTED_CAPABILITY     uint8 = 7  // Unsupported Capability
	NOTIF_SUBCODE_ROLE_MISMATCH              uint8 = 11 // Role Mismatch
)

OPEN Message Error subcodes, Updated: 2023-01-18

View Source
const (
	NOTIF_SUBCODE_MALFORMED_ATTR_LIST          uint8 = 1  // Malformed Attribute List
	NOTIF_SUBCODE_UNRECOGNIZED_WELL_KNOWN_ATTR uint8 = 2  // Unrecognized Well-known Attribute
	NOTIF_SUBCODE_MISSING_WELL_KNOWN_ATTR      uint8 = 3  // Missing Well-known Attribute
	NOTIF_SUBCODE_ATTR_FLAGS_ERR               uint8 = 4  // Attribute Flags Error
	NOTIF_SUBCODE_ATTR_LEN_ERR                 uint8 = 5  // Attribute Length Error
	NOTIF_SUBCODE_INVALID_ORIGIN_ATTR          uint8 = 6  // Invalid ORIGIN Attribute
	NOTIF_SUBCODE_INVALID_NEXT_HOP_ATTR        uint8 = 8  // Invalid NEXT_HOP Attribute
	NOTIF_SUBCODE_OPTIONAL_ATTR_ERR            uint8 = 9  // Optional Attribute Error
	NOTIF_SUBCODE_INVALID_NETWORK_FIELD        uint8 = 10 // Invalid Network Field
	NOTIF_SUBCODE_MALFORMED_AS_PATH            uint8 = 11 // Malformed AS_PATH
)

UPDATE Message Error subcodes, Updated: 2023-01-18

View Source
const (
	NOTIF_SUBCODE_RX_UNEXPECTED_MESSAGE_OPENSENT    uint8 = 1 // Receive Unexpected Message in OpenSent State
	NOTIF_SUBCODE_RX_UNEXPECTED_MESSAGE_OPENCONFIRM uint8 = 2 // Receive Unexpected Message in OpenConfirm State
	NOTIF_SUBCODE_RX_UNEXPECTED_MESSAGE_ESTABLISHED uint8 = 3 // Receive Unexpected Message in Established State
)

BGP Finite State Machine Error Subcodes, Updated: 2023-01-18

View Source
const (
	NOTIF_SUBCODE_MAX_NUM_OF_PREFIXES_REACHED uint8 = 1  // Maximum Number of Prefixes Reached
	NOTIF_SUBCODE_ADMIN_SHUTDOWN              uint8 = 2  // Administrative Shutdown
	NOTIF_SUBCODE_PEER_DECONFIGURED           uint8 = 3  // Peer De-configured
	NOTIF_SUBCODE_ADMIN_RESET                 uint8 = 4  // Administrative Reset
	NOTIF_SUBCODE_CONN_REJECTED               uint8 = 5  // Connection Rejected
	NOTIF_SUBCODE_OTHER_CONFIG_CHANGE         uint8 = 6  // Other Configuration Change
	NOTIF_SUBCODE_CONN_COLLISION_RESOLUTION   uint8 = 7  // Connection Collision Resolution
	NOTIF_SUBCODE_OUT_OF_RESOURCES            uint8 = 8  // Out of Resources
	NOTIF_SUBCODE_HARD_RESET                  uint8 = 9  // Hard Reset
	NOTIF_SUBCODE_BFD_DOWN                    uint8 = 10 // BFD Down
)

BGP Cease NOTIFICATION message subcodes, Updated: 2023-01-18

View Source
const (
	// DefaultHoldTimeSeconds is the default hold down time in seconds.
	DefaultHoldTimeSeconds uint16 = 90
	// DefaultIdleHoldTime is the default idle state hold time for a peer.
	DefaultIdleHoldTime = time.Second * 5
	// DefaultConnectRetryTime is the default maximum time spent waiting for an
	// outbound dial to connect.
	//
	// https://tools.ietf.org/html/rfc4271#section-8.2.2
	// The exact value of the ConnectRetryTimer is a local matter, but it
	// SHOULD be sufficiently large to allow TCP initialization.
	DefaultConnectRetryTime = time.Second * 5
	// DefaultPort is the default TCP port for a peer.
	DefaultPort = 179
)
View Source
const (
	NOTIF_SUBCODE_INVALID_MESSAGE_LEN uint8 = 1 // Invalid Message Length
)

BGP ROUTE-REFRESH Message Error subcodes, Updated: 2023-01-18

Variables

View Source
var (
	ErrServerClosed      = errors.New("server closed")
	ErrPeerNotExist      = errors.New("peer does not exist")
	ErrPeerAlreadyExists = errors.New("peer already exists")
)

Functions

func DecodeMPIPv6Prefixes added in v0.7.0

func DecodeMPIPv6Prefixes(b []byte) ([]netip.Prefix, error)

DecodeMPIPv6Prefixes decodes IPv6 prefixes in b with multiprotocol error handling consistent with RFC7606.

func DecodeMPReachIPv6NextHops added in v0.7.0

func DecodeMPReachIPv6NextHops(nh []byte) ([]netip.Addr, error)

DecodeMPReachIPv6NextHops decodes one or two (RFC2545) IPv6 next hops contained in nh. Error handling is consistent with RFC7606.

func SetLogger

func SetLogger(l Logger)

SetLogger enables logging with the provided Logger.

func SetTCPMD5Signature added in v0.2.0

func SetTCPMD5Signature(fd int, address netip.Addr, prefixLen uint8,
	key string) error

SetTCPMD5Signature sets a tcp md5 signature on a socket for the provided address, prefix length, and key. This function is only supported on Linux. To unset a signature provide an empty key. Prefix length is ignored on kernels < 4.13.

https://tools.ietf.org/html/rfc2385

Types

type ASPathAttr added in v0.7.0

type ASPathAttr struct {
	ASSet      []uint32
	ASSequence []uint32
}

func (*ASPathAttr) Decode added in v0.7.0

func (a *ASPathAttr) Decode(flags PathAttrFlags, b []byte) error

type AddPathPrefix added in v0.8.0

type AddPathPrefix struct {
	Prefix netip.Prefix
	ID     uint32
}

AddPathPrefix is a prefix with an add-path ID. https://www.rfc-editor.org/rfc/rfc7911#section-3

func DecodeMPIPv6AddPathPrefixes added in v0.8.0

func DecodeMPIPv6AddPathPrefixes(b []byte) ([]AddPathPrefix, error)

DecodeMPIPv6AddPathPrefixes decodes IPv6 add-path prefixes in b with multiprotocol error handling consistent with RFC7606.

type AddPathTuple added in v0.8.0

type AddPathTuple struct {
	AFI  uint16
	SAFI uint8
	Tx   bool
	Rx   bool
}

func DecodeAddPathTuples added in v0.8.0

func DecodeAddPathTuples(b []byte) ([]AddPathTuple, error)

func (*AddPathTuple) Decode added in v0.8.0

func (a *AddPathTuple) Decode(b []byte) error

func (*AddPathTuple) Encode added in v0.8.0

func (a *AddPathTuple) Encode() []byte

type AggregatorPathAttr added in v0.7.0

type AggregatorPathAttr struct {
	AS uint32
	IP netip.Addr
}

func (*AggregatorPathAttr) Decode added in v0.7.0

func (a *AggregatorPathAttr) Decode(flags PathAttrFlags, b []byte) error

type AtomicAggregatePathAttr added in v0.7.0

type AtomicAggregatePathAttr bool

func (*AtomicAggregatePathAttr) Decode added in v0.7.0

func (a *AtomicAggregatePathAttr) Decode(flags PathAttrFlags, b []byte) error

type AttrDiscardUpdateErr added in v0.7.0

type AttrDiscardUpdateErr struct {
	Code         uint8
	Notification *Notification
}

AttrDiscardUpdateErr represents an error encountered during UPDATE message handling. The usage of this error is described in https://www.rfc-editor.org/rfc/rfc7606#section-2

Attribute discard: In this approach, the malformed attribute MUST be discarded and the UPDATE message continues to be processed. This approach MUST NOT be used except in the case of an attribute that has no effect on route selection or installation.

func (*AttrDiscardUpdateErr) AsSessionReset added in v0.7.0

func (a *AttrDiscardUpdateErr) AsSessionReset() *Notification

func (*AttrDiscardUpdateErr) Error added in v0.7.0

func (a *AttrDiscardUpdateErr) Error() string

type Capability

type Capability struct {
	Code  uint8
	Value []byte
}

Capability is a BGP capability as defined by RFC5492.

func NewAddPathCapability added in v0.8.0

func NewAddPathCapability(tuples []AddPathTuple) Capability

NewAddPathCapability returns an add-path Capability for the provided AddPathTuples.

func NewMPExtensionsCapability added in v0.3.0

func NewMPExtensionsCapability(afi uint16, safi uint8) Capability

NewMPExtensionsCapability returns a Multiprotocol Extensions Capability for the provided AFI and SAFI.

func (Capability) Equal added in v0.8.0

func (c Capability) Equal(d Capability) bool

type ClusterListPathAttr added in v0.7.0

type ClusterListPathAttr []netip.Addr

func (*ClusterListPathAttr) Decode added in v0.7.0

func (c *ClusterListPathAttr) Decode(flags PathAttrFlags, b []byte) error

type CommunitiesPathAttr added in v0.7.0

type CommunitiesPathAttr []uint32

func (*CommunitiesPathAttr) Decode added in v0.7.0

func (c *CommunitiesPathAttr) Decode(flags PathAttrFlags, b []byte) error

type DecodeFn added in v0.7.0

type DecodeFn[T any] func(t T, b []byte) error

func NewNLRIAddPathDecodeFn added in v0.8.0

func NewNLRIAddPathDecodeFn[T any](fn func(t T, a []AddPathPrefix) error) DecodeFn[T]

NewNLRIAddPathDecodeFn returns a DecodeFn to be used by an UpdateDecoder for decoding the NLRI field of an UPDATE message containing add-path prefixes. The closure fn will be passed type T and a slice of AddPathPrefix.

func NewNLRIDecodeFn added in v0.7.0

func NewNLRIDecodeFn[T any](fn func(t T, p []netip.Prefix) error) DecodeFn[T]

NewNLRIDecodeFn returns a DecodeFn to be used by an UpdateDecoder for decoding the NLRI field of an UPDATE message. The closure fn will be passed type T and a slice of netip.Prefix.

func NewWithdrawnAddPathRoutesDecodeFn added in v0.8.0

func NewWithdrawnAddPathRoutesDecodeFn[T any](fn func(t T, a []AddPathPrefix) error) DecodeFn[T]

NewWithdrawnAddPathRoutesDecodeFn returns a DecodeFn to be used by an UpdateDecoder for decoding the withdrawn routes field of an UPDATE message containing add-path prefixes. The closure fn will be passed type T and a slice of AddPathPrefix.

func NewWithdrawnRoutesDecodeFn added in v0.7.0

func NewWithdrawnRoutesDecodeFn[T any](fn func(t T, p []netip.Prefix) error) DecodeFn[T]

NewWithdrawnRoutesDecodeFn returns a DecodeFn to be used by an UpdateDecoder for decoding the withdrawn routes field of an UPDATE message. The closure fn will be passed type T and a slice of netip.Prefix.

type LargeCommunitiesPathAttr added in v0.8.3

type LargeCommunitiesPathAttr []LargeCommunity

func (*LargeCommunitiesPathAttr) Decode added in v0.8.3

func (l *LargeCommunitiesPathAttr) Decode(flags PathAttrFlags, b []byte) error

type LargeCommunity added in v0.8.3

type LargeCommunity struct {
	GlobalAdmin, LocalData1, LocalData2 uint32
}

type LocalPrefPathAttr added in v0.7.0

type LocalPrefPathAttr uint32

func (*LocalPrefPathAttr) Decode added in v0.7.0

func (l *LocalPrefPathAttr) Decode(flags PathAttrFlags, b []byte) error

type Logger

type Logger func(...interface{})

Logger is a log.Print-compatible function

type MEDPathAttr added in v0.7.0

type MEDPathAttr uint32

func (*MEDPathAttr) Decode added in v0.7.0

func (m *MEDPathAttr) Decode(flags PathAttrFlags, b []byte) error

type MPPathAttrDecodeFn added in v0.7.0

type MPPathAttrDecodeFn[T any] func(t T, flags PathAttrFlags, b []byte) error

func NewMPReachNLRIDecodeFn added in v0.7.0

func NewMPReachNLRIDecodeFn[T any](fn func(t T, afi uint16, safi uint8, nh, nlri []byte) error) MPPathAttrDecodeFn[T]

NewMPReachNLRIDecodeFn returns a MPPathAttrDecodeFn that can be used to compose logic for decoding a MP_REACH_NLRI path attribute through the provided closure fn. The closure fn will be passed type T, the afi, safi, next hop bytes, and nlri bytes.

func NewMPUnreachNLRIDecodeFn added in v0.7.0

func NewMPUnreachNLRIDecodeFn[T any](fn func(t T, afi uint16, safi uint8, withdrawn []byte) error) MPPathAttrDecodeFn[T]

NewMPUnreachNLRIDecodeFn returns a MPPathAttrDecodeFn that can be used to compose logic for decoding a MP_UNREACH_NLRI path attribute through the provided closure fn. The closure fn will be passed type T, the afi, safi, and withdrawn field for the path attribute.

type NextHopPathAttr added in v0.7.0

type NextHopPathAttr netip.Addr

func (*NextHopPathAttr) Decode added in v0.7.0

func (n *NextHopPathAttr) Decode(flags PathAttrFlags, b []byte) error

type Notification

type Notification struct {
	Code    uint8
	Subcode uint8
	Data    []byte
}

Notification is a Notification message.

func UpdateNotificationFromErr added in v0.7.0

func UpdateNotificationFromErr(err error) *Notification

UpdateNotificationFromErr finds the highest severity *Notification in err's tree. This is useful for Plugins using UpdateDecoder that do not handle the additional error approaches described by RFC7606, and instead are designed to send a *Notification when any error occurs.

The severity order from highest to lowest is *Notification, *TreatAsWithdrawUpdateErr, *AttrDiscardUpdateErr, UpdateError (not one of the previous concrete types). If there are multiple errors contained in err's tree of the same severity the earliest found is returned. A *Notification with code NOTIF_CODE_UPDATE_MESSAGE_ERR, no subcode, and no data is returned in the event that a *Notification cannot be extracted from err.

func (*Notification) AsSessionReset added in v0.7.0

func (n *Notification) AsSessionReset() *Notification

func (*Notification) Error added in v0.7.0

func (n *Notification) Error() string

type OriginPathAttr added in v0.7.0

type OriginPathAttr uint8

func (*OriginPathAttr) Decode added in v0.7.0

func (o *OriginPathAttr) Decode(flags PathAttrFlags, b []byte) error

type OriginatorIDPathAttr added in v0.7.0

type OriginatorIDPathAttr netip.Addr

func (*OriginatorIDPathAttr) Decode added in v0.7.0

func (o *OriginatorIDPathAttr) Decode(flags PathAttrFlags, b []byte) error

type PathAttrFlags added in v0.7.0

type PathAttrFlags uint8

PathAttrFlags represents the flags for a path attribute.

func (PathAttrFlags) ExtendedLen added in v0.7.0

func (p PathAttrFlags) ExtendedLen() bool

ExtendedLen defines whether the Attribute Length is one octet (if set to 0) or two octets (if set to 1).

func (PathAttrFlags) Optional added in v0.7.0

func (p PathAttrFlags) Optional() bool

Optional defines whether the attribute is optional (if set to 1) or well-known (if set to 0).

func (PathAttrFlags) Partial added in v0.7.0

func (p PathAttrFlags) Partial() bool

Partial defines whether the information contained in the optional transitive attribute is partial (if set to 1) or complete (if set to 0).

func (PathAttrFlags) Transitive added in v0.7.0

func (p PathAttrFlags) Transitive() bool

Transitive defines whether an optional attribute is transitive (if set to 1) or non-transitive (if set to 0).

func (PathAttrFlags) Validate added in v0.7.0

func (p PathAttrFlags) Validate(forCode uint8, attrData []byte, wantOptional, wantTransitive bool) error

type PathAttrsDecodeFn added in v0.7.0

type PathAttrsDecodeFn[T any] func(t T, code uint8, flags PathAttrFlags, b []byte) error

PathAttrsDecodeFn is used by an instance of an UpdateDecoder to decode path attributes in an UPDATE message. It is invoked per-path attribute where code is the attribute code, flags are the attribute flags, and b contains the attribute data.

type PeerConfig

type PeerConfig struct {
	// RemoteAddress is the remote address of the peer.
	RemoteAddress netip.Addr

	// LocalAS is the local autonomous system number to populate in outbound
	// OPEN messages.
	LocalAS uint32

	// RemoteAS is the autonomous system number to expect in OPEN messages
	// from this peer.
	RemoteAS uint32
}

PeerConfig is the required configuration for a Peer.

type PeerOption

type PeerOption interface {
	// contains filtered or unexported methods
}

func WithConnectRetryTime added in v0.2.0

func WithConnectRetryTime(t time.Duration) PeerOption

WithConnectRetryTime returns a PeerOption that sets the connect retry time for a peer.

func WithDialerControl added in v0.2.0

func WithDialerControl(fn func(network, address string,
	c syscall.RawConn) error) PeerOption

WithDialerControl returns a PeerOption that sets the outbound net.Dialer Control field. This is commonly used to set socket options, e.g. ip TTL, tcp md5, tcp_nodelay, etc...

func WithHoldTime added in v0.6.0

func WithHoldTime(seconds uint16) PeerOption

WithHoldTime returns a PeerOption that sets the hold time (in seconds) to be advertised to the peer via OPEN message. Hold time MUST be 0 or >= 3 seconds.

func WithIdleHoldTime added in v0.2.0

func WithIdleHoldTime(t time.Duration) PeerOption

WithIdleHoldTime returns a PeerOption that sets the idle hold time for a peer. Idle hold time controls how quickly a peer can oscillate from idle to the connect state.

func WithLocalAddress added in v0.5.0

func WithLocalAddress(localAddress netip.Addr) PeerOption

WithLocalAddress returns a PeerOption that specifies the source address to use when dialing outbound, and to verify as a destination for inbound connections. Without this PeerOption corebgp behaves loosely, accepting inbound connections regardless of the destination address, and falling back on the OS for outbound source address selection.

func WithPassive added in v0.2.0

func WithPassive() PeerOption

WithPassive returns a PeerOption that sets a Peer to passive mode. In passive mode a peer will not dial out and will only accept incoming connections.

func WithPort added in v0.2.0

func WithPort(p int) PeerOption

WithPort returns a PeerOption that sets the TCP port for a peer.

type Plugin

type Plugin interface {
	// GetCapabilities is fired when a peer's FSM is in the Connect state prior
	// to sending an Open message. The returned capabilities are included in the
	// Open message sent to the peer.
	//
	// The four-octet AS number space capability will be implicitly handled,
	// Plugin implementations are not required to return it.
	GetCapabilities(peer PeerConfig) []Capability

	// OnOpenMessage is fired when an Open message is received from a peer
	// during the OpenSent state. Returning a non-nil Notification will cause it
	// to be sent to the peer and the FSM will transition to the Idle state.
	//
	// Remote peers MUST include the four-octet AS number space capability in
	// their open message. corebgp will return a Notification message if a
	// remote peer does not support said capability, and will not invoke
	// OnOpenMessage.
	//
	// Per RFC5492 a BGP speaker should only send a Notification if a required
	// capability is missing; unknown or unsupported capabilities should be
	// ignored.
	OnOpenMessage(peer PeerConfig, routerID netip.Addr, capabilities []Capability) *Notification

	// OnEstablished is fired when a peer's FSM transitions to the Established
	// state. The returned UpdateMessageHandler will be fired when an Update
	// message is received from the peer.
	//
	// The provided writer can be used to send Update messages to the peer for
	// the lifetime of the FSM's current, established state. It should be
	// discarded once OnClose() fires.
	OnEstablished(peer PeerConfig, writer UpdateMessageWriter) UpdateMessageHandler

	// OnClose is fired when a peer's FSM transitions out of the Established
	// state.
	OnClose(peer PeerConfig)
}

Plugin is a BGP peer plugin.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a BGP server that manages peers.

func NewServer

func NewServer(routerID netip.Addr) (*Server, error)

NewServer creates a new Server.

func (*Server) AddPeer

func (s *Server) AddPeer(config PeerConfig, plugin Plugin,
	opts ...PeerOption) error

AddPeer adds a peer to the Server to be handled with the provided Plugin and PeerOptions.

func (*Server) Close

func (s *Server) Close()

Close stops the Server. An instance of a stopped Server cannot be re-used.

func (*Server) DeletePeer

func (s *Server) DeletePeer(ip netip.Addr) error

DeletePeer deletes a peer from the Server.

func (*Server) GetPeer added in v0.2.0

func (s *Server) GetPeer(ip netip.Addr) (PeerConfig, error)

GetPeer returns the configuration for the provided peer, or an error if it does not exist.

func (*Server) ListPeers added in v0.2.0

func (s *Server) ListPeers() []PeerConfig

ListPeers returns the configuration for all peers.

func (*Server) Serve

func (s *Server) Serve(listeners []net.Listener) error

Serve starts all peers' FSMs, starts handling incoming connections if a non-nil listener is provided, and then blocks. Serve returns ErrServerClosed upon Close() or a listener error if one occurs.

type TreatAsWithdrawUpdateErr added in v0.7.0

type TreatAsWithdrawUpdateErr struct {
	Code         uint8
	Notification *Notification
}

TreatAsWithdrawUpdateErr represents an error encountered during UPDATE message handling. The usage of this error is described in https://www.rfc-editor.org/rfc/rfc7606#section-2

Treat-as-withdraw: In this approach, the UPDATE message containing the path attribute in question MUST be treated as though all contained routes had been withdrawn just as if they had been listed in the WITHDRAWN ROUTES field (or in the MP_UNREACH_NLRI attribute if appropriate) of the UPDATE message, thus causing them to be removed from the Adj-RIB-In according to the procedures of [RFC4271].

func (*TreatAsWithdrawUpdateErr) AsSessionReset added in v0.7.0

func (t *TreatAsWithdrawUpdateErr) AsSessionReset() *Notification

func (*TreatAsWithdrawUpdateErr) Error added in v0.7.0

func (t *TreatAsWithdrawUpdateErr) Error() string

type UpdateDecoder added in v0.7.0

type UpdateDecoder[T any] struct {
	// contains filtered or unexported fields
}

UpdateDecoder decodes UPDATE messages. Type T can be passed to its underlying field-specific decode functions.

Example

ExampleUpdateDecoder demonstrates an UpdateDecoder that decodes UPDATE messages containing IPv4 and IPv6 routes.

package main

import (
	"fmt"
	"net/netip"

	"github.com/jwhited/corebgp"
)

type updateMessage struct {
	withdrawn     []netip.Prefix
	origin        uint8
	asPath        []uint32
	nextHop       netip.Addr
	communities   []uint32
	nlri          []netip.Prefix
	ipv6NextHops  []netip.Addr
	ipv6NLRI      []netip.Prefix
	ipv6Withdrawn []netip.Prefix
}

func newPathAttrsDecodeFn() func(m *updateMessage, code uint8, flags corebgp.PathAttrFlags, b []byte) error {
	reachDecodeFn := corebgp.NewMPReachNLRIDecodeFn[*updateMessage](
		func(m *updateMessage, afi uint16, safi uint8, nh, nlri []byte) error {
			if afi == corebgp.AFI_IPV6 && safi == corebgp.SAFI_UNICAST {
				nhs, err := corebgp.DecodeMPReachIPv6NextHops(nh)
				if err != nil {
					return err
				}
				prefixes, err := corebgp.DecodeMPIPv6Prefixes(nlri)
				if err != nil {
					return err
				}
				m.ipv6NextHops = nhs
				m.ipv6NLRI = prefixes
			}
			return nil
		},
	)
	unreachDecodeFn := corebgp.NewMPUnreachNLRIDecodeFn[*updateMessage](
		func(m *updateMessage, afi uint16, safi uint8, withdrawn []byte) error {
			if afi == corebgp.AFI_IPV6 && safi == corebgp.SAFI_UNICAST {
				prefixes, err := corebgp.DecodeMPIPv6Prefixes(withdrawn)
				if err != nil {
					return err
				}
				m.ipv6Withdrawn = prefixes
			}
			return nil
		},
	)
	return func(m *updateMessage, code uint8, flags corebgp.PathAttrFlags, b []byte) error {
		switch code {
		case corebgp.PATH_ATTR_ORIGIN:
			var o corebgp.OriginPathAttr
			err := o.Decode(flags, b)
			if err != nil {
				return err
			}
			m.origin = uint8(o)
			return nil
		case corebgp.PATH_ATTR_AS_PATH:
			var a corebgp.ASPathAttr
			err := a.Decode(flags, b)
			if err != nil {
				return err
			}
			m.asPath = a.ASSequence
			return nil
		case corebgp.PATH_ATTR_NEXT_HOP:
			var nh corebgp.NextHopPathAttr
			err := nh.Decode(flags, b)
			if err != nil {
				return err
			}
			m.nextHop = netip.Addr(nh)
			return nil
		case corebgp.PATH_ATTR_COMMUNITY:
			var comms corebgp.CommunitiesPathAttr
			err := comms.Decode(flags, b)
			if err != nil {
				return err
			}
			m.communities = comms
		case corebgp.PATH_ATTR_MP_REACH_NLRI:
			return reachDecodeFn(m, flags, b)
		case corebgp.PATH_ATTR_MP_UNREACH_NLRI:
			return unreachDecodeFn(m, flags, b)
		}
		return nil
	}
}

// ExampleUpdateDecoder demonstrates an UpdateDecoder that decodes UPDATE
// messages containing IPv4 and IPv6 routes.
func main() {
	ud := corebgp.NewUpdateDecoder[*updateMessage](
		corebgp.NewWithdrawnRoutesDecodeFn[*updateMessage](func(u *updateMessage, withdrawn []netip.Prefix) error {
			u.withdrawn = withdrawn
			return nil
		}),
		newPathAttrsDecodeFn(),
		corebgp.NewNLRIDecodeFn[*updateMessage](func(u *updateMessage, nlri []netip.Prefix) error {
			u.nlri = nlri
			return nil
		}),
	)

	m := &updateMessage{}
	fmt.Println("=== ipv4 ===")
	fmt.Println(ud.Decode(m, []byte{
		0x00, 0x03, // withdrawn routes length
		0x10, 0x0a, 0x00, // withdrawn 10.0.0.0/16
		0x00, 0x1b, // total path attr len
		0x40, 0x01, 0x01, 0x01, // origin egp
		0x40, 0x02, 0x06, 0x02, 0x01, 0x00, 0x00, 0xfd, 0xea, // as path 65002
		0x40, 0x03, 0x04, 0xc0, 0x00, 0x02, 0x02, // next hop 192.0.2.2
		0xc0, 0x08, 0x04, 0xfd, 0xea, 0xff, 0xff, // communities 65002:65535
		0x18, 0xc0, 0x00, 0x02, // nlri 192.0.2.0/24
	}))
	fmt.Println(m.withdrawn)
	fmt.Println(m.origin)
	fmt.Println(m.asPath)
	fmt.Println(m.nextHop)
	fmt.Println(m.nlri)
	fmt.Println(m.communities)

	m = &updateMessage{}
	fmt.Println("=== ipv6 ===")
	fmt.Println(ud.Decode(m, []byte{
		0x00, 0x00, // withdrawn routes length
		0x00, 0x3f, // total path attr len
		// extended len MP_REACH_NLRI 2001:db8::/64 nhs 2001:db8::2 & fe80::42:c0ff:fe00:202
		0x90, 0x0e, 0x00, 0x2e, 0x00, 0x02, 0x01, 0x20, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xc0, 0xff, 0xfe, 0x00, 0x02, 0x02, 0x00, 0x40, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
		0x40, 0x01, 0x01, 0x01, // origin egp
		0x40, 0x02, 0x06, 0x02, 0x01, 0x00, 0x00, 0xfd, 0xea, // as path 65002
	}))
	fmt.Println(m.origin)
	fmt.Println(m.asPath)
	fmt.Println(m.ipv6NextHops)
	fmt.Println(m.ipv6NLRI)

}
Output:

=== ipv4 ===
<nil>
[10.0.0.0/16]
1
[65002]
192.0.2.2
[192.0.2.0/24]
[4260036607]
=== ipv6 ===
<nil>
1
[65002]
[2001:db8::2 fe80::42:c0ff:fe00:202]
[2001:db8::/64]

func NewUpdateDecoder added in v0.7.0

func NewUpdateDecoder[T any](
	wrFn DecodeFn[T],
	paFn PathAttrsDecodeFn[T],
	nlriFn DecodeFn[T],
) *UpdateDecoder[T]

NewUpdateDecoder returns a new instance of an UpdateDecoder where wrFn is used to decode withdrawn routes, paFn is used to decode path attributes, and nlriFn is used to decode network layer reachability info.

func (*UpdateDecoder[T]) Decode added in v0.7.0

func (s *UpdateDecoder[T]) Decode(t T, b []byte) error

Decode decodes the UPDATE message contained in b. Type T is passed to the field-specific decode functions. Decode may return multiple errors, which can be accessed via error unwrapping. See UpdateError for information on returned errors. UpdateNotificationFromErr can be used to extract a *Notification from a non-nil Decode error.

type UpdateError added in v0.7.0

type UpdateError interface {
	error

	// AsSessionReset returns a *Notification that can be used to represent
	// the error as a NOTIFICATION message to be sent to the remote peer. This
	// can be used where usage of UpdateDecoder does not implement the revised
	// error handling described by RFC7606, and instead intends for all errors
	// to result in a session reset.
	AsSessionReset() *Notification
}

UpdateError represents an error handling an UPDATE message. UpdateError is used throughout the decoding logic in this package. It provides the option of following either the UPDATE error handling originally defined in RFC4271 OR the revised handling defined in RFC7606.

type UpdateMessageHandler

type UpdateMessageHandler func(peer PeerConfig, updateMessage []byte) *Notification

UpdateMessageHandler handles Update messages. If a non-nil Notification is returned it will be sent to the peer and the FSM will transition out of the Established state.

type UpdateMessageWriter

type UpdateMessageWriter interface {
	// WriteUpdate sends an update message to the remote peer. An error is
	// returned if the write fails and/or the FSM is no longer in an established
	// state.
	WriteUpdate([]byte) error
}

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL