bgpfix

module
v0.0.0-...-4712b44 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2023 License: MIT

README

BGPFix Golang Library

Go Reference

WORK IN PROGRESS PREVIEW 09/2023

A generic-purpose, high-performance Golang library for bridging the gaps in BGP.

The main idea is it can "fix" or "extend" BGP sessions in-flight, possibly adding new features or protection layers to proprietary BGP speakers (think big router vendors). As an example, the vision is it can be used to implement:

If you're interested in bgpfix, you might also want to see:

Idea

The overall idea is presented below. You don't need to use the whole library, eg. you may stick to the basic BGP message marshal / unmarshal procedures.

bgpfix idea

The above explains the concept of a Pipe: it has two directions used to exchange BGP messages between 2 speakers on the left (L) and right (R) hand side of the picture.

Each Msg sent to the In channel of a particular direction will go through a set of callbacks (think "plugins") configured in the pipe Options. Each callback can read, write, modify, synthesize, or drop messages before they reach the Out channel. In addition to BGP messages, callbacks may emit Events - such as the standard events of the Pipe - which event handlers may subscribe to in the pipe Options.

Example

A basic example on how to establish a BGP session with a router, and print all messages as JSON to stdout:

package main

import (
	"context"
	"fmt"
	"net"
	"net/netip"

	"github.com/bgpfix/bgpfix/msg"
	"github.com/bgpfix/bgpfix/pipe"
	"github.com/bgpfix/bgpfix/speaker"
	"github.com/bgpfix/bgpfix/util"
)

func main() {
	// create a BGP pipe, enable timestamps
	p := pipe.NewPipe(context.Background())
	p.Options.Tstamp = true

	// add our callback and event handlers
	p.Options.OnMsg(print, 0) // call print() on every BGP message in L or R direction
	p.Options.OnEvent(event)  // call event() on any pipe event

	// attach a BGP speaker
	spk := speaker.NewSpeaker(context.Background())
	spk.Options.Passive = false
	spk.Options.LocalASN = 65055
	spk.Options.LocalId = netip.MustParseAddr("1.1.1.1")
	spk.Attach(p)             // attach spk to p using callbacks

	// dial the target
	conn, err := net.Dial("tcp", os.Args[1]) // assumes a ":179" suffix
	if err != nil {
		panic(err)
	}

	// 1. read from conn -> write to p.R.In
	// 2. read from p.L.Out -> write to conn
	util.CopyThrough(p, conn, nil)
}

func print(m *msg.Msg) pipe.Action {
	fmt.Printf("%s\n", m.ToJSON(nil))
	return 0
}

func event(ev *pipe.Event) bool {
	switch ev.Type {
	case pipe.EVENT_OPEN:
		fmt.Printf("OPEN sent and received, caps=%s", p.Caps.ToJSON(nil))
	}
	return true
}

JSON

bgpfix has full, bidirectional BGP to JSON translation support.

For example, below we connect to the Flowspec version of the great BGP Blackholing project by @LukaszBromirski:

pjf@pjf:~/bgp2json$ ./bgp2json -active -asn 65055 85.232.240.180:179 | jq .
[
  "2023-08-18T11:33:41.298",
  1,
  "L",
  "OPEN",
  -1,
  {
	"bgp": 4,
	"asn": 65055,
	"id": "0.0.0.1",
	"hold": 90,
	"caps": {
	  "MP": [
		"IPV4/UNICAST",
		"IPV4/FLOWSPEC",
		"IPV6/UNICAST",
		"IPV6/FLOWSPEC"
	  ],
	  "ROUTE_REFRESH": true,
	  "EXTENDED_MESSAGE": true,
	  "AS4": 65055
	}
  }
]
[
  "2023-08-18T11:33:41.324",
  1,
  "R",
  "OPEN",
  56,
  {
	"bgp": 4,
	"asn": 65055,
	"id": "85.232.240.180",
	"hold": 7200,
	"caps": {
	  "MP": [
		"IPV4/FLOWSPEC"
	  ],
	  "ROUTE_REFRESH": true,
	  "EXTENDED_NEXTHOP": [
		"IPV4/UNICAST/IPV6",
		"IPV4/MULTICAST/IPV6",
		"IPV4/MPLS_VPN/IPV6"
	  ],
	  "AS4": 65055,
	  "PRE_ROUTE_REFRESH": true
	}
  }
]
[
  "2023-08-18T11:33:41.325",
  2,
  "L",
  "KEEPALIVE",
  0,
  null
]
[
  "2023-08-18T11:33:41.348",
  2,
  "R",
  "KEEPALIVE",
  0,
  null
]
[
  "2023-08-18T11:33:46.352",
  3,
  "R",
  "UPDATE",
  316,
  {
	"attrs": {
	  "ORIGIN": {
		"flags": "T",
		"value": "IGP"
	  },
	  "ASPATH": {
		"flags": "T",
		"value": []
	  },
	  "LOCALPREF": {
		"flags": "T",
		"value": 100
	  },
	  "ORIGINATOR": {
		"flags": "O",
		"value": "85.232.240.170"
	  },
	  "CLUSTER_LIST": {
		"flags": "O",
		"value": [
		  "85.232.240.180"
		]
	  },
	  "MP_REACH": {
		"flags": "OX",
		"value": {
		  "af": "IPV4/FLOWSPEC",
		  "nexthop": "192.0.2.1",
		  "rules": [
			{
			  "SRC": "2.59.255.53/32",
			  "PROTO": [
				{
				  "op": "==",
				  "val": 6
				}
			  ],
			  "PORT_DST": [
				{
				  "op": "==",
				  "val": 25
				}
			  ]
			},
			/*** ... cut many lines ... ***/
		  ]
		}
	  },
	  "EXT_COMMUNITY": {
		"flags": "OT",
		"value": [
		  {
			"type": "FLOW_RATE_BYTES",
			"value": 0
		  }
		]
	  }
	}
  }
]
[
  "2023-08-18T11:33:46.455",
  9,
  "R",
  "UPDATE",
  10,
  {
	"attrs": {
	  "MP_UNREACH": {
		"flags": "O",
		"value": {
		  "af": "IPV4/FLOWSPEC",
		  "rules": []
		}
	  }
	}
  }
]

Supported RFCs (incl. partial/wip support)

Author

Pawel Foremski @pforemski 2023

Directories

Path Synopsis
Package af implements AFI, SAFI, and combinations
Package af implements AFI, SAFI, and combinations
Package attrs represents BGP path attributes.
Package attrs represents BGP path attributes.
Package binary provides binary read/write methods.
Package binary provides binary read/write methods.
Package caps implements BGP capabilities.
Package caps implements BGP capabilities.
Package json provides JSON utilities and wrappers around buger/jsonparser
Package json provides JSON utilities and wrappers around buger/jsonparser
Package mrt supports BGP data in MRT format (RFC6396)
Package mrt supports BGP data in MRT format (RFC6396)
Package msg represents BGP messages.
Package msg represents BGP messages.
Package pipe provides BGP message processing with callbacks.
Package pipe provides BGP message processing with callbacks.
Package speaker provides a very basic BGP speaker.
Package speaker provides a very basic BGP speaker.

Jump to

Keyboard shortcuts

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