diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2018-07-07 13:48:38 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2018-07-07 20:44:25 +0900 |
commit | c4775c42510d1f1ddd55036dc19e982712fa6a0b (patch) | |
tree | 6ec8b61d4338c809e239e3003a2d32d480898e22 /table/table_manager.go | |
parent | b3079759aa13172fcb548a83da9a9653d8d5fed4 (diff) |
follow Standard Go Project Layout
https://github.com/golang-standards/project-layout
Now you can see clearly what are private and public library code.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'table/table_manager.go')
-rw-r--r-- | table/table_manager.go | 356 |
1 files changed, 0 insertions, 356 deletions
diff --git a/table/table_manager.go b/table/table_manager.go deleted file mode 100644 index 26581cea..00000000 --- a/table/table_manager.go +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package table - -import ( - "bytes" - "fmt" - "net" - "time" - - farm "github.com/dgryski/go-farm" - log "github.com/sirupsen/logrus" - - "github.com/osrg/gobgp/packet/bgp" -) - -const ( - GLOBAL_RIB_NAME = "global" -) - -func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo, timestamp time.Time) []*Path { - update := m.Body.(*bgp.BGPUpdate) - - if y, f := update.IsEndOfRib(); y { - // this message has no normal updates or withdrawals. - return []*Path{NewEOR(f)} - } - - adds := make([]bgp.AddrPrefixInterface, 0, len(update.NLRI)) - for _, nlri := range update.NLRI { - adds = append(adds, nlri) - } - - dels := make([]bgp.AddrPrefixInterface, 0, len(update.WithdrawnRoutes)) - for _, nlri := range update.WithdrawnRoutes { - dels = append(dels, nlri) - } - - attrs := make([]bgp.PathAttributeInterface, 0, len(update.PathAttributes)) - var reach *bgp.PathAttributeMpReachNLRI - for _, attr := range update.PathAttributes { - switch a := attr.(type) { - case *bgp.PathAttributeMpReachNLRI: - reach = a - case *bgp.PathAttributeMpUnreachNLRI: - l := make([]bgp.AddrPrefixInterface, 0, len(a.Value)) - l = append(l, a.Value...) - dels = append(dels, l...) - default: - attrs = append(attrs, attr) - } - } - - listLen := len(adds) + len(dels) - if reach != nil { - listLen += len(reach.Value) - } - - var hash uint32 - if len(adds) > 0 || reach != nil { - total := bytes.NewBuffer(make([]byte, 0)) - for _, a := range attrs { - b, _ := a.Serialize() - total.Write(b) - } - hash = farm.Hash32(total.Bytes()) - } - - pathList := make([]*Path, 0, listLen) - for _, nlri := range adds { - p := NewPath(peerInfo, nlri, false, attrs, timestamp, false) - p.SetHash(hash) - pathList = append(pathList, p) - } - if reach != nil { - reachAttrs := make([]bgp.PathAttributeInterface, len(attrs)+1) - copy(reachAttrs, attrs) - // we sort attributes when creating a bgp message from paths - reachAttrs[len(reachAttrs)-1] = reach - - for _, nlri := range reach.Value { - p := NewPath(peerInfo, nlri, false, reachAttrs, timestamp, false) - p.SetHash(hash) - pathList = append(pathList, p) - } - } - for _, nlri := range dels { - p := NewPath(peerInfo, nlri, true, []bgp.PathAttributeInterface{}, timestamp, false) - pathList = append(pathList, p) - } - return pathList -} - -type TableManager struct { - Tables map[bgp.RouteFamily]*Table - Vrfs map[string]*Vrf - rfList []bgp.RouteFamily -} - -func NewTableManager(rfList []bgp.RouteFamily) *TableManager { - t := &TableManager{ - Tables: make(map[bgp.RouteFamily]*Table), - Vrfs: make(map[string]*Vrf), - rfList: rfList, - } - for _, rf := range rfList { - t.Tables[rf] = NewTable(rf) - } - return t -} - -func (manager *TableManager) GetRFlist() []bgp.RouteFamily { - return manager.rfList -} - -func (manager *TableManager) AddVrf(name string, id uint32, rd bgp.RouteDistinguisherInterface, importRt, exportRt []bgp.ExtendedCommunityInterface, info *PeerInfo) ([]*Path, error) { - if _, ok := manager.Vrfs[name]; ok { - return nil, fmt.Errorf("vrf %s already exists", name) - } - log.WithFields(log.Fields{ - "Topic": "Vrf", - "Key": name, - "Rd": rd, - "ImportRt": importRt, - "ExportRt": exportRt, - }).Debugf("add vrf") - manager.Vrfs[name] = &Vrf{ - Name: name, - Id: id, - Rd: rd, - ImportRt: importRt, - ExportRt: exportRt, - } - msgs := make([]*Path, 0, len(importRt)) - nexthop := "0.0.0.0" - for _, target := range importRt { - nlri := bgp.NewRouteTargetMembershipNLRI(info.AS, target) - pattr := make([]bgp.PathAttributeInterface, 0, 2) - pattr = append(pattr, bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP)) - pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri})) - msgs = append(msgs, NewPath(info, nlri, false, pattr, time.Now(), false)) - } - return msgs, nil -} - -func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) { - if _, ok := manager.Vrfs[name]; !ok { - return nil, fmt.Errorf("vrf %s not found", name) - } - msgs := make([]*Path, 0) - vrf := manager.Vrfs[name] - for _, t := range manager.Tables { - msgs = append(msgs, t.deletePathsByVrf(vrf)...) - } - log.WithFields(log.Fields{ - "Topic": "Vrf", - "Key": vrf.Name, - "Rd": vrf.Rd, - "ImportRt": vrf.ImportRt, - "ExportRt": vrf.ExportRt, - }).Debugf("delete vrf") - delete(manager.Vrfs, name) - rtcTable := manager.Tables[bgp.RF_RTC_UC] - msgs = append(msgs, rtcTable.deleteRTCPathsByVrf(vrf, manager.Vrfs)...) - return msgs, nil -} - -func (tm *TableManager) update(newPath *Path) *Update { - t := tm.Tables[newPath.GetRouteFamily()] - t.validatePath(newPath) - dst := t.getOrCreateDest(newPath.GetNlri()) - u := dst.Calculate(newPath) - if len(dst.knownPathList) == 0 { - t.deleteDest(dst) - } - return u -} - -func (manager *TableManager) GetPathListByPeer(info *PeerInfo, rf bgp.RouteFamily) []*Path { - if t, ok := manager.Tables[rf]; ok { - pathList := make([]*Path, 0, len(t.destinations)) - for _, dst := range t.destinations { - for _, p := range dst.knownPathList { - if p.GetSource().Equal(info) { - pathList = append(pathList, p) - } - } - } - return pathList - } - return nil -} - -func (manager *TableManager) Update(newPath *Path) []*Update { - if newPath == nil || newPath.IsEOR() { - return nil - } - - // Except for a special case with EVPN, we'll have one destination. - updates := make([]*Update, 0, 1) - family := newPath.GetRouteFamily() - if _, ok := manager.Tables[family]; ok { - updates = append(updates, manager.update(newPath)) - - if family == bgp.RF_EVPN { - for _, p := range manager.handleMacMobility(newPath) { - updates = append(updates, manager.update(p)) - } - } - } - return updates -} - -// EVPN MAC MOBILITY HANDLING -// -// RFC7432 15. MAC Mobility -// -// A PE receiving a MAC/IP Advertisement route for a MAC address with a -// different Ethernet segment identifier and a higher sequence number -// than that which it had previously advertised withdraws its MAC/IP -// Advertisement route. -func (manager *TableManager) handleMacMobility(path *Path) []*Path { - pathList := make([]*Path, 0) - nlri := path.GetNlri().(*bgp.EVPNNLRI) - if path.IsWithdraw || path.IsLocal() || nlri.RouteType != bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT { - return nil - } - for _, path2 := range manager.GetPathList(GLOBAL_RIB_NAME, 0, []bgp.RouteFamily{bgp.RF_EVPN}) { - if !path2.IsLocal() || path2.GetNlri().(*bgp.EVPNNLRI).RouteType != bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT { - continue - } - f := func(p *Path) (bgp.EthernetSegmentIdentifier, net.HardwareAddr, int) { - nlri := p.GetNlri().(*bgp.EVPNNLRI) - d := nlri.RouteTypeData.(*bgp.EVPNMacIPAdvertisementRoute) - ecs := p.GetExtCommunities() - seq := -1 - for _, ec := range ecs { - if t, st := ec.GetTypes(); t == bgp.EC_TYPE_EVPN && st == bgp.EC_SUBTYPE_MAC_MOBILITY { - seq = int(ec.(*bgp.MacMobilityExtended).Sequence) - break - } - } - return d.ESI, d.MacAddress, seq - } - e1, m1, s1 := f(path) - e2, m2, s2 := f(path2) - if bytes.Equal(m1, m2) && !bytes.Equal(e1.Value, e2.Value) && s1 > s2 { - pathList = append(pathList, path2.Clone(true)) - } - } - return pathList -} - -func (manager *TableManager) tables(list ...bgp.RouteFamily) []*Table { - l := make([]*Table, 0, len(manager.Tables)) - if len(list) == 0 { - for _, v := range manager.Tables { - l = append(l, v) - } - return l - } - for _, f := range list { - if t, ok := manager.Tables[f]; ok { - l = append(l, t) - } - } - return l -} - -func (manager *TableManager) getDestinationCount(rfList []bgp.RouteFamily) int { - count := 0 - for _, t := range manager.tables(rfList...) { - count += len(t.GetDestinations()) - } - return count -} - -func (manager *TableManager) GetBestPathList(id string, as uint32, rfList []bgp.RouteFamily) []*Path { - if SelectionOptions.DisableBestPathSelection { - // Note: If best path selection disabled, there is no best path. - return nil - } - paths := make([]*Path, 0, manager.getDestinationCount(rfList)) - for _, t := range manager.tables(rfList...) { - paths = append(paths, t.Bests(id, as)...) - } - return paths -} - -func (manager *TableManager) GetBestMultiPathList(id string, rfList []bgp.RouteFamily) [][]*Path { - if !UseMultiplePaths.Enabled || SelectionOptions.DisableBestPathSelection { - // Note: If multi path not enabled or best path selection disabled, - // there is no best multi path. - return nil - } - paths := make([][]*Path, 0, manager.getDestinationCount(rfList)) - for _, t := range manager.tables(rfList...) { - paths = append(paths, t.MultiBests(id)...) - } - return paths -} - -func (manager *TableManager) GetPathList(id string, as uint32, rfList []bgp.RouteFamily) []*Path { - paths := make([]*Path, 0, manager.getDestinationCount(rfList)) - for _, t := range manager.tables(rfList...) { - paths = append(paths, t.GetKnownPathList(id, as)...) - } - return paths -} - -func (manager *TableManager) GetPathListWithNexthop(id string, rfList []bgp.RouteFamily, nexthop net.IP) []*Path { - paths := make([]*Path, 0, manager.getDestinationCount(rfList)) - for _, rf := range rfList { - if t, ok := manager.Tables[rf]; ok { - for _, path := range t.GetKnownPathList(id, 0) { - if path.GetNexthop().Equal(nexthop) { - paths = append(paths, path) - } - } - } - } - return paths -} - -func (manager *TableManager) GetDestination(path *Path) *Destination { - if path == nil { - return nil - } - family := path.GetRouteFamily() - t, ok := manager.Tables[family] - if !ok { - return nil - } - return t.GetDestination(path.GetNlri()) -} - -func (manager *TableManager) TableInfo(id string, as uint32, family bgp.RouteFamily) (*TableInfo, error) { - t, ok := manager.Tables[family] - if !ok { - return nil, fmt.Errorf("address family %s is not configured", family) - } - return t.Info(id, as), nil -} |