From 4a8fd3efa90682d0d072d3fcc5c0df837552a6a8 Mon Sep 17 00:00:00 2001 From: Daniel Czerwonk <daniel@dan-nrw.de> Date: Sun, 27 May 2018 15:31:22 +0200 Subject: [PATCH] sending large communities --- main.go | 4 ++ protocols/bgp/packet/path_attributes.go | 2 +- protocols/bgp/server/bgp_update.go | 70 +++++++++++++++++++ protocols/bgp/server/update_sender.go | 26 +------ .../bgp/server/update_sender_add_path.go | 27 +------ 5 files changed, 81 insertions(+), 48 deletions(-) create mode 100644 protocols/bgp/server/bgp_update.go diff --git a/main.go b/main.go index 7e19a5aa..29c4b0d4 100644 --- a/main.go +++ b/main.go @@ -22,6 +22,10 @@ func main() { err := b.Start(&config.Global{ Listen: true, + LocalAddressList: []net.IP{ + net.IPv4(169, 254, 100, 1), + net.IPv4(169, 254, 200, 0), + }, }) if err != nil { logrus.Fatalf("Unable to start BGP server: %v", err) diff --git a/protocols/bgp/packet/path_attributes.go b/protocols/bgp/packet/path_attributes.go index 3d9e2a08..2e988bfe 100644 --- a/protocols/bgp/packet/path_attributes.go +++ b/protocols/bgp/packet/path_attributes.go @@ -566,7 +566,7 @@ func ParseASPathStr(asPathString string) (*PathAttribute, error) { }, nil } -func largeCommunityAttributeForString(s string) (*PathAttribute, error) { +func LargeCommunityAttributeForString(s string) (*PathAttribute, error) { strs := strings.Split(s, " ") coms := make([]LargeCommunity, len(strs)) diff --git a/protocols/bgp/server/bgp_update.go b/protocols/bgp/server/bgp_update.go new file mode 100644 index 00000000..28018bf1 --- /dev/null +++ b/protocols/bgp/server/bgp_update.go @@ -0,0 +1,70 @@ +package server + +import ( + "fmt" + "strings" + + "github.com/bio-routing/bio-rd/net" + "github.com/bio-routing/bio-rd/protocols/bgp/packet" + "github.com/bio-routing/bio-rd/route" +) + +func updateMessageForPath(pfx net.Prefix, p *route.Path, fsm *FSM) (*packet.BGPUpdate, error) { + pathAttrs, err := pathAttribues(p, fsm) + if err != nil { + return nil, err + } + + return &packet.BGPUpdate{ + PathAttributes: pathAttrs, + NLRI: &packet.NLRI{ + IP: pfx.Addr(), + Pfxlen: pfx.Pfxlen(), + }, + }, nil +} + +func pathAttribues(p *route.Path, fsm *FSM) (*packet.PathAttribute, error) { + asPathPA, err := packet.ParseASPathStr(strings.TrimRight(fmt.Sprintf("%d %s", fsm.localASN, p.BGPPath.ASPath), " ")) + if err != nil { + return nil, fmt.Errorf("Unable to parse AS path: %v", err) + } + + origin := &packet.PathAttribute{ + TypeCode: packet.OriginAttr, + Value: p.BGPPath.Origin, + Next: asPathPA, + } + + nextHop := &packet.PathAttribute{ + TypeCode: packet.NextHopAttr, + Value: p.BGPPath.NextHop, + } + asPathPA.Next = nextHop + + if p.BGPPath != nil { + err := addOptionalPathAttribues(p, nextHop) + + if err != nil { + return nil, err + } + } + + return origin, nil +} + +func addOptionalPathAttribues(p *route.Path, parent *packet.PathAttribute) error { + current := parent + + if len(p.BGPPath.LargeCommunities) > 0 { + largeCommunities, err := packet.LargeCommunityAttributeForString(p.BGPPath.LargeCommunities) + if err != nil { + return fmt.Errorf("Could not create large community attribute: %v", err) + } + + current.Next = largeCommunities + current = largeCommunities + } + + return nil +} diff --git a/protocols/bgp/server/update_sender.go b/protocols/bgp/server/update_sender.go index a5d05887..4a514ec4 100644 --- a/protocols/bgp/server/update_sender.go +++ b/protocols/bgp/server/update_sender.go @@ -2,12 +2,10 @@ package server import ( "fmt" - "strings" log "github.com/sirupsen/logrus" "github.com/bio-routing/bio-rd/net" - "github.com/bio-routing/bio-rd/protocols/bgp/packet" "github.com/bio-routing/bio-rd/route" "github.com/bio-routing/bio-rd/routingtable" ) @@ -26,28 +24,10 @@ func newUpdateSender(fsm *FSM) *UpdateSender { // AddPath serializes a new path and sends out a BGP update message func (u *UpdateSender) AddPath(pfx net.Prefix, p *route.Path) error { - asPathPA, err := packet.ParseASPathStr(strings.TrimRight(fmt.Sprintf("%d %s", u.fsm.localASN, p.BGPPath.ASPath), " ")) + update, err := updateMessageForPath(pfx, p, u.fsm) if err != nil { - return fmt.Errorf("Unable to parse AS path: %v", err) - } - - update := &packet.BGPUpdate{ - PathAttributes: &packet.PathAttribute{ - TypeCode: packet.OriginAttr, - Value: p.BGPPath.Origin, - Next: &packet.PathAttribute{ - TypeCode: packet.ASPathAttr, - Value: asPathPA.Value, - Next: &packet.PathAttribute{ - TypeCode: packet.NextHopAttr, - Value: p.BGPPath.NextHop, - }, - }, - }, - NLRI: &packet.NLRI{ - IP: pfx.Addr(), - Pfxlen: pfx.Pfxlen(), - }, + log.Errorf("Unable to create BGP Update: %v", err) + return nil } updateBytes, err := update.SerializeUpdate() diff --git a/protocols/bgp/server/update_sender_add_path.go b/protocols/bgp/server/update_sender_add_path.go index e7b46577..f7c51c56 100644 --- a/protocols/bgp/server/update_sender_add_path.go +++ b/protocols/bgp/server/update_sender_add_path.go @@ -2,12 +2,10 @@ package server import ( "fmt" - "strings" log "github.com/sirupsen/logrus" "github.com/bio-routing/bio-rd/net" - "github.com/bio-routing/bio-rd/protocols/bgp/packet" "github.com/bio-routing/bio-rd/route" "github.com/bio-routing/bio-rd/routingtable" ) @@ -26,29 +24,10 @@ func newUpdateSenderAddPath(fsm *FSM) *UpdateSenderAddPath { // AddPath serializes a new path and sends out a BGP update message func (u *UpdateSenderAddPath) AddPath(pfx net.Prefix, p *route.Path) error { - asPathPA, err := packet.ParseASPathStr(strings.TrimRight(fmt.Sprintf("%d %s", u.fsm.localASN, p.BGPPath.ASPath), " ")) + update, err := updateMessageForPath(pfx, p, u.fsm) if err != nil { - return fmt.Errorf("Unable to parse AS path: %v", err) - } - - update := &packet.BGPUpdateAddPath{ - PathAttributes: &packet.PathAttribute{ - TypeCode: packet.OriginAttr, - Value: p.BGPPath.Origin, - Next: &packet.PathAttribute{ - TypeCode: packet.ASPathAttr, - Value: asPathPA.Value, - Next: &packet.PathAttribute{ - TypeCode: packet.NextHopAttr, - Value: p.BGPPath.NextHop, - }, - }, - }, - NLRI: &packet.NLRIAddPath{ - PathIdentifier: p.BGPPath.PathIdentifier, - IP: pfx.Addr(), - Pfxlen: pfx.Pfxlen(), - }, + log.Errorf("Unable to create BGP Update: %v", err) + return nil } updateBytes, err := update.SerializeUpdate() -- GitLab