Skip to content
Snippets Groups Projects
path.go 1.92 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oliver Herms's avatar
    Oliver Herms committed
    import (
    	"fmt"
    )
    
    Oliver Herms's avatar
    Oliver Herms committed
    
    
    type Path struct {
    	Type       uint8
    	StaticPath *StaticPath
    	BGPPath    *BGPPath
    }
    
    
    // Select returns negative if p < q, 0 if paths are equal, positive if p > q
    func (p *Path) Select(q *Path) int8 {
    
    	switch {
    	case p == nil && q == nil:
    		return 0
    	case p == nil:
    		return -1
    	case q == nil:
    		return 1
    	default:
    	}
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    	if p.Type > q.Type {
    		return 1
    	}
    
    	if p.Type < q.Type {
    		return -1
    	}
    
    	switch p.Type {
    	case BGPPathType:
    
    		return p.BGPPath.Select(q.BGPPath)
    
    Oliver Herms's avatar
    Oliver Herms committed
    	case StaticPathType:
    
    		return p.StaticPath.Select(q.StaticPath)
    
    Oliver Herms's avatar
    Oliver Herms committed
    	}
    
    	panic("Unknown path type")
    }
    
    func (p *Path) ECMP(q *Path) bool {
    	switch p.Type {
    	case BGPPathType:
    		return p.BGPPath.ECMP(q.BGPPath)
    	case StaticPathType:
    		return p.StaticPath.ECMP(q.StaticPath)
    	}
    
    	panic("Unknown path type")
    }
    
    
    func (p *Path) Equal(q *Path) bool {
    	if p == nil || q == nil {
    		return false
    	}
    
    
    	if p.Type != q.Type {
    		return false
    	}
    
    	switch p.Type {
    	case BGPPathType:
    		return p.BGPPath.Equal(q.BGPPath)
    	case StaticPathType:
    		return p.StaticPath.Equal(q.StaticPath)
    	}
    
    	return p.Select(q) == 0
    
    Oliver Herms's avatar
    Oliver Herms committed
    
    // PathsDiff gets the list of elements contained by a but not b
    func PathsDiff(a, b []*Path) []*Path {
    	ret := make([]*Path, 0)
    
    	for _, pa := range a {
    		if !pathsContains(pa, b) {
    			ret = append(ret, pa)
    		}
    	}
    
    	return ret
    }
    
    func pathsContains(needle *Path, haystack []*Path) bool {
    	for _, p := range haystack {
    		if p == needle {
    			return true
    		}
    	}
    
    	return false
    }
    
    func (p *Path) Print() string {
    	protocol := ""
    	switch p.Type {
    	case StaticPathType:
    		protocol = "static"
    	case BGPPathType:
    		protocol = "BGP"
    	}
    
    	ret := fmt.Sprintf("\tProtocol: %s\n", protocol)
    	switch p.Type {
    	case StaticPathType:
    		ret += "Not implemented yet"
    	case BGPPathType:
    		ret += p.BGPPath.Print()
    	}
    
    	return ret
    }
    
    
    func (p *Path) Copy() *Path {
    	if p == nil {
    		return nil
    	}
    
    	cp := *p
    	cp.BGPPath = cp.BGPPath.Copy()
    	cp.StaticPath = cp.StaticPath.Copy()
    
    	return &cp
    }