diff --git a/api/core/v1alpha1/evpninstance_types.go b/api/core/v1alpha1/evpninstance_types.go
index d38fb01b7..be03ab3e1 100644
--- a/api/core/v1alpha1/evpninstance_types.go
+++ b/api/core/v1alpha1/evpninstance_types.go
@@ -85,6 +85,11 @@ type EVPNInstanceSpec struct {
// +optional
// +kubebuilder:validation:XValidation:rule="self.name == oldSelf.name",message="VRFRef is immutable"
VRFRef *LocalObjectReference `json:"vrfRef,omitempty"`
+
+ // SuppressARP overrides the NVE-level ARP suppression setting for this VNI.
+ // When unset, the NVE-level SuppressARP setting takes precedence.
+ // +optional
+ SuppressARP *bool `json:"suppressARP,omitempty"`
}
// EVPNInstanceType defines the type of EVPN instance.
diff --git a/api/core/v1alpha1/zz_generated.deepcopy.go b/api/core/v1alpha1/zz_generated.deepcopy.go
index 1ab6b9e18..ef9944b4a 100644
--- a/api/core/v1alpha1/zz_generated.deepcopy.go
+++ b/api/core/v1alpha1/zz_generated.deepcopy.go
@@ -2049,6 +2049,11 @@ func (in *EVPNInstanceSpec) DeepCopyInto(out *EVPNInstanceSpec) {
*out = new(LocalObjectReference)
**out = **in
}
+ if in.SuppressARP != nil {
+ in, out := &in.SuppressARP, &out.SuppressARP
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EVPNInstanceSpec.
diff --git a/charts/network-operator/templates/crd/evpninstances.networking.metal.ironcore.dev.yaml b/charts/network-operator/templates/crd/evpninstances.networking.metal.ironcore.dev.yaml
index 519d3d2d4..7a91dc3eb 100644
--- a/charts/network-operator/templates/crd/evpninstances.networking.metal.ironcore.dev.yaml
+++ b/charts/network-operator/templates/crd/evpninstances.networking.metal.ironcore.dev.yaml
@@ -168,6 +168,11 @@ spec:
x-kubernetes-list-map-keys:
- value
x-kubernetes-list-type: map
+ suppressARP:
+ description: |-
+ SuppressARP overrides the NVE-level ARP suppression setting for this VNI.
+ When unset, the NVE-level SuppressARP setting takes precedence.
+ type: boolean
type:
description: |-
Type specifies the EVPN instance type.
diff --git a/config/crd/bases/networking.metal.ironcore.dev_evpninstances.yaml b/config/crd/bases/networking.metal.ironcore.dev_evpninstances.yaml
index 8ee981b5f..f0d04fb02 100644
--- a/config/crd/bases/networking.metal.ironcore.dev_evpninstances.yaml
+++ b/config/crd/bases/networking.metal.ironcore.dev_evpninstances.yaml
@@ -165,6 +165,11 @@ spec:
x-kubernetes-list-map-keys:
- value
x-kubernetes-list-type: map
+ suppressARP:
+ description: |-
+ SuppressARP overrides the NVE-level ARP suppression setting for this VNI.
+ When unset, the NVE-level SuppressARP setting takes precedence.
+ type: boolean
type:
description: |-
Type specifies the EVPN instance type.
diff --git a/docs/api-reference/index.md b/docs/api-reference/index.md
index ed271ca0e..d4d8a6b3e 100644
--- a/docs/api-reference/index.md
+++ b/docs/api-reference/index.md
@@ -1943,6 +1943,7 @@ _Appears in:_
| `routeTargets` _[EVPNRouteTarget](#evpnroutetarget) array_ | RouteTargets is the list of route targets for the EVI. | | MinItems: 1
Optional: \{\}
|
| `vlanRef` _[LocalObjectReference](#localobjectreference)_ | VLANRef is a reference to a VLAN resource for which this EVPNInstance builds the MAC-VRF.
This field is only applicable when Type is Bridged (L2VNI).
The VLAN resource must exist in the same namespace.
Immutable. | | Optional: \{\}
|
| `vrfRef` _[LocalObjectReference](#localobjectreference)_ | VRFRef is a reference to a VRF resource for which this EVPNInstance provides the L3VNI.
This field is only applicable when Type is Routed (L3VNI).
The VRF resource must exist in the same namespace.
Immutable. | | Optional: \{\}
|
+| `suppressARP` _boolean_ | SuppressARP overrides the NVE-level ARP suppression setting for this VNI.
When unset, the NVE-level SuppressARP setting takes precedence. | | Optional: \{\}
|
#### EVPNInstanceStatus
diff --git a/internal/provider/cisco/nxos/nve.go b/internal/provider/cisco/nxos/nve.go
index cb46c33e7..70a7f15fb 100644
--- a/internal/provider/cisco/nxos/nve.go
+++ b/internal/provider/cisco/nxos/nve.go
@@ -68,6 +68,7 @@ type VNI struct {
AssociateVrfFlag bool `json:"associateVrfFlag"`
McastGroup Option[string] `json:"mcastGroup"`
Vni int32 `json:"vni"`
+ SuppressARP Option[bool] `json:"suppressARP"`
}
func (*VNI) IsListItem() {}
diff --git a/internal/provider/cisco/nxos/nve_test.go b/internal/provider/cisco/nxos/nve_test.go
index 3a545f767..dc7c856a9 100644
--- a/internal/provider/cisco/nxos/nve_test.go
+++ b/internal/provider/cisco/nxos/nve_test.go
@@ -22,6 +22,20 @@ func init() {
McastGroup: NewOption("239.1.1.100"),
}
Register("vni", vni)
+
+ suppressARPTrue := true
+ vniSuppressARPTrue := &VNI{
+ Vni: 100011,
+ SuppressARP: Option[bool]{Value: &suppressARPTrue},
+ }
+ Register("vni_suppress_arp_true", vniSuppressARPTrue)
+
+ suppressARPFalse := false
+ vniSuppressARPFalse := &VNI{
+ Vni: 100012,
+ SuppressARP: Option[bool]{Value: &suppressARPFalse},
+ }
+ Register("vni_suppress_arp_false", vniSuppressARPFalse)
nveInfraVLANs := &NVEInfraVLANs{
InfraVLANList: []*NVEInfraVLAN{
{ID: 4052},
diff --git a/internal/provider/cisco/nxos/option.go b/internal/provider/cisco/nxos/option.go
index 7e70ee4e8..3a938a1c1 100644
--- a/internal/provider/cisco/nxos/option.go
+++ b/internal/provider/cisco/nxos/option.go
@@ -33,7 +33,7 @@ func (o Option[T]) MarshalJSON() ([]byte, error) {
}
func (o *Option[T]) UnmarshalJSON(b []byte) error {
- if len(b) == 0 || string(b) == `null` {
+ if len(b) == 0 || string(b) == `null` || string(b) == `"DME_UNSET_PROPERTY_MARKER"` {
o.Value = nil
return nil
}
diff --git a/internal/provider/cisco/nxos/provider.go b/internal/provider/cisco/nxos/provider.go
index 4e1fc96b9..21288b5ee 100644
--- a/internal/provider/cisco/nxos/provider.go
+++ b/internal/provider/cisco/nxos/provider.go
@@ -1117,6 +1117,10 @@ func (p *Provider) EnsureEVPNInstance(ctx context.Context, req *provider.EVPNIns
if req.EVPNInstance.Spec.MulticastGroupAddress != "" {
vni.McastGroup = NewOption(req.EVPNInstance.Spec.MulticastGroupAddress)
}
+ if req.EVPNInstance.Spec.SuppressARP != nil {
+ v := *req.EVPNInstance.Spec.SuppressARP
+ vni.SuppressARP = Option[bool]{Value: &v}
+ }
sb.Update(vni)
switch req.EVPNInstance.Spec.Type {
diff --git a/internal/provider/cisco/nxos/testdata/vni.json b/internal/provider/cisco/nxos/testdata/vni.json
index 8f4e8cfe0..1792184e5 100644
--- a/internal/provider/cisco/nxos/testdata/vni.json
+++ b/internal/provider/cisco/nxos/testdata/vni.json
@@ -10,7 +10,8 @@
{
"associateVrfFlag": false,
"mcastGroup": "239.1.1.100",
- "vni": 100010
+ "vni": 100010,
+ "suppressARP": "DME_UNSET_PROPERTY_MARKER"
}
]
}
diff --git a/internal/provider/cisco/nxos/testdata/vni_suppress_arp_false.json b/internal/provider/cisco/nxos/testdata/vni_suppress_arp_false.json
new file mode 100644
index 000000000..5223aff2d
--- /dev/null
+++ b/internal/provider/cisco/nxos/testdata/vni_suppress_arp_false.json
@@ -0,0 +1,23 @@
+{
+ "eps-items": {
+ "epId-items": {
+ "Ep-list": [
+ {
+ "epId": "1",
+ "nws-items": {
+ "vni-items": {
+ "Nw-list": [
+ {
+ "associateVrfFlag": false,
+ "mcastGroup": "DME_UNSET_PROPERTY_MARKER",
+ "vni": 100012,
+ "suppressARP": false
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/internal/provider/cisco/nxos/testdata/vni_suppress_arp_true.json b/internal/provider/cisco/nxos/testdata/vni_suppress_arp_true.json
new file mode 100644
index 000000000..2528b3c06
--- /dev/null
+++ b/internal/provider/cisco/nxos/testdata/vni_suppress_arp_true.json
@@ -0,0 +1,23 @@
+{
+ "eps-items": {
+ "epId-items": {
+ "Ep-list": [
+ {
+ "epId": "1",
+ "nws-items": {
+ "vni-items": {
+ "Nw-list": [
+ {
+ "associateVrfFlag": false,
+ "mcastGroup": "DME_UNSET_PROPERTY_MARKER",
+ "vni": 100011,
+ "suppressARP": true
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/test/gnmi/testdata/cisco-nxos-gnmi/evpninstance.txtar b/test/gnmi/testdata/cisco-nxos-gnmi/evpninstance.txtar
index fd0fae846..0a275a34b 100644
--- a/test/gnmi/testdata/cisco-nxos-gnmi/evpninstance.txtar
+++ b/test/gnmi/testdata/cisco-nxos-gnmi/evpninstance.txtar
@@ -86,7 +86,8 @@ spec:
{
"associateVrfFlag": false,
"mcastGroup": "DME_UNSET_PROPERTY_MARKER",
- "vni": 10100
+ "vni": 10100,
+ "suppressARP": "DME_UNSET_PROPERTY_MARKER"
}
]
}