summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/server.go12
-rw-r--r--server/zclient.go41
2 files changed, 53 insertions, 0 deletions
diff --git a/server/server.go b/server/server.go
index b8d54b8c..5b644dfe 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1183,6 +1183,18 @@ func (s *BgpServer) DeletePath(uuid []byte, f bgp.RouteFamily, vrfId string, pat
}, true)
}
+func (s *BgpServer) UpdatePath(vrfId string, pathList []*table.Path) error {
+ err := s.mgmtOperation(func() error {
+ if err := s.fixupApiPath(vrfId, pathList); err != nil {
+ return err
+ }
+
+ s.propagateUpdate(nil, pathList)
+ return nil
+ }, true)
+ return err
+}
+
func (s *BgpServer) Start(c *config.Global) error {
return s.mgmtOperation(func() error {
if err := config.SetDefaultGlobalConfigValues(c); err != nil {
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)