Skip to content
Snippets Groups Projects
Commit ef9400a0 authored by Daniel Czerwonk's avatar Daniel Czerwonk
Browse files

as path refactoring

parent 27c11bad
No related branches found
No related tags found
No related merge requests found
package packet
import "fmt"
type ASPath []ASPathSegment
type ASPathSegment struct {
Type uint8
Count uint8
ASNs []uint32
}
func (pa ASPath) String() (ret string) {
for _, p := range pa {
if p.Type == ASSet {
ret += " ("
}
n := len(p.ASNs)
for i, asn := range p.ASNs {
if i < n-1 {
ret += fmt.Sprintf("%d ", asn)
continue
}
ret += fmt.Sprintf("%d", asn)
}
if p.Type == ASSet {
ret += ")"
}
}
return
}
func (pa ASPath) Length() (ret uint16) {
for _, p := range pa {
if p.Type == ASSet {
ret++
continue
}
ret += uint16(len(p.ASNs))
}
return
}
......@@ -173,13 +173,6 @@ type NLRIAddPath struct {
Next *NLRIAddPath
}
type ASPath []ASPathSegment
type ASPathSegment struct {
Type uint8
Count uint8
ASNs []uint32
}
type Aggretator struct {
Addr uint32
ASN uint16
......
......@@ -3,7 +3,6 @@ package packet
import (
"bytes"
"fmt"
"strconv"
"strings"
"github.com/taktv6/tflow2/convert"
......@@ -344,39 +343,6 @@ func (pa *PathAttribute) setLength(buf *bytes.Buffer) (int, error) {
return bytesRead, nil
}
func (pa *PathAttribute) ASPathString() (ret string) {
for _, p := range pa.Value.(ASPath) {
if p.Type == ASSet {
ret += " ("
}
n := len(p.ASNs)
for i, asn := range p.ASNs {
if i < n-1 {
ret += fmt.Sprintf("%d ", asn)
continue
}
ret += fmt.Sprintf("%d", asn)
}
if p.Type == ASSet {
ret += ")"
}
}
return
}
func (pa *PathAttribute) ASPathLen() (ret uint16) {
for _, p := range pa.Value.(ASPath) {
if p.Type == ASSet {
ret++
continue
}
ret += uint16(len(p.ASNs))
}
return
}
func (a *PathAttribute) CommunityString() string {
s := ""
for _, com := range a.Value.([]uint32) {
......@@ -587,57 +553,6 @@ func (pa *PathAttribute) serializeLargeCommunities(buf *bytes.Buffer) uint8 {
return length
}
// ParseASPathStr converts an AS path from string representation info an PathAttribute object
func ParseASPathStr(asPathString string) (*PathAttribute, error) {
asPath := ASPath{}
currentType := ASSequence
newSegmentNeeded := true
currentSegment := -1
for _, asn := range strings.Split(asPathString, " ") {
if asn == "" {
continue
}
if isBeginOfASSet(asn) {
currentType = ASSet
newSegmentNeeded = true
asn = strings.Replace(asn, "(", "", 1)
}
if newSegmentNeeded {
seg := ASPathSegment{
Type: uint8(currentType),
ASNs: make([]uint32, 0),
}
asPath = append(asPath, seg)
currentSegment++
newSegmentNeeded = false
}
if isEndOfASSset(asn) {
currentType = ASSequence
newSegmentNeeded = true
asn = strings.Replace(asn, ")", "", 1)
}
numericASN, err := strconv.Atoi(asn)
if err != nil {
return nil, fmt.Errorf("Unable to convert ASN: %v", err)
}
asPath[currentSegment].ASNs = append(asPath[currentSegment].ASNs, uint32(numericASN))
if len(asPath[currentSegment].ASNs) == MaxASNsSegment {
newSegmentNeeded = true
}
}
return &PathAttribute{
TypeCode: ASPathAttr,
Value: asPath,
}, nil
}
func LargeCommunityAttributeForString(s string) (*PathAttribute, error) {
strs := strings.Split(s, " ")
coms := make([]LargeCommunity, len(strs))
......@@ -656,14 +571,6 @@ func LargeCommunityAttributeForString(s string) (*PathAttribute, error) {
}, nil
}
func isBeginOfASSet(asPathPart string) bool {
return strings.Contains(asPathPart, "(")
}
func isEndOfASSset(asPathPart string) bool {
return strings.Contains(asPathPart, ")")
}
func fourBytesToUint32(address [4]byte) uint32 {
return uint32(address[0])<<24 + uint32(address[1])<<16 + uint32(address[2])<<8 + uint32(address[3])
}
......
......@@ -230,8 +230,8 @@ func (s *establishedState) updates(u *packet.BGPUpdate) {
case packet.NextHopAttr:
path.BGPPath.NextHop = pa.Value.(uint32)
case packet.ASPathAttr:
path.BGPPath.ASPath = pa.ASPathString()
path.BGPPath.ASPathLen = pa.ASPathLen()
path.BGPPath.ASPath = pa.Value.(packet.ASPath)
path.BGPPath.ASPathLen = path.BGPPath.ASPath.Length()
case packet.CommunitiesAttr:
path.BGPPath.Communities = pa.Value.([]uint32)
case packet.LargeCommunitiesAttr:
......
......@@ -3,7 +3,6 @@ package server
import (
"fmt"
"io"
"strings"
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
"github.com/bio-routing/bio-rd/route"
......@@ -11,22 +10,22 @@ import (
)
func pathAttribues(p *route.Path) (*packet.PathAttribute, error) {
asPathPA, err := packet.ParseASPathStr(strings.TrimRight(p.BGPPath.ASPath, " "))
if err != nil {
return nil, fmt.Errorf("Unable to parse AS path: %v", err)
asPath := &packet.PathAttribute{
TypeCode: packet.ASPathAttr,
Value: p.BGPPath.ASPath,
}
origin := &packet.PathAttribute{
TypeCode: packet.OriginAttr,
Value: p.BGPPath.Origin,
Next: asPathPA,
}
asPath.Next = origin
nextHop := &packet.PathAttribute{
TypeCode: packet.NextHopAttr,
Value: p.BGPPath.NextHop,
}
asPathPA.Next = nextHop
origin.Next = nextHop
localPref := &packet.PathAttribute{
TypeCode: packet.LocalPrefAttr,
......
......@@ -3,9 +3,9 @@ package route
import (
"crypto/sha256"
"fmt"
"strconv"
"strings"
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
"github.com/taktv6/tflow2/convert"
)
......@@ -14,7 +14,7 @@ type BGPPath struct {
PathIdentifier uint32
NextHop uint32
LocalPref uint32
ASPath string
ASPath packet.ASPath
ASPathLen uint16
Origin uint8
MED uint32
......@@ -155,7 +155,7 @@ func (b *BGPPath) Print() string {
}
ret := fmt.Sprintf("\t\tLocal Pref: %d\n", b.LocalPref)
ret += fmt.Sprintf("\t\tOrigin: %s\n", origin)
ret += fmt.Sprintf("\t\tAS Path: %s\n", b.ASPath)
ret += fmt.Sprintf("\t\tAS Path: %s\n")
nh := uint32To4Byte(b.NextHop)
ret += fmt.Sprintf("\t\tNEXT HOP: %d.%d.%d.%d\n", nh[0], nh[1], nh[2], nh[3])
ret += fmt.Sprintf("\t\tMED: %d\n", b.MED)
......@@ -172,16 +172,31 @@ func (b *BGPPath) Prepend(asn uint32, times uint16) {
return
}
asnStr := strconv.FormatUint(uint64(asn), 10)
first := b.ASPath[0]
if len(b.ASPath) == 0 || first.Type == packet.ASSet {
b.insertNewASSequence()
}
for i := 0; i < int(times); i++ {
if len(b.ASPath) == packet.MaxASNsSegment {
b.insertNewASSequence()
}
}
b.ASPathLen = b.ASPath.Length()
}
path := make([]string, times+1)
for i := 0; uint16(i) < times; i++ {
path[i] = asnStr
func (b *BGPPath) insertNewASSequence() packet.ASPath {
pa := make(packet.ASPath, len(b.ASPath)+1)
copy(pa[1:], b.ASPath)
pa[0] = packet.ASPathSegment{
ASNs: make([]uint32, 0),
Count: 0,
Type: packet.ASSequence,
}
path[times] = b.ASPath
b.ASPath = strings.TrimSuffix(strings.Join(path, " "), " ")
b.ASPathLen = b.ASPathLen + times
return pa
}
func (p *BGPPath) Copy() *BGPPath {
......
......@@ -3,7 +3,6 @@ package adjRIBIn
import (
"sync"
"github.com/bio-routing/bio-rd/protocols/bgp/packet"
"github.com/bio-routing/bio-rd/routingtable/filter"
"github.com/bio-routing/bio-rd/net"
......@@ -80,10 +79,7 @@ func (a *AdjRIBIn) AddPath(pfx net.Prefix, p *route.Path) error {
}
func (a *AdjRIBIn) ourASNsInPath(p *route.Path) bool {
// Don't accept path via iBGP which contain our ASN
ASPathAttr, _ := packet.ParseASPathStr(p.BGPPath.ASPath)
for _, pathSegment := range ASPathAttr.Value.(packet.ASPath) {
for _, pathSegment := range p.BGPPath.ASPath {
for _, asn := range pathSegment.ASNs {
if a.contributingASNs.IsContributingASN(asn) {
return true
......
......@@ -52,7 +52,7 @@ func (a *AdjRIBOut) AddPath(pfx bnet.Prefix, p *route.Path) error {
p = p.Copy()
if !a.neighbor.IBGP && !a.neighbor.RouteServerClient {
p.BGPPath.ASPath = fmt.Sprintf("%d %s", a.neighbor.LocalASN, p.BGPPath.ASPath)
p.BGPPath.Prepend(a.neighbor.LocalASN, 1)
}
if !a.neighbor.IBGP && !a.neighbor.RouteServerClient {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment