Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
634 changes: 502 additions & 132 deletions feature/ttl/otg_tests/egress/egress_handle_ttl_test.go

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion feature/ttl/otg_tests/egress/metadata.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ platform_exceptions: {
static_mpls_lsp_oc_unsupported: true
gre_decapsulation_oc_unsupported: true
decapsulate_gue_oc_unsupported: true
decap_icmp_ttl_exceeded_unsupported: true
}
}
}
101 changes: 101 additions & 0 deletions internal/cfgplugins/dut_initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const (
FeatureHierarchicalFIB
FeatureSecondaryDefaultLookup
FeatureAnpf
FeatureICMPForwarding

aristaTcamProfileMplsTracking = `
hardware counter feature traffic-policy in
Expand Down Expand Up @@ -1367,6 +1368,105 @@ hardware tcam
packet ipv4 vxlan forwarding bridged decap
!
system profile anPF
`
aristaICMPForwarding = `
hardware tcam
profile test-customtcam
system-rule overriding-action redirect
feature acl vlan ipv6 egress
key field forwarding-type
action count
packet ipv6 forwarding bridged
packet ipv6 forwarding routed
feature cfm
packet ipv4 forwarding bridged
packet ipv6 forwarding bridged
packet non-ip forwarding bridged
feature interface-policing
action count police-interface
packet ipv4 forwarding bridged
packet ipv4 forwarding routed
packet ipv6 forwarding bridged
packet ipv6 forwarding routed
packet non-ip forwarding bridged
feature l2-protocol forwarding
key size limit 160
key field dst-mac vlan-tag-format
action redirect-to-cpu
packet non-ip forwarding bridged
feature mirror ip
key size limit 160
key field dscp dst-ip ip-frag ip-protocol l4-dst-port l4-ops l4-src-port src-ip tcp-control
action count mirror
packet ipv4 forwarding bridged
packet ipv4 forwarding routed
packet ipv4 forwarding routed multicast
packet ipv4 non-vxlan forwarding routed decap
feature mpls
key size limit 160
action drop redirect set-ecn
packet ipv4 mpls ipv4 forwarding mpls decap
packet ipv4 mpls ipv6 forwarding mpls decap
packet ipv4 gue mpls forwarding mpls decap
packet ipv6 gue mpls forwarding mpls decap
packet mpls ipv4 forwarding mpls
packet mpls ipv6 forwarding mpls
packet mpls non-ip forwarding mpls
feature mpls pop ingress
feature mpls pop ingress multicast
packet mpls ipv4 forwarding mpls php
packet mpls ipv6 forwarding mpls php
feature qos ip
sequence 90
port qualifier size 2 bits
key field dscp dst-ip forwarding-type ip-frag ip-protocol l4-dst-port l4-ops-7b l4-src-port outer-vlan-id src-ip tcp-control vlan-tag-format
action count set-drop-precedence set-dscp set-policer set-tc
packet ipv4 forwarding bridged
packet ipv4 forwarding routed
packet ipv4 forwarding routed multicast
packet ipv4 mpls ipv4 forwarding mpls decap
packet ipv4 mpls ipv6 forwarding mpls decap
packet ipv4 non-vxlan forwarding routed decap
feature qos ipv6
port qualifier size 2 bits
key field dst-ipv6 ipv6-next-header ipv6-traffic-class l4-dst-port l4-src-port src-ipv6-high src-ipv6-low
action count set-drop-precedence set-dscp set-policer set-tc
packet ipv6 forwarding routed
feature qos mac
key size limit 160
port qualifier size 2 bits
key field forwarding-type ipv6-traffic-class mpls-traffic-class vlan
action count set-dscp set-policer set-tc
packet ipv6 forwarding bridged
packet mpls forwarding bridged decap
packet mpls ipv4 forwarding mpls
packet mpls ipv6 forwarding mpls
packet mpls non-ip forwarding mpls
packet non-ip forwarding bridged
feature traffic-policy port ipv4
port qualifier size 12 bits
key field dscp dst-ip-label dst-mac dst-port ip-frag ip-fragment-offset ip-length ip-protocol ipv4-mc l4-dst-port l4-src-port src-ip-label src-mac tcp-control ttl
action copy-ttl count drop redirect set-dscp set-fwd-layer-index set-policer set-tc set-ttl
packet ipv4 forwarding bridged
packet ipv4 forwarding routed
packet ipv4 mpls ipv4 forwarding mpls decap
packet ipv4 non-vxlan forwarding routed decap
packet mpls ipv4 forwarding bridged
packet mpls ipv4 forwarding mpls
packet mpls ipv4 forwarding routed decap
feature traffic-policy port ipv6
port qualifier size 12 bits
key field dst-ipv6-label dst-mac hop-limit ipv6-length ipv6-mc ipv6-next-header ipv6-traffic-class l4-dst-port l4-src-port src-ipv6-label src-mac tcp-control
action copy-ttl count drop redirect set-dscp set-fwd-layer-index set-tc set-ttl
packet ipv4 mpls ipv6 forwarding mpls decap
packet ipv6 forwarding bridged
packet ipv6 forwarding routed
packet ipv6 forwarding routed decap
packet mpls ipv6 forwarding bridged
packet mpls ipv6 forwarding mpls
packet mpls ipv6 forwarding routed decap
!
system profile test-customtcam
`
)

Expand All @@ -1391,6 +1491,7 @@ var (
FeatureOptimizeFIBAndCounters: aristaOptimizeFIBAndCounters,
FeatureAnpf: aristaAnpfTcamProfile,
FeatureHierarchicalFIB: aristaHierarchicalFIB,
FeatureICMPForwarding: aristaICMPForwarding,
}

nokiaHardwareInitMap = map[FeatureType]string{
Expand Down
11 changes: 9 additions & 2 deletions internal/cfgplugins/mpls.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,22 @@ func RemoveStaticMplsLspPushLabel(t *testing.T, dut *ondatra.DUTDevice, lspName
gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Mpls().Config(), mplsCfg)
}

// MPLSStaticLSPByPass configures a static MPLS LSP POP label binding with an
// optional access-list bypass. It uses CLI configuration when OpenConfig static
// MPLS LSP configuration is unsupported on the DUT.
func MPLSStaticLSPByPass(t *testing.T, batch *gnmi.SetBatch, dut *ondatra.DUTDevice, lspName string, incomingLabel uint32, nextHopIP string, protocolType string, byPass bool) {
if deviations.StaticMplsLspOCUnsupported(dut) {
cliConfig := ""
switch dut.Vendor() {
case ondatra.ARISTA:
bypassStr := ""
if byPass {
bypassStr = "access-list bypass"
}
cliConfig = fmt.Sprintf(`
mpls ip
mpls static top-label %v %s pop payload-type %s access-list bypass
`, incomingLabel, nextHopIP, protocolType)
mpls static top-label %v %s pop payload-type %s %s
`, incomingLabel, nextHopIP, protocolType, bypassStr)
helpers.GnmiCLIConfig(t, dut, cliConfig)
default:
t.Errorf("Deviation StaticMplsLspOCUnsupported is not handled for the dut: %v", dut.Vendor())
Expand Down
204 changes: 173 additions & 31 deletions internal/cfgplugins/policyforwarding.go
Original file line number Diff line number Diff line change
Expand Up @@ -1216,52 +1216,54 @@ func trafficPolicyCliConfig(t *testing.T, dut *ondatra.DUTDevice, policyName str
}
}

// Configure GRE decapsulated. Adding deviation when device doesn't support OC
func NewConfigureGRETunnel(t *testing.T, dut *ondatra.DUTDevice, decapIp string, decapGrpName string) {
// GRETunnelParams contains the parameters required to configure a GRE decapsulation tunnel.
type GRETunnelParams struct {
DecapIP string
DecapGroupName string
DecapInterface string
}

// NewConfigureGRETunnel configures GRE decapsulation on the DUT and returns the batch.
func NewConfigureGRETunnel(t *testing.T, dut *ondatra.DUTDevice, batch *gnmi.SetBatch, cfg GRETunnelParams) *gnmi.SetBatch {
if deviations.GreDecapsulationOCUnsupported(dut) {
var decapIPAddr string
if strings.Contains(decapIp, "/") {
decapIPAddr = strings.Split(decapIp, "/")[0]
if strings.Contains(cfg.DecapIP, "/") {
decapIPAddr = strings.Split(cfg.DecapIP, "/")[0]
} else {
decapIPAddr = decapIp
decapIPAddr = cfg.DecapIP
}
switch dut.Vendor() {
case ondatra.ARISTA:
cliConfig := fmt.Sprintf(`
ip decap-group %s
tunnel type gre
tunnel decap-ip %s
`, decapGrpName, decapIPAddr)
`, cfg.DecapGroupName, decapIPAddr)
helpers.GnmiCLIConfig(t, dut, cliConfig)

default:
t.Errorf("deviation GreDecapsulationUnsupported is not handled for the dut: %v", dut.Vendor())
}
} else {
d := &oc.Root{}
ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut))
ni1.SetType(oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE)
npf := ni1.GetOrCreatePolicyForwarding()
np := npf.GetOrCreatePolicy("PBR-MAP")
np.PolicyId = ygot.String("PBR-MAP")
np.Type = oc.Policy_Type_PBR_POLICY

npRule := np.GetOrCreateRule(10)
ip := npRule.GetOrCreateIpv4()
ip.DestinationAddressPrefixSet = ygot.String(decapIp)
npAction := npRule.GetOrCreateAction()
npAction.DecapsulateGre = ygot.Bool(true)

port := dut.Port(t, "port1")
ingressPort := port.Name()
t.Logf("Applying forwarding policy on interface %v ... ", ingressPort)

intf := npf.GetOrCreateInterface(ingressPort)
intf.ApplyForwardingPolicy = ygot.String("PBR-MAP")
intf.GetOrCreateInterfaceRef().Interface = ygot.String(ingressPort)

gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Config(), ni1)
return batch
}
d := &oc.Root{}
ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut))
ni1.SetType(oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE)
npf := ni1.GetOrCreatePolicyForwarding()
np := npf.GetOrCreatePolicy(cfg.DecapGroupName)
np.PolicyId = ygot.String(cfg.DecapGroupName)
np.Type = oc.Policy_Type_PBR_POLICY
npRule := np.GetOrCreateRule(0)
ip := npRule.GetOrCreateIpv4()
ip.DestinationAddress = ygot.String(cfg.DecapIP)
ip.Protocol = oc.PacketMatchTypes_IP_PROTOCOL_IP_GRE
npAction := npRule.GetOrCreateAction()
npAction.DecapsulateGre = ygot.Bool(true)
t.Logf("Applying forwarding policy on interface %v ... ", cfg.DecapInterface)
intf := npf.GetOrCreateInterface(cfg.DecapInterface)
intf.ApplyForwardingPolicy = ygot.String(cfg.DecapGroupName)
intf.GetOrCreateInterfaceRef().Interface = ygot.String(cfg.DecapInterface)
gnmi.BatchUpdate(batch, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Config(), ni1)
return batch
}

// ConfigureDutWithGueDecap configures the DUT to decapsulate GUE (Generic UDP Encapsulation) traffic. It supports both native CLI configuration (for vendors like Arista) and OpenConfig (GNMI) configuration.
Expand Down Expand Up @@ -2120,3 +2122,143 @@ func RemoveDecapGroupConfigGueIPv6Scale(t *testing.T, dut *ondatra.DUTDevice, pa
}
gnmi.Delete(t, dut, pfPath.Policy(params.PolicyID).Config())
}

// GUEDecapParams contains the parameters required to configure GUE
// decapsulation on the DUT.
type GUEDecapParams struct {
GUEPort int
IPType string
TunnelIP string
DecapInt string
PolicyName string
PolicyID int
}

// NewConfigureDutWithGueDecap configures the DUT to decapsulate GUE traffic.
// It supports native CLI configuration for devices that do not support the
// required OpenConfig configuration and OpenConfig configuration otherwise.
func NewConfigureDutWithGueDecap(t *testing.T, dut *ondatra.DUTDevice, batch *gnmi.SetBatch, params GUEDecapParams) *gnmi.SetBatch {
t.Helper()
t.Logf("Configure DUT with decapsulation UDP port %v", params.GUEPort)
payloadType := params.IPType
if deviations.DecapsulateGueOCUnsupported(dut) {
switch dut.Vendor() {
case ondatra.ARISTA:
if strings.EqualFold(params.IPType, "ipv4") {
payloadType = "ip"
}
// The global tunnel type binding is required in addition to the
// decap-group so the UDP destination port is associated with the
// payload type.
cliConfig := fmt.Sprintf(`
ip decap-group type udp destination port %[1]d payload %[2]s
tunnel type %[3]s-over-udp udp destination port %[1]d
ip decap-group %[4]s
tunnel type udp
tunnel decap-ip %[5]s
`,
params.GUEPort, payloadType, params.IPType, params.PolicyName, params.TunnelIP)
helpers.GnmiCLIConfig(t, dut, cliConfig)
default:
t.Errorf(
"deviation DecapsulateGueOCUnsupported is not handled for the DUT: %v",
dut.Vendor(),
)
}
return batch
}
d := &oc.Root{}
ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut))
ni1.SetType(oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE)
npf := ni1.GetOrCreatePolicyForwarding()
np := npf.GetOrCreatePolicy(params.PolicyName)
np.PolicyId = ygot.String(params.PolicyName)
np.Type = oc.Policy_Type_PBR_POLICY
npRule := np.GetOrCreateRule(uint32(params.PolicyID))
if strings.Contains(params.TunnelIP, ":") {
payloadType = "ipv6"
}
if strings.EqualFold(payloadType, "ipv6") {
ip := npRule.GetOrCreateIpv6()
ip.DestinationAddress = ygot.String(params.TunnelIP)
ip.Protocol = oc.PacketMatchTypes_IP_PROTOCOL_IP_UDP
} else {
ip := npRule.GetOrCreateIpv4()
ip.DestinationAddress = ygot.String(params.TunnelIP)
ip.Protocol = oc.PacketMatchTypes_IP_PROTOCOL_IP_UDP
}
npRule.GetOrCreateTransport().SetDestinationPort(oc.UnionUint16(params.GUEPort))
npAction := npRule.GetOrCreateAction()
if strings.EqualFold(params.IPType, "mpls") {
npAction.DecapsulateMplsInUdp = ygot.Bool(true)
} else {
npAction.DecapsulateGue = ygot.Bool(true)
}
t.Logf("Applying forwarding policy %v on interface %v ...", params.PolicyName, params.DecapInt)
intf := npf.GetOrCreateInterface(params.DecapInt)
intf.ApplyForwardingPolicy = ygot.String(params.PolicyName)
intf.GetOrCreateInterfaceRef().Interface = ygot.String(params.DecapInt)
gnmi.BatchUpdate(batch, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Config(), ni1)
return batch
}

// NewRemoveDutGueDecap removes the GUE decapsulation configuration previously applied by
// NewConfigureDutWithGueDecap for the same params, restoring the DUT to its original state.
func NewRemoveDutGueDecap(t *testing.T, dut *ondatra.DUTDevice, params GUEDecapParams) {
t.Helper()
t.Logf("Removing GUE decapsulation configuration for UDP port %v", params.GUEPort)
if deviations.DecapsulateGueOCUnsupported(dut) {
switch dut.Vendor() {
case ondatra.ARISTA:
payloadType := params.IPType
if strings.EqualFold(params.IPType, "ipv4") {
payloadType = "ip"
}
cliConfig := fmt.Sprintf(`
no ip decap-group %[1]s
no tunnel type %[2]s-over-udp udp destination port %[3]d
no ip decap-group type udp destination port %[3]d payload %[4]s
`,
params.PolicyName, params.IPType, params.GUEPort, payloadType)
helpers.GnmiCLIConfig(t, dut, cliConfig)
default:
t.Logf(
"Skipping GUE decap-group removal: deviation DecapsulateGueOCUnsupported is not handled for the DUT: %v",
dut.Vendor(),
)
}
return
}
pf := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding()
// A dedicated batch is used so that only the deletes below are pushed to the DUT.
cleanupBatch := &gnmi.SetBatch{}
gnmi.BatchDelete(cleanupBatch, pf.Interface(params.DecapInt).Config())
gnmi.BatchDelete(cleanupBatch, pf.Policy(params.PolicyName).Config())
cleanupBatch.Set(t, dut)
}

// NewRemoveGRETunnel removes the GRE decapsulation configuration previously applied by
// NewConfigureGRETunnel for the same params, restoring the DUT to its original state.
func NewRemoveGRETunnel(t *testing.T, dut *ondatra.DUTDevice, cfg GRETunnelParams) {
t.Helper()
t.Logf("Removing GRE decapsulation configuration for decap-group %v", cfg.DecapGroupName)
if deviations.GreDecapsulationOCUnsupported(dut) {
switch dut.Vendor() {
case ondatra.ARISTA:
helpers.GnmiCLIConfig(t, dut, fmt.Sprintf("no ip decap-group %s\n", cfg.DecapGroupName))
default:
t.Logf(
"Skipping GRE decap-group removal: deviation GreDecapsulationOCUnsupported is not handled for the DUT: %v",
dut.Vendor(),
)
}
return
}
pf := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding()
// A dedicated batch is used here: the setup batch still holds every interface/LSP/GRE update
// applied during configuration and reusing it would re-push all of it along with the deletes.
cleanupBatch := &gnmi.SetBatch{}
gnmi.BatchDelete(cleanupBatch, pf.Interface(cfg.DecapInterface).Config())
gnmi.BatchDelete(cleanupBatch, pf.Policy(cfg.DecapGroupName).Config())
cleanupBatch.Set(t, dut)
}
7 changes: 7 additions & 0 deletions internal/deviations/deviations.go
Original file line number Diff line number Diff line change
Expand Up @@ -2395,3 +2395,10 @@ func BgpAdjRibOcUnsupported(dut *ondatra.DUTDevice) bool {
func AigpMetricIncrement(dut *ondatra.DUTDevice) bool {
return lookupDUTDeviations(dut).GetAigpMetricIncrement()
}

// DecapICMPTTLExceededUnsupported returns true if the device does not support
// generating ICMP TTL Exceeded messages for decapsulated packets.
// Arista: https://partnerissuetracker.corp.google.com/issues/556092813
func DecapICMPTTLExceededUnsupported(dut *ondatra.DUTDevice) bool {
return lookupDUTDeviations(dut).GetDecapIcmpTtlExceededUnsupported()
}
Loading
Loading