summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-08-17 15:54:07 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-08-19 13:29:33 +0900
commitc14a63575c62addaf96c78f4de9aef6e3c430f0f (patch)
tree272698e91435a7cd0a765dee37069096f4052501
parent22b43f7ae7daf381520a529157be4c71c11c2bc8 (diff)
table: withdraw self-generated vrfed routes when a vrf deleted
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--packet/bgp.go21
-rw-r--r--server/server.go48
-rw-r--r--table/table.go25
-rw-r--r--table/table_manager.go42
4 files changed, 103 insertions, 33 deletions
diff --git a/packet/bgp.go b/packet/bgp.go
index a38f4bca..c910f310 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -1395,6 +1395,10 @@ func (er *EVPNEthernetAutoDiscoveryRoute) String() string {
return fmt.Sprintf("[type:A-D][rd:%s][esi:%s][etag:%d][label:%d]", er.RD, er.ESI, er.ETag, er.Label)
}
+func (er *EVPNEthernetAutoDiscoveryRoute) rd() RouteDistinguisherInterface {
+ return er.RD
+}
+
type EVPNMacIPAdvertisementRoute struct {
RD RouteDistinguisherInterface
ESI EthernetSegmentIdentifier
@@ -1487,6 +1491,10 @@ func (er *EVPNMacIPAdvertisementRoute) String() string {
return fmt.Sprintf("[type:macadv][rd:%s][esi:%s][etag:%d][mac:%s][ip:%s][labels:%v]", er.RD, er.ESI.String(), er.ETag, er.MacAddress, er.IPAddress, er.Labels)
}
+func (er *EVPNMacIPAdvertisementRoute) rd() RouteDistinguisherInterface {
+ return er.RD
+}
+
type EVPNMulticastEthernetTagRoute struct {
RD RouteDistinguisherInterface
ETag uint32
@@ -1541,6 +1549,10 @@ func (er *EVPNMulticastEthernetTagRoute) String() string {
return fmt.Sprintf("[type:multicast][rd:%s][etag:%d][ip:%s]", er.RD, er.ETag, er.IPAddress)
}
+func (er *EVPNMulticastEthernetTagRoute) rd() RouteDistinguisherInterface {
+ return er.RD
+}
+
type EVPNEthernetSegmentRoute struct {
RD RouteDistinguisherInterface
ESI EthernetSegmentIdentifier
@@ -1595,12 +1607,17 @@ type EVPNRouteTypeInterface interface {
DecodeFromBytes([]byte) error
Serialize() ([]byte, error)
String() string
+ rd() RouteDistinguisherInterface
}
func (er *EVPNEthernetSegmentRoute) String() string {
return fmt.Sprintf("[type:esi][rd:%s][esi:%d][ip:%s]", er.RD, er.ESI, er.IPAddress)
}
+func (er *EVPNEthernetSegmentRoute) rd() RouteDistinguisherInterface {
+ return er.RD
+}
+
func getEVPNRouteType(t uint8) (EVPNRouteTypeInterface, error) {
switch t {
case EVPN_ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY:
@@ -1686,6 +1703,10 @@ func (n *EVPNNLRI) MarshalJSON() ([]byte, error) {
})
}
+func (n *EVPNNLRI) RD() RouteDistinguisherInterface {
+ return n.RouteTypeData.rd()
+}
+
func NewEVPNNLRI(routetype uint8, length uint8, routetypedata EVPNRouteTypeInterface) *EVPNNLRI {
return &EVPNNLRI{
routetype,
diff --git a/server/server.go b/server/server.go
index 11fd807a..db1ce6d7 100644
--- a/server/server.go
+++ b/server/server.go
@@ -967,13 +967,11 @@ ERR:
}
-func (server *BgpServer) handleVrfMod(arg *api.ModVrfArguments) error {
- vrfs := server.localRibMap[GLOBAL_RIB_NAME].rib.Vrfs
+func (server *BgpServer) handleVrfMod(arg *api.ModVrfArguments) ([]*table.Path, error) {
+ manager := server.localRibMap[GLOBAL_RIB_NAME].rib
+ var msgs []*table.Path
switch arg.Operation {
case api.Operation_ADD:
- if _, ok := vrfs[arg.Vrf.Name]; ok {
- return fmt.Errorf("vrf %s already exists", arg.Vrf.Name)
- }
rd := bgp.GetRouteDistinguisher(arg.Vrf.Rd)
f := func(bufs [][]byte) ([]bgp.ExtendedCommunityInterface, error) {
ret := make([]bgp.ExtendedCommunityInterface, 0, len(bufs))
@@ -988,42 +986,26 @@ func (server *BgpServer) handleVrfMod(arg *api.ModVrfArguments) error {
}
importRt, err := f(arg.Vrf.ImportRt)
if err != nil {
- return err
+ return nil, err
}
exportRt, err := f(arg.Vrf.ImportRt)
if err != nil {
- return err
+ return nil, err
}
- log.WithFields(log.Fields{
- "Topic": "Vrf",
- "Key": arg.Vrf.Name,
- "Rd": rd,
- "ImportRt": importRt,
- "ExportRt": exportRt,
- }).Debugf("add vrf")
- vrfs[arg.Vrf.Name] = &table.Vrf{
- Name: arg.Vrf.Name,
- Rd: rd,
- ImportRt: importRt,
- ExportRt: exportRt,
+ err = manager.AddVrf(arg.Vrf.Name, rd, importRt, exportRt)
+ if err != nil {
+ return nil, err
}
case api.Operation_DEL:
- if _, ok := vrfs[arg.Vrf.Name]; !ok {
- return fmt.Errorf("vrf %s not found", arg.Vrf.Name)
+ var err error
+ msgs, err = manager.DeleteVrf(arg.Vrf.Name)
+ if err != nil {
+ return nil, err
}
- vrf := vrfs[arg.Vrf.Name]
- log.WithFields(log.Fields{
- "Topic": "Vrf",
- "Key": vrf.Name,
- "Rd": vrf.Rd,
- "ImportRt": vrf.ImportRt,
- "ExportRt": vrf.ExportRt,
- }).Debugf("delete vrf")
- delete(vrfs, arg.Vrf.Name)
default:
- return fmt.Errorf("unknown operation:", arg.Operation)
+ return nil, fmt.Errorf("unknown operation:", arg.Operation)
}
- return nil
+ return msgs, nil
}
func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path {
@@ -1074,7 +1056,7 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path {
goto END
case REQ_VRF_MOD:
arg := req.Data.(*api.ModVrfArguments)
- result.ResponseErr = server.handleVrfMod(arg)
+ msgs, result.ResponseErr = server.handleVrfMod(arg)
default:
result.ResponseErr = fmt.Errorf("unknown request type:", req.RequestType)
}
diff --git a/table/table.go b/table/table.go
index a5f867d4..3bc5bb3f 100644
--- a/table/table.go
+++ b/table/table.go
@@ -69,6 +69,31 @@ func (t *Table) DeleteDestByPeer(peerInfo *PeerInfo) []*Destination {
return changedDests
}
+func (t *Table) deletePathsByVrf(vrf *Vrf) []*Path {
+ pathList := make([]*Path, 0)
+ for _, dest := range t.destinations {
+ for _, p := range dest.GetKnownPathList() {
+ var rd bgp.RouteDistinguisherInterface
+ nlri := p.GetNlri()
+ switch nlri.(type) {
+ case *bgp.LabeledVPNIPAddrPrefix:
+ rd = nlri.(*bgp.LabeledVPNIPAddrPrefix).RD
+ case *bgp.LabeledVPNIPv6AddrPrefix:
+ rd = nlri.(*bgp.LabeledVPNIPv6AddrPrefix).RD
+ case *bgp.EVPNNLRI:
+ rd = nlri.(*bgp.EVPNNLRI).RD()
+ default:
+ return pathList
+ }
+ if p.IsLocal() && vrf.Rd.String() == rd.String() {
+ p.IsWithdraw = true
+ pathList = append(pathList, p)
+ }
+ }
+ }
+ return pathList
+}
+
func (t *Table) deleteDestByNlri(nlri bgp.AddrPrefixInterface) *Destination {
destinations := t.GetDestinations()
dest := destinations[t.tableKey(nlri)]
diff --git a/table/table_manager.go b/table/table_manager.go
index 41630246..e44babe7 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -17,6 +17,7 @@ package table
import (
"bytes"
+ "fmt"
log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet"
"net"
@@ -134,6 +135,47 @@ func (manager *TableManager) OwnerName() string {
return manager.owner
}
+func (manager *TableManager) AddVrf(name string, rd bgp.RouteDistinguisherInterface, importRt, exportRt []bgp.ExtendedCommunityInterface) error {
+ if _, ok := manager.Vrfs[name]; ok {
+ return 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,
+ Rd: rd,
+ ImportRt: importRt,
+ ExportRt: exportRt,
+ }
+ return 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)
+ return msgs, nil
+}
+
func (manager *TableManager) calculate(destinationList []*Destination) ([]*Path, error) {
newPaths := make([]*Path, 0)