diff options
Diffstat (limited to 'table')
-rw-r--r-- | table/destination.go | 365 | ||||
-rw-r--r-- | table/destination_test.go | 28 | ||||
-rw-r--r-- | table/message.go | 14 | ||||
-rw-r--r-- | table/path.go | 470 | ||||
-rw-r--r-- | table/path_test.go | 78 | ||||
-rw-r--r-- | table/table.go | 304 | ||||
-rw-r--r-- | table/table_manager.go | 109 | ||||
-rw-r--r-- | table/table_manager_test.go | 245 | ||||
-rw-r--r-- | table/table_test.go | 48 |
9 files changed, 432 insertions, 1229 deletions
diff --git a/table/destination.go b/table/destination.go index a520c192..dc6e073f 100644 --- a/table/destination.go +++ b/table/destination.go @@ -23,7 +23,6 @@ import ( "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/packet" "net" - "reflect" ) const ( @@ -63,56 +62,32 @@ func (lhs *PeerInfo) Equal(rhs *PeerInfo) bool { return false } -type Destination interface { - Calculate(localAsn uint32) (Path, string, error) - getRouteFamily() bgp.RouteFamily - setRouteFamily(ROUTE_FAMILY bgp.RouteFamily) - getNlri() bgp.AddrPrefixInterface - setNlri(nlri bgp.AddrPrefixInterface) - getBestPathReason() string - setBestPathReason(string) - GetBestPath() Path - setBestPath(path Path) - getKnownPathList() []Path - setKnownPathList([]Path) - String() string - addWithdraw(withdraw Path) - addNewPath(newPath Path) - constructWithdrawPath() Path - removeOldPathsFromSource(source *PeerInfo) []Path - ToApiStruct() *api.Destination - MarshalJSON() ([]byte, error) -} - -type DestinationDefault struct { - ROUTE_FAMILY bgp.RouteFamily +type Destination struct { + routeFamily bgp.RouteFamily nlri bgp.AddrPrefixInterface - knownPathList []Path - withdrawList []Path - newPathList []Path - bestPath Path + knownPathList []*Path + withdrawList []*Path + newPathList []*Path + bestPath *Path bestPathReason string - oldBestPath Path + oldBestPath *Path } -func NewDestinationDefault(nlri bgp.AddrPrefixInterface) *DestinationDefault { - destination := &DestinationDefault{} - destination.ROUTE_FAMILY = bgp.RF_IPv4_UC - destination.nlri = nlri - destination.knownPathList = make([]Path, 0) - destination.withdrawList = make([]Path, 0) - destination.newPathList = make([]Path, 0) - destination.bestPath = nil - destination.bestPathReason = "" - destination.oldBestPath = nil - return destination +func NewDestination(nlri bgp.AddrPrefixInterface) *Destination { + return &Destination{ + routeFamily: bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI()), + nlri: nlri, + knownPathList: make([]*Path, 0), + withdrawList: make([]*Path, 0), + newPathList: make([]*Path, 0), + } } -func (dd *DestinationDefault) MarshalJSON() ([]byte, error) { +func (dd *Destination) MarshalJSON() ([]byte, error) { return json.Marshal(dd.ToApiStruct()) } -func (dd *DestinationDefault) ToApiStruct() *api.Destination { +func (dd *Destination) ToApiStruct() *api.Destination { prefix := dd.getNlri().String() idx := func() int { @@ -128,7 +103,7 @@ func (dd *DestinationDefault) ToApiStruct() *api.Destination { return 0 }() - paths := func(arg []Path) []*api.Path { + paths := func(arg []*Path) []*api.Path { ret := make([]*api.Path, 0, len(arg)) for _, p := range arg { ret = append(ret, p.ToApiStruct()) @@ -143,59 +118,59 @@ func (dd *DestinationDefault) ToApiStruct() *api.Destination { } } -func (dd *DestinationDefault) getRouteFamily() bgp.RouteFamily { - return dd.ROUTE_FAMILY +func (dd *Destination) getRouteFamily() bgp.RouteFamily { + return dd.routeFamily } -func (dd *DestinationDefault) setRouteFamily(ROUTE_FAMILY bgp.RouteFamily) { - dd.ROUTE_FAMILY = ROUTE_FAMILY +func (dd *Destination) setRouteFamily(routeFamily bgp.RouteFamily) { + dd.routeFamily = routeFamily } -func (dd *DestinationDefault) getNlri() bgp.AddrPrefixInterface { +func (dd *Destination) getNlri() bgp.AddrPrefixInterface { return dd.nlri } -func (dd *DestinationDefault) setNlri(nlri bgp.AddrPrefixInterface) { +func (dd *Destination) setNlri(nlri bgp.AddrPrefixInterface) { dd.nlri = nlri } -func (dd *DestinationDefault) getBestPathReason() string { +func (dd *Destination) getBestPathReason() string { return dd.bestPathReason } -func (dd *DestinationDefault) setBestPathReason(reason string) { +func (dd *Destination) setBestPathReason(reason string) { dd.bestPathReason = reason } -func (dd *DestinationDefault) GetBestPath() Path { +func (dd *Destination) GetBestPath() *Path { return dd.bestPath } -func (dd *DestinationDefault) setBestPath(path Path) { +func (dd *Destination) setBestPath(path *Path) { dd.bestPath = path } -func (dd *DestinationDefault) getKnownPathList() []Path { +func (dd *Destination) getKnownPathList() []*Path { return dd.knownPathList } -func (dd *DestinationDefault) setKnownPathList(List []Path) { +func (dd *Destination) setKnownPathList(List []*Path) { dd.knownPathList = List } -func (dd *DestinationDefault) addWithdraw(withdraw Path) { +func (dd *Destination) addWithdraw(withdraw *Path) { dd.validatePath(withdraw) dd.withdrawList = append(dd.withdrawList, withdraw) } -func (dd *DestinationDefault) addNewPath(newPath Path) { +func (dd *Destination) addNewPath(newPath *Path) { dd.validatePath(newPath) dd.newPathList = append(dd.newPathList, newPath) } -func (dd *DestinationDefault) removeOldPathsFromSource(source *PeerInfo) []Path { - removePaths := make([]Path, 0) - tempKnownPathList := make([]Path, 0) +func (dd *Destination) removeOldPathsFromSource(source *PeerInfo) []*Path { + removePaths := make([]*Path, 0) + tempKnownPathList := make([]*Path, 0) for _, path := range dd.knownPathList { if path.GetSource().Equal(source) { @@ -208,14 +183,14 @@ func (dd *DestinationDefault) removeOldPathsFromSource(source *PeerInfo) []Path return removePaths } -func (dd *DestinationDefault) validatePath(path Path) { - if path == nil || path.GetRouteFamily() != dd.ROUTE_FAMILY { +func (dd *Destination) validatePath(path *Path) { + if path == nil || path.GetRouteFamily() != dd.routeFamily { log.WithFields(log.Fields{ "Topic": "Table", "Key": dd.getNlri().String(), "Path": path, - "ExpectedRF": dd.ROUTE_FAMILY, + "ExpectedRF": dd.routeFamily, }).Error("path is nil or invalid route family") } } @@ -226,7 +201,7 @@ func (dd *DestinationDefault) validatePath(path Path) { // // Modifies destination's state related to stored paths. Removes withdrawn // paths from known paths. Also, adds new paths to known paths. -func (dest *DestinationDefault) Calculate(localAsn uint32) (Path, string, error) { +func (dest *Destination) Calculate(localAsn uint32) (*Path, string, error) { // First remove the withdrawn paths. // Note: If we want to support multiple paths per destination we may @@ -258,7 +233,7 @@ func (dest *DestinationDefault) Calculate(localAsn uint32) (Path, string, error) dest.knownPathList = append(dest.knownPathList, dest.newPathList...) // Clear new paths as we copied them. - dest.newPathList = make([]Path, 0) + dest.newPathList = make([]*Path, 0) // If we do not have any paths to this destination, then we do not have // new best path. @@ -283,7 +258,7 @@ func (dest *DestinationDefault) Calculate(localAsn uint32) (Path, string, error) //we can receive withdraws for such paths and withdrawals may not be //stopped by the same policies. //""" -func (dest *DestinationDefault) removeWithdrawals() { +func (dest *Destination) removeWithdrawals() { log.WithFields(log.Fields{ "Topic": "Table", @@ -309,8 +284,8 @@ func (dest *DestinationDefault) removeWithdrawals() { // If we have some known paths and some withdrawals, we find matches and // delete them first. - matches := make(map[string]Path) - wMatches := make(map[string]Path) + matches := make(map[string]*Path) + wMatches := make(map[string]*Path) // Match all withdrawals from destination paths. for _, withdraw := range dest.withdrawList { var isFound bool = false @@ -371,7 +346,7 @@ func (dest *DestinationDefault) removeWithdrawals() { } } -func (dest *DestinationDefault) computeKnownBestPath(localAsn uint32) (Path, string, error) { +func (dest *Destination) computeKnownBestPath(localAsn uint32) (*Path, string, error) { // """Computes the best path among known paths. // @@ -399,7 +374,7 @@ func (dest *DestinationDefault) computeKnownBestPath(localAsn uint32) (Path, str return currentBestPath, bestPathReason, nil } -func (dest *DestinationDefault) removeOldPaths() { +func (dest *Destination) removeOldPaths() { // """Identifies which of known paths are old and removes them. // // Known paths will no longer have paths whose new version is present in @@ -410,7 +385,7 @@ func (dest *DestinationDefault) removeOldPaths() { knownPaths := dest.knownPathList for _, newPath := range newPaths { - oldPaths := make([]Path, 0) + oldPaths := make([]*Path, 0) for _, path := range knownPaths { // Here we just check if source is same and not check if path // version num. as newPaths are implicit withdrawal of old @@ -442,7 +417,7 @@ func (dest *DestinationDefault) removeOldPaths() { dest.knownPathList = knownPaths } -func deleteAt(list []Path, pos int) ([]Path, bool) { +func deleteAt(list []*Path, pos int) ([]*Path, bool) { if list != nil { list = append(list[:pos], list[pos+1:]...) return list, true @@ -451,7 +426,7 @@ func deleteAt(list []Path, pos int) ([]Path, bool) { } // remove item from slice by object itself -func removeWithPath(list []Path, path Path) ([]Path, bool) { +func removeWithPath(list []*Path, path *Path) ([]*Path, bool) { for index, p := range list { if p == path { @@ -462,7 +437,7 @@ func removeWithPath(list []Path, path Path) ([]Path, bool) { return list, false } -func computeBestPath(localAsn uint32, path1, path2 Path) (Path, string) { +func computeBestPath(localAsn uint32, path1, path2 *Path) (*Path, string) { //Compares given paths and returns best path. // @@ -495,7 +470,7 @@ func computeBestPath(localAsn uint32, path1, path2 Path) (Path, string) { // Assumes paths from NC has source equal to None. // - var bestPath Path + var bestPath *Path bestPathReason := BPR_UNKNOWN // Follow best path calculation algorithm steps. @@ -553,7 +528,7 @@ func computeBestPath(localAsn uint32, path1, path2 Path) (Path, string) { return bestPath, bestPathReason } -func compareByReachableNexthop(path1, path2 Path) Path { +func compareByReachableNexthop(path1, path2 *Path) *Path { // Compares given paths and selects best path based on reachable next-hop. // // If no path matches this criteria, return None. @@ -562,7 +537,7 @@ func compareByReachableNexthop(path1, path2 Path) Path { return nil } -func compareByHighestWeight(path1, path2 Path) Path { +func compareByHighestWeight(path1, path2 *Path) *Path { // Selects a path with highest weight. // // Weight is BGPS specific parameter. It is local to the router on which it @@ -573,7 +548,7 @@ func compareByHighestWeight(path1, path2 Path) Path { return nil } -func compareByLocalPref(path1, path2 Path) Path { +func compareByLocalPref(path1, path2 *Path) *Path { // Selects a path with highest local-preference. // // Unlike the weight attribute, which is only relevant to the local @@ -603,7 +578,7 @@ func compareByLocalPref(path1, path2 Path) Path { } } -func compareByLocalOrigin(path1, path2 Path) Path { +func compareByLocalOrigin(path1, path2 *Path) *Path { // Select locally originating path as best path. // Locally originating routes are network routes, redistributed routes, @@ -628,7 +603,7 @@ func compareByLocalOrigin(path1, path2 Path) Path { return nil } -func compareByASPath(path1, path2 Path) Path { +func compareByASPath(path1, path2 *Path) *Path { // Calculated the best-paths by comparing as-path lengths. // // Shortest as-path length is preferred. If both path have same lengths, @@ -659,7 +634,7 @@ func compareByASPath(path1, path2 Path) Path { } } -func compareByOrigin(path1, path2 Path) Path { +func compareByOrigin(path1, path2 *Path) *Path { // Select the best path based on origin attribute. // // IGP is preferred over EGP; EGP is preferred over Incomplete. @@ -692,7 +667,7 @@ func compareByOrigin(path1, path2 Path) Path { } } -func compareByMED(path1, path2 Path) Path { +func compareByMED(path1, path2 *Path) *Path { // Select the path based with lowest MED value. // // If both paths have same MED, return None. @@ -702,7 +677,7 @@ func compareByMED(path1, path2 Path) Path { // compare MED among not only same AS path but also all path, // like bgp always-compare-med log.Debugf("enter compareByMED") - getMed := func(path Path) uint32 { + getMed := func(path *Path) uint32 { _, attribute := path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) if attribute == nil { return 0 @@ -722,7 +697,7 @@ func compareByMED(path1, path2 Path) Path { return path2 } -func compareByASNumber(localAsn uint32, path1, path2 Path) Path { +func compareByASNumber(localAsn uint32, path1, path2 *Path) *Path { //Select the path based on source (iBGP/eBGP) peer. // @@ -748,7 +723,7 @@ func compareByASNumber(localAsn uint32, path1, path2 Path) Path { return nil } -func compareByIGPCost(path1, path2 Path) Path { +func compareByIGPCost(path1, path2 *Path) *Path { // Select the route with the lowest IGP cost to the next hop. // // Return None if igp cost is same. @@ -757,7 +732,7 @@ func compareByIGPCost(path1, path2 Path) Path { return nil } -func compareByRouterID(localAsn uint32, path1, path2 Path) (Path, error) { +func compareByRouterID(localAsn uint32, path1, path2 *Path) (*Path, error) { // Select the route received from the peer with the lowest BGP router ID. // // If both paths are eBGP paths, then we do not do any tie breaking, i.e we do @@ -804,220 +779,6 @@ func compareByRouterID(localAsn uint32, path1, path2 Path) (Path, error) { } } -// return Destination's string representation -func (dest *DestinationDefault) String() string { - str := fmt.Sprintf("Destination NLRI: %s", dest.getPrefix().String()) - return str -} - -func (dest *DestinationDefault) constructWithdrawPath() Path { - path := &IPv4Path{} - return path -} - -func (dest *DestinationDefault) getPrefix() net.IP { - var ip net.IP - switch p := dest.nlri.(type) { - case *bgp.NLRInfo: - ip = p.IPAddrPrefix.IPAddrPrefixDefault.Prefix - case *bgp.WithdrawnRoute: - ip = p.IPAddrPrefix.IPAddrPrefixDefault.Prefix - } - return ip -} - -/* -* Definition of inherited Destination interface - */ - -type IPv4Destination struct { - *DestinationDefault - //need structure -} - -func NewIPv4Destination(nlri bgp.AddrPrefixInterface) *IPv4Destination { - ipv4Destination := &IPv4Destination{} - ipv4Destination.DestinationDefault = NewDestinationDefault(nlri) - ipv4Destination.DestinationDefault.ROUTE_FAMILY = bgp.RF_IPv4_UC - //need Processing - return ipv4Destination -} - -func (ipv4d *IPv4Destination) String() string { - str := fmt.Sprintf("Destination NLRI: %s", ipv4d.getPrefix().String()) - return str -} - -type IPv6Destination struct { - *DestinationDefault - //need structure -} - -func NewIPv6Destination(nlri bgp.AddrPrefixInterface) *IPv6Destination { - ipv6Destination := &IPv6Destination{} - ipv6Destination.DestinationDefault = NewDestinationDefault(nlri) - ipv6Destination.DestinationDefault.ROUTE_FAMILY = bgp.RF_IPv6_UC - //need Processing - return ipv6Destination -} - -func (ipv6d *IPv6Destination) String() string { - - str := fmt.Sprintf("Destination NLRI: %s", ipv6d.getPrefix().String()) - return str -} - -func (ipv6d *IPv6Destination) getPrefix() net.IP { - var ip net.IP - log.Debugf("type %s", reflect.TypeOf(ipv6d.nlri)) - switch p := ipv6d.nlri.(type) { - case *bgp.IPv6AddrPrefix: - ip = p.IPAddrPrefix.IPAddrPrefixDefault.Prefix - case *bgp.WithdrawnRoute: - ip = p.IPAddrPrefix.IPAddrPrefixDefault.Prefix - } - return ip -} - -func (ipv6d *IPv6Destination) MarshalJSON() ([]byte, error) { - prefix := ipv6d.getNlri().(*bgp.IPv6AddrPrefix).Prefix - idx := func() int { - for i, p := range ipv6d.DestinationDefault.knownPathList { - if p == ipv6d.DestinationDefault.GetBestPath() { - return i - } - } - log.WithFields(log.Fields{ - "Topic": "Table", - "Key": prefix.String(), - }).Panic("no best path") - return 0 - }() - return json.Marshal(struct { - Prefix string - Paths []Path - BestPathIdx int `json:"best_path_idx"` - }{ - Prefix: prefix.String(), - Paths: ipv6d.knownPathList, - BestPathIdx: idx, - }) -} - -type IPv4VPNDestination struct { - *DestinationDefault - //need structure -} - -func NewIPv4VPNDestination(nlri bgp.AddrPrefixInterface) *IPv4VPNDestination { - ipv4VPNDestination := &IPv4VPNDestination{} - ipv4VPNDestination.DestinationDefault = NewDestinationDefault(nlri) - ipv4VPNDestination.DestinationDefault.ROUTE_FAMILY = bgp.RF_IPv4_VPN - //need Processing - return ipv4VPNDestination -} - -func (ipv4vpnd *IPv4VPNDestination) String() string { - - str := fmt.Sprintf("Destination NLRI: %s", ipv4vpnd.getPrefix().String()) - return str -} - -func (ipv4vpnd *IPv4VPNDestination) getPrefix() net.IP { - var ip net.IP - log.Debugf("type %s", reflect.TypeOf(ipv4vpnd.nlri)) - switch p := ipv4vpnd.nlri.(type) { - case *bgp.IPv6AddrPrefix: - ip = p.IPAddrPrefix.IPAddrPrefixDefault.Prefix - case *bgp.WithdrawnRoute: - ip = p.IPAddrPrefix.IPAddrPrefixDefault.Prefix - } - return ip -} - -func (ipv4vpnd *IPv4VPNDestination) MarshalJSON() ([]byte, error) { - prefix := ipv4vpnd.getNlri().(*bgp.LabelledVPNIPAddrPrefix).Prefix - idx := func() int { - for i, p := range ipv4vpnd.DestinationDefault.knownPathList { - if p == ipv4vpnd.DestinationDefault.GetBestPath() { - return i - } - } - log.WithFields(log.Fields{ - "Topic": "Table", - "Key": prefix.String(), - }).Panic("no best path") - return 0 - }() - return json.Marshal(struct { - Prefix string - Paths []Path - BestPathIdx int `json:"best_path_idx"` - }{ - Prefix: prefix.String(), - Paths: ipv4vpnd.knownPathList, - BestPathIdx: idx, - }) -} - -type EVPNDestination struct { - *DestinationDefault - //need structure -} - -func NewEVPNDestination(nlri bgp.AddrPrefixInterface) *EVPNDestination { - EVPNDestination := &EVPNDestination{} - EVPNDestination.DestinationDefault = NewDestinationDefault(nlri) - EVPNDestination.DestinationDefault.ROUTE_FAMILY = bgp.RF_EVPN - //need Processing - return EVPNDestination -} - -func (evpnd *EVPNDestination) MarshalJSON() ([]byte, error) { - nlri := evpnd.getNlri().(*bgp.EVPNNLRI) - idx := func() int { - for i, p := range evpnd.DestinationDefault.knownPathList { - if p == evpnd.DestinationDefault.GetBestPath() { - return i - } - } - log.WithFields(log.Fields{ - "Topic": "Table", - "Key": nlri.String(), - }).Panic("no best path") - return 0 - }() - return json.Marshal(struct { - Prefix string - Paths []Path - BestPathIdx int `json:"best_path_idx"` - }{ - Prefix: nlri.String(), - Paths: evpnd.knownPathList, - BestPathIdx: idx, - }) -} - -type EncapDestination struct { - *DestinationDefault -} - -func NewEncapDestination(nlri bgp.AddrPrefixInterface) *EncapDestination { - d := NewDestinationDefault(nlri) - d.ROUTE_FAMILY = bgp.RF_ENCAP - return &EncapDestination{ - DestinationDefault: d, - } -} - -type RouteTargetDestination struct { - *DestinationDefault -} - -func NewRouteTargetDestination(nlri bgp.AddrPrefixInterface) *RouteTargetDestination { - d := NewDestinationDefault(nlri) - d.ROUTE_FAMILY = bgp.RF_RTC_UC - return &RouteTargetDestination{ - DestinationDefault: d, - } +func (dest *Destination) String() string { + return fmt.Sprintf("Destination NLRI: %s", dest.nlri.String()) } diff --git a/table/destination_test.go b/table/destination_test.go index 7c30764a..dbdf19a2 100644 --- a/table/destination_test.go +++ b/table/destination_test.go @@ -27,51 +27,51 @@ import ( func TestDestinationNewIPv4(t *testing.T) { peerD := DestCreatePeer() pathD := DestCreatePath(peerD) - ipv4d := NewIPv4Destination(pathD[0].GetNlri()) + ipv4d := NewDestination(pathD[0].GetNlri()) assert.NotNil(t, ipv4d) } func TestDestinationNewIPv6(t *testing.T) { peerD := DestCreatePeer() pathD := DestCreatePath(peerD) - ipv6d := NewIPv6Destination(pathD[0].GetNlri()) + ipv6d := NewDestination(pathD[0].GetNlri()) assert.NotNil(t, ipv6d) } func TestDestinationSetRouteFamily(t *testing.T) { - dd := &DestinationDefault{} + dd := &Destination{} dd.setRouteFamily(bgp.RF_IPv4_UC) rf := dd.getRouteFamily() assert.Equal(t, rf, bgp.RF_IPv4_UC) } func TestDestinationGetRouteFamily(t *testing.T) { - dd := &DestinationDefault{} + dd := &Destination{} dd.setRouteFamily(bgp.RF_IPv6_UC) rf := dd.getRouteFamily() assert.Equal(t, rf, bgp.RF_IPv6_UC) } func TestDestinationSetNlri(t *testing.T) { - dd := &DestinationDefault{} + dd := &Destination{} nlri := bgp.NewNLRInfo(24, "13.2.3.1") dd.setNlri(nlri) r_nlri := dd.getNlri() assert.Equal(t, r_nlri, nlri) } func TestDestinationGetNlri(t *testing.T) { - dd := &DestinationDefault{} + dd := &Destination{} nlri := bgp.NewNLRInfo(24, "10.110.123.1") dd.setNlri(nlri) r_nlri := dd.getNlri() assert.Equal(t, r_nlri, nlri) } func TestDestinationSetBestPathReason(t *testing.T) { - dd := &DestinationDefault{} + dd := &Destination{} reason := "reason1" dd.setBestPathReason(reason) r_reason := dd.getBestPathReason() assert.Equal(t, r_reason, reason) } func TestDestinationGetBestPathReason(t *testing.T) { - dd := &DestinationDefault{} + dd := &Destination{} reason := "reason2" dd.setBestPathReason(reason) r_reason := dd.getBestPathReason() @@ -80,7 +80,7 @@ func TestDestinationGetBestPathReason(t *testing.T) { func TestDestinationSetBestPath(t *testing.T) { peerD := DestCreatePeer() pathD := DestCreatePath(peerD) - ipv4d := NewIPv4Destination(pathD[0].GetNlri()) + ipv4d := NewDestination(pathD[0].GetNlri()) ipv4d.setBestPath(pathD[0]) r_pathD := ipv4d.GetBestPath() assert.Equal(t, r_pathD, pathD[0]) @@ -88,7 +88,7 @@ func TestDestinationSetBestPath(t *testing.T) { func TestDestinationGetBestPath(t *testing.T) { peerD := DestCreatePeer() pathD := DestCreatePath(peerD) - ipv4d := NewIPv4Destination(pathD[0].GetNlri()) + ipv4d := NewDestination(pathD[0].GetNlri()) ipv4d.setBestPath(pathD[0]) r_pathD := ipv4d.GetBestPath() assert.Equal(t, r_pathD, pathD[0]) @@ -96,7 +96,7 @@ func TestDestinationGetBestPath(t *testing.T) { func TestDestinationCalculate(t *testing.T) { peerD := DestCreatePeer() pathD := DestCreatePath(peerD) - ipv4d := NewIPv4Destination(pathD[0].GetNlri()) + ipv4d := NewDestination(pathD[0].GetNlri()) //best path selection ipv4d.addNewPath(pathD[0]) ipv4d.addNewPath(pathD[1]) @@ -114,17 +114,17 @@ func DestCreatePeer() []*PeerInfo { return peerD } -func DestCreatePath(peerD []*PeerInfo) []Path { +func DestCreatePath(peerD []*PeerInfo) []*Path { bgpMsgD1 := updateMsgD1() bgpMsgD2 := updateMsgD2() bgpMsgD3 := updateMsgD3() - pathD := make([]Path, 3) + pathD := make([]*Path, 3) for i, msg := range []*bgp.BGPMessage{bgpMsgD1, bgpMsgD2, bgpMsgD3} { updateMsgD := msg.Body.(*bgp.BGPUpdate) nlriList := updateMsgD.NLRI pathAttributes := updateMsgD.PathAttributes nlri_info := nlriList[0] - pathD[i], _ = CreatePath(peerD[i], &nlri_info, pathAttributes, false, time.Now()) + pathD[i] = NewPath(peerD[i], &nlri_info, false, pathAttributes, false, time.Now()) } return pathD } diff --git a/table/message.go b/table/message.go index 4455e06b..7ae01152 100644 --- a/table/message.go +++ b/table/message.go @@ -128,15 +128,15 @@ func cloneAttrSlice(attrs []bgp.PathAttributeInterface) []bgp.PathAttributeInter return clonedAttrs } -func UpdatePathAttrs(path Path, global *config.Global, peer *config.Neighbor) { +func UpdatePathAttrs(path *Path, global *config.Global, peer *config.Neighbor) { path.updatePathAttrs(global, peer) } -func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage { +func createUpdateMsgFromPath(path *Path, msg *bgp.BGPMessage) *bgp.BGPMessage { rf := path.GetRouteFamily() if rf == bgp.RF_IPv4_UC { - if path.IsWithdraw() { + if path.IsWithdraw { draw := path.GetNlri().(*bgp.WithdrawnRoute) if msg != nil { u := msg.Body.(*bgp.BGPUpdate) @@ -156,7 +156,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage { } } } else if rf == bgp.RF_IPv6_UC || rf == bgp.RF_EVPN || rf == bgp.RF_ENCAP || rf == bgp.RF_RTC_UC { - if path.IsWithdraw() { + if path.IsWithdraw { if msg != nil { idx, _ := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI) u := msg.Body.(*bgp.BGPUpdate) @@ -207,7 +207,7 @@ func isSamePathAttrs(pList1 []bgp.PathAttributeInterface, pList2 []bgp.PathAttri return true } -func isMergeable(p1 Path, p2 Path) bool { +func isMergeable(p1, p2 *Path) bool { return false if p1 == nil { return false @@ -221,8 +221,8 @@ func isMergeable(p1 Path, p2 Path) bool { return false } -func CreateUpdateMsgFromPaths(pathList []Path) []*bgp.BGPMessage { - var pre Path +func CreateUpdateMsgFromPaths(pathList []*Path) []*bgp.BGPMessage { + var pre *Path var msgs []*bgp.BGPMessage for _, path := range pathList { y := isMergeable(pre, path) diff --git a/table/path.go b/table/path.go index 390d5f1d..7ede28b8 100644 --- a/table/path.go +++ b/table/path.go @@ -16,63 +16,27 @@ package table import ( - "encoding/json" "fmt" log "github.com/Sirupsen/logrus" "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet" + "math" "net" "reflect" "time" - "math" ) -type Path interface { - String() string - getPathAttrs() []bgp.PathAttributeInterface - getPathAttr(bgp.BGPAttrType) (int, bgp.PathAttributeInterface) - updatePathAttrs(global *config.Global, peer *config.Neighbor) - GetRouteFamily() bgp.RouteFamily - GetAsPathLen() int - GetAsList() []uint32 - GetAsSeqList() []uint32 - GetCommunities() []uint32 - SetCommunities([]uint32, bool) - RemoveCommunities([]uint32) int - ClearCommunities() - GetMed() uint32 - SetMed(int64, bool) error - setSource(source *PeerInfo) - GetSource() *PeerInfo - GetSourceAs() uint32 - GetNexthop() net.IP - SetNexthop(net.IP) - setWithdraw(withdraw bool) - IsWithdraw() bool - GetNlri() bgp.AddrPrefixInterface - getPrefix() string - setMedSetByTargetNeighbor(medSetByTargetNeighbor bool) - getMedSetByTargetNeighbor() bool - Clone(IsWithdraw bool) Path - getTimestamp() time.Time - setTimestamp(t time.Time) - isLocal() bool - ToApiStruct() *api.Path - MarshalJSON() ([]byte, error) -} - -type PathDefault struct { - routeFamily bgp.RouteFamily +type Path struct { source *PeerInfo - withdraw bool + IsWithdraw bool nlri bgp.AddrPrefixInterface pathAttrs []bgp.PathAttributeInterface medSetByTargetNeighbor bool timestamp time.Time } -func NewPathDefault(rf bgp.RouteFamily, source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pattrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *PathDefault { +func NewPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pattrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, timestamp time.Time) *Path { if !isWithdraw && pattrs == nil { log.WithFields(log.Fields{ "Topic": "Table", @@ -82,15 +46,14 @@ func NewPathDefault(rf bgp.RouteFamily, source *PeerInfo, nlri bgp.AddrPrefixInt return nil } - path := &PathDefault{} - path.routeFamily = rf - path.pathAttrs = pattrs - path.nlri = nlri - path.source = source - path.withdraw = isWithdraw - path.medSetByTargetNeighbor = medSetByTargetNeighbor - path.timestamp = now - return path + return &Path{ + source: source, + IsWithdraw: isWithdraw, + nlri: nlri, + pathAttrs: pattrs, + medSetByTargetNeighbor: medSetByTargetNeighbor, + timestamp: timestamp, + } } func cloneAsPath(asAttr *bgp.PathAttributeAsPath) *bgp.PathAttributeAsPath { @@ -104,7 +67,7 @@ func cloneAsPath(asAttr *bgp.PathAttributeAsPath) *bgp.PathAttributeAsPath { return bgp.NewPathAttributeAsPath(newASparams) } -func (pd *PathDefault) updatePathAttrs(global *config.Global, peer *config.Neighbor) { +func (path *Path) updatePathAttrs(global *config.Global, peer *config.Neighbor) { if peer.RouteServer.RouteServerClient { return @@ -112,7 +75,7 @@ func (pd *PathDefault) updatePathAttrs(global *config.Global, peer *config.Neigh if peer.PeerType == config.PEER_TYPE_EXTERNAL { // NEXTHOP handling - pd.SetNexthop(peer.LocalAddress) + path.SetNexthop(peer.LocalAddress) // AS_PATH handling // @@ -136,12 +99,12 @@ func (pd *PathDefault) updatePathAttrs(global *config.Global, peer *config.Neigh // 3) if the AS_PATH is empty, the local system creates a path // segment of type AS_SEQUENCE, places its own AS into that // segment, and places that segment into the AS_PATH. - idx, originalAsPath := pd.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH) + idx, originalAsPath := path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH) if idx < 0 { log.Fatal("missing AS_PATH mandatory attribute") } asPath := cloneAsPath(originalAsPath.(*bgp.PathAttributeAsPath)) - pd.pathAttrs[idx] = asPath + path.pathAttrs[idx] = asPath fst := asPath.Value[0].(*bgp.As4PathParam) if len(asPath.Value) > 0 && fst.Type == bgp.BGP_ASPATH_ATTR_TYPE_SEQ && fst.ASLen() < 255 { @@ -153,20 +116,20 @@ func (pd *PathDefault) updatePathAttrs(global *config.Global, peer *config.Neigh } // MED Handling - idx, _ = pd.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) + idx, _ = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) if idx >= 0 { - pd.pathAttrs = append(pd.pathAttrs[:idx], pd.pathAttrs[idx+1:]...) + path.pathAttrs = append(path.pathAttrs[:idx], path.pathAttrs[idx+1:]...) } } else if peer.PeerType == config.PEER_TYPE_INTERNAL { // For iBGP peers we are required to send local-pref attribute // for connected or local prefixes. // We set default local-pref 100. p := bgp.NewPathAttributeLocalPref(100) - idx, _ := pd.getPathAttr(bgp.BGP_ATTR_TYPE_LOCAL_PREF) + idx, _ := path.getPathAttr(bgp.BGP_ATTR_TYPE_LOCAL_PREF) if idx < 0 { - pd.pathAttrs = append(pd.pathAttrs, p) + path.pathAttrs = append(path.pathAttrs, p) } else { - pd.pathAttrs[idx] = p + path.pathAttrs[idx] = p } } else { log.WithFields(log.Fields{ @@ -176,76 +139,71 @@ func (pd *PathDefault) updatePathAttrs(global *config.Global, peer *config.Neigh } } -func (pd *PathDefault) getTimestamp() time.Time { - return pd.timestamp +func (path *Path) getTimestamp() time.Time { + return path.timestamp } -func (pd *PathDefault) setTimestamp(t time.Time) { - pd.timestamp = t +func (path *Path) setTimestamp(t time.Time) { + path.timestamp = t } -func (pd *PathDefault) isLocal() bool { +func (path *Path) isLocal() bool { var ret bool - if pd.source.Address == nil { + if path.source.Address == nil { ret = true } return ret } -func (pd *PathDefault) ToApiStruct() *api.Path { +func (path *Path) ToApiStruct() *api.Path { pathAttrs := func(arg []bgp.PathAttributeInterface) []*api.PathAttr { ret := make([]*api.PathAttr, 0, len(arg)) for _, a := range arg { ret = append(ret, a.ToApiStruct()) } return ret - }(pd.getPathAttrs()) + }(path.getPathAttrs()) return &api.Path{ - Nlri: pd.GetNlri().ToApiStruct(), - Nexthop: pd.GetNexthop().String(), + Nlri: path.GetNlri().ToApiStruct(), + Nexthop: path.GetNexthop().String(), Attrs: pathAttrs, - Age: int64(time.Now().Sub(pd.timestamp).Seconds()), - IsWithdraw: pd.IsWithdraw(), + Age: int64(time.Now().Sub(path.timestamp).Seconds()), + IsWithdraw: path.IsWithdraw, } } -func (pd *PathDefault) MarshalJSON() ([]byte, error) { - return json.Marshal(pd.ToApiStruct()) -} - // create new PathAttributes -func (pd *PathDefault) Clone(isWithdraw bool) Path { - nlri := pd.nlri - if pd.GetRouteFamily() == bgp.RF_IPv4_UC && isWithdraw { - if pd.IsWithdraw() { - nlri = pd.nlri +func (path *Path) Clone(isWithdraw bool) *Path { + nlri := path.nlri + if path.GetRouteFamily() == bgp.RF_IPv4_UC && isWithdraw { + if path.IsWithdraw { + nlri = path.nlri } else { - nlri = &bgp.WithdrawnRoute{pd.nlri.(*bgp.NLRInfo).IPAddrPrefix} + nlri = &bgp.WithdrawnRoute{path.nlri.(*bgp.NLRInfo).IPAddrPrefix} } } - newPathAttrs := make([]bgp.PathAttributeInterface, len(pd.pathAttrs)) - for i, v := range pd.pathAttrs { + newPathAttrs := make([]bgp.PathAttributeInterface, len(path.pathAttrs)) + for i, v := range path.pathAttrs { newPathAttrs[i] = v } - path, _ := CreatePath(pd.source, nlri, newPathAttrs, isWithdraw, pd.timestamp) - return path + return NewPath(path.source, nlri, isWithdraw, newPathAttrs, false, path.timestamp) } -func (pd *PathDefault) GetRouteFamily() bgp.RouteFamily { - return pd.routeFamily +func (path *Path) GetRouteFamily() bgp.RouteFamily { + return bgp.AfiSafiToRouteFamily(path.nlri.AFI(), path.nlri.SAFI()) } -func (pd *PathDefault) setSource(source *PeerInfo) { - pd.source = source +func (path *Path) setSource(source *PeerInfo) { + path.source = source } -func (pd *PathDefault) GetSource() *PeerInfo { - return pd.source +func (path *Path) GetSource() *PeerInfo { + return path.source } -func (pd *PathDefault) GetSourceAs() uint32 { - _, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH) +func (path *Path) GetSourceAs() uint32 { + _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH) if attr != nil { asPathParam := attr.(*bgp.PathAttributeAsPath).Value if len(asPathParam) == 0 { @@ -260,57 +218,49 @@ func (pd *PathDefault) GetSourceAs() uint32 { return 0 } -func (pd *PathDefault) GetNexthop() net.IP { - _, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) +func (path *Path) GetNexthop() net.IP { + _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) if attr != nil { return attr.(*bgp.PathAttributeNextHop).Value } - _, attr = pd.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) + _, attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) if attr != nil { return attr.(*bgp.PathAttributeMpReachNLRI).Nexthop } return net.IP{} } -func (pd *PathDefault) SetNexthop(nexthop net.IP) { - idx, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) +func (path *Path) SetNexthop(nexthop net.IP) { + idx, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) if attr != nil { newNexthop := bgp.NewPathAttributeNextHop(nexthop.String()) - pd.pathAttrs[idx] = newNexthop + path.pathAttrs[idx] = newNexthop } - idx, attr = pd.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) + idx, attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) if attr != nil { oldNlri := attr.(*bgp.PathAttributeMpReachNLRI) newNlri := bgp.NewPathAttributeMpReachNLRI(nexthop.String(), oldNlri.Value) - pd.pathAttrs[idx] = newNlri + path.pathAttrs[idx] = newNlri } } -func (pd *PathDefault) setWithdraw(withdraw bool) { - pd.withdraw = withdraw -} - -func (pd *PathDefault) IsWithdraw() bool { - return pd.withdraw +func (path *Path) GetNlri() bgp.AddrPrefixInterface { + return path.nlri } -func (pd *PathDefault) GetNlri() bgp.AddrPrefixInterface { - return pd.nlri -} - -func (pd *PathDefault) setMedSetByTargetNeighbor(medSetByTargetNeighbor bool) { - pd.medSetByTargetNeighbor = medSetByTargetNeighbor +func (path *Path) setMedSetByTargetNeighbor(medSetByTargetNeighbor bool) { + path.medSetByTargetNeighbor = medSetByTargetNeighbor } -func (pd *PathDefault) getMedSetByTargetNeighbor() bool { - return pd.medSetByTargetNeighbor +func (path *Path) getMedSetByTargetNeighbor() bool { + return path.medSetByTargetNeighbor } -func (pd *PathDefault) getPathAttrs() []bgp.PathAttributeInterface { - return pd.pathAttrs +func (path *Path) getPathAttrs() []bgp.PathAttributeInterface { + return path.pathAttrs } -func (pd *PathDefault) getPathAttr(pattrType bgp.BGPAttrType) (int, bgp.PathAttributeInterface) { +func (path *Path) getPathAttr(pattrType bgp.BGPAttrType) (int, bgp.PathAttributeInterface) { attrMap := [bgp.BGP_ATTR_TYPE_AS4_AGGREGATOR + 1]reflect.Type{} attrMap[bgp.BGP_ATTR_TYPE_ORIGIN] = reflect.TypeOf(&bgp.PathAttributeOrigin{}) attrMap[bgp.BGP_ATTR_TYPE_AS_PATH] = reflect.TypeOf(&bgp.PathAttributeAsPath{}) @@ -329,7 +279,7 @@ func (pd *PathDefault) getPathAttr(pattrType bgp.BGPAttrType) (int, bgp.PathAttr attrMap[bgp.BGP_ATTR_TYPE_AS4_AGGREGATOR] = reflect.TypeOf(&bgp.PathAttributeAs4Aggregator{}) t := attrMap[pattrType] - for i, p := range pd.pathAttrs { + for i, p := range path.pathAttrs { if t == reflect.TypeOf(p) { return i, p } @@ -338,24 +288,23 @@ func (pd *PathDefault) getPathAttr(pattrType bgp.BGPAttrType) (int, bgp.PathAttr } // return Path's string representation -func (pi *PathDefault) String() string { - str := fmt.Sprintf("IPv4Path Source: %v, ", pi.GetSource()) - str = str + fmt.Sprintf(" NLRI: %s, ", pi.getPrefix()) - str = str + fmt.Sprintf(" nexthop: %s, ", pi.GetNexthop().String()) - str = str + fmt.Sprintf(" withdraw: %s, ", pi.IsWithdraw()) - //str = str + fmt.Sprintf(" path attributes: %s, ", pi.getPathAttributeMap()) +func (path *Path) String() string { + str := fmt.Sprintf("Source: %v, ", path.GetSource()) + str += fmt.Sprintf(" NLRI: %s, ", path.getPrefix()) + str += fmt.Sprintf(" nexthop: %s, ", path.GetNexthop()) + str += fmt.Sprintf(" withdraw: %s, ", path.IsWithdraw) return str } -func (pi *PathDefault) getPrefix() string { - return pi.nlri.String() +func (path *Path) getPrefix() string { + return path.nlri.String() } // GetAsPathLen returns the number of AS_PATH -func (pd *PathDefault) GetAsPathLen() int { +func (path *Path) GetAsPathLen() int { var length int = 0 - if _, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH); attr != nil { + if _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH); attr != nil { aspath := attr.(*bgp.PathAttributeAsPath) for _, paramIf := range aspath.Value { segment := paramIf.(*bgp.As4PathParam) @@ -365,19 +314,19 @@ func (pd *PathDefault) GetAsPathLen() int { return length } -func (pd *PathDefault) GetAsList() []uint32 { - return pd.getAsListofSpecificType(true, true) +func (path *Path) GetAsList() []uint32 { + return path.getAsListofSpecificType(true, true) } -func (pd *PathDefault) GetAsSeqList() []uint32 { - return pd.getAsListofSpecificType(true, false) +func (path *Path) GetAsSeqList() []uint32 { + return path.getAsListofSpecificType(true, false) } -func (pd *PathDefault) getAsListofSpecificType(getAsSeq, getAsSet bool) []uint32 { +func (path *Path) getAsListofSpecificType(getAsSeq, getAsSet bool) []uint32 { asList := []uint32{} - if _, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH); attr != nil { + if _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH); attr != nil { aspath := attr.(*bgp.PathAttributeAsPath) for _, paramIf := range aspath.Value { segment := paramIf.(*bgp.As4PathParam) @@ -393,9 +342,9 @@ func (pd *PathDefault) getAsListofSpecificType(getAsSeq, getAsSet bool) []uint32 return asList } -func (pd *PathDefault) GetCommunities() []uint32 { +func (path *Path) GetCommunities() []uint32 { communityList := []uint32{} - if _, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_COMMUNITIES); attr != nil { + if _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_COMMUNITIES); attr != nil { communities := attr.(*bgp.PathAttributeCommunities) communityList = append(communityList, communities.Value...) } @@ -404,7 +353,7 @@ func (pd *PathDefault) GetCommunities() []uint32 { // SetCommunities adds or replaces communities with new ones. // If the length of communites is 0, it does nothing. -func (pd *PathDefault) SetCommunities(communities []uint32, doReplace bool) { +func (path *Path) SetCommunities(communities []uint32, doReplace bool) { if len(communities) == 0 { // do nothing @@ -412,7 +361,7 @@ func (pd *PathDefault) SetCommunities(communities []uint32, doReplace bool) { } newList := make([]uint32, 0) - idx, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_COMMUNITIES) + idx, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_COMMUNITIES) if attr != nil { c := attr.(*bgp.PathAttributeCommunities) if doReplace { @@ -422,11 +371,11 @@ func (pd *PathDefault) SetCommunities(communities []uint32, doReplace bool) { newList = append(newList, communities...) } newCommunities := bgp.NewPathAttributeCommunities(newList) - pd.pathAttrs[idx] = newCommunities + path.pathAttrs[idx] = newCommunities } else { newList = append(newList, communities...) newCommunities := bgp.NewPathAttributeCommunities(newList) - pd.pathAttrs = append(pd.pathAttrs, newCommunities) + path.pathAttrs = append(path.pathAttrs, newCommunities) } } @@ -434,7 +383,7 @@ func (pd *PathDefault) SetCommunities(communities []uint32, doReplace bool) { // RemoveCommunities removes specific communities. // If the length of communites is 0, it does nothing. // If all communities are removed, it removes Communities path attribute itself. -func (pd *PathDefault) RemoveCommunities(communities []uint32) int { +func (path *Path) RemoveCommunities(communities []uint32) int { if len(communities) == 0 { // do nothing @@ -451,7 +400,7 @@ func (pd *PathDefault) RemoveCommunities(communities []uint32) int { } count := 0 - idx, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_COMMUNITIES) + idx, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_COMMUNITIES) if attr != nil { newList := make([]uint32, 0) c := attr.(*bgp.PathAttributeCommunities) @@ -466,39 +415,41 @@ func (pd *PathDefault) RemoveCommunities(communities []uint32) int { if len(newList) != 0 { newCommunities := bgp.NewPathAttributeCommunities(newList) - pd.pathAttrs[idx] = newCommunities + path.pathAttrs[idx] = newCommunities } else { - pd.pathAttrs = append(pd.pathAttrs[:idx], pd.pathAttrs[idx+1:]...) + path.pathAttrs = append(path.pathAttrs[:idx], path.pathAttrs[idx+1:]...) } } return count } // ClearCommunities removes Communities path attribute. -func (pd *PathDefault) ClearCommunities() { - idx, _ := pd.getPathAttr(bgp.BGP_ATTR_TYPE_COMMUNITIES) +func (path *Path) ClearCommunities() { + idx, _ := path.getPathAttr(bgp.BGP_ATTR_TYPE_COMMUNITIES) if idx >= 0 { - pd.pathAttrs = append(pd.pathAttrs[:idx], pd.pathAttrs[idx+1:]...) + path.pathAttrs = append(path.pathAttrs[:idx], path.pathAttrs[idx+1:]...) } } -func (pd *PathDefault) GetMed() uint32 { - _, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) - med := attr.(*bgp.PathAttributeMultiExitDisc).Value - return med +func (path *Path) GetMed() (uint32, error) { + _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) + if attr == nil { + return 0, fmt.Errorf("no med path attr") + } + return attr.(*bgp.PathAttributeMultiExitDisc).Value, nil } // SetMed replace, add or subtraction med with new ones. -func (pd *PathDefault) SetMed(med int64, doReplace bool) error { +func (path *Path) SetMed(med int64, doReplace bool) error { parseMed := func(orgMed uint32, med int64, doReplace bool) (*bgp.PathAttributeMultiExitDisc, error) { newMed := &bgp.PathAttributeMultiExitDisc{} if doReplace { newMed = bgp.NewPathAttributeMultiExitDisc(uint32(med)) } else { - if int64(orgMed) + med < 0 { + if int64(orgMed)+med < 0 { return nil, fmt.Errorf("med value invalid. it's underflow threshold.") - } else if int64(orgMed) + med > int64(math.MaxUint32) { + } else if int64(orgMed)+med > int64(math.MaxUint32) { return nil, fmt.Errorf("med value invalid. it's overflow threshold.") } newMed = bgp.NewPathAttributeMultiExitDisc(uint32(int64(orgMed) + med)) @@ -506,220 +457,21 @@ func (pd *PathDefault) SetMed(med int64, doReplace bool) error { return newMed, nil } - idx, attr := pd.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) - if attr != nil{ + idx, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) + if attr != nil { m := attr.(*bgp.PathAttributeMultiExitDisc) newMed, err := parseMed(m.Value, med, doReplace) - if err != nil{ + if err != nil { return err } - pd.pathAttrs[idx] = newMed + path.pathAttrs[idx] = newMed } else { m := 0 newMed, err := parseMed(uint32(m), med, doReplace) - if err != nil{ - pd.pathAttrs = append(pd.pathAttrs, &bgp.PathAttributeMultiExitDisc{}) + if err != nil { return err } - pd.pathAttrs = append(pd.pathAttrs, newMed) + path.pathAttrs = append(path.pathAttrs, newMed) } return nil } - -// create Path object based on route family -func CreatePath(source *PeerInfo, nlri bgp.AddrPrefixInterface, attrs []bgp.PathAttributeInterface, isWithdraw bool, now time.Time) (Path, error) { - - rf := bgp.RouteFamily(int(nlri.AFI())<<16 | int(nlri.SAFI())) - log.Debugf("CreatePath afi: %d, safi: %d ", int(nlri.AFI()), nlri.SAFI()) - var path Path - - switch rf { - case bgp.RF_IPv4_UC: - log.Debugf("CreatePath RouteFamily : %s", bgp.RF_IPv4_UC.String()) - path = NewIPv4Path(source, nlri, isWithdraw, attrs, false, now) - case bgp.RF_IPv6_UC: - log.Debugf("CreatePath RouteFamily : %s", bgp.RF_IPv6_UC.String()) - path = NewIPv6Path(source, nlri, isWithdraw, attrs, false, now) - case bgp.RF_IPv4_VPN: - log.Debugf("CreatePath RouteFamily : %s", bgp.RF_IPv4_VPN.String()) - path = NewIPv4VPNPath(source, nlri, isWithdraw, attrs, false, now) - case bgp.RF_EVPN: - log.Debugf("CreatePath RouteFamily : %s", bgp.RF_EVPN.String()) - path = NewEVPNPath(source, nlri, isWithdraw, attrs, false, now) - case bgp.RF_ENCAP: - log.Debugf("CreatePath RouteFamily : %s", bgp.RF_ENCAP.String()) - path = NewEncapPath(source, nlri, isWithdraw, attrs, false, now) - case bgp.RF_RTC_UC: - log.Debugf("CreatePath RouteFamily : %s", bgp.RF_RTC_UC) - path = NewRouteTargetPath(source, nlri, isWithdraw, attrs, false, now) - default: - return path, fmt.Errorf("Unsupported RouteFamily: %s", rf) - } - return path, nil -} - -/* -* Definition of inherited Path interface - */ -type IPv4Path struct { - *PathDefault -} - -func NewIPv4Path(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *IPv4Path { - ipv4Path := &IPv4Path{} - ipv4Path.PathDefault = NewPathDefault(bgp.RF_IPv4_UC, source, nlri, isWithdraw, attrs, medSetByTargetNeighbor, now) - return ipv4Path -} - -func (ipv4p *IPv4Path) setPathDefault(pd *PathDefault) { - ipv4p.PathDefault = pd -} -func (ipv4p *IPv4Path) getPathDefault() *PathDefault { - return ipv4p.PathDefault -} - -type IPv6Path struct { - *PathDefault -} - -func NewIPv6Path(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *IPv6Path { - ipv6Path := &IPv6Path{} - ipv6Path.PathDefault = NewPathDefault(bgp.RF_IPv6_UC, source, nlri, isWithdraw, attrs, medSetByTargetNeighbor, now) - return ipv6Path -} - -func (ipv6p *IPv6Path) setPathDefault(pd *PathDefault) { - ipv6p.PathDefault = pd -} - -func (ipv6p *IPv6Path) getPathDefault() *PathDefault { - return ipv6p.PathDefault -} - -// return IPv6Path's string representation -func (ipv6p *IPv6Path) String() string { - str := fmt.Sprintf("IPv6Path Source: %v, ", ipv6p.GetSource()) - str = str + fmt.Sprintf(" NLRI: %s, ", ipv6p.getPrefix()) - str = str + fmt.Sprintf(" nexthop: %s, ", ipv6p.GetNexthop().String()) - str = str + fmt.Sprintf(" withdraw: %s, ", ipv6p.IsWithdraw()) - //str = str + fmt.Sprintf(" path attributes: %s, ", ipv6p.getPathAttributeMap()) - return str -} - -type IPv4VPNPath struct { - *PathDefault -} - -func NewIPv4VPNPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *IPv4VPNPath { - ipv4VPNPath := &IPv4VPNPath{} - ipv4VPNPath.PathDefault = NewPathDefault(bgp.RF_IPv4_VPN, source, nlri, isWithdraw, attrs, medSetByTargetNeighbor, now) - return ipv4VPNPath -} - -func (ipv4vpnp *IPv4VPNPath) setPathDefault(pd *PathDefault) { - ipv4vpnp.PathDefault = pd -} - -func (ipv4vpnp *IPv4VPNPath) getPathDefault() *PathDefault { - return ipv4vpnp.PathDefault -} - -// return IPv4VPNPath's string representation -func (ipv4vpnp *IPv4VPNPath) String() string { - str := fmt.Sprintf("IPv4VPNPath Source: %v, ", ipv4vpnp.GetSource()) - str = str + fmt.Sprintf(" NLRI: %s, ", ipv4vpnp.getPrefix()) - str = str + fmt.Sprintf(" nexthop: %s, ", ipv4vpnp.GetNexthop().String()) - str = str + fmt.Sprintf(" withdraw: %s, ", ipv4vpnp.IsWithdraw()) - //str = str + fmt.Sprintf(" path attributes: %s, ", ipv4vpnp.getPathAttributeMap()) - return str -} - -func (ipv4vpnp *IPv4VPNPath) MarshalJSON() ([]byte, error) { - return json.Marshal(struct { - Network string - Nexthop string - Attrs []bgp.PathAttributeInterface - Age int64 - }{ - Network: ipv4vpnp.getPrefix(), - Nexthop: ipv4vpnp.PathDefault.GetNexthop().String(), - Attrs: ipv4vpnp.PathDefault.getPathAttrs(), - Age: int64(time.Now().Sub(ipv4vpnp.PathDefault.timestamp).Seconds()), - }) -} - -type EVPNPath struct { - *PathDefault -} - -func NewEVPNPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *EVPNPath { - EVPNPath := &EVPNPath{} - EVPNPath.PathDefault = NewPathDefault(bgp.RF_EVPN, source, nlri, isWithdraw, attrs, medSetByTargetNeighbor, now) - return EVPNPath -} - -func (evpnp *EVPNPath) setPathDefault(pd *PathDefault) { - evpnp.PathDefault = pd -} - -func (evpnp *EVPNPath) getPathDefault() *PathDefault { - return evpnp.PathDefault -} - -// return EVPNPath's string representation -func (evpnp *EVPNPath) String() string { - str := fmt.Sprintf("EVPNPath Source: %v, ", evpnp.GetSource()) - str = str + fmt.Sprintf(" NLRI: %s, ", evpnp.getPrefix()) - str = str + fmt.Sprintf(" nexthop: %s, ", evpnp.GetNexthop().String()) - str = str + fmt.Sprintf(" withdraw: %s, ", evpnp.IsWithdraw()) - //str = str + fmt.Sprintf(" path attributes: %s, ", evpnp.getPathAttributeMap()) - return str -} - -func (evpnp *EVPNPath) MarshalJSON() ([]byte, error) { - return json.Marshal(struct { - Network string - Nexthop string - Attrs []bgp.PathAttributeInterface - Age int64 - }{ - Network: evpnp.getPrefix(), - Nexthop: evpnp.PathDefault.GetNexthop().String(), - Attrs: evpnp.PathDefault.getPathAttrs(), - Age: int64(time.Now().Sub(evpnp.PathDefault.timestamp).Seconds()), - }) -} - -type EncapPath struct { - *PathDefault -} - -func NewEncapPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *EncapPath { - return &EncapPath{ - PathDefault: NewPathDefault(bgp.RF_ENCAP, source, nlri, isWithdraw, attrs, medSetByTargetNeighbor, now), - } -} - -func (p *EncapPath) setPathDefault(pd *PathDefault) { - p.PathDefault = pd -} -func (p *EncapPath) getPathDefault() *PathDefault { - return p.PathDefault -} - -type RouteTargetPath struct { - *PathDefault -} - -func NewRouteTargetPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, attrs []bgp.PathAttributeInterface, medSetByTargetNeighbor bool, now time.Time) *RouteTargetPath { - return &RouteTargetPath{ - PathDefault: NewPathDefault(bgp.RF_RTC_UC, source, nlri, isWithdraw, attrs, medSetByTargetNeighbor, now), - } -} - -func (p *RouteTargetPath) setPathDefault(pd *PathDefault) { - p.PathDefault = pd -} -func (p *RouteTargetPath) getPathDefault() *PathDefault { - return p.PathDefault -} diff --git a/table/path_test.go b/table/path_test.go index 230a2628..44381fd7 100644 --- a/table/path_test.go +++ b/table/path_test.go @@ -12,56 +12,18 @@ import ( func TestPathNewIPv4(t *testing.T) { peerP := PathCreatePeer() pathP := PathCreatePath(peerP) - ipv4p := NewIPv4Path(pathP[0].GetSource(), pathP[0].GetNlri(), true, pathP[0].getPathAttrs(), pathP[0].getMedSetByTargetNeighbor(), time.Now()) + ipv4p := NewPath(pathP[0].GetSource(), pathP[0].GetNlri(), true, pathP[0].getPathAttrs(), pathP[0].getMedSetByTargetNeighbor(), time.Now()) assert.NotNil(t, ipv4p) } func TestPathNewIPv6(t *testing.T) { peerP := PathCreatePeer() pathP := PathCreatePath(peerP) - ipv6p := NewIPv6Path(pathP[0].GetSource(), pathP[0].GetNlri(), true, pathP[0].getPathAttrs(), pathP[0].getMedSetByTargetNeighbor(), time.Now()) + ipv6p := NewPath(pathP[0].GetSource(), pathP[0].GetNlri(), true, pathP[0].getPathAttrs(), pathP[0].getMedSetByTargetNeighbor(), time.Now()) assert.NotNil(t, ipv6p) } -func TestPathIPv4SetDefault(t *testing.T) { - pd := &PathDefault{withdraw: true} - ipv4p := &IPv4Path{} - ipv4p.setPathDefault(pd) - r_pd := ipv4p.getPathDefault() - assert.Equal(t, r_pd, pd) -} - -func TestPathIPv4GetDefault(t *testing.T) { - pd := &PathDefault{withdraw: false} - ipv4p := &IPv4Path{} - ipv4p.setPathDefault(pd) - r_pd := ipv4p.getPathDefault() - assert.Equal(t, r_pd, pd) -} - -func TestPathIPv6SetDefault(t *testing.T) { - pd := &PathDefault{} - ipv6p := &IPv6Path{} - ipv6p.setPathDefault(pd) - r_pd := ipv6p.getPathDefault() - assert.Equal(t, r_pd, pd) -} - -func TestPathIPv6GetDefault(t *testing.T) { - pd := &PathDefault{} - ipv6p := &IPv6Path{} - ipv6p.setPathDefault(pd) - r_pd := ipv6p.getPathDefault() - assert.Equal(t, r_pd, pd) -} - -func TestPathGetRouteFamily(t *testing.T) { - pd := &PathDefault{routeFamily: bgp.RF_IPv6_UC} - rf := pd.GetRouteFamily() - assert.Equal(t, rf, bgp.RF_IPv6_UC) -} - func TestPathSetSource(t *testing.T) { - pd := &PathDefault{} + pd := &Path{} pr := &PeerInfo{AS: 65000} pd.setSource(pr) r_pr := pd.GetSource() @@ -69,32 +31,16 @@ func TestPathSetSource(t *testing.T) { } func TestPathGetSource(t *testing.T) { - pd := &PathDefault{} + pd := &Path{} pr := &PeerInfo{AS: 65001} pd.setSource(pr) r_pr := pd.GetSource() assert.Equal(t, r_pr, pr) } -func TestPathSetWithdraw(t *testing.T) { - pd := &PathDefault{} - wd := true - pd.setWithdraw(wd) - r_wd := pd.IsWithdraw() - assert.Equal(t, r_wd, wd) -} - -func TestPathGetWithdaw(t *testing.T) { - pd := &PathDefault{} - wd := false - pd.setWithdraw(wd) - r_wd := pd.IsWithdraw() - assert.Equal(t, r_wd, wd) -} - func TestPathGetNlri(t *testing.T) { nlri := bgp.NewNLRInfo(24, "13.2.3.2") - pd := &PathDefault{ + pd := &Path{ nlri: nlri, } r_nlri := pd.GetNlri() @@ -102,7 +48,7 @@ func TestPathGetNlri(t *testing.T) { } func TestPathSetMedSetByTargetNeighbor(t *testing.T) { - pd := &PathDefault{} + pd := &Path{} msbt := true pd.setMedSetByTargetNeighbor(msbt) r_msbt := pd.getMedSetByTargetNeighbor() @@ -110,7 +56,7 @@ func TestPathSetMedSetByTargetNeighbor(t *testing.T) { } func TestPathGetMedSetByTargetNeighbor(t *testing.T) { - pd := &PathDefault{} + pd := &Path{} msbt := true pd.setMedSetByTargetNeighbor(msbt) r_msbt := pd.getMedSetByTargetNeighbor() @@ -124,7 +70,7 @@ func TestPathCreatePath(t *testing.T) { nlriList := updateMsgP.NLRI pathAttributes := updateMsgP.PathAttributes nlri_info := nlriList[0] - path, _ := CreatePath(peerP[0], &nlri_info, pathAttributes, false, time.Now()) + path := NewPath(peerP[0], &nlri_info, false, pathAttributes, false, time.Now()) assert.NotNil(t, path) } @@ -170,7 +116,7 @@ func TestASPathLen(t *testing.T) { update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() - p, _ := CreatePath(peer[0], &update.NLRI[0], update.PathAttributes, false, time.Now()) + p := NewPath(peer[0], &update.NLRI[0], false, update.PathAttributes, false, time.Now()) assert.Equal(10, p.GetAsPathLen()) } @@ -182,17 +128,17 @@ func PathCreatePeer() []*PeerInfo { return peerP } -func PathCreatePath(peerP []*PeerInfo) []Path { +func PathCreatePath(peerP []*PeerInfo) []*Path { bgpMsgP1 := updateMsgP1() bgpMsgP2 := updateMsgP2() bgpMsgP3 := updateMsgP3() - pathP := make([]Path, 3) + pathP := make([]*Path, 3) for i, msg := range []*bgp.BGPMessage{bgpMsgP1, bgpMsgP2, bgpMsgP3} { updateMsgP := msg.Body.(*bgp.BGPUpdate) nlriList := updateMsgP.NLRI pathAttributes := updateMsgP.PathAttributes nlri_info := nlriList[0] - pathP[i], _ = CreatePath(peerP[i], &nlri_info, pathAttributes, false, time.Now()) + pathP[i] = NewPath(peerP[i], &nlri_info, false, pathAttributes, false, time.Now()) } return pathP } diff --git a/table/table.go b/table/table.go index 7fa6b17a..b3d21840 100644 --- a/table/table.go +++ b/table/table.go @@ -21,52 +21,30 @@ import ( "reflect" ) -type Table interface { - createDest(nlri bgp.AddrPrefixInterface) Destination - GetDestinations() map[string]Destination - setDestinations(destinations map[string]Destination) - getDestination(key string) Destination - setDestination(key string, dest Destination) - tableKey(nlri bgp.AddrPrefixInterface) string - validatePath(path Path) - validateNlri(nlri bgp.AddrPrefixInterface) - DeleteDestByPeer(*PeerInfo) []Destination +type Table struct { + routeFamily bgp.RouteFamily + destinations map[string]*Destination } -type TableDefault struct { - ROUTE_FAMILY bgp.RouteFamily - destinations map[string]Destination - //need SignalBus -} - -func NewTableDefault(scope_id int) *TableDefault { - table := &TableDefault{} - table.ROUTE_FAMILY = bgp.RF_IPv4_UC - table.destinations = make(map[string]Destination) - return table - -} - -func (td *TableDefault) GetRoutefamily() bgp.RouteFamily { - return td.ROUTE_FAMILY +func NewTable(rf bgp.RouteFamily) *Table { + return &Table{ + routeFamily: rf, + destinations: make(map[string]*Destination), + } } -//Creates destination -//Implements interface -func (td *TableDefault) createDest(nlri *bgp.NLRInfo) Destination { - //return NewDestination(td, nlri) - log.Error("CreateDest NotImplementedError") - return nil +func (t *Table) GetRoutefamily() bgp.RouteFamily { + return t.routeFamily } -func insert(table Table, path Path) Destination { - var dest Destination +func (t *Table) insert(path *Path) *Destination { + var dest *Destination - table.validatePath(path) - table.validateNlri(path.GetNlri()) - dest = getOrCreateDest(table, path.GetNlri()) + t.validatePath(path) + t.validateNlri(path.GetNlri()) + dest = t.getOrCreateDest(path.GetNlri()) - if path.IsWithdraw() { + if path.IsWithdraw { // withdraw insert dest.addWithdraw(path) } else { @@ -76,27 +54,10 @@ func insert(table Table, path Path) Destination { return dest } -/* -//Cleans table of any path that do not have any RT in common with interested_rts -// Commented out because it is a VPN-related processing -func (td *TableDefault) cleanUninterestingPaths(interested_rts) int { - uninterestingDestCount = 0 - for _, dest := range td.destinations { - addedWithdraw :=dest.withdrawUnintrestingPaths(interested_rts) - if addedWithdraw{ - //need _signal_bus.dest_changed(dest) - uninterestingDestCount += 1 - } - } - return uninterestingDestCount - // need content -} -*/ - -func (td *TableDefault) DeleteDestByPeer(peerInfo *PeerInfo) []Destination { - changedDests := make([]Destination, 0) - for _, dest := range td.destinations { - newKnownPathList := make([]Path, 0) +func (t *Table) DeleteDestByPeer(peerInfo *PeerInfo) []*Destination { + changedDests := make([]*Destination, 0) + for _, dest := range t.destinations { + newKnownPathList := make([]*Path, 0) for _, p := range dest.getKnownPathList() { if !p.GetSource().Equal(peerInfo) { newKnownPathList = append(newKnownPathList, p) @@ -110,32 +71,32 @@ func (td *TableDefault) DeleteDestByPeer(peerInfo *PeerInfo) []Destination { return changedDests } -func deleteDestByNlri(table Table, nlri bgp.AddrPrefixInterface) Destination { - table.validateNlri(nlri) - destinations := table.GetDestinations() - dest := destinations[table.tableKey(nlri)] +func (t *Table) deleteDestByNlri(nlri bgp.AddrPrefixInterface) *Destination { + t.validateNlri(nlri) + destinations := t.GetDestinations() + dest := destinations[t.tableKey(nlri)] if dest != nil { - delete(destinations, table.tableKey(nlri)) + delete(destinations, t.tableKey(nlri)) } return dest } -func deleteDest(table Table, dest Destination) { - destinations := table.GetDestinations() - delete(destinations, table.tableKey(dest.getNlri())) +func (t *Table) deleteDest(dest *Destination) { + destinations := t.GetDestinations() + delete(destinations, t.tableKey(dest.getNlri())) } -func (td *TableDefault) validatePath(path Path) { - if path == nil || path.GetRouteFamily() != td.ROUTE_FAMILY { +func (t *Table) validatePath(path *Path) { + if path == nil || path.GetRouteFamily() != t.routeFamily { if path == nil { log.WithFields(log.Fields{ "Topic": "Table", - "Key": td.ROUTE_FAMILY, + "Key": t.routeFamily, }).Error("path is nil") - } else if path.GetRouteFamily() != td.ROUTE_FAMILY { + } else if path.GetRouteFamily() != t.routeFamily { log.WithFields(log.Fields{ "Topic": "Table", - "Key": td.ROUTE_FAMILY, + "Key": t.routeFamily, "Prefix": path.GetNlri().String(), "ReceivedRf": path.GetRouteFamily().String(), }).Error("Invalid path. RouteFamily mismatch") @@ -149,7 +110,7 @@ func (td *TableDefault) validatePath(path Path) { if !y { log.WithFields(log.Fields{ "Topic": "Table", - "Key": td.ROUTE_FAMILY, + "Key": t.routeFamily, "As": as, }).Fatal("AsPathParam must be converted to As4PathParam") } @@ -160,43 +121,43 @@ func (td *TableDefault) validatePath(path Path) { if attr != nil { log.WithFields(log.Fields{ "Topic": "Table", - "Key": td.ROUTE_FAMILY, + "Key": t.routeFamily, }).Fatal("AS4_PATH must be converted to AS_PATH") } } -func (td *TableDefault) validateNlri(nlri bgp.AddrPrefixInterface) { +func (t *Table) validateNlri(nlri bgp.AddrPrefixInterface) { if nlri == nil { log.WithFields(log.Fields{ "Topic": "Table", - "Key": td.ROUTE_FAMILY, + "Key": t.routeFamily, "Nlri": nlri, }).Error("Invalid Vpnv4 prefix given.") } } -func getOrCreateDest(table Table, nlri bgp.AddrPrefixInterface) Destination { - log.Debugf("getOrCreateDest Table type : %s", reflect.TypeOf(table)) - tableKey := table.tableKey(nlri) - dest := table.getDestination(tableKey) +func (t *Table) getOrCreateDest(nlri bgp.AddrPrefixInterface) *Destination { + log.Debugf("getOrCreateDest Table type : %s", reflect.TypeOf(t)) + tableKey := t.tableKey(nlri) + dest := t.getDestination(tableKey) // If destination for given prefix does not exist we create it. if dest == nil { log.Debugf("getOrCreateDest dest with key %s is not found", tableKey) - dest = table.createDest(nlri) - table.setDestination(tableKey, dest) + dest = NewDestination(nlri) + t.setDestination(tableKey, dest) } return dest } -func (td *TableDefault) GetDestinations() map[string]Destination { - return td.destinations +func (t *Table) GetDestinations() map[string]*Destination { + return t.destinations } -func (td *TableDefault) setDestinations(destinations map[string]Destination) { - td.destinations = destinations +func (t *Table) setDestinations(destinations map[string]*Destination) { + t.destinations = destinations } -func (td *TableDefault) getDestination(key string) Destination { - dest, ok := td.destinations[key] +func (t *Table) getDestination(key string) *Destination { + dest, ok := t.destinations[key] if ok { return dest } else { @@ -204,171 +165,10 @@ func (td *TableDefault) getDestination(key string) Destination { } } -func (td *TableDefault) setDestination(key string, dest Destination) { - td.destinations[key] = dest -} - -//Implements interface -func (td *TableDefault) tableKey(nlri bgp.AddrPrefixInterface) string { - //need Inheritance over ride - //return &nlri.IPAddrPrefix.IPAddrPrefixDefault.Prefix - log.Error("CreateDest NotImplementedError") - return "" -} - -/* -* Definition of inherited Table interface - */ - -type IPv4Table struct { - *TableDefault - //need structure -} - -func NewIPv4Table(scope_id int) *IPv4Table { - ipv4Table := &IPv4Table{} - ipv4Table.TableDefault = NewTableDefault(scope_id) - ipv4Table.TableDefault.ROUTE_FAMILY = bgp.RF_IPv4_UC - //need Processing - return ipv4Table -} - -//Creates destination -//Implements interface -func (ipv4t *IPv4Table) createDest(nlri bgp.AddrPrefixInterface) Destination { - return NewIPv4Destination(nlri) -} - -//make tablekey -//Implements interface -func (ipv4t *IPv4Table) tableKey(nlri bgp.AddrPrefixInterface) string { - switch p := nlri.(type) { - case *bgp.NLRInfo: - return p.IPAddrPrefix.IPAddrPrefixDefault.String() - case *bgp.WithdrawnRoute: - return p.IPAddrPrefix.IPAddrPrefixDefault.String() - } - log.Fatal() - return "" -} - -type IPv6Table struct { - *TableDefault - //need structure -} - -func NewIPv6Table(scope_id int) *IPv6Table { - ipv6Table := &IPv6Table{} - ipv6Table.TableDefault = NewTableDefault(scope_id) - ipv6Table.TableDefault.ROUTE_FAMILY = bgp.RF_IPv6_UC - //need Processing - return ipv6Table -} - -//Creates destination -//Implements interface -func (ipv6t *IPv6Table) createDest(nlri bgp.AddrPrefixInterface) Destination { - return Destination(NewIPv6Destination(nlri)) -} - -//make tablekey -//Implements interface -func (ipv6t *IPv6Table) tableKey(nlri bgp.AddrPrefixInterface) string { - - addrPrefix := nlri.(*bgp.IPv6AddrPrefix) - return addrPrefix.IPAddrPrefixDefault.String() - -} - -type IPv4VPNTable struct { - *TableDefault - //need structure -} - -func NewIPv4VPNTable(scope_id int) *IPv4VPNTable { - ipv4VPNTable := &IPv4VPNTable{} - ipv4VPNTable.TableDefault = NewTableDefault(scope_id) - ipv4VPNTable.TableDefault.ROUTE_FAMILY = bgp.RF_IPv4_VPN - //need Processing - return ipv4VPNTable -} - -//Creates destination -//Implements interface -func (ipv4vpnt *IPv4VPNTable) createDest(nlri bgp.AddrPrefixInterface) Destination { - return Destination(NewIPv4VPNDestination(nlri)) -} - -//make tablekey -//Implements interface -func (ipv4vpnt *IPv4VPNTable) tableKey(nlri bgp.AddrPrefixInterface) string { - - addrPrefix := nlri.(*bgp.LabelledVPNIPAddrPrefix) - return addrPrefix.IPAddrPrefixDefault.String() - -} - -type EVPNTable struct { - *TableDefault - //need structure -} - -func NewEVPNTable(scope_id int) *EVPNTable { - EVPNTable := &EVPNTable{} - EVPNTable.TableDefault = NewTableDefault(scope_id) - EVPNTable.TableDefault.ROUTE_FAMILY = bgp.RF_EVPN - //need Processing - return EVPNTable -} - -//Creates destination -//Implements interface -func (ipv4vpnt *EVPNTable) createDest(nlri bgp.AddrPrefixInterface) Destination { - return Destination(NewEVPNDestination(nlri)) -} - -//make tablekey -//Implements interface -func (ipv4vpnt *EVPNTable) tableKey(nlri bgp.AddrPrefixInterface) string { - - addrPrefix := nlri.(*bgp.EVPNNLRI) - return addrPrefix.String() -} - -type EncapTable struct { - *TableDefault -} - -func NewEncapTable() *EncapTable { - EncapTable := &EncapTable{} - EncapTable.TableDefault = NewTableDefault(0) - EncapTable.TableDefault.ROUTE_FAMILY = bgp.RF_ENCAP - return EncapTable -} - -func (t *EncapTable) createDest(nlri bgp.AddrPrefixInterface) Destination { - return Destination(NewEncapDestination(nlri)) -} - -func (t *EncapTable) tableKey(nlri bgp.AddrPrefixInterface) string { - return nlri.String() -} - -type RouteTargetTable struct { - *TableDefault -} - -func NewRouteTargetTable() *RouteTargetTable { - routeTargetTable := &RouteTargetTable{} - routeTargetTable.TableDefault = NewTableDefault(0) - routeTargetTable.TableDefault.ROUTE_FAMILY = bgp.RF_RTC_UC - return routeTargetTable -} - -func (t *RouteTargetTable) createDest(nlri bgp.AddrPrefixInterface) Destination { - return Destination(NewRouteTargetDestination(nlri)) +func (t *Table) setDestination(key string, dest *Destination) { + t.destinations[key] = dest } -func (t *RouteTargetTable) tableKey(nlri bgp.AddrPrefixInterface) string { +func (t *Table) tableKey(nlri bgp.AddrPrefixInterface) string { return nlri.String() } diff --git a/table/table_manager.go b/table/table_manager.go index eb4a20bf..f94eab9e 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -22,35 +22,35 @@ import ( "time" ) -func nlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []Path { +func nlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []*Path { updateMsg := m.Body.(*bgp.BGPUpdate) pathAttributes := updateMsg.PathAttributes - pathList := make([]Path, 0) + pathList := make([]*Path, 0) for _, nlri_info := range updateMsg.NLRI { // define local variable to pass nlri's address to CreatePath var nlri bgp.NLRInfo = nlri_info // create Path object - path, _ := CreatePath(p, &nlri, pathAttributes, false, now) + path := NewPath(p, &nlri, false, pathAttributes, false, now) pathList = append(pathList, path) } return pathList } -func withdraw2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []Path { +func withdraw2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []*Path { updateMsg := m.Body.(*bgp.BGPUpdate) pathAttributes := updateMsg.PathAttributes - pathList := make([]Path, 0) + pathList := make([]*Path, 0) for _, nlriWithdraw := range updateMsg.WithdrawnRoutes { // define local variable to pass nlri's address to CreatePath var w bgp.WithdrawnRoute = nlriWithdraw // create withdrawn Path object - path, _ := CreatePath(p, &w, pathAttributes, true, now) + path := NewPath(p, &w, true, pathAttributes, false, now) pathList = append(pathList, path) } return pathList } -func mpreachNlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []Path { +func mpreachNlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []*Path { updateMsg := m.Body.(*bgp.BGPUpdate) pathAttributes := updateMsg.PathAttributes attrList := []*bgp.PathAttributeMpReachNLRI{} @@ -62,19 +62,19 @@ func mpreachNlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []Path { break } } - pathList := make([]Path, 0) + pathList := make([]*Path, 0) for _, mp := range attrList { nlri_info := mp.Value for _, nlri := range nlri_info { - path, _ := CreatePath(p, nlri, pathAttributes, false, now) + path := NewPath(p, nlri, false, pathAttributes, false, now) pathList = append(pathList, path) } } return pathList } -func mpunreachNlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []Path { +func mpunreachNlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []*Path { updateMsg := m.Body.(*bgp.BGPUpdate) pathAttributes := updateMsg.PathAttributes attrList := []*bgp.PathAttributeMpUnreachNLRI{} @@ -86,21 +86,21 @@ func mpunreachNlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []Path { break } } - pathList := make([]Path, 0) + pathList := make([]*Path, 0) for _, mp := range attrList { nlri_info := mp.Value for _, nlri := range nlri_info { - path, _ := CreatePath(p, nlri, pathAttributes, true, now) + path := NewPath(p, nlri, true, pathAttributes, false, now) pathList = append(pathList, path) } } return pathList } -func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo) []Path { - pathList := make([]Path, 0) +func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo) []*Path { + pathList := make([]*Path, 0) now := time.Now() pathList = append(pathList, nlri2Path(m, peerInfo, now)...) pathList = append(pathList, withdraw2Path(m, peerInfo, now)...) @@ -110,30 +110,16 @@ func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo) []Path { } type TableManager struct { - Tables map[bgp.RouteFamily]Table + Tables map[bgp.RouteFamily]*Table localAsn uint32 owner string } func NewTableManager(owner string, rfList []bgp.RouteFamily) *TableManager { t := &TableManager{} - t.Tables = make(map[bgp.RouteFamily]Table) + t.Tables = make(map[bgp.RouteFamily]*Table) for _, rf := range rfList { - // FIXME: NewIPTable() should handle all cases. - switch rf { - case bgp.RF_IPv4_UC: - t.Tables[bgp.RF_IPv4_UC] = NewIPv4Table(0) - case bgp.RF_IPv6_UC: - t.Tables[bgp.RF_IPv6_UC] = NewIPv6Table(0) - case bgp.RF_IPv4_VPN: - t.Tables[bgp.RF_IPv4_VPN] = NewIPv4VPNTable(0) - case bgp.RF_EVPN: - t.Tables[bgp.RF_EVPN] = NewEVPNTable(0) - case bgp.RF_ENCAP: - t.Tables[bgp.RF_ENCAP] = NewEncapTable() - case bgp.RF_RTC_UC: - t.Tables[bgp.RF_RTC_UC] = NewRouteTargetTable() - } + t.Tables[rf] = NewTable(rf) } t.owner = owner return t @@ -143,8 +129,8 @@ func (manager *TableManager) OwnerName() string { return manager.owner } -func (manager *TableManager) calculate(destinationList []Destination) ([]Path, error) { - newPaths := make([]Path, 0) +func (manager *TableManager) calculate(destinationList []*Destination) ([]*Path, error) { + newPaths := make([]*Path, 0) for _, destination := range destinationList { // compute best path @@ -201,7 +187,6 @@ func (manager *TableManager) calculate(destinationList []Destination) ([]Path, e } destination.setBestPath(nil) } else { - log.WithFields(log.Fields{ "Topic": "table", "Owner": manager.owner, @@ -225,7 +210,7 @@ func (manager *TableManager) calculate(destinationList []Destination) ([]Path, e if len(destination.getKnownPathList()) == 0 && destination.GetBestPath() == nil { rf := destination.getRouteFamily() t := manager.Tables[rf] - deleteDest(t, destination) + t.deleteDest(destination) log.WithFields(log.Fields{ "Topic": "table", "Owner": manager.owner, @@ -237,32 +222,32 @@ func (manager *TableManager) calculate(destinationList []Destination) ([]Path, e return newPaths, nil } -func (manager *TableManager) DeletePathsforPeer(peerInfo *PeerInfo, rf bgp.RouteFamily) ([]Path, error) { - if _, ok := manager.Tables[rf]; ok { - destinationList := manager.Tables[rf].DeleteDestByPeer(peerInfo) +func (manager *TableManager) DeletePathsforPeer(peerInfo *PeerInfo, rf bgp.RouteFamily) ([]*Path, error) { + if t, ok := manager.Tables[rf]; ok { + destinationList := t.DeleteDestByPeer(peerInfo) return manager.calculate(destinationList) } - return []Path{}, nil + return []*Path{}, nil } -func (manager *TableManager) ProcessPaths(pathList []Path) ([]Path, error) { - destinationList := make([]Destination, 0) +func (manager *TableManager) ProcessPaths(pathList []*Path) ([]*Path, error) { + destinationList := make([]*Destination, 0, len(pathList)) for _, path := range pathList { rf := path.GetRouteFamily() - if _, ok := manager.Tables[rf]; ok { - destination := insert(manager.Tables[rf], path) - destinationList = append(destinationList, destination) + if t, ok := manager.Tables[rf]; ok { + destinationList = append(destinationList, t.insert(path)) } } return manager.calculate(destinationList) } -func (manager *TableManager) GetPathList(rf bgp.RouteFamily) []Path { +func (manager *TableManager) GetPathList(rf bgp.RouteFamily) []*Path { if _, ok := manager.Tables[rf]; !ok { - return []Path{} + return []*Path{} } - var paths []Path - for _, dest := range manager.Tables[rf].GetDestinations() { + destinations := manager.Tables[rf].GetDestinations() + paths := make([]*Path, 0, len(destinations)) + for _, dest := range destinations { paths = append(paths, dest.GetBestPath()) } return paths @@ -270,7 +255,7 @@ func (manager *TableManager) GetPathList(rf bgp.RouteFamily) []Path { // process BGPUpdate message // this function processes only BGPUpdate -func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]Path, error) { +func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]*Path, error) { // check msg's type if it's BGPUpdate if message.Header.Type != bgp.BGP_MSG_UPDATE { log.WithFields(log.Fields{ @@ -279,7 +264,7 @@ func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPM "key": fromPeer.Address.String(), "Type": message.Header.Type, }).Warn("message is not BGPUpdate") - return []Path{}, nil + return []*Path{}, nil } return manager.ProcessPaths(ProcessMessage(message, fromPeer)) @@ -302,12 +287,12 @@ func NewAdjRib(rfList []bgp.RouteFamily) *AdjRib { return r } -func (adj *AdjRib) update(rib map[bgp.RouteFamily]map[string]*ReceivedRoute, pathList []Path) { +func (adj *AdjRib) update(rib map[bgp.RouteFamily]map[string]*ReceivedRoute, pathList []*Path) { for _, path := range pathList { rf := path.GetRouteFamily() key := path.getPrefix() old, found := rib[rf][key] - if path.IsWithdraw() { + if path.IsWithdraw { if found { delete(rib[rf], key) } @@ -320,32 +305,32 @@ func (adj *AdjRib) update(rib map[bgp.RouteFamily]map[string]*ReceivedRoute, pat } } -func (adj *AdjRib) UpdateIn(pathList []Path) { +func (adj *AdjRib) UpdateIn(pathList []*Path) { adj.update(adj.adjRibIn, pathList) } -func (adj *AdjRib) UpdateOut(pathList []Path) { +func (adj *AdjRib) UpdateOut(pathList []*Path) { adj.update(adj.adjRibOut, pathList) } -func (adj *AdjRib) getPathList(rib map[string]*ReceivedRoute) []Path { - pathList := make([]Path, 0, len(rib)) +func (adj *AdjRib) getPathList(rib map[string]*ReceivedRoute) []*Path { + pathList := make([]*Path, 0, len(rib)) for _, rr := range rib { pathList = append(pathList, rr.path) } return pathList } -func (adj *AdjRib) GetInPathList(rf bgp.RouteFamily) []Path { +func (adj *AdjRib) GetInPathList(rf bgp.RouteFamily) []*Path { if _, ok := adj.adjRibIn[rf]; !ok { - return []Path{} + return []*Path{} } return adj.getPathList(adj.adjRibIn[rf]) } -func (adj *AdjRib) GetOutPathList(rf bgp.RouteFamily) []Path { +func (adj *AdjRib) GetOutPathList(rf bgp.RouteFamily) []*Path { if _, ok := adj.adjRibOut[rf]; !ok { - return []Path{} + return []*Path{} } return adj.getPathList(adj.adjRibOut[rf]) } @@ -373,7 +358,7 @@ func (adj *AdjRib) DropAll(rf bgp.RouteFamily) { } type ReceivedRoute struct { - path Path + path *Path filtered bool } @@ -381,7 +366,7 @@ func (rr *ReceivedRoute) String() string { return rr.path.getPrefix() } -func NewReceivedRoute(path Path, filtered bool) *ReceivedRoute { +func NewReceivedRoute(path *Path, filtered bool) *ReceivedRoute { rroute := &ReceivedRoute{ path: path, diff --git a/table/table_manager_test.go b/table/table_manager_test.go index d65db21f..206b322e 100644 --- a/table/table_manager_test.go +++ b/table/table_manager_test.go @@ -22,7 +22,6 @@ import ( "github.com/stretchr/testify/assert" "net" "os" - "reflect" "testing" ) @@ -73,13 +72,12 @@ func TestProcessBGPUpdate_0_select_onlypath_ipv4(t *testing.T) { peer := peerR1() pList, err := tm.ProcessUpdate(peer, bgpMessage) assert.Equal(t, len(pList), 1) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute pathAttributes := bgpMessage.Body.(*bgp.BGPUpdate).PathAttributes @@ -124,13 +122,12 @@ func TestProcessBGPUpdate_0_select_onlypath_ipv6(t *testing.T) { peer := peerR1() pList, err := tm.ProcessUpdate(peer, bgpMessage) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, expectedType, reflect.TypeOf(path).String()) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage.Body.(*bgp.BGPUpdate).PathAttributes @@ -204,19 +201,18 @@ func TestProcessBGPUpdate_1_select_high_localpref_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -290,19 +286,18 @@ func TestProcessBGPUpdate_1_select_high_localpref_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -376,7 +371,7 @@ func TestProcessBGPUpdate_2_select_local_origin_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) var peer2 *PeerInfo = &PeerInfo{ @@ -384,13 +379,12 @@ func TestProcessBGPUpdate_2_select_local_origin_ipv4(t *testing.T) { } pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -464,7 +458,7 @@ func TestProcessBGPUpdate_2_select_local_origin_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) var peer2 *PeerInfo = &PeerInfo{ @@ -473,13 +467,12 @@ func TestProcessBGPUpdate_2_select_local_origin_ipv6(t *testing.T) { pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -526,19 +519,18 @@ func TestProcessBGPUpdate_3_select_aspath_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) bgpMessage2 := update_fromR2() peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -583,19 +575,18 @@ func TestProcessBGPUpdate_3_select_aspath_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) bgpMessage2 := update_fromR2_ipv6() peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, expectedType, reflect.TypeOf(path).String()) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -669,19 +660,18 @@ func TestProcessBGPUpdate_4_select_low_origin_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -755,19 +745,18 @@ func TestProcessBGPUpdate_4_select_low_origin_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -841,19 +830,18 @@ func TestProcessBGPUpdate_5_select_low_med_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -927,19 +915,18 @@ func TestProcessBGPUpdate_5_select_low_med_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -1015,19 +1002,18 @@ func TestProcessBGPUpdate_6_select_ebgp_path_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -1102,19 +1088,18 @@ func TestProcessBGPUpdate_6_select_ebgp_path_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -1192,19 +1177,18 @@ func TestProcessBGPUpdate_7_select_low_routerid_path_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer3 := peerR3() pList, err = tm.ProcessUpdate(peer3, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -1279,19 +1263,18 @@ func TestProcessBGPUpdate_7_select_low_routerid_path_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer3 := peerR3() pList, err = tm.ProcessUpdate(peer3, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -1366,22 +1349,21 @@ func TestProcessBGPUpdate_8_withdraw_path_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute - checkPattr := func(expected *bgp.BGPMessage, actual Path) { + checkPattr := func(expected *bgp.BGPMessage, actual *Path) { pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes expectedOrigin := pathAttributes[0] _, attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN) @@ -1421,12 +1403,11 @@ func TestProcessBGPUpdate_8_withdraw_path_ipv4(t *testing.T) { pList, err = tm.ProcessUpdate(peer2, bgpMessage3) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) path = pList[0] - expectedType = "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) checkPattr(bgpMessage1, path) // check destination @@ -1476,19 +1457,18 @@ func TestProcessBGPUpdate_8_mpunreach_path_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) peer2 := peerR2() pList, err = tm.ProcessUpdate(peer2, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -1514,7 +1494,7 @@ func TestProcessBGPUpdate_8_mpunreach_path_ipv6(t *testing.T) { assert.Equal(t, expectedMed, pathMed) // check PathAttribute - checkPattr := func(expected *bgp.BGPMessage, actual Path) { + checkPattr := func(expected *bgp.BGPMessage, actual *Path) { pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes expectedNexthopAttr := pathAttributes[0] @@ -1556,12 +1536,11 @@ func TestProcessBGPUpdate_8_mpunreach_path_ipv6(t *testing.T) { pList, err = tm.ProcessUpdate(peer2, bgpMessage3) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) path = pList[0] - expectedType = "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) checkPattr(bgpMessage1, path) // check destination @@ -1601,21 +1580,20 @@ func TestProcessBGPUpdate_bestpath_lost_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) pList, err = tm.ProcessUpdate(peer1, bgpMessage1_w) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), true) + assert.Equal(t, pList[0].IsWithdraw, true) assert.NoError(t, err) // check old best path path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute - checkPattr := func(expected *bgp.BGPMessage, actual Path) { + checkPattr := func(expected *bgp.BGPMessage, actual *Path) { pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes expectedOrigin := pathAttributes[0] _, attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN) @@ -1670,7 +1648,7 @@ func TestProcessBGPUpdate_bestpath_lost_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // path1 mpunreach @@ -1680,16 +1658,15 @@ func TestProcessBGPUpdate_bestpath_lost_ipv6(t *testing.T) { pList, err = tm.ProcessUpdate(peer1, bgpMessage1_w) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), true) + assert.Equal(t, pList[0].IsWithdraw, true) assert.NoError(t, err) // check old best path path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute - checkPattr := func(expected *bgp.BGPMessage, actual Path) { + checkPattr := func(expected *bgp.BGPMessage, actual *Path) { pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes expectedNexthopAttr := pathAttributes[0] @@ -1760,21 +1737,20 @@ func TestProcessBGPUpdate_implicit_withdrwal_ipv4(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) pList, err = tm.ProcessUpdate(peer1, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv4Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC) // check PathAttribute - checkPattr := func(expected *bgp.BGPMessage, actual Path) { + checkPattr := func(expected *bgp.BGPMessage, actual *Path) { pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes expectedOrigin := pathAttributes[0] _, attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN) @@ -1847,18 +1823,17 @@ func TestProcessBGPUpdate_implicit_withdrwal_ipv6(t *testing.T) { peer1 := peerR1() pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) pList, err = tm.ProcessUpdate(peer1, bgpMessage2) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check type path := pList[0] - expectedType := "*table.IPv6Path" - assert.Equal(t, reflect.TypeOf(path).String(), expectedType) + assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC) // check PathAttribute pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes @@ -1884,7 +1859,7 @@ func TestProcessBGPUpdate_implicit_withdrwal_ipv6(t *testing.T) { assert.Equal(t, expectedMed, pathMed) // check PathAttribute - checkPattr := func(expected *bgp.BGPMessage, actual Path) { + checkPattr := func(expected *bgp.BGPMessage, actual *Path) { pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes expectedNexthopAttr := pathAttributes[0] @@ -1941,7 +1916,7 @@ func TestProcessBGPUpdate_multiple_nlri_ipv4(t *testing.T) { } // check PathAttribute - checkPattr := func(expected *bgp.BGPMessage, actual Path) { + checkPattr := func(expected *bgp.BGPMessage, actual *Path) { pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes expectedOrigin := pathAttributes[0] _, attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN) @@ -1967,9 +1942,8 @@ func TestProcessBGPUpdate_multiple_nlri_ipv4(t *testing.T) { assert.Equal(t, len(pathAttributes), len(actual.getPathAttrs())) } - checkBestPathResult := func(pType, prefix, nexthop string, p Path, m *bgp.BGPMessage) { - expectedType := pType - assert.Equal(t, reflect.TypeOf(p).String(), expectedType) + checkBestPathResult := func(rf bgp.RouteFamily, prefix, nexthop string, p *Path, m *bgp.BGPMessage) { + assert.Equal(t, p.GetRouteFamily(), rf) checkPattr(m, p) // check destination assert.Equal(t, prefix, p.getPrefix()) @@ -2016,39 +1990,39 @@ func TestProcessBGPUpdate_multiple_nlri_ipv4(t *testing.T) { pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 5, len(pList)) for _, p := range pList { - assert.Equal(t, p.IsWithdraw(), false) + assert.Equal(t, p.IsWithdraw, false) } assert.NoError(t, err) - checkBestPathResult("*table.IPv4Path", "10.10.10.0/24", "192.168.50.1", pList[0], bgpMessage1) - checkBestPathResult("*table.IPv4Path", "20.20.20.0/24", "192.168.50.1", pList[1], bgpMessage1) - checkBestPathResult("*table.IPv4Path", "30.30.30.0/24", "192.168.50.1", pList[2], bgpMessage1) - checkBestPathResult("*table.IPv4Path", "40.40.40.0/24", "192.168.50.1", pList[3], bgpMessage1) - checkBestPathResult("*table.IPv4Path", "50.50.50.0/24", "192.168.50.1", pList[4], bgpMessage1) + checkBestPathResult(bgp.RF_IPv4_UC, "10.10.10.0/24", "192.168.50.1", pList[0], bgpMessage1) + checkBestPathResult(bgp.RF_IPv4_UC, "20.20.20.0/24", "192.168.50.1", pList[1], bgpMessage1) + checkBestPathResult(bgp.RF_IPv4_UC, "30.30.30.0/24", "192.168.50.1", pList[2], bgpMessage1) + checkBestPathResult(bgp.RF_IPv4_UC, "40.40.40.0/24", "192.168.50.1", pList[3], bgpMessage1) + checkBestPathResult(bgp.RF_IPv4_UC, "50.50.50.0/24", "192.168.50.1", pList[4], bgpMessage1) pList, err = tm.ProcessUpdate(peer1, bgpMessage2) assert.Equal(t, 5, len(pList)) for _, p := range pList { - assert.Equal(t, p.IsWithdraw(), false) + assert.Equal(t, p.IsWithdraw, false) } assert.NoError(t, err) - checkBestPathResult("*table.IPv4Path", "11.11.11.0/24", "192.168.50.1", pList[0], bgpMessage2) - checkBestPathResult("*table.IPv4Path", "22.22.22.0/24", "192.168.50.1", pList[1], bgpMessage2) - checkBestPathResult("*table.IPv4Path", "33.33.33.0/24", "192.168.50.1", pList[2], bgpMessage2) - checkBestPathResult("*table.IPv4Path", "44.44.44.0/24", "192.168.50.1", pList[3], bgpMessage2) - checkBestPathResult("*table.IPv4Path", "55.55.55.0/24", "192.168.50.1", pList[4], bgpMessage2) + checkBestPathResult(bgp.RF_IPv4_UC, "11.11.11.0/24", "192.168.50.1", pList[0], bgpMessage2) + checkBestPathResult(bgp.RF_IPv4_UC, "22.22.22.0/24", "192.168.50.1", pList[1], bgpMessage2) + checkBestPathResult(bgp.RF_IPv4_UC, "33.33.33.0/24", "192.168.50.1", pList[2], bgpMessage2) + checkBestPathResult(bgp.RF_IPv4_UC, "44.44.44.0/24", "192.168.50.1", pList[3], bgpMessage2) + checkBestPathResult(bgp.RF_IPv4_UC, "55.55.55.0/24", "192.168.50.1", pList[4], bgpMessage2) pList, err = tm.ProcessUpdate(peer1, bgpMessage3) assert.Equal(t, 2, len(pList)) for _, p := range pList { - assert.Equal(t, p.IsWithdraw(), false) + assert.Equal(t, p.IsWithdraw, false) } assert.NoError(t, err) pList, err = tm.ProcessUpdate(peer1, bgpMessage4) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check table @@ -2076,7 +2050,7 @@ func TestProcessBGPUpdate_multiple_nlri_ipv6(t *testing.T) { } // check PathAttribute - checkPattr := func(expected *bgp.BGPMessage, actual Path) { + checkPattr := func(expected *bgp.BGPMessage, actual *Path) { pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes pathNexthop := pathAttributes[4] _, attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) @@ -2108,9 +2082,8 @@ func TestProcessBGPUpdate_multiple_nlri_ipv6(t *testing.T) { } - checkBestPathResult := func(pType, prefix, nexthop string, p Path, m *bgp.BGPMessage) { - expectedType := pType - assert.Equal(t, reflect.TypeOf(p).String(), expectedType) + checkBestPathResult := func(rf bgp.RouteFamily, prefix, nexthop string, p *Path, m *bgp.BGPMessage) { + assert.Equal(t, p.GetRouteFamily(), rf) checkPattr(m, p) // check destination assert.Equal(t, prefix, p.getPrefix()) @@ -2163,39 +2136,39 @@ func TestProcessBGPUpdate_multiple_nlri_ipv6(t *testing.T) { pList, err := tm.ProcessUpdate(peer1, bgpMessage1) assert.Equal(t, 5, len(pList)) for _, p := range pList { - assert.Equal(t, p.IsWithdraw(), false) + assert.Equal(t, p.IsWithdraw, false) } assert.NoError(t, err) - checkBestPathResult("*table.IPv6Path", "2001:123:1210:11::/64", "2001::192:168:50:1", pList[0], bgpMessage1) - checkBestPathResult("*table.IPv6Path", "2001:123:1220:11::/64", "2001::192:168:50:1", pList[1], bgpMessage1) - checkBestPathResult("*table.IPv6Path", "2001:123:1230:11::/64", "2001::192:168:50:1", pList[2], bgpMessage1) - checkBestPathResult("*table.IPv6Path", "2001:123:1240:11::/64", "2001::192:168:50:1", pList[3], bgpMessage1) - checkBestPathResult("*table.IPv6Path", "2001:123:1250:11::/64", "2001::192:168:50:1", pList[4], bgpMessage1) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1210:11::/64", "2001::192:168:50:1", pList[0], bgpMessage1) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1220:11::/64", "2001::192:168:50:1", pList[1], bgpMessage1) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1230:11::/64", "2001::192:168:50:1", pList[2], bgpMessage1) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1240:11::/64", "2001::192:168:50:1", pList[3], bgpMessage1) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1250:11::/64", "2001::192:168:50:1", pList[4], bgpMessage1) pList, err = tm.ProcessUpdate(peer1, bgpMessage2) assert.Equal(t, 5, len(pList)) for _, p := range pList { - assert.Equal(t, p.IsWithdraw(), false) + assert.Equal(t, p.IsWithdraw, false) } assert.NoError(t, err) - checkBestPathResult("*table.IPv6Path", "2001:123:1211:11::/64", "2001::192:168:50:1", pList[0], bgpMessage2) - checkBestPathResult("*table.IPv6Path", "2001:123:1222:11::/64", "2001::192:168:50:1", pList[1], bgpMessage2) - checkBestPathResult("*table.IPv6Path", "2001:123:1233:11::/64", "2001::192:168:50:1", pList[2], bgpMessage2) - checkBestPathResult("*table.IPv6Path", "2001:123:1244:11::/64", "2001::192:168:50:1", pList[3], bgpMessage2) - checkBestPathResult("*table.IPv6Path", "2001:123:1255:11::/64", "2001::192:168:50:1", pList[4], bgpMessage2) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1211:11::/64", "2001::192:168:50:1", pList[0], bgpMessage2) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1222:11::/64", "2001::192:168:50:1", pList[1], bgpMessage2) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1233:11::/64", "2001::192:168:50:1", pList[2], bgpMessage2) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1244:11::/64", "2001::192:168:50:1", pList[3], bgpMessage2) + checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1255:11::/64", "2001::192:168:50:1", pList[4], bgpMessage2) pList, err = tm.ProcessUpdate(peer1, bgpMessage3) assert.Equal(t, 2, len(pList)) for _, p := range pList { - assert.Equal(t, p.IsWithdraw(), false) + assert.Equal(t, p.IsWithdraw, false) } assert.NoError(t, err) pList, err = tm.ProcessUpdate(peer1, bgpMessage4) assert.Equal(t, 1, len(pList)) - assert.Equal(t, pList[0].IsWithdraw(), false) + assert.Equal(t, pList[0].IsWithdraw, false) assert.NoError(t, err) // check table @@ -2225,7 +2198,7 @@ func TestProcessBGPUpdate_Timestamp(t *testing.T) { m1 := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) peer := peerR1() pList1 := ProcessMessage(m1, peer) - path1 := pList1[0].(*IPv4Path) + path1 := pList1[0] t1 := path1.timestamp adjRib.UpdateIn(pList1) diff --git a/table/table_test.go b/table/table_test.go index fe15204c..de8b271c 100644 --- a/table/table_test.go +++ b/table/table_test.go @@ -22,54 +22,40 @@ import ( "time" ) -func TestTableCreateDestDefault(t *testing.T) { - td := NewTableDefault(0) - nlri := bgp.NewNLRInfo(24, "13.2.3.1") - cd := td.createDest(nlri) - assert.Nil(t, cd) -} - -func TestTableTableKeyDefault(t *testing.T) { - td := NewTableDefault(0) - nlri := bgp.NewNLRInfo(24, "13.2.3.1") - tk := td.tableKey(nlri) - assert.Equal(t, tk, "") -} - func TestTableDeleteDestByNlri(t *testing.T) { peerT := TableCreatePeer() pathT := TableCreatePath(peerT) - ipv4t := NewIPv4Table(0) + ipv4t := NewTable(bgp.RF_IPv4_UC) for _, path := range pathT { tableKey := ipv4t.tableKey(path.GetNlri()) - dest := ipv4t.createDest(path.GetNlri()) + dest := NewDestination(path.GetNlri()) ipv4t.setDestination(tableKey, dest) } tableKey := ipv4t.tableKey(pathT[0].GetNlri()) gdest := ipv4t.getDestination(tableKey) - rdest := deleteDestByNlri(ipv4t, pathT[0].GetNlri()) + rdest := ipv4t.deleteDestByNlri(pathT[0].GetNlri()) assert.Equal(t, rdest, gdest) } func TestTableDeleteDest(t *testing.T) { peerT := TableCreatePeer() pathT := TableCreatePath(peerT) - ipv4t := NewIPv4Table(0) + ipv4t := NewTable(bgp.RF_IPv4_UC) for _, path := range pathT { tableKey := ipv4t.tableKey(path.GetNlri()) - dest := ipv4t.createDest(path.GetNlri()) + dest := NewDestination(path.GetNlri()) ipv4t.setDestination(tableKey, dest) } tableKey := ipv4t.tableKey(pathT[0].GetNlri()) - dest := ipv4t.createDest(pathT[0].GetNlri()) + dest := NewDestination(pathT[0].GetNlri()) ipv4t.setDestination(tableKey, dest) - deleteDest(ipv4t, dest) + ipv4t.deleteDest(dest) gdest := ipv4t.getDestination(tableKey) assert.Nil(t, gdest) } func TestTableGetRouteFamily(t *testing.T) { - ipv4t := NewIPv4Table(0) + ipv4t := NewTable(bgp.RF_IPv4_UC) rf := ipv4t.GetRoutefamily() assert.Equal(t, rf, bgp.RF_IPv4_UC) } @@ -77,11 +63,11 @@ func TestTableGetRouteFamily(t *testing.T) { func TestTableSetDestinations(t *testing.T) { peerT := TableCreatePeer() pathT := TableCreatePath(peerT) - ipv4t := NewIPv4Table(0) - destinations := make(map[string]Destination) + ipv4t := NewTable(bgp.RF_IPv4_UC) + destinations := make(map[string]*Destination) for _, path := range pathT { tableKey := ipv4t.tableKey(path.GetNlri()) - dest := ipv4t.createDest(path.GetNlri()) + dest := NewDestination(path.GetNlri()) destinations[tableKey] = dest } ipv4t.setDestinations(destinations) @@ -91,11 +77,11 @@ func TestTableSetDestinations(t *testing.T) { func TestTableGetDestinations(t *testing.T) { peerT := DestCreatePeer() pathT := DestCreatePath(peerT) - ipv4t := NewIPv4Table(0) - destinations := make(map[string]Destination) + ipv4t := NewTable(bgp.RF_IPv4_UC) + destinations := make(map[string]*Destination) for _, path := range pathT { tableKey := ipv4t.tableKey(path.GetNlri()) - dest := ipv4t.createDest(path.GetNlri()) + dest := NewDestination(path.GetNlri()) destinations[tableKey] = dest } ipv4t.setDestinations(destinations) @@ -111,17 +97,17 @@ func TableCreatePeer() []*PeerInfo { return peerT } -func TableCreatePath(peerT []*PeerInfo) []Path { +func TableCreatePath(peerT []*PeerInfo) []*Path { bgpMsgT1 := updateMsgT1() bgpMsgT2 := updateMsgT2() bgpMsgT3 := updateMsgT3() - pathT := make([]Path, 3) + pathT := make([]*Path, 3) for i, msg := range []*bgp.BGPMessage{bgpMsgT1, bgpMsgT2, bgpMsgT3} { updateMsgT := msg.Body.(*bgp.BGPUpdate) nlriList := updateMsgT.NLRI pathAttributes := updateMsgT.PathAttributes nlri_info := nlriList[0] - pathT[i], _ = CreatePath(peerT[i], &nlri_info, pathAttributes, false, time.Now()) + pathT[i] = NewPath(peerT[i], &nlri_info, false, pathAttributes, false, time.Now()) } return pathT } |