summaryrefslogtreecommitdiffhomepage
path: root/table/table_manager.go
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2018-07-07 13:48:38 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2018-07-07 20:44:25 +0900
commitc4775c42510d1f1ddd55036dc19e982712fa6a0b (patch)
tree6ec8b61d4338c809e239e3003a2d32d480898e22 /table/table_manager.go
parentb3079759aa13172fcb548a83da9a9653d8d5fed4 (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.go356
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
-}