Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split some ZAPI-related code to different files in sysrib #232

Merged
merged 6 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions dataplane/forwarding/protocol/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (

"github.com/go-logr/logr"
"github.com/go-logr/logr/funcr"
"github.com/golang/glog"
log "github.com/golang/glog"

"github.com/openconfig/lemming/dataplane/forwarding/infra/fwdattribute"
Expand Down Expand Up @@ -214,7 +213,7 @@ func (pl packetLogger) Init(_ logr.RuntimeInfo) {}
// For example, commandline flags might be used to set the logging
// verbosity and disable some info logs.
func (pl packetLogger) Enabled(level int) bool {
return bool(glog.V(glog.Level(level)))
return bool(log.V(log.Level(level)))
}

// Info logs a non-error message with the given key/value pairs as context.
Expand Down
1 change: 1 addition & 0 deletions sysrib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go_library(
srcs = [
"logger.go",
"server.go",
"server_zapi.go",
"static.go",
"sysrib.go",
"util.go",
Expand Down
100 changes: 4 additions & 96 deletions sysrib/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"github.com/google/gopacket/layers"
"github.com/openconfig/gribigo/afthelper"
"github.com/openconfig/ygnmi/ygnmi"
"github.com/wenovus/gobgp/v3/pkg/zebra"
"golang.org/x/exp/maps"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -191,21 +190,20 @@ func (s *Server) Start(gClient gpb.GNMIClient, target, zapiURL string) error {

go grpcServer.Serve(lis)

// Start ZAPI server.
// BEGIN Start ZAPI server.
if zapiURL != "" {
if s.zServer, err = StartZServer(zapiURL, 0, s); err != nil {
return err
}
}
// END Start ZAPI server.

return nil
}

// Stop stops the sysrib server.
func (s *Server) Stop() {
if s.zServer != nil {
s.zServer.Stop()
}
s.zServer.Stop()
}

// monitorConnectedIntfs starts a gothread to check for connected prefixes from
Expand Down Expand Up @@ -545,49 +543,6 @@ func (s *Server) programRoute(r *ResolvedRoute) error {
return s.dataplane.ProgramRoute(r)
}

// convertToZAPIRoute converts a route to a ZAPI route for redistributing to
// other protocols (e.g. BGP).
func convertToZAPIRoute(routeKey RouteKey, route *Route, rr *ResolvedRoute) (*zebra.IPRouteBody, error) {
if route.Connected != nil {
// TODO(wenbli): Connected route redistribution not supported.
// This is not needed right now since only need to redistribute
// non-connected routes. It also breaks some of the integration tests.
return nil, nil
}
vrfID, err := niNameToVrfID(routeKey.NIName)
if err != nil {
return nil, err
}

_, ipnet, err := net.ParseCIDR(rr.Prefix)
if err != nil {
return nil, fmt.Errorf("gribigo/zapi: %v", err)
}
prefixLen, _ := ipnet.Mask.Size()

var nexthops []zebra.Nexthop
for nh := range rr.Nexthops {
nexthops = append(nexthops, zebra.Nexthop{
VrfID: vrfID,
Gate: net.ParseIP(nh.Address),
Weight: uint32(nh.Weight),
})
}

return &zebra.IPRouteBody{
Flags: zebra.FlagAllowRecursion,
Type: zebra.RouteStatic,
Safi: zebra.SafiUnicast,
Message: zebra.MessageNexthop,
Prefix: zebra.Prefix{
Prefix: ipnet.IP,
PrefixLen: uint8(prefixLen),
},
Nexthops: nexthops,
Distance: route.RoutePref.AdminDistance,
}, nil
}

// ResolveAndProgramDiff walks through each prefix in the RIB, resolving it and
// programs the forwarding plane.
//
Expand Down Expand Up @@ -672,19 +627,7 @@ func (s *Server) resolveAndProgramDiffAux(niName string, ni *NIRIB, prefix strin
s.PrintProgrammedRoutes()
}
// ZAPI: If a new/updated route is programmed, redistribute it to clients.
// TODO(wenbli): RedistributeRouteDel
zrouteBody, err := convertToZAPIRoute(rr.RouteKey, route, rr)
if err != nil {
log.Warningf("failed to convert resolved route to zebra BGP route: %v", err)
}
if zrouteBody != nil && s.zServer != nil {
log.V(1).Info("Sending new route to ZAPI clients: ", zrouteBody)
s.zServer.ClientMutex.RLock()
for conn := range s.zServer.ClientMap {
serverSendMessage(conn, zebra.RedistributeRouteAdd, zrouteBody)
}
s.zServer.ClientMutex.RUnlock()
}
distributeRoute(s.zServer, rr, route)
default:
// No diff, so don't do anything.
}
Expand Down Expand Up @@ -769,41 +712,6 @@ func (s *Server) setRoute(niName string, route *Route) error {
return nil
}

// setZebraRoute calls setRoute after reformatting a zebra-formatted input route.
func (s *Server) setZebraRoute(niName string, zroute *zebra.IPRouteBody) error {
if s == nil {
return fmt.Errorf("cannot add route to nil sysrib server")
}
log.V(1).Infof("setZebraRoute: %+v", *zroute)
route := convertZebraRoute(niName, zroute)
return s.setRoute(niName, route)
}

// convertZebraRoute converts a zebra route to a Sysrib route.
func convertZebraRoute(niName string, zroute *zebra.IPRouteBody) *Route {
var nexthops []*afthelper.NextHopSummary
for _, znh := range zroute.Nexthops {
nexthops = append(nexthops, &afthelper.NextHopSummary{
Weight: 1,
Address: znh.Gate.String(),
NetworkInstance: niName,
})
}
var routePref RoutePreference
switch zroute.Type {
case zebra.RouteBGP:
routePref.AdminDistance = AdminDistanceBGP
}
routePref.Metric = zroute.Metric
return &Route{
Prefix: fmt.Sprintf("%s/%d", zroute.Prefix.Prefix.String(), zroute.Prefix.PrefixLen),
// NextHops is the set of IP nexthops that the route uses if
// it is not a connected route.
NextHops: nexthops,
RoutePref: routePref,
}
}

// addInterfacePrefix adds a prefix to the sysrib as a connected route.
func (s *Server) addInterfacePrefix(name string, ifindex int32, prefix string, niName string) error {
log.V(1).Infof("Adding interface prefix: intf %s, idx %d, prefix %s, ni %s", name, ifindex, prefix, niName)
Expand Down
118 changes: 118 additions & 0 deletions sysrib/server_zapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sysrib

import (
"fmt"
"net"

log "github.com/golang/glog"
"github.com/openconfig/gribigo/afthelper"
"github.com/wenovus/gobgp/v3/pkg/zebra"
)

func distributeRoute(s *ZServer, rr *ResolvedRoute, route *Route) {
// TODO(wenbli): RedistributeRouteDel
zrouteBody, err := convertToZAPIRoute(rr.RouteKey, route, rr)
if err != nil {
log.Warningf("failed to convert resolved route to zebra BGP route: %v", err)
}
if zrouteBody != nil && s != nil {
log.V(1).Info("Sending new route to ZAPI clients: ", zrouteBody)
s.ClientMutex.RLock()
for conn := range s.ClientMap {
serverSendMessage(conn, zebra.RedistributeRouteAdd, zrouteBody)
}
s.ClientMutex.RUnlock()
}
}

// convertToZAPIRoute converts a route to a ZAPI route for redistributing to
// other protocols (e.g. BGP).
func convertToZAPIRoute(routeKey RouteKey, route *Route, rr *ResolvedRoute) (*zebra.IPRouteBody, error) {
if route.Connected != nil {
// TODO(wenbli): Connected route redistribution not supported.
// This is not needed right now since only need to redistribute
// non-connected routes. It also breaks some of the integration tests.
return nil, nil
}
vrfID, err := niNameToVrfID(routeKey.NIName)
if err != nil {
return nil, err
}

_, ipnet, err := net.ParseCIDR(rr.Prefix)
if err != nil {
return nil, fmt.Errorf("gribigo/zapi: %v", err)
}
prefixLen, _ := ipnet.Mask.Size()

var nexthops []zebra.Nexthop
for nh := range rr.Nexthops {
nexthops = append(nexthops, zebra.Nexthop{
VrfID: vrfID,
Gate: net.ParseIP(nh.Address),
Weight: uint32(nh.Weight),
})
}

return &zebra.IPRouteBody{
Flags: zebra.FlagAllowRecursion,
Type: zebra.RouteStatic,
Safi: zebra.SafiUnicast,
Message: zebra.MessageNexthop,
Prefix: zebra.Prefix{
Prefix: ipnet.IP,
PrefixLen: uint8(prefixLen),
},
Nexthops: nexthops,
Distance: route.RoutePref.AdminDistance,
}, nil
}

// setZebraRoute calls setRoute after reformatting a zebra-formatted input route.
func (s *Server) setZebraRoute(niName string, zroute *zebra.IPRouteBody) error {
if s == nil {
return fmt.Errorf("cannot add route to nil sysrib server")
}
log.V(1).Infof("setZebraRoute: %+v", *zroute)
route := convertZebraRoute(niName, zroute)
return s.setRoute(niName, route)
}

// convertZebraRoute converts a zebra route to a Sysrib route.
func convertZebraRoute(niName string, zroute *zebra.IPRouteBody) *Route {
var nexthops []*afthelper.NextHopSummary
for _, znh := range zroute.Nexthops {
nexthops = append(nexthops, &afthelper.NextHopSummary{
Weight: 1,
Address: znh.Gate.String(),
NetworkInstance: niName,
})
}
var routePref RoutePreference
switch zroute.Type {
case zebra.RouteBGP:
routePref.AdminDistance = AdminDistanceBGP
}
routePref.Metric = zroute.Metric
return &Route{
Prefix: fmt.Sprintf("%s/%d", zroute.Prefix.Prefix.String(), zroute.Prefix.PrefixLen),
// NextHops is the set of IP nexthops that the route uses if
// it is not a connected route.
NextHops: nexthops,
RoutePref: routePref,
}
}