Skip to content

Commit

Permalink
Reactor test
Browse files Browse the repository at this point in the history
  • Loading branch information
DanG100 committed Dec 6, 2023
1 parent d3339c7 commit 9c1a030
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 112 deletions.
222 changes: 115 additions & 107 deletions dataplane/dplanerc/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,36 +137,131 @@ func New(conn grpc.ClientConnInterface, switchID, cpuPortID uint64, contextID st
return r
}

func (ni *Reconciler) macReactor(v *ygnmi.Value[*oc.Interface]) error {
config, _ := v.Val()
state := ni.getOrCreateInterface(config.GetName())
intf := ocInterface{name: config.GetName(), subintf: 0}
data := ni.ocInterfaceData[intf]
if data == nil {
return nil
}

if config.GetOrCreateEthernet().MacAddress != nil {
if config.GetEthernet().GetMacAddress() != state.GetEthernet().GetMacAddress() {
log.V(1).Infof("setting interface %s hw-addr %q", data.hostifDevName, config.GetEthernet().GetMacAddress())
if err := ni.ifaceMgr.SetHWAddr(config.GetName(), config.GetEthernet().GetMacAddress()); err != nil {
log.Warningf("Failed to set mac address of port: %v", err)
}
}
} else {
// Deleting the configured MAC address means it should be the system-assigned MAC address, as detailed in the OpenConfig schema.
// https://openconfig.net/projects/models/schemadocs/yangdoc/openconfig-interfaces.html#interfaces-interface-ethernet-state-mac-address
if state.GetEthernet().GetHwMacAddress() != state.GetEthernet().GetMacAddress() {
log.V(1).Infof("resetting interface %s hw-addr %q", data.hostifDevName, state.GetEthernet().GetHwMacAddress())
if err := ni.ifaceMgr.SetHWAddr(config.GetName(), state.GetEthernet().GetHwMacAddress()); err != nil {
log.Warningf("Failed to set mac address of port: %v", err)
}
}
}
return nil
}

type prefixPair struct {

Check failure on line 169 in dataplane/dplanerc/interface.go

View workflow job for this annotation

GitHub Actions / lint

type `prefixPair` is unused (unused)
cfgIP, stateIP *string
cfgPL, statePL *uint8
}

func (ni *Reconciler) addrV4Reactor(v *ygnmi.Value[*oc.Interface]) error {
log.V(1).Infof("ipv4 reactor")
config, _ := v.Val()
state := ni.getOrCreateInterface(config.GetName())
intf := ocInterface{name: config.GetName(), subintf: 0}
data := ni.ocInterfaceData[intf]
if data == nil {
log.V(1).Infof("ipv4 reactor 3: %v, path %v, config %+v, subint %+v", config.GetName(), v.Path, config, config.GetSubinterface(0))
return nil
}
log.V(1).Infof("ipv4 reactor 2")

changedIP := v.Path.Elem[6].Key["ip"]
configIP := config.GetOrCreateSubinterface(0).GetOrCreateIpv4().GetAddress(changedIP)
stateIP := state.GetOrCreateSubinterface(0).GetOrCreateIpv4().GetAddress(changedIP)

if configIP == nil && stateIP != nil {
log.V(1).Infof("Deleting IP interface %s: IP: %v, PL: %v", data.hostifDevName, stateIP.GetIp(), stateIP.GetPrefixLength())
if err := ni.ifaceMgr.DeleteIP(data.hostifDevName, stateIP.GetIp(), int(stateIP.GetPrefixLength())); err != nil {
log.Warningf("Failed to set ip address of port: %v", err)
}
return nil
}

log.V(1).Infof("Adding IP interface %s: IP: %v, PL: %v", data.hostifDevName, configIP.GetIp(), configIP.GetPrefixLength())
if err := ni.ifaceMgr.ReplaceIP(data.hostifDevName, configIP.GetIp(), int(configIP.GetPrefixLength())); err != nil {
log.Warningf("Failed to set ip address of port: %v", err)
}

return nil
}

func (ni *Reconciler) addrV6Reactor(v *ygnmi.Value[*oc.Interface]) error {
config, _ := v.Val()
state := ni.getOrCreateInterface(config.GetName())
intf := ocInterface{name: config.GetName(), subintf: 0}
data := ni.ocInterfaceData[intf]
if data == nil {
return nil
}

changedIP := v.Path.Elem[6].Key["ip"]
configIP := config.GetOrCreateSubinterface(0).GetOrCreateIpv6().GetAddress(changedIP)
stateIP := state.GetOrCreateSubinterface(0).GetOrCreateIpv6().GetAddress(changedIP)

if configIP == nil && stateIP != nil {
log.V(1).Infof("Deleting IP interface %s: IP: %v, State PL: %v", data.hostifDevName, stateIP.GetIp(), stateIP.GetPrefixLength())
if err := ni.ifaceMgr.DeleteIP(data.hostifDevName, stateIP.GetIp(), int(stateIP.GetPrefixLength())); err != nil {
log.Warningf("Failed to set ip address of port: %v", err)
}
return nil
}

log.V(1).Infof("Adding IP interface %s: IP: %v, State PL: %v", data.hostifDevName, configIP.GetIp(), configIP.GetPrefixLength())
if err := ni.ifaceMgr.ReplaceIP(data.hostifDevName, configIP.GetIp(), int(configIP.GetPrefixLength())); err != nil {
log.Warningf("Failed to set ip address of port: %v", err)
}

return nil
}

// Start starts running the handler, watching the cache and the kernel interfaces.
func (ni *Reconciler) StartInterface(ctx context.Context, client *ygnmi.Client) error {
log.Info("starting interface handler")
b := &ocpath.Batch{}
ni.c = client

if err := ni.setupPorts(ctx); err != nil {
return fmt.Errorf("failed to setup ports: %v", err)
}

b := ygnmi.NewWildcardBatch(ocpath.Root().InterfaceAny().Config())
b.AddReactor(ocpath.Root().InterfaceAny().Ethernet().MacAddress().Config(), ni.macReactor)
b.AddReactor(ocpath.Root().InterfaceAny().Subinterface(0).Ipv4().AddressAny().Ip().Config(), ni.addrV4Reactor)
b.AddReactor(ocpath.Root().InterfaceAny().Subinterface(0).Ipv6().AddressAny().Ip().Config(), ni.addrV6Reactor)
b.AddReactor(ocpath.Root().InterfaceAny().Subinterface(0).Ipv4().AddressAny().PrefixLength().Config(), ni.addrV4Reactor)
b.AddReactor(ocpath.Root().InterfaceAny().Subinterface(0).Ipv6().AddressAny().PrefixLength().Config(), ni.addrV6Reactor)

b.AddPaths(
ocpath.Root().InterfaceAny().Name().Config().PathStruct(),
ocpath.Root().InterfaceAny().Ethernet().MacAddress().Config().PathStruct(),
ocpath.Root().InterfaceAny().Subinterface(0).Enabled().Config().PathStruct(), // TODO: Support the parent interface config/enabled controling the subinterface state.
ocpath.Root().InterfaceAny().Subinterface(0).Ipv4().AddressAny().Ip().Config().PathStruct(),
ocpath.Root().InterfaceAny().Subinterface(0).Ipv4().AddressAny().PrefixLength().Config().PathStruct(),
ocpath.Root().InterfaceAny().Subinterface(0).Ipv6().AddressAny().Ip().Config().PathStruct(),
ocpath.Root().InterfaceAny().Subinterface(0).Ipv6().AddressAny().PrefixLength().Config().PathStruct(),
ocpath.Root().InterfaceAny().Name().Config(),
ocpath.Root().InterfaceAny().Ethernet().MacAddress().Config(),
ocpath.Root().InterfaceAny().Subinterface(0).Enabled().Config(), // TODO: Support the parent interface config/enabled controling the subinterface state.
)
cancelCtx, cancelFn := context.WithCancel(ctx)

watcher := ygnmi.Watch(cancelCtx, ni.c, b.Config(), func(val *ygnmi.Value[*oc.Root]) error {
watcher := ygnmi.WatchAll(cancelCtx, ni.c, b.Query(), func(val *ygnmi.Value[*oc.Interface]) error {
log.V(2).Info("reconciling interfaces")
root, ok := val.Val()
if !ok || root.Interface == nil {
i, ok := val.Val()
if !ok {
return ygnmi.Continue
}
for _, i := range root.Interface {
ni.reconcile(cancelCtx, i)
}
ni.reconcile(cancelCtx, i)
return ygnmi.Continue
})

Expand Down Expand Up @@ -262,8 +357,12 @@ func (ni *Reconciler) startCounterUpdates(ctx context.Context) {
}
ni.stateMu.RUnlock()
for _, intfName := range intfNames {
data, ok := ni.ocInterfaceData[intfName]
if !ok {
continue
}
stats, err := ni.portClient.GetPortStats(ctx, &saipb.GetPortStatsRequest{
Oid: ni.ocInterfaceData[intfName].portID,
Oid: data.portID,
CounterIds: []saipb.PortStat{
saipb.PortStat_PORT_STAT_IF_IN_UCAST_PKTS,
saipb.PortStat_PORT_STAT_IF_IN_NON_UCAST_PKTS,
Expand Down Expand Up @@ -299,24 +398,6 @@ func (ni *Reconciler) reconcile(ctx context.Context, config *oc.Interface) {
}
state := ni.getOrCreateInterface(config.GetName())

if config.GetOrCreateEthernet().MacAddress != nil {
if config.GetEthernet().GetMacAddress() != state.GetEthernet().GetMacAddress() {
log.V(1).Infof("setting interface %s hw-addr %q", data.hostifDevName, config.GetEthernet().GetMacAddress())
if err := ni.ifaceMgr.SetHWAddr(config.GetName(), config.GetEthernet().GetMacAddress()); err != nil {
log.Warningf("Failed to set mac address of port: %v", err)
}
}
} else {
// Deleting the configured MAC address means it should be the system-assigned MAC address, as detailed in the OpenConfig schema.
// https://openconfig.net/projects/models/schemadocs/yangdoc/openconfig-interfaces.html#interfaces-interface-ethernet-state-mac-address
if state.GetEthernet().GetHwMacAddress() != state.GetEthernet().GetMacAddress() {
log.V(1).Infof("resetting interface %s hw-addr %q", data.hostifDevName, state.GetEthernet().GetHwMacAddress())
if err := ni.ifaceMgr.SetHWAddr(config.GetName(), state.GetEthernet().GetHwMacAddress()); err != nil {
log.Warningf("Failed to set mac address of port: %v", err)
}
}
}

if config.GetOrCreateSubinterface(intf.subintf).Enabled != nil {
if state.GetOrCreateSubinterface(intf.subintf).Enabled == nil || config.GetSubinterface(intf.subintf).GetEnabled() != state.GetSubinterface(intf.subintf).GetEnabled() {
log.V(1).Infof("setting interface %s enabled %t", data.hostifDevName, config.GetSubinterface(intf.subintf).GetEnabled())
Expand Down Expand Up @@ -350,79 +431,6 @@ func (ni *Reconciler) reconcile(ctx context.Context, config *oc.Interface) {
}
}
}

type prefixPair struct {
cfgIP, stateIP *string
cfgPL, statePL *uint8
}

// Get all state IPs and their corresponding config IPs (if they exist).
var interfacePairs []*prefixPair
for _, addr := range state.GetOrCreateSubinterface(0).GetOrCreateIpv4().Address {
pair := &prefixPair{
stateIP: addr.Ip,
statePL: addr.PrefixLength,
}
if pairAddr := config.GetSubinterface(0).GetIpv4().GetAddress(addr.GetIp()); pairAddr != nil {
pair.cfgIP = pairAddr.Ip
pair.cfgPL = pairAddr.PrefixLength
}
interfacePairs = append(interfacePairs, pair)
}
for _, addr := range state.GetOrCreateSubinterface(0).GetOrCreateIpv6().Address {
pair := &prefixPair{
stateIP: addr.Ip,
statePL: addr.PrefixLength,
}
if pairAddr := config.GetSubinterface(0).GetIpv6().GetAddress(addr.GetIp()); pairAddr != nil {
pair.cfgIP = pairAddr.Ip
pair.cfgPL = pairAddr.PrefixLength
}
interfacePairs = append(interfacePairs, pair)
}

// Get all config IPs and their corresponding state IPs (if they exist).
for _, addr := range config.GetOrCreateSubinterface(0).GetOrCreateIpv4().Address {
pair := &prefixPair{
cfgIP: addr.Ip,
cfgPL: addr.PrefixLength,
}
if pairAddr := state.GetSubinterface(0).GetIpv4().GetAddress(addr.GetIp()); pairAddr != nil {
pair.stateIP = pairAddr.Ip
pair.statePL = pairAddr.PrefixLength
}
interfacePairs = append(interfacePairs, pair)
}
for _, addr := range config.GetOrCreateSubinterface(0).GetOrCreateIpv6().Address {
pair := &prefixPair{
cfgIP: addr.Ip,
cfgPL: addr.PrefixLength,
}
if pairAddr := state.GetSubinterface(0).GetIpv6().GetAddress(addr.GetIp()); pairAddr != nil {
pair.stateIP = pairAddr.Ip
pair.statePL = pairAddr.PrefixLength
}
interfacePairs = append(interfacePairs, pair)
}

for _, pair := range interfacePairs {
// If an IP exists in state, but not in config, remove the IP.
if (pair.stateIP != nil && pair.statePL != nil) && (pair.cfgIP == nil && pair.cfgPL == nil) {
log.V(1).Infof("Delete Config IP: %v, Config PL: %v. State IP: %v, State PL: %v", pair.cfgIP, pair.cfgPL, *pair.stateIP, *pair.statePL)
log.V(2).Infof("deleting interface %s ip %s/%d", data.hostifDevName, *pair.stateIP, *pair.statePL)
if err := ni.ifaceMgr.DeleteIP(data.hostifDevName, *pair.stateIP, int(*pair.statePL)); err != nil {
log.Warningf("Failed to set ip address of port: %v", err)
}
}
// If an IP exists in config, but not in state (or state is different) add the IP.
if (pair.cfgIP != nil && pair.cfgPL != nil) && (pair.stateIP == nil || *pair.statePL != *pair.cfgPL) {
log.V(1).Infof("Set Config IP: %v, Config PL: %v. State IP: %v, State PL: %v", *pair.cfgIP, *pair.cfgPL, pair.stateIP, pair.statePL)
log.V(2).Infof("setting interface %s ip %s/%d", data.hostifDevName, *pair.cfgIP, *pair.cfgPL)
if err := ni.ifaceMgr.ReplaceIP(data.hostifDevName, *pair.cfgIP, int(*pair.cfgPL)); err != nil {
log.Warningf("Failed to set ip address of port: %v", err)
}
}
}
}

// getOrCreateInterface returns the state interface from the cache.
Expand Down Expand Up @@ -680,7 +688,7 @@ func (ni *Reconciler) setupPorts(ctx context.Context) error {
if i.Name == "lo" || i.Name == "eth0" || strings.HasSuffix(i.Name, internalSuffix) {
continue
}
log.Info("creating interfaces for %v", i.Name)
log.Infof("creating interfaces for %v", i.Name)
ocIntf := ocInterface{
name: i.Name,
subintf: 0,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/openconfig/gribigo v0.0.0-20231116195824-d8605fda9f33
github.com/openconfig/kne v0.1.15
github.com/openconfig/ondatra v0.4.3
github.com/openconfig/ygnmi v0.10.1
github.com/openconfig/ygnmi v0.10.3-0.20231206202950-b0c82a63c12e
github.com/openconfig/ygot v0.29.16
github.com/osrg/gobgp/v3 v3.20.0
github.com/p4lang/p4runtime v1.4.0-rc.5.0.20220728214547-13f0d02a521e
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1133,8 +1133,8 @@ github.com/openconfig/ondatra v0.4.3 h1:M6moqZRuA87aXNbHkZgj/U+Jj4WOjzgTC/EM1ARq
github.com/openconfig/ondatra v0.4.3/go.mod h1:WEZ0twDTtctPYDJ6D0zeyKwdXfEHRpKV7At0xPHMrBs=
github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07 h1:X631iD/B0ximGFb5P9LY5wHju4SiedxUhc5UZEo7VSw=
github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07/go.mod h1:bmpU0kIsCiXuncozViVuQx1HqolC3C94H7lD9KKmoTo=
github.com/openconfig/ygnmi v0.10.1 h1:Rdl3AglEUPdl+MGBRuHeaYbMFPUGpolkOJ/vAQhsZz4=
github.com/openconfig/ygnmi v0.10.1/go.mod h1:JKQ8HVkxH27Q8hHQHrb5uRj2uoyZp2CmJ6JbivXtD3g=
github.com/openconfig/ygnmi v0.10.3-0.20231206202950-b0c82a63c12e h1:TN13TezEZ6Vptv2lrB9GyMMetNV8rPxvOh6oz0RdvPo=
github.com/openconfig/ygnmi v0.10.3-0.20231206202950-b0c82a63c12e/go.mod h1:DWK7RTgfhrBNXQhA7+CnkNY986LxsoVShWsd0s9CeQY=
github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs=
github.com/openconfig/ygot v0.10.4/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ=
github.com/openconfig/ygot v0.13.2/go.mod h1:kJN0yCXIH07dOXvNBEFm3XxXdnDD5NI6K99tnD5x49c=
Expand Down
4 changes: 2 additions & 2 deletions repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -1688,8 +1688,8 @@ def go_repositories():
go_repository(
name = "com_github_openconfig_ygnmi",
importpath = "github.com/openconfig/ygnmi",
sum = "h1:Rdl3AglEUPdl+MGBRuHeaYbMFPUGpolkOJ/vAQhsZz4=",
version = "v0.10.1",
sum = "h1:TN13TezEZ6Vptv2lrB9GyMMetNV8rPxvOh6oz0RdvPo=",
version = "v0.10.3-0.20231206202950-b0c82a63c12e",
)
go_repository(
name = "com_github_openconfig_ygot",
Expand Down

0 comments on commit 9c1a030

Please sign in to comment.