Skip to content
Snippets Groups Projects
bgp.go 3.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oliver Herms's avatar
    Oliver Herms committed
    import (
    	"fmt"
    
    	"strconv"
    	"strings"
    
    Oliver Herms's avatar
    Oliver Herms committed
    
    	"github.com/taktv6/tflow2/convert"
    )
    
    
    // BGPPath represents a set of BGP path attributes
    type BGPPath struct {
    	PathIdentifier uint32
    	NextHop        uint32
    	LocalPref      uint32
    	ASPath         string
    	ASPathLen      uint16
    	Origin         uint8
    	MED            uint32
    	EBGP           bool
    	BGPIdentifier  uint32
    	Source         uint32
    }
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    // ECMP determines if routes b and c are euqal in terms of ECMP
    func (b *BGPPath) ECMP(c *BGPPath) bool {
    	return b.LocalPref == c.LocalPref && b.ASPathLen == c.ASPathLen && b.MED == c.MED && b.Origin == c.Origin
    }
    
    Oliver Herms's avatar
    Oliver Herms committed
    // Compare returns negative if b < c, 0 if paths are equal, positive if b > c
    func (b *BGPPath) Compare(c *BGPPath) int8 {
    	if c.LocalPref < b.LocalPref {
    		return 1
    	}
    
    Oliver Herms's avatar
    Oliver Herms committed
    	if c.LocalPref > b.LocalPref {
    		return -1
    	}
    
    Oliver Herms's avatar
    Oliver Herms committed
    	if c.ASPathLen > b.ASPathLen {
    		return 1
    	}
    
    Oliver Herms's avatar
    Oliver Herms committed
    	if c.ASPathLen < b.ASPathLen {
    		return -1
    	}
    
    Oliver Herms's avatar
    Oliver Herms committed
    	if c.Origin > b.Origin {
    		return 1
    	}
    
    	if c.Origin < b.Origin {
    		return -1
    
    Oliver Herms's avatar
    Oliver Herms committed
    	if c.MED > b.MED {
    		return 1
    	}
    
    	if c.MED < b.MED {
    		return -1
    	}
    
    	if c.BGPIdentifier < b.BGPIdentifier {
    		return 1
    	}
    
    	if c.BGPIdentifier > b.BGPIdentifier {
    		return -1
    	}
    
    	if c.Source < b.Source {
    		return 1
    	}
    
    	if c.Source > b.Source {
    		return -1
    	}
    
    
    	if c.NextHop < b.NextHop {
    		return 1
    	}
    
    	if c.NextHop > b.NextHop {
    		return -1
    	}
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    	return 0
    
    }
    
    func (b *BGPPath) betterECMP(c *BGPPath) bool {
    	if c.LocalPref < b.LocalPref {
    		return false
    	}
    
    	if c.LocalPref > b.LocalPref {
    		return true
    	}
    
    	if c.ASPathLen > b.ASPathLen {
    		return false
    	}
    
    	if c.ASPathLen < b.ASPathLen {
    		return true
    	}
    
    	if c.Origin > b.Origin {
    		return false
    	}
    
    	if c.Origin < b.Origin {
    		return true
    	}
    
    	if c.MED > b.MED {
    		return false
    	}
    
    	if c.MED < b.MED {
    		return true
    	}
    
    	return false
    }
    
    func (b *BGPPath) better(c *BGPPath) bool {
    	if b.betterECMP(c) {
    		return true
    	}
    
    	if c.BGPIdentifier < b.BGPIdentifier {
    		return true
    	}
    
    	if c.Source < b.Source {
    		return true
    	}
    
    	return false
    }
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    func (b *BGPPath) Print() string {
    	origin := ""
    	switch b.Origin {
    	case 0:
    		origin = "Incomplete"
    	case 1:
    		origin = "EGP"
    	case 2:
    		origin = "IGP"
    	}
    	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)
    	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)
    
    	return ret
    }
    
    
    func (b *BGPPath) Prepend(asn uint32, times uint16) {
    
    	if times == 0 {
    		return
    	}
    
    	asnStr := strconv.FormatUint(uint64(asn), 10)
    
    	path := make([]string, times+1)
    
    	for i := 0; uint16(i) < times; i++ {
    
    		path[i] = asnStr
    
    	path[times] = b.ASPath
    
    	b.ASPath = strings.TrimSuffix(strings.Join(path, " "), " ")
    	b.ASPathLen = b.ASPathLen + times
    
    Daniel Czerwonk's avatar
    Daniel Czerwonk committed
    func (p *BGPPath) Copy() *BGPPath {
    	if p == nil {
    		return nil
    	}
    
    	cp := *p
    	return &cp
    }
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    func uint32To4Byte(addr uint32) [4]byte {
    	slice := convert.Uint32Byte(addr)
    	ret := [4]byte{
    		slice[0],
    		slice[1],
    		slice[2],
    		slice[3],
    	}
    	return ret
    }