summaryrefslogtreecommitdiffhomepage
path: root/server/zclient.go
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2017-02-15 12:34:07 +0900
committerIWASE Yusuke <iwase.yusuke0@gmail.com>2017-03-06 11:11:54 +0900
commit2c35b2446d571650e2124fde5e12463b62a33b9e (patch)
tree1812497786528a1b7f03c1eba2b4f164e0deab16 /server/zclient.go
parent7ba46c1af545514f7d185ecd53cff3d5e62ad194 (diff)
server/zclient: Update nexthop state based on NEXTHOP_UPDATE
This patch enables server/zclient to update the metric or the reachability state to the nexthop for implementing the Nexthop Tracking features. Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Diffstat (limited to 'server/zclient.go')
-rw-r--r--server/zclient.go41
1 files changed, 41 insertions, 0 deletions
diff --git a/server/zclient.go b/server/zclient.go
index 622a0c2a..537da7b6 100644
--- a/server/zclient.go
+++ b/server/zclient.go
@@ -284,6 +284,40 @@ func createPathFromIPRouteMessage(m *zebra.Message) *table.Path {
return path
}
+func createPathListFromNexthopUpdateMessage(m *zebra.Message, manager *table.TableManager) (pathList, error) {
+ body := m.Body.(*zebra.NexthopUpdateBody)
+ isNexthopInvalid := len(body.Nexthops) == 0
+
+ var rfList []bgp.RouteFamily
+ switch body.Family {
+ case uint16(syscall.AF_INET):
+ rfList = []bgp.RouteFamily{bgp.RF_IPv4_UC, bgp.RF_IPv4_VPN}
+ case uint16(syscall.AF_INET6):
+ rfList = []bgp.RouteFamily{bgp.RF_IPv6_UC, bgp.RF_IPv6_VPN}
+ default:
+ return nil, fmt.Errorf("invalid address family: %d", body.Family)
+ }
+
+ paths := manager.GetPathListWithNexthop(table.GLOBAL_RIB_NAME, rfList, body.Prefix)
+ updatedPathList := make(pathList, 0, len(paths))
+ for _, path := range paths {
+ newPath := path.Clone(false)
+ if isNexthopInvalid {
+ // If NEXTHOP_UPDATE message does NOT contain any nexthop,
+ // invalidates the nexthop reachability.
+ newPath.IsNexthopInvalid = true
+ } else {
+ // If NEXTHOP_UPDATE message contains valid nexthops,
+ // copies Metric into MED.
+ newPath.IsNexthopInvalid = false
+ newPath.SetMed(int64(body.Metric), true)
+ }
+ updatedPathList = append(updatedPathList, newPath)
+ }
+
+ return updatedPathList, nil
+}
+
type zebraClient struct {
client *zebra.Client
server *BgpServer
@@ -312,6 +346,13 @@ func (z *zebraClient) loop() {
log.Errorf("failed to add path from zebra: %s", p)
}
}
+ case *zebra.NexthopUpdateBody:
+ body := msg.Body.(*zebra.NexthopUpdateBody)
+ if paths, err := createPathListFromNexthopUpdateMessage(msg, z.server.globalRib); err != nil {
+ log.Errorf("failed to create updated path list related to nexthop %s", body.Prefix.String())
+ } else if err = z.server.UpdatePath("", paths); err != nil {
+ log.Errorf("failed to update path related to nexthop %s", body.Prefix.String())
+ }
}
case ev := <-w.Event():
msg := ev.(*WatchEventBestPath)