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

Broadcom SONiC Support #112

Draft
wants to merge 40 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
4e4a8ff
Add AgentX for SONiC
robertvolkmann Sep 21, 2023
ee07fc2
Log switch config in log level debug
robertvolkmann Sep 21, 2023
9b3e159
Fix tests
robertvolkmann Sep 21, 2023
fadd8c6
Merge branch 'master' into add-agentx-for-sonic
robertvolkmann Sep 21, 2023
54c1065
A suffix for the vtep is mandatory on Broadcom SONiC, e.g. vtep-*
robertvolkmann Nov 6, 2023
7f087c7
Align to new linter testifylint
robertvolkmann Nov 6, 2023
b905d2e
Align to new linter protogetter
robertvolkmann Nov 6, 2023
27b1d80
Merge branch 'golangci-lint-1.55' into broadcom-support
robertvolkmann Nov 6, 2023
ce8f3b2
Merge branch 'master' into broadcom-support
majst01 Nov 6, 2023
f00c72f
Support authentication against Redis
robertvolkmann Nov 7, 2023
5e10fe2
Merge remote-tracking branch 'origin/add-agentx-for-sonic' into broad…
robertvolkmann Nov 7, 2023
2c59d8a
Add iproute2 for `ip vrf exec`
robertvolkmann Nov 7, 2023
7b50433
Revert "Add iproute2 for `ip vrf exec`"
robertvolkmann Nov 8, 2023
be0bce2
Use front panel name instead of alias as identifier
robertvolkmann Nov 8, 2023
9dbc29f
Revert "Use front panel name instead of alias as identifier"
robertvolkmann Nov 8, 2023
ba91b7c
Set admin_status for new VLANs
robertvolkmann Nov 9, 2023
94c49b8
Retrieve name of the VTEP from ConfigDB
robertvolkmann Nov 9, 2023
d83f412
Only last element of the retrieved key contains the name of the vtep
robertvolkmann Nov 9, 2023
de735b7
Set fallback to false for VRFs
robertvolkmann Nov 9, 2023
80eaa94
Revert "Fix tests"
robertvolkmann Nov 9, 2023
4750b4e
Revert "Log switch config in log level debug"
robertvolkmann Nov 9, 2023
4b2952f
Revert "Add AgentX for SONiC"
robertvolkmann Nov 9, 2023
95210f9
Reapply "Use front panel name instead of alias as identifier"
robertvolkmann Dec 12, 2023
c36f06b
Reapply "Add AgentX for SONiC"
robertvolkmann Dec 13, 2023
63ed9d4
Add missing agentx to template tests
robertvolkmann Jan 11, 2024
42f7308
Switch to symmetric IRB
robertvolkmann Jan 23, 2024
d97bd79
Merge tag 'refs/tags/v0.10.2' into broadcom-support
robertvolkmann Apr 17, 2024
784be7b
Merge branch 'master' into broadcom-support
robertvolkmann May 8, 2024
94f5801
Revert "support for switch port toggle on/off (#119)"
robertvolkmann Jun 18, 2024
b343231
Make it possible to manually configure VLAN
simcod Jul 4, 2024
7e4ca4f
Add default vlan value
simcod Jul 4, 2024
c95a201
Adjust naming
simcod Jul 4, 2024
a1df785
Renaming
simcod Jul 5, 2024
8ddb488
Implement review
simcod Jul 5, 2024
4f2d5ea
Implement review
simcod Jul 5, 2024
5b59664
Change naming from vlan to pxeVlan
robertvolkmann Jul 5, 2024
7305bcc
Use VLAN ID instead of VLAN-ID in the comments
robertvolkmann Jul 5, 2024
db5b17c
Merge branch 'refs/heads/configure-vlan' into broadcom-support
robertvolkmann Jul 5, 2024
f1e3c4f
Fix linter
robertvolkmann Jul 5, 2024
5efa716
Merge tag 'v0.12.0' into broadcom-support
robertvolkmann Sep 26, 2024
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
71 changes: 8 additions & 63 deletions cmd/internal/core/reconfigure-switch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package core

import (
"fmt"
"net"
"os"
"slices"
"strconv"
Expand All @@ -24,7 +23,7 @@ func (c *Core) ReconfigureSwitch() {
for range t.C {
c.log.Info("trigger reconfiguration")
start := time.Now()
s, err := c.reconfigureSwitch(host)
err := c.reconfigureSwitch(host)
elapsed := time.Since(start)
c.log.Info("reconfiguration took", "elapsed", elapsed)

Expand All @@ -33,7 +32,6 @@ func (c *Core) ReconfigureSwitch() {
ns := elapsed.Nanoseconds()
nr := &models.V1SwitchNotifyRequest{
SyncDuration: &ns,
PortStates: make(map[string]string),
}
if err != nil {
errStr := err.Error()
Expand All @@ -44,34 +42,6 @@ func (c *Core) ReconfigureSwitch() {
c.log.Info("reconfiguration succeeded")
}

// fill the port states of the switch
var nics []*models.V1SwitchNic
if s != nil {
nics = s.Nics
}
for _, n := range nics {
if n == nil || n.Name == nil {
// lets log the whole nic because the name could be empty; lets hope there is some useful information
// in the nic
c.log.Error("could not check if link is up", "nic", n)
c.metrics.CountError("switch-reconfiguration")
continue
}
isup, err := isLinkUp(*n.Name)
if err != nil {
c.log.Error("could not check if link is up", "error", err, "nicname", *n.Name)
nr.PortStates[*n.Name] = models.V1SwitchNicActualUNKNOWN
c.metrics.CountError("switch-reconfiguration")
continue
}
if isup {
nr.PortStates[*n.Name] = models.V1SwitchNicActualUP
} else {
nr.PortStates[*n.Name] = models.V1SwitchNicActualDOWN
}

}

params.Body = nr
_, err = c.driver.SwitchOperations().NotifySwitch(params, nil)
if err != nil {
Expand All @@ -81,37 +51,37 @@ func (c *Core) ReconfigureSwitch() {
}
}

func (c *Core) reconfigureSwitch(switchName string) (*models.V1SwitchResponse, error) {
func (c *Core) reconfigureSwitch(switchName string) error {
params := sw.NewFindSwitchParams()
params.ID = switchName
fsr, err := c.driver.SwitchOperations().FindSwitch(params, nil)
if err != nil {
return nil, fmt.Errorf("could not fetch switch from metal-api: %w", err)
return fmt.Errorf("could not fetch switch from metal-api: %w", err)
}

s := fsr.Payload
switchConfig, err := c.buildSwitcherConfig(s)
if err != nil {
return nil, fmt.Errorf("could not build switcher config: %w", err)
return fmt.Errorf("could not build switcher config: %w", err)
}

err = fillEth0Info(switchConfig, c.managementGateway)
if err != nil {
return nil, fmt.Errorf("could not gather information about eth0 nic: %w", err)
return fmt.Errorf("could not gather information about eth0 nic: %w", err)
}

c.log.Info("assembled new config for switch", "config", switchConfig)
if !c.enableReconfigureSwitch {
c.log.Debug("skip config application because of environment setting")
return s, nil
return nil
}

err = c.nos.Apply(switchConfig)
if err != nil {
return nil, fmt.Errorf("could not apply switch config: %w", err)
return fmt.Errorf("could not apply switch config: %w", err)
}

return s, nil
return nil
}

func (c *Core) buildSwitcherConfig(s *models.V1SwitchResponse) (*types.Conf, error) {
Expand Down Expand Up @@ -139,18 +109,10 @@ func (c *Core) buildSwitcherConfig(s *models.V1SwitchResponse) (*types.Conf, err
Unprovisioned: []string{},
Vrfs: map[string]*types.Vrf{},
Firewalls: map[string]*types.Firewall{},
DownPorts: map[string]bool{},
}
p.BladePorts = c.additionalBridgePorts
for _, nic := range s.Nics {
port := *nic.Name

if isPortStatusEqual(models.V1SwitchNicActualDOWN, nic.Actual) {
if has := p.DownPorts[port]; !has {
p.DownPorts[port] = true
}
}

if slices.Contains(p.Underlay, port) {
continue
}
Expand Down Expand Up @@ -248,20 +210,3 @@ func fillEth0Info(c *types.Conf, gw string) error {
c.Ports.Eth0.Gateway = gw
return nil
}

// isLinkUp checks if the interface with the given name is up.
// It returns a boolean indicating if the interface is up, and an error if there was a problem checking the interface.
func isLinkUp(nicname string) (bool, error) {
nic, err := net.InterfaceByName(nicname)
if err != nil {
return false, fmt.Errorf("cannot query interface %q : %w", nicname, err)
}
return nic.Flags&net.FlagUp != 0, nil
}

func isPortStatusEqual(stat string, other *string) bool {
if other == nil {
return false
}
return strings.EqualFold(stat, *other)
}
1 change: 0 additions & 1 deletion cmd/internal/core/reconfigure-switch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ func TestBuildSwitcherConfig(t *testing.T) {
ASN: 420000001,
AdditionalRouteMapCIDRs: []string{"10.240.0.0/12"},
Ports: types.Ports{
DownPorts: map[string]bool{},
Underlay: []string{"swp31", "swp32"},
Unprovisioned: []string{"swp1"},
Firewalls: map[string]*types.Firewall{
Expand Down
5 changes: 2 additions & 3 deletions cmd/internal/switcher/cumulus/cumulus.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@ func New(log *slog.Logger, frrTplFile, interfacesTplFile string) *Cumulus {
}

func (c *Cumulus) Apply(cfg *types.Conf) error {
withoutDownPorts := cfg.NewWithoutDownPorts()
err := c.interfacesApplier.Apply(withoutDownPorts)
err := c.interfacesApplier.Apply(cfg)
if err != nil {
return err
}

return c.frrApplier.Apply(withoutDownPorts)
return c.frrApplier.Apply(cfg)
}

func (c *Cumulus) IsInitialized() (initialized bool, err error) {
Expand Down
6 changes: 4 additions & 2 deletions cmd/internal/switcher/sonic/db/appldb.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ package db

import (
"context"

"github.com/redis/go-redis/v9"
)

type ApplDB struct {
c *Client
}

func newApplDB(addr string, id int, sep string) *ApplDB {
func newApplDB(rdb *redis.Client, sep string) *ApplDB {
return &ApplDB{
c: NewClient(addr, id, sep),
c: NewClient(rdb, sep),
}
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/internal/switcher/sonic/db/asicdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ type AsicDB struct {

type OID string

func newAsicDB(addr string, id int, sep string) *AsicDB {
func newAsicDB(rdb *redis.Client, sep string) *AsicDB {
return &AsicDB{
c: NewClient(addr, id, sep),
c: NewClient(rdb, sep),
}
}

Expand Down
7 changes: 1 addition & 6 deletions cmd/internal/switcher/sonic/db/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@ type Client struct {
sep string
}

func NewClient(addr string, id int, sep string) *Client {
rdb := redis.NewClient(&redis.Options{
Addr: addr,
DB: id,
PoolSize: 1,
})
func NewClient(rdb *redis.Client, sep string) *Client {
return &Client{
rdb: rdb,
sep: sep,
Expand Down
52 changes: 37 additions & 15 deletions cmd/internal/switcher/sonic/db/configdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package db
import (
"context"
"fmt"

"github.com/redis/go-redis/v9"
)

const (
Expand All @@ -16,15 +18,15 @@ const (
portTable = "PORT"
adminStatus = "admin_status"
adminStatusUp = "up"
adminStatusDown = "down"
mtu = "mtu"
fec = "fec"
fecRS = "rs"
fecNone = "none"
)

type ConfigDB struct {
c *Client
c *Client
vtep string
}

type Port struct {
Expand All @@ -33,9 +35,9 @@ type Port struct {
FecRs bool
}

func newConfigDB(addr string, id int, sep string) *ConfigDB {
func newConfigDB(rdb *redis.Client, sep string) *ConfigDB {
return &ConfigDB{
c: NewClient(addr, id, sep),
c: NewClient(rdb, sep),
}
}

Expand All @@ -49,7 +51,7 @@ func (d *ConfigDB) CreateVlan(ctx context.Context, vid uint16) error {
vlanId := fmt.Sprintf("%d", vid)
key := Key{"VLAN", "Vlan" + vlanId}

return d.c.HSet(ctx, key, Val{"vlanid": vlanId})
return d.c.HSet(ctx, key, Val{"admin_status": "up", "vlanid": vlanId})
}

func (d *ConfigDB) AreNeighborsSuppressed(ctx context.Context, vid uint16) (bool, error) {
Expand Down Expand Up @@ -116,10 +118,10 @@ func (d *ConfigDB) ExistVrf(ctx context.Context, vrf string) (bool, error) {
return d.c.Exists(ctx, key)
}

func (d *ConfigDB) CreateVrf(ctx context.Context, vrf string) error {
func (d *ConfigDB) CreateVrf(ctx context.Context, vrf string, vni uint32) error {
key := Key{"VRF", vrf}

return d.c.HSet(ctx, key, Val{"NULL": "NULL"})
return d.c.HSet(ctx, key, Val{"fallback": "false", "vni": fmt.Sprintf("%d", vni)})
}

func (d *ConfigDB) SetVrfMember(ctx context.Context, interfaceName string, vrf string) error {
Expand All @@ -135,20 +137,44 @@ func (d *ConfigDB) GetVrfMembership(ctx context.Context, interfaceName string) (
}

func (d *ConfigDB) ExistVxlanTunnelMap(ctx context.Context, vid uint16, vni uint32) (bool, error) {
key := Key{"VXLAN_TUNNEL_MAP", "vtep", fmt.Sprintf("map_%d_Vlan%d", vni, vid)}
if d.vtep == "" {
if err := d.obtainVTEPName(ctx); err != nil {
return false, err
}
}
key := Key{"VXLAN_TUNNEL_MAP", d.vtep, fmt.Sprintf("map_%d_Vlan%d", vni, vid)}

return d.c.Exists(ctx, key)
}

func (d *ConfigDB) CreateVxlanTunnelMap(ctx context.Context, vid uint16, vni uint32) error {
key := Key{"VXLAN_TUNNEL_MAP", "vtep", fmt.Sprintf("map_%d_Vlan%d", vni, vid)}
if d.vtep == "" {
if err := d.obtainVTEPName(ctx); err != nil {
return err
}
}
key := Key{"VXLAN_TUNNEL_MAP", d.vtep, fmt.Sprintf("map_%d_Vlan%d", vni, vid)}
val := Val{
"vlan": fmt.Sprintf("Vlan%d", vid),
"vni": fmt.Sprintf("%d", vni),
}
return d.c.HSet(ctx, key, val)
}

func (d *ConfigDB) obtainVTEPName(ctx context.Context) error {
pattern := Key{"VXLAN_TUNNEL", "*"}
keys, err := d.c.Keys(ctx, pattern)
if err != nil {
return err
}
if len(keys) != 1 {
return fmt.Errorf("could not find name of the vtep")
}
key := []string(keys[0])
d.vtep = key[len(key)-1]
return nil
}

func (d *ConfigDB) DeleteInterfaceConfiguration(ctx context.Context, interfaceName string) error {
key := Key{interfaceTable, interfaceName}

Expand Down Expand Up @@ -205,12 +231,8 @@ func (d *ConfigDB) SetPortMtu(ctx context.Context, interfaceName string, val str
return d.c.HSet(ctx, key, Val{mtu: val})
}

func (d *ConfigDB) SetAdminStatusUp(ctx context.Context, interfaceName string, up bool) error {
func (d *ConfigDB) SetAdminStatusUp(ctx context.Context, interfaceName string) error {
key := Key{portTable, interfaceName}

status := adminStatusUp
if !up {
status = adminStatusDown
}
return d.c.HSet(ctx, key, Val{adminStatus: status})
return d.c.HSet(ctx, key, Val{adminStatus: adminStatusUp})
}
6 changes: 4 additions & 2 deletions cmd/internal/switcher/sonic/db/countersdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ package db

import (
"context"

"github.com/redis/go-redis/v9"
)

type CountersDB struct {
c *Client
}

func newCountersDB(addr string, id int, sep string) *CountersDB {
func newCountersDB(rdb *redis.Client, sep string) *CountersDB {
return &CountersDB{
c: NewClient(addr, id, sep),
c: NewClient(rdb, sep),
}
}

Expand Down
Loading