diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2015-08-30 21:36:41 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-31 22:48:50 +0900 |
commit | 375e1d65b2c90c3d287b83633ec13efde9aa62a2 (patch) | |
tree | 80980c59f300924005b674d5e0beacae85c7acab /table | |
parent | 955409c37ce17daf346e30aa1d1e2d40767ebb43 (diff) |
server: support route reflector behavior
scenario_test is also added
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'table')
-rw-r--r-- | table/destination.go | 12 | ||||
-rw-r--r-- | table/path.go | 40 |
2 files changed, 47 insertions, 5 deletions
diff --git a/table/destination.go b/table/destination.go index 290830a4..5889fb5b 100644 --- a/table/destination.go +++ b/table/destination.go @@ -52,11 +52,13 @@ func CidrToRadixkey(cidr string) string { } type PeerInfo struct { - AS uint32 - ID net.IP - LocalAS uint32 - LocalID net.IP - Address net.IP + AS uint32 + ID net.IP + LocalAS uint32 + LocalID net.IP + Address net.IP + RouteReflectorClient bool + RouteReflectorClusterID net.IP } func (lhs *PeerInfo) Equal(rhs *PeerInfo) bool { diff --git a/table/path.go b/table/path.go index 62f0e437..6dbb1f24 100644 --- a/table/path.go +++ b/table/path.go @@ -118,6 +118,32 @@ func (path *Path) UpdatePathAttrs(global *config.Global, peer *config.Neighbor) } else { path.pathAttrs[idx] = p } + + // RFC4456: BGP Route Reflection + // 8. Avoiding Routing Information Loops + info := path.source + if peer.RouteReflector.RouteReflectorConfig.RouteReflectorClient { + // This attribute will carry the BGP Identifier of the originator of the route in the local AS. + // A BGP speaker SHOULD NOT create an ORIGINATOR_ID attribute if one already exists. + idx, _ = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGINATOR_ID) + if idx < 0 { + p := bgp.NewPathAttributeOriginatorId(info.ID.String()) + path.pathAttrs = append(path.pathAttrs, p) + } + // When an RR reflects a route, it MUST prepend the local CLUSTER_ID to the CLUSTER_LIST. + // If the CLUSTER_LIST is empty, it MUST create a new one. + idx, _ = path.getPathAttr(bgp.BGP_ATTR_TYPE_CLUSTER_LIST) + id := string(peer.RouteReflector.RouteReflectorConfig.RouteReflectorClusterId) + if idx < 0 { + p := bgp.NewPathAttributeClusterList([]string{id}) + path.pathAttrs = append(path.pathAttrs, p) + } else { + p := path.pathAttrs[idx].(*bgp.PathAttributeClusterList) + p.Value = append([]net.IP{net.ParseIP(id).To4()}, p.Value...) + path.pathAttrs[idx] = p + } + } + } else { log.WithFields(log.Fields{ "Topic": "Peer", @@ -582,6 +608,20 @@ func (path *Path) SetMed(med int64, doReplace bool) error { return nil } +func (path *Path) GetOriginatorID() net.IP { + if _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGINATOR_ID); attr != nil { + return attr.(*bgp.PathAttributeOriginatorId).Value + } + return nil +} + +func (path *Path) GetClusterList() []net.IP { + if _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_CLUSTER_LIST); attr != nil { + return attr.(*bgp.PathAttributeClusterList).Value + } + return nil +} + func (lhs *Path) Equal(rhs *Path) bool { if rhs == nil { return false |