Skip to content
Snippets Groups Projects
update_helper.go 1.99 KiB
Newer Older
  • Learn to ignore specific revisions
  • package server
    
    import (
    	"fmt"
    
    	"strings"
    
    	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
    	"github.com/bio-routing/bio-rd/route"
    
    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)
    	}
    
    	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
    
    
    Daniel Czerwonk's avatar
    Daniel Czerwonk committed
    	localPref := &packet.PathAttribute{
    		TypeCode: packet.LocalPrefAttr,
    		Value:    p.BGPPath.LocalPref,
    	}
    	nextHop.Next = localPref
    
    
    	if p.BGPPath != nil {
    
    Daniel Czerwonk's avatar
    Daniel Czerwonk committed
    		err := addOptionalPathAttribues(p, localPref)
    
    
    		if err != nil {
    			return nil, err
    		}
    	}
    
    	return origin, nil
    }
    
    func addOptionalPathAttribues(p *route.Path, parent *packet.PathAttribute) error {
    	current := parent
    
    
    Daniel Czerwonk's avatar
    Daniel Czerwonk committed
    	if len(p.BGPPath.Communities) > 0 {
    		communities, err := packet.CommunityAttributeForString(p.BGPPath.Communities)
    		if err != nil {
    			return fmt.Errorf("Could not create communities attribute: %v", err)
    		}
    
    		current.Next = communities
    		current = communities
    	}
    
    
    	if len(p.BGPPath.LargeCommunities) > 0 {
    		largeCommunities, err := packet.LargeCommunityAttributeForString(p.BGPPath.LargeCommunities)
    		if err != nil {
    
    Daniel Czerwonk's avatar
    Daniel Czerwonk committed
    			return fmt.Errorf("Could not create large communities attribute: %v", err)
    
    		}
    
    		current.Next = largeCommunities
    		current = largeCommunities
    	}
    
    	return nil
    }
    
    
    type serializeAbleUpdate interface {
    	SerializeUpdate() ([]byte, error)
    }
    
    func serializeAndSendUpdate(out io.Writer, update serializeAbleUpdate) error {
    	updateBytes, err := update.SerializeUpdate()
    	if err != nil {
    		log.Errorf("Unable to serialize BGP Update: %v", err)
    		return nil
    	}
    
    	_, err = out.Write(updateBytes)
    	if err != nil {
    		return fmt.Errorf("Failed sending Update: %v", err)
    	}
    	return nil
    }