summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2018-02-22 09:51:07 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2018-02-23 14:40:48 +0900
commitaf84d6d79cec19209188f1f40d575b64aea23586 (patch)
treecb00fb3e6a16c884a8fd5d62b3341eeffe152f5f
parent77a3484a1223033065df7986987a7ad0b0043ab7 (diff)
zclient: Avoid directly access to RIB
In order to avoid races, zclient should not access to RIB without calling APIs of BgpServer. But currently zclient directly accesses to the global RIB when handling NEXTHO_UPDATE messages. This patch fixes this problem by calling BgpServer.GetRib(). Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
-rw-r--r--server/zclient.go46
1 files changed, 28 insertions, 18 deletions
diff --git a/server/zclient.go b/server/zclient.go
index 93cdac1b..7c311643 100644
--- a/server/zclient.go
+++ b/server/zclient.go
@@ -381,21 +381,19 @@ func createPathFromIPRouteMessage(m *zebra.Message) *table.Path {
return path
}
-func createPathListFromNexthopUpdateMessage(m *zebra.Message, manager *table.TableManager, nhtManager *nexthopTrackingManager) (pathList, *zebra.NexthopRegisterBody, error) {
- body := m.Body.(*zebra.NexthopUpdateBody)
- isNexthopInvalid := len(body.Nexthops) == 0
-
- var rfList []bgp.RouteFamily
+func rfListFromNexthopUpdateBody(body *zebra.NexthopUpdateBody) (rfList []bgp.RouteFamily) {
switch body.Family {
case uint16(syscall.AF_INET):
- rfList = []bgp.RouteFamily{bgp.RF_IPv4_UC, bgp.RF_IPv4_VPN}
+ return []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, nil, fmt.Errorf("invalid address family: %d", body.Family)
+ return []bgp.RouteFamily{bgp.RF_IPv6_UC, bgp.RF_IPv6_VPN}
}
+ return nil
+}
- paths := manager.GetPathListWithNexthop(table.GLOBAL_RIB_NAME, rfList, body.Prefix)
+func createPathListFromNexthopUpdateMessage(body *zebra.NexthopUpdateBody, manager *table.TableManager, nhtManager *nexthopTrackingManager) (pathList, *zebra.NexthopRegisterBody, error) {
+ isNexthopInvalid := len(body.Nexthops) == 0
+ paths := manager.GetPathListWithNexthop(table.GLOBAL_RIB_NAME, rfListFromNexthopUpdateBody(body), body.Prefix)
pathsLen := len(paths)
// If there is no path bound for the updated nexthop, send
@@ -466,14 +464,26 @@ func (z *zebraClient) loop() {
}
}
case *zebra.NexthopUpdateBody:
- if z.nhtManager != nil {
- if paths, b, err := createPathListFromNexthopUpdateMessage(msg, z.server.globalRib, z.nhtManager); err != nil {
- log.Errorf("failed to create updated path list related to nexthop %s", body.Prefix.String())
- } else {
- z.nhtManager.scheduleUpdate(paths)
- if b != nil {
- z.client.SendNexthopRegister(msg.Header.VrfId, b, true)
- }
+ if z.nhtManager == nil {
+ continue
+ }
+ manager := &table.TableManager{
+ Tables: make(map[bgp.RouteFamily]*table.Table),
+ }
+ for _, rf := range rfListFromNexthopUpdateBody(body) {
+ rib, err := z.server.GetRib("", rf, nil)
+ if err != nil {
+ log.Errorf("failed to get global rib by family %s", rf.String())
+ continue
+ }
+ manager.Tables[rf] = rib
+ }
+ if paths, b, err := createPathListFromNexthopUpdateMessage(body, manager, z.nhtManager); err != nil {
+ log.Errorf("failed to create updated path list related to nexthop %s", body.Prefix.String())
+ } else {
+ z.nhtManager.scheduleUpdate(paths)
+ if b != nil {
+ z.client.SendNexthopRegister(msg.Header.VrfId, b, true)
}
}
}