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

Reactor test #339

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
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 @@
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 @@
}
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 @@
}
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 @@
}
}
}

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 @@
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
Loading