diff --git a/dataplane/BUILD b/dataplane/BUILD index 4455d5f5..fce55910 100644 --- a/dataplane/BUILD +++ b/dataplane/BUILD @@ -2,11 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "dataplane", - srcs = ["server.go"], + srcs = [ + "reconcilers_linux.go", + "reconcilers_nonlinux.go", + "server.go", + ], importpath = "github.com/openconfig/lemming/dataplane", visibility = ["//visibility:public"], deps = [ - "//dataplane/handlers", "//dataplane/internal/engine", "//gnmi/oc", "//gnmi/reconciler", @@ -16,5 +19,49 @@ go_library( "@com_github_openconfig_ygnmi//ygnmi", "@org_golang_google_grpc//:go_default_library", "@org_golang_google_grpc//credentials/local", - ], + ] + select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:android": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:darwin": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:dragonfly": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:freebsd": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:ios": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:js": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:netbsd": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:openbsd": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:plan9": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:solaris": [ + "//dataplane/handlers", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "//dataplane/handlers", + ], + "//conditions:default": [], + }), ) diff --git a/dataplane/forwarding/fwdport/ports/BUILD b/dataplane/forwarding/fwdport/ports/BUILD index 5a6a6cd2..86e3f60c 100644 --- a/dataplane/forwarding/fwdport/ports/BUILD +++ b/dataplane/forwarding/fwdport/ports/BUILD @@ -21,17 +21,27 @@ go_library( "//dataplane/forwarding/infra/fwdpacket", "//dataplane/forwarding/util/hash/crc16", "//dataplane/forwarding/util/queue", - "//dataplane/internal/kernel", "//internal/debug", "//proto/forwarding", "@com_github_golang_glog//:glog", "@com_github_google_gopacket//:gopacket", - "@com_github_google_gopacket//afpacket", "@com_github_google_gopacket//layers", "@com_github_google_gopacket//pcapgo", - "@com_github_vishvananda_netlink//:netlink", - "@org_golang_x_sys//unix", - ], + ] + select({ + "@io_bazel_rules_go//go/platform:android": [ + "//dataplane/internal/kernel", + "@com_github_google_gopacket//afpacket", + "@com_github_vishvananda_netlink//:netlink", + "@org_golang_x_sys//unix", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "//dataplane/internal/kernel", + "@com_github_google_gopacket//afpacket", + "@com_github_vishvananda_netlink//:netlink", + "@org_golang_x_sys//unix", + ], + "//conditions:default": [], + }), ) go_test( diff --git a/dataplane/forwarding/fwdport/ports/kernel.go b/dataplane/forwarding/fwdport/ports/kernel.go index b3eca9e1..d03c5c61 100644 --- a/dataplane/forwarding/fwdport/ports/kernel.go +++ b/dataplane/forwarding/fwdport/ports/kernel.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package ports import ( diff --git a/dataplane/forwarding/fwdport/ports/tap.go b/dataplane/forwarding/fwdport/ports/tap.go index 68742f08..ad0d37b0 100644 --- a/dataplane/forwarding/fwdport/ports/tap.go +++ b/dataplane/forwarding/fwdport/ports/tap.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package ports import ( diff --git a/dataplane/handlers/BUILD b/dataplane/handlers/BUILD index 91fd61ef..f0b9e305 100644 --- a/dataplane/handlers/BUILD +++ b/dataplane/handlers/BUILD @@ -10,19 +10,33 @@ go_library( visibility = ["//visibility:public"], deps = [ "//dataplane/internal/engine", - "//dataplane/internal/kernel", "//gnmi", - "//gnmi/gnmiclient", - "//gnmi/oc", - "//gnmi/oc/ocpath", "//gnmi/reconciler", "//proto/dataplane", - "//proto/forwarding", "@com_github_golang_glog//:glog", "@com_github_openconfig_ygnmi//schemaless", "@com_github_openconfig_ygnmi//ygnmi", - "@com_github_openconfig_ygot//ygot", - "@com_github_vishvananda_netlink//:netlink", - "@org_golang_x_sys//unix", - ], + ] + select({ + "@io_bazel_rules_go//go/platform:android": [ + "//dataplane/internal/kernel", + "//gnmi/gnmiclient", + "//gnmi/oc", + "//gnmi/oc/ocpath", + "//proto/forwarding", + "@com_github_openconfig_ygot//ygot", + "@com_github_vishvananda_netlink//:netlink", + "@org_golang_x_sys//unix", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "//dataplane/internal/kernel", + "//gnmi/gnmiclient", + "//gnmi/oc", + "//gnmi/oc/ocpath", + "//proto/forwarding", + "@com_github_openconfig_ygot//ygot", + "@com_github_vishvananda_netlink//:netlink", + "@org_golang_x_sys//unix", + ], + "//conditions:default": [], + }), ) diff --git a/dataplane/handlers/interface.go b/dataplane/handlers/interface.go index 2c3ae27e..2130174b 100644 --- a/dataplane/handlers/interface.go +++ b/dataplane/handlers/interface.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Package handlers contains gNMI task handlers. package handlers diff --git a/dataplane/internal/engine/BUILD b/dataplane/internal/engine/BUILD index a036d041..1effab80 100644 --- a/dataplane/internal/engine/BUILD +++ b/dataplane/internal/engine/BUILD @@ -4,6 +4,8 @@ go_library( name = "engine", srcs = [ "engine.go", + "engine_linux.go", + "engine_nonlinux.go", "helpers.go", ], importpath = "github.com/openconfig/lemming/dataplane/internal/engine", @@ -15,8 +17,15 @@ go_library( "//proto/dataplane", "//proto/forwarding", "@com_github_golang_glog//:glog", - "@com_github_vishvananda_netlink//:netlink", "@org_golang_google_grpc//codes", "@org_golang_google_grpc//status", - ], + ] + select({ + "@io_bazel_rules_go//go/platform:android": [ + "@com_github_vishvananda_netlink//:netlink", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "@com_github_vishvananda_netlink//:netlink", + ], + "//conditions:default": [], + }), ) diff --git a/dataplane/internal/engine/engine.go b/dataplane/internal/engine/engine.go index d65f4bd6..386a725c 100644 --- a/dataplane/internal/engine/engine.go +++ b/dataplane/internal/engine/engine.go @@ -26,8 +26,6 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/vishvananda/netlink" - "github.com/openconfig/lemming/dataplane/forwarding" "github.com/openconfig/lemming/dataplane/forwarding/attributes" "github.com/openconfig/lemming/dataplane/forwarding/fwdconfig" @@ -92,29 +90,7 @@ func New(ctx context.Context) (*Engine, error) { internalToExternalID: map[string]string{}, } - updCh := make(chan netlink.AddrUpdate) - doneCh := make(chan struct{}) - - go func() { - for { - upd := <-updCh - l, err := netlink.LinkByIndex(upd.LinkIndex) - if err != nil { - log.Warningf("failed to get link: %v", err) - continue - } - e.ipToDevNameMu.Lock() - if upd.NewAddr { - log.Infof("added new ip %s to device %s", upd.LinkAddress.IP.String(), l.Attrs().Name) - e.ipToDevName[upd.LinkAddress.IP.String()] = l.Attrs().Name - } else { - delete(e.ipToDevName, upd.LinkAddress.IP.String()) - } - e.ipToDevNameMu.Unlock() - } - }() - - netlink.AddrSubscribe(updCh, doneCh) + e.handleIPUpdates() _, err := e.Server.ContextCreate(context.Background(), &fwdpb.ContextCreateRequest{ ContextId: &fwdpb.ContextId{Id: e.id}, diff --git a/dataplane/internal/engine/engine_linux.go b/dataplane/internal/engine/engine_linux.go new file mode 100644 index 00000000..f537b596 --- /dev/null +++ b/dataplane/internal/engine/engine_linux.go @@ -0,0 +1,49 @@ +// 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. + +//go:build linux + +package engine + +import ( + "github.com/vishvananda/netlink" + + log "github.com/golang/glog" +) + +func (e *Engine) handleIPUpdates() { + updCh := make(chan netlink.AddrUpdate) + doneCh := make(chan struct{}) + + go func() { + for { + upd := <-updCh + l, err := netlink.LinkByIndex(upd.LinkIndex) + if err != nil { + log.Warningf("failed to get link: %v", err) + continue + } + e.ipToDevNameMu.Lock() + if upd.NewAddr { + log.Infof("added new ip %s to device %s", upd.LinkAddress.IP.String(), l.Attrs().Name) + e.ipToDevName[upd.LinkAddress.IP.String()] = l.Attrs().Name + } else { + delete(e.ipToDevName, upd.LinkAddress.IP.String()) + } + e.ipToDevNameMu.Unlock() + } + }() + + netlink.AddrSubscribe(updCh, doneCh) +} diff --git a/dataplane/internal/engine/engine_nonlinux.go b/dataplane/internal/engine/engine_nonlinux.go new file mode 100644 index 00000000..775292a5 --- /dev/null +++ b/dataplane/internal/engine/engine_nonlinux.go @@ -0,0 +1,19 @@ +// 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. + +//go:build !linux + +package engine + +func (e *Engine) handleIPUpdates() {} diff --git a/dataplane/internal/kernel/BUILD b/dataplane/internal/kernel/BUILD index 65679d26..34785e63 100644 --- a/dataplane/internal/kernel/BUILD +++ b/dataplane/internal/kernel/BUILD @@ -5,8 +5,15 @@ go_library( srcs = ["kernel.go"], importpath = "github.com/openconfig/lemming/dataplane/internal/kernel", visibility = ["//dataplane:__subpackages__"], - deps = [ - "@com_github_vishvananda_netlink//:netlink", - "@org_golang_x_sys//unix", - ], + deps = select({ + "@io_bazel_rules_go//go/platform:android": [ + "@com_github_vishvananda_netlink//:netlink", + "@org_golang_x_sys//unix", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "@com_github_vishvananda_netlink//:netlink", + "@org_golang_x_sys//unix", + ], + "//conditions:default": [], + }), ) diff --git a/dataplane/internal/kernel/kernel.go b/dataplane/internal/kernel/kernel.go index 38589f23..8b40a78e 100644 --- a/dataplane/internal/kernel/kernel.go +++ b/dataplane/internal/kernel/kernel.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // Package kernel contains funcs that interact with the kernel (sycalls, netlink). package kernel diff --git a/dataplane/internal/kernel/kerneltest/BUILD b/dataplane/internal/kernel/kerneltest/BUILD index fb2526bd..38fc8aac 100644 --- a/dataplane/internal/kernel/kerneltest/BUILD +++ b/dataplane/internal/kernel/kerneltest/BUILD @@ -5,16 +5,32 @@ go_library( srcs = ["kernel.go"], importpath = "github.com/openconfig/lemming/dataplane/internal/kernel/kerneltest", visibility = ["//dataplane:__subpackages__"], - deps = ["@com_github_vishvananda_netlink//:netlink"], + deps = select({ + "@io_bazel_rules_go//go/platform:android": [ + "@com_github_vishvananda_netlink//:netlink", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "@com_github_vishvananda_netlink//:netlink", + ], + "//conditions:default": [], + }), ) go_test( name = "kerneltest_test", srcs = ["kernel_test.go"], embed = [":kerneltest"], - deps = [ - "@com_github_google_go_cmp//cmp", - "@com_github_openconfig_gnmi//errdiff", - "@com_github_vishvananda_netlink//:netlink", - ], + deps = select({ + "@io_bazel_rules_go//go/platform:android": [ + "@com_github_google_go_cmp//cmp", + "@com_github_openconfig_gnmi//errdiff", + "@com_github_vishvananda_netlink//:netlink", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "@com_github_google_go_cmp//cmp", + "@com_github_openconfig_gnmi//errdiff", + "@com_github_vishvananda_netlink//:netlink", + ], + "//conditions:default": [], + }), ) diff --git a/dataplane/internal/kernel/kerneltest/kernel.go b/dataplane/internal/kernel/kerneltest/kernel.go index 3476db45..0a969f24 100644 --- a/dataplane/internal/kernel/kerneltest/kernel.go +++ b/dataplane/internal/kernel/kerneltest/kernel.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + // package kerneltest contains fake implemetation of structs in kernel package package kerneltest diff --git a/dataplane/internal/kernel/kerneltest/kernel_test.go b/dataplane/internal/kernel/kerneltest/kernel_test.go index fdd81c5c..8065e39c 100644 --- a/dataplane/internal/kernel/kerneltest/kernel_test.go +++ b/dataplane/internal/kernel/kerneltest/kernel_test.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux + package kerneltest import ( diff --git a/dataplane/reconcilers_linux.go b/dataplane/reconcilers_linux.go new file mode 100644 index 00000000..6b78425b --- /dev/null +++ b/dataplane/reconcilers_linux.go @@ -0,0 +1,28 @@ +// Copyright 2022 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. + +//go:build linux + +// Package dataplane is an implementation of the dataplane HAL API. +package dataplane + +import ( + "github.com/openconfig/lemming/dataplane/handlers" + "github.com/openconfig/lemming/dataplane/internal/engine" + "github.com/openconfig/lemming/gnmi/reconciler" +) + +func getReconcilers(e *engine.Engine) []reconciler.Reconciler { + return []reconciler.Reconciler{handlers.NewInterface(e), handlers.NewRoute(e)} +} diff --git a/dataplane/reconcilers_nonlinux.go b/dataplane/reconcilers_nonlinux.go new file mode 100644 index 00000000..eda1c7c9 --- /dev/null +++ b/dataplane/reconcilers_nonlinux.go @@ -0,0 +1,28 @@ +// Copyright 2022 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. + +//go:build !linux + +// Package dataplane is an implementation of the dataplane HAL API. +package dataplane + +import ( + "github.com/openconfig/lemming/dataplane/handlers" + "github.com/openconfig/lemming/dataplane/internal/engine" + "github.com/openconfig/lemming/gnmi/reconciler" +) + +func getReconcilers(e *engine.Engine) []reconciler.Reconciler { + return []reconciler.Reconciler{handlers.NewRoute(e)} +} diff --git a/dataplane/server.go b/dataplane/server.go index 72bb1377..77b8cb87 100644 --- a/dataplane/server.go +++ b/dataplane/server.go @@ -24,7 +24,6 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/local" - "github.com/openconfig/lemming/dataplane/handlers" "github.com/openconfig/lemming/dataplane/internal/engine" "github.com/openconfig/lemming/gnmi/oc" "github.com/openconfig/lemming/gnmi/reconciler" @@ -84,7 +83,7 @@ func (d *Dataplane) Start(ctx context.Context, c gpb.GNMIClient, target string) return err } d.fwd = fc - d.reconcilers = append(d.reconcilers, handlers.NewInterface(d.e), handlers.NewRoute(d.e)) + d.reconcilers = append(d.reconcilers, getReconcilers(d.e)...) for _, rec := range d.reconcilers { if err := rec.Start(ctx, c, target); err != nil { diff --git a/lemming.go b/lemming.go index 98bd14c4..4be22e05 100644 --- a/lemming.go +++ b/lemming.go @@ -19,8 +19,15 @@ import ( "context" "fmt" "net" + "runtime" "sync" + "github.com/spf13/viper" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/reflection" + "k8s.io/klog/v2" + "github.com/openconfig/lemming/bgp" "github.com/openconfig/lemming/dataplane" fgnmi "github.com/openconfig/lemming/gnmi" @@ -32,11 +39,6 @@ import ( fgribi "github.com/openconfig/lemming/gribi" fp4rt "github.com/openconfig/lemming/p4rt" "github.com/openconfig/lemming/sysrib" - "github.com/spf13/viper" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/reflection" - "k8s.io/klog/v2" log "github.com/golang/glog" ) @@ -153,6 +155,10 @@ func New(targetName, zapiURL string, opts ...Option) (*Device, error) { var recs []reconciler.Reconciler if viper.GetBool("enable_dataplane") { + if runtime.GOOS != "linux" { + return nil, fmt.Errorf("dataplane only supported on linux, GOOS is %s", runtime.GOOS) + } + log.Info("enabling dataplane") var err error dplane, err = dataplane.New(context.Background())