summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-05-01 10:06:42 +0000
committerISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-05-01 10:16:09 +0000
commit232b30117c8eafc5cae7aec81ce9fafe742bdd4b (patch)
tree235342a7345b6034f02a1864485a4c96e25d3ea2
parentcea5941db2dd9268ad35b5f494480350d747d404 (diff)
table: add support for route target constraint nlri
add rtc route $ gobgp global rib add 65000 77 -a rtc check it $ gobgp global rib -a rtc Network Next Hop AS_PATH Age Attrs *> 65001:65000:75 0.0.0.0 [65001] 00:15:35 [{Origin: IGP}] Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--config/default.go1
-rw-r--r--gobgp/main.go29
-rw-r--r--server/grpc_server.go2
-rw-r--r--server/peer.go27
-rw-r--r--table/destination.go12
-rw-r--r--table/message.go2
-rw-r--r--table/path.go20
-rw-r--r--table/table.go19
-rw-r--r--table/table_manager.go2
9 files changed, 113 insertions, 1 deletions
diff --git a/config/default.go b/config/default.go
index 2f1bedda..6e08a70e 100644
--- a/config/default.go
+++ b/config/default.go
@@ -35,6 +35,7 @@ func SetDefaultConfigValues(md toml.MetaData, bt *Bgp) error {
AfiSafi{AfiSafiName: "ipv6-unicast"},
AfiSafi{AfiSafiName: "l2vpn-evpn"},
AfiSafi{AfiSafiName: "encap"},
+ AfiSafi{AfiSafiName: "rtc"},
}
}
diff --git a/gobgp/main.go b/gobgp/main.go
index 634e95be..80bf6865 100644
--- a/gobgp/main.go
+++ b/gobgp/main.go
@@ -237,6 +237,8 @@ func checkAddressFamily() (*api.AddressFamily, error) {
rf = api.AF_EVPN
case "encap":
rf = api.AF_ENCAP
+ case "rtc":
+ rf = api.AF_RTC
case "":
e = fmt.Errorf("address family is not specified")
default:
@@ -409,6 +411,33 @@ func modPath(modtype string, eArgs []string) error {
path.Attrs = append(path.Attrs, attr)
}
+ case api.AF_RTC:
+ if !(len(eArgs) == 3 && eArgs[0] == "default") && len(eArgs) < 4 {
+ return fmt.Errorf("usage: global rib add <asn> <local admin> -a rtc")
+ }
+ var asn, admin int
+
+ if eArgs[0] != "default" {
+ asn, err = strconv.Atoi(eArgs[0])
+ if err != nil {
+ return fmt.Errorf("invalid asn: %s", eArgs[0])
+ }
+ admin, err = strconv.Atoi(eArgs[1])
+ if err != nil {
+ return fmt.Errorf("invalid local admin: %s", eArgs[1])
+ }
+ }
+ path.Nlri = &api.Nlri{
+ Af: rf,
+ RtNlri: &api.RTNlri{
+ Target: &api.ExtendedCommunity{
+ Type: api.EXTENDED_COMMUNITIE_TYPE_TWO_OCTET_AS_SPECIFIC,
+ Subtype: api.EXTENDED_COMMUNITIE_SUBTYPE_ROUTE_TARGET,
+ Asn: uint32(asn),
+ LocalAdmin: uint32(admin),
+ },
+ },
+ }
}
switch modtype {
case "add":
diff --git a/server/grpc_server.go b/server/grpc_server.go
index 01acaf3d..c218a4ac 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -56,6 +56,8 @@ func convertAf2Rf(af *api.AddressFamily) (bgp.RouteFamily, error) {
return bgp.RF_EVPN, nil
} else if af.Equal(api.AF_ENCAP) {
return bgp.RF_ENCAP, nil
+ } else if af.Equal(api.AF_RTC) {
+ return bgp.RF_RTC_UC, nil
}
return bgp.RouteFamily(0), fmt.Errorf("unsupported address family: %v", af)
diff --git a/server/peer.go b/server/peer.go
index 64235613..7af2653e 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -422,6 +422,33 @@ func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) {
}
}(path.Attrs)
+ case bgp.RF_RTC_UC:
+ var ec bgp.ExtendedCommunityInterface
+ target := path.Nlri.RtNlri.Target
+ ec_type := target.Type
+ ec_subtype := target.Subtype
+ switch ec_type {
+ case api.EXTENDED_COMMUNITIE_TYPE_TWO_OCTET_AS_SPECIFIC:
+ if target.Asn == 0 && target.LocalAdmin == 0 {
+ break
+ }
+ ec = &bgp.TwoOctetAsSpecificExtended{
+ SubType: bgp.ExtendedCommunityAttrSubType(ec_subtype),
+ AS: uint16(target.Asn),
+ LocalAdmin: target.LocalAdmin,
+ IsTransitive: true,
+ }
+ default:
+ result.ResponseErr = fmt.Errorf("Invalid endpoint ip address: %s", path.Nlri.Prefix)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return
+ }
+
+ nlri = bgp.NewRouteTargetMembershipNLRI(peer.globalConfig.As, ec)
+
+ pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri}))
+
default:
result.ResponseErr = fmt.Errorf("Unsupported address family: %s", rf)
grpcReq.ResponseCh <- result
diff --git a/table/destination.go b/table/destination.go
index bf4afe63..a01c6e04 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -1043,3 +1043,15 @@ func NewEncapDestination(nlri bgp.AddrPrefixInterface) *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,
+ }
+}
diff --git a/table/message.go b/table/message.go
index 70e2ffcd..5b444ce0 100644
--- a/table/message.go
+++ b/table/message.go
@@ -155,7 +155,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage {
return bgp.NewBGPUpdateMessage([]bgp.WithdrawnRoute{}, pathAttrs, []bgp.NLRInfo{*nlri})
}
}
- } else if rf == bgp.RF_IPv6_UC || rf == bgp.RF_EVPN || rf == bgp.RF_ENCAP {
+ } else if rf == bgp.RF_IPv6_UC || rf == bgp.RF_EVPN || rf == bgp.RF_ENCAP || rf == bgp.RF_RTC_UC {
if path.IsWithdraw() {
if msg != nil {
idx, _ := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI)
diff --git a/table/path.go b/table/path.go
index 88765d44..0d52d343 100644
--- a/table/path.go
+++ b/table/path.go
@@ -384,6 +384,9 @@ func CreatePath(source *PeerInfo, nlri bgp.AddrPrefixInterface, attrs []bgp.Path
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)
}
@@ -538,3 +541,20 @@ func (p *EncapPath) setPathDefault(pd *PathDefault) {
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/table.go b/table/table.go
index b1434732..22499f5a 100644
--- a/table/table.go
+++ b/table/table.go
@@ -353,3 +353,22 @@ func (t *EncapTable) createDest(nlri bgp.AddrPrefixInterface) Destination {
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 *RouteTargetTable) tableKey(nlri bgp.AddrPrefixInterface) string {
+ return nlri.String()
+}
diff --git a/table/table_manager.go b/table/table_manager.go
index d4da1735..8d3b18ca 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -131,6 +131,8 @@ func NewTableManager(owner string, rfList []bgp.RouteFamily) *TableManager {
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.owner = owner