diff --git a/src/yangerd/internal/collector/routing.go b/src/yangerd/internal/collector/routing.go index 554d0a32..410a2e4b 100644 --- a/src/yangerd/internal/collector/routing.go +++ b/src/yangerd/internal/collector/routing.go @@ -129,7 +129,7 @@ func (c *RoutingCollector) collectOSPF(ctx context.Context) interface{} { } ospf["ietf-ospf:address-family"] = "ipv4" - var areas []interface{} + areas := make([]interface{}, 0) areasRaw, _ := data["areas"].(map[string]interface{}) for areaID, valRaw := range areasRaw { values, ok := valRaw.(map[string]interface{}) @@ -145,7 +145,7 @@ func (c *RoutingCollector) collectOSPF(ctx context.Context) interface{} { area["ietf-ospf:area-type"] = at } - var interfaces []interface{} + interfaces := make([]interface{}, 0) ifacesRaw, _ := values["interfaces"].([]interface{}) for _, ifaceRaw := range ifacesRaw { iface, ok := ifaceRaw.(map[string]interface{}) @@ -218,7 +218,7 @@ func (c *RoutingCollector) collectOSPF(ctx context.Context) interface{} { } } - var neighbors []interface{} + neighbors := make([]interface{}, 0) neighsRaw, _ := iface["neighbors"].([]interface{}) for _, neighRaw := range neighsRaw { neigh, ok := neighRaw.(map[string]interface{}) @@ -351,7 +351,7 @@ func (c *RoutingCollector) addOSPFRoutes(ctx context.Context, ospf map[string]in route["route-tag"] = v } - var nexthops []interface{} + nexthops := make([]interface{}, 0) hopsRaw, _ := info["nexthops"].([]interface{}) for _, hopRaw := range hopsRaw { hop, ok := hopRaw.(map[string]interface{}) diff --git a/src/yangerd/internal/zapi/zapi.go b/src/yangerd/internal/zapi/zapi.go index a1993fba..21a5c4c0 100644 --- a/src/yangerd/internal/zapi/zapi.go +++ b/src/yangerd/internal/zapi/zapi.go @@ -62,13 +62,14 @@ const ( RouteSystem RouteType = 0 RouteKernel RouteType = 1 RouteConnect RouteType = 2 - RouteStatic RouteType = 3 - RouteRIP RouteType = 4 - RouteRIPNG RouteType = 5 - RouteOSPF RouteType = 6 - RouteOSPF6 RouteType = 7 - RouteISIS RouteType = 8 - RouteBGP RouteType = 9 + RouteLocal RouteType = 3 + RouteStatic RouteType = 4 + RouteRIP RouteType = 5 + RouteRIPNG RouteType = 6 + RouteOSPF RouteType = 7 + RouteOSPF6 RouteType = 8 + RouteISIS RouteType = 9 + RouteBGP RouteType = 10 ) // AFI values. diff --git a/src/yangerd/internal/zapiwatcher/zapiwatcher.go b/src/yangerd/internal/zapiwatcher/zapiwatcher.go index fc10e891..540c860c 100644 --- a/src/yangerd/internal/zapiwatcher/zapiwatcher.go +++ b/src/yangerd/internal/zapiwatcher/zapiwatcher.go @@ -27,6 +27,7 @@ const ( var subscribeTypes = []zapi.RouteType{ zapi.RouteKernel, zapi.RouteConnect, + zapi.RouteLocal, zapi.RouteStatic, zapi.RouteRIP, zapi.RouteOSPF, @@ -35,9 +36,10 @@ var subscribeTypes = []zapi.RouteType{ var routeTypeToProtocol = map[zapi.RouteType]string{ zapi.RouteKernel: "infix-routing:kernel", zapi.RouteConnect: "ietf-routing:direct", + zapi.RouteLocal: "ietf-routing:direct", zapi.RouteStatic: "ietf-routing:static", zapi.RouteOSPF: "ietf-ospf:ospfv2", - zapi.RouteRIP: "ietf-rip:ripv2", + zapi.RouteRIP: "ietf-rip:rip", } type ZAPIWatcher struct { @@ -118,6 +120,7 @@ func (w *ZAPIWatcher) connect(ctx context.Context) (net.Conn, error) { conn.Close() return nil, fmt.Errorf("send redistribute-add: %w", err) } + w.log.Debug("zapi watcher: subscribed", "afi", afi, "routeType", rt) } } @@ -142,20 +145,34 @@ func (w *ZAPIWatcher) processMessages(ctx context.Context, conn net.Conn) error } func (w *ZAPIWatcher) handleMessage(hdr zapi.Header, body []byte) { + w.log.Debug("zapi watcher: message", "cmd", hdr.Command, "vrf", hdr.VrfID, "len", hdr.Length) + switch hdr.Command { case zapi.CmdRedistRouteAdd: route, err := zapi.DecodeRoute(body) if err != nil { - w.log.Warn("zapi watcher: decode route add", "err", err) + w.log.Warn("zapi watcher: decode route add", "err", err, "bodyLen", len(body)) return } + w.log.Debug("zapi watcher: route add", + "type", route.Type, + "prefix", route.Prefix.String(), + "distance", route.Distance, + "metric", route.Metric, + "nexthops", len(route.Nexthops), + "msg", route.Message, + ) w.addRoute(route) case zapi.CmdRedistRouteDel: route, err := zapi.DecodeRoute(body) if err != nil { - w.log.Warn("zapi watcher: decode route del", "err", err) + w.log.Warn("zapi watcher: decode route del", "err", err, "bodyLen", len(body)) return } + w.log.Debug("zapi watcher: route del", + "type", route.Type, + "prefix", route.Prefix.String(), + ) w.deleteRoute(route) } } @@ -166,8 +183,10 @@ func (w *ZAPIWatcher) addRoute(route *zapi.Route) { w.mu.Lock() w.routes[key] = transformRoute(route) + routeCount := len(w.routes) w.mu.Unlock() + w.log.Debug("zapi watcher: stored route", "key", key, "totalRoutes", routeCount) w.writeRibs() } @@ -275,7 +294,7 @@ func transformRoute(route *zapi.Route) json.RawMessage { routeNode := map[string]any{ destKey: route.Prefix.String(), "source-protocol": routeProtocol(route.Type), - "route-preference": route.Metric, + "route-preference": route.Distance, "next-hop": map[string]any{ "next-hop-list": map[string]any{ "next-hop": nextHops, diff --git a/src/yangerd/internal/zapiwatcher/zapiwatcher_test.go b/src/yangerd/internal/zapiwatcher/zapiwatcher_test.go index 4741773a..39904ad8 100644 --- a/src/yangerd/internal/zapiwatcher/zapiwatcher_test.go +++ b/src/yangerd/internal/zapiwatcher/zapiwatcher_test.go @@ -18,7 +18,7 @@ func TestRouteProtocol(t *testing.T) { {"connect", zapi.RouteConnect, "ietf-routing:direct"}, {"static", zapi.RouteStatic, "ietf-routing:static"}, {"ospf", zapi.RouteOSPF, "ietf-ospf:ospfv2"}, - {"rip", zapi.RouteRIP, "ietf-rip:ripv2"}, + {"rip", zapi.RouteRIP, "ietf-rip:rip"}, {"unknown defaults to kernel", zapi.RouteType(99), "infix-routing:kernel"}, {"zero defaults to kernel", zapi.RouteType(0), "infix-routing:kernel"}, } @@ -68,8 +68,9 @@ func TestRibName(t *testing.T) { func TestTransformRoute(t *testing.T) { route := &zapi.Route{ - Type: zapi.RouteStatic, - Metric: 100, + Type: zapi.RouteStatic, + Distance: 1, + Metric: 100, Prefix: net.IPNet{ IP: net.ParseIP("10.0.0.0").To4(), Mask: net.CIDRMask(24, 32), @@ -91,8 +92,8 @@ func TestTransformRoute(t *testing.T) { t.Errorf("source-protocol = %v, want %q", got, "ietf-routing:static") } - if got, ok := parsed["route-preference"].(float64); !ok || int(got) != 100 { - t.Errorf("route-preference = %v, want 100", parsed["route-preference"]) + if got, ok := parsed["route-preference"].(float64); !ok || int(got) != 1 { + t.Errorf("route-preference = %v, want 1 (admin distance)", parsed["route-preference"]) } nhContainer, ok := parsed["next-hop"].(map[string]any) @@ -114,8 +115,9 @@ func TestTransformRoute(t *testing.T) { func TestTransformRouteIPv6(t *testing.T) { route := &zapi.Route{ - Type: zapi.RouteOSPF, - Metric: 10, + Type: zapi.RouteOSPF, + Distance: 110, + Metric: 10, Prefix: net.IPNet{ IP: net.ParseIP("2001:db8::").To16(), Mask: net.CIDRMask(48, 128),