diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-02-15 12:34:07 +0900 |
---|---|---|
committer | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-03-06 11:11:54 +0900 |
commit | 2c35b2446d571650e2124fde5e12463b62a33b9e (patch) | |
tree | 1812497786528a1b7f03c1eba2b4f164e0deab16 /server/zclient.go | |
parent | 7ba46c1af545514f7d185ecd53cff3d5e62ad194 (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.go | 41 |
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) |