diff --git a/main.go b/main.go index 7e19a5aa8d1e0d982435fe12dd8229eecfbb1a35..29c4b0d418f890d0778b3b9001bcfea95a690cfe 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 3d9e2a080f543667f8d95a170da318f1c2314a04..2e988bfe973002dd890cea3ed30fc88f6e10ebad 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 0000000000000000000000000000000000000000..28018bf102a420b49b513f057765a50ad7890e52 --- /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 a5d05887f026cf336e3792e405fa7c456eae6e74..4a514ec4c5529c10846124ca2c4371a1022e40e6 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 e7b46577c594c5b5f84e115981ac560777899d11..f7c51c569953946b7a290ce1c5facc7c2c2b48ae 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()