Skip to content

Commit 0acde97

Browse files
committed
feat(agent): support for static ARP entries
Signed-off-by: Emanuele Di Pascale <[email protected]>
1 parent a4c3d65 commit 0acde97

File tree

3 files changed

+102
-1
lines changed

3 files changed

+102
-1
lines changed

pkg/agent/dozer/bcm/enforcer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,13 @@ const (
100100
ActionWeightPortChannelConfigFallbackUpdate
101101

102102
ActionWeightInterfaceSubinterfaceIPsDelete
103+
ActionWeghtInterfaceStaticARPDelete
103104
ActionWeightVRFAttachedHostDelete
104105
ActionWeightVRFInterfaceDelete
105106
ActionWeightACLInterfaceDelete
106107
ActionWeightInterfaceSubinterfaceDelete
107108
ActionWeightInterfaceSubinterfaceUpdate
109+
ActionWeghtInterfaceStaticARPUpdate
108110
ActionWeightVRFInterfaceUpdate
109111
ActionWeightVRFAttachedHostUpdate
110112
ActionWeightInterfaceSubinterfaceIPsUpdate

pkg/agent/dozer/bcm/spec_interface.go

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ var specInterfaceEnforcer = &DefaultValueEnforcer[string, *dozer.SpecInterface]{
8686
return errors.Wrap(err, "failed to handle interface IPs")
8787
}
8888

89+
actualStaticARPs, desiredStaticARPs := ValueOrNil(actual, desired,
90+
func(value *dozer.SpecInterface) map[string]*dozer.SpecStaticARP { return value.StaticARPs })
91+
if err := specInterfaceVLANStaticARPsEnforcer.Handle(basePath, actualStaticARPs, desiredStaticARPs, actions); err != nil {
92+
return errors.Wrap(err, "failed to handle interface static ARPs")
93+
}
94+
8995
if err := specInterfaceEthernetBaseEnforcer.Handle(basePath, name, actual, desired, actions); err != nil {
9096
return errors.Wrap(err, "failed to handle interface ethernet")
9197
}
@@ -228,6 +234,56 @@ var specInterfaceVLANIPEnforcer = &DefaultValueEnforcer[string, *dozer.SpecInter
228234
},
229235
}
230236

237+
var specInterfaceVLANStaticARPsEnforcer = &DefaultMapEnforcer[string, *dozer.SpecStaticARP]{
238+
Summary: "Interface %s VLAN Static ARPs",
239+
ValueHandler: specInterfaceVLANStaticARPEnforcer,
240+
}
241+
242+
var specInterfaceVLANStaticARPEnforcer = &DefaultValueEnforcer[string, *dozer.SpecStaticARP]{
243+
Summary: "Interface VLAN Static ARP %s",
244+
Path: "/routed-vlan/ipv4/neighbors/neighbor[ip=%s]",
245+
UpdateWeight: ActionWeghtInterfaceStaticARPUpdate,
246+
DeleteWeight: ActionWeghtInterfaceStaticARPDelete,
247+
Marshal: func(name string, value *dozer.SpecStaticARP) (ygot.ValidatedGoStruct, error) {
248+
return &oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_Neighbors{
249+
Neighbor: map[string]*oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_Neighbors_Neighbor{
250+
name: {
251+
Ip: pointer.To(name),
252+
Config: &oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_Neighbors_Neighbor_Config{
253+
Ip: pointer.To(name),
254+
LinkLayerAddress: pointer.To(value.MAC),
255+
},
256+
},
257+
},
258+
}, nil
259+
},
260+
}
261+
262+
var specInterfaceSubinterfaceStaticARPsEnforcer = &DefaultMapEnforcer[string, *dozer.SpecStaticARP]{
263+
Summary: "Subinterface %s Static ARPs",
264+
ValueHandler: specInterfaceSubinterfaceStaticARPEnforcer,
265+
}
266+
267+
var specInterfaceSubinterfaceStaticARPEnforcer = &DefaultValueEnforcer[string, *dozer.SpecStaticARP]{
268+
Summary: "SubInterface Static ARP %s",
269+
Path: "/ipv4/neighbors/neighbor[ip=%s]",
270+
UpdateWeight: ActionWeghtInterfaceStaticARPUpdate,
271+
DeleteWeight: ActionWeghtInterfaceStaticARPDelete,
272+
Marshal: func(name string, value *dozer.SpecStaticARP) (ygot.ValidatedGoStruct, error) {
273+
return &oc.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface_Ipv4_Neighbors{
274+
Neighbor: map[string]*oc.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface_Ipv4_Neighbors_Neighbor{
275+
name: {
276+
Ip: pointer.To(name),
277+
Config: &oc.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface_Ipv4_Neighbors_Neighbor_Config{
278+
Ip: pointer.To(name),
279+
LinkLayerAddress: pointer.To(value.MAC),
280+
},
281+
},
282+
},
283+
}, nil
284+
},
285+
}
286+
231287
var specInterfaceVLANProxyARPEnforcer = &DefaultValueEnforcer[string, *dozer.SpecInterface]{
232288
Summary: "Interface VLAN Proxy-ARP",
233289
Path: "/routed-vlan/ipv4/proxy-arp/config",
@@ -302,6 +358,12 @@ var specInterfaceSubinterfaceEnforcer = &DefaultValueEnforcer[uint32, *dozer.Spe
302358
return errors.Wrap(err, "failed to handle subinterface IPs")
303359
}
304360

361+
actualStaticARPs, desiredStaticARPs := ValueOrNil(actual, desired,
362+
func(value *dozer.SpecSubinterface) map[string]*dozer.SpecStaticARP { return value.StaticARPs })
363+
if err := specInterfaceSubinterfaceStaticARPsEnforcer.Handle(basePath, actualStaticARPs, desiredStaticARPs, actions); err != nil {
364+
return errors.Wrap(err, "failed to handle subinterface static ARPs")
365+
}
366+
305367
return nil // TODO
306368
},
307369
}
@@ -636,6 +698,7 @@ func unmarshalOCInterfaces(agent *agentapi.Agent, ocVal *oc.OpenconfigInterfaces
636698
MTU: mtu,
637699
Subinterfaces: map[uint32]*dozer.SpecSubinterface{},
638700
VLANIPs: map[string]*dozer.SpecInterfaceIP{},
701+
StaticARPs: map[string]*dozer.SpecStaticARP{},
639702
}
640703

641704
// just skip interfaces disabled by Fabric
@@ -650,7 +713,8 @@ func unmarshalOCInterfaces(agent *agentapi.Agent, ocVal *oc.OpenconfigInterfaces
650713
}
651714

652715
subIface := &dozer.SpecSubinterface{
653-
IPs: map[string]*dozer.SpecInterfaceIP{},
716+
IPs: map[string]*dozer.SpecInterfaceIP{},
717+
StaticARPs: map[string]*dozer.SpecStaticARP{},
654718
}
655719

656720
if sub.Ipv4 != nil && sub.Ipv4.Addresses != nil {
@@ -677,6 +741,18 @@ func unmarshalOCInterfaces(agent *agentapi.Agent, ocVal *oc.OpenconfigInterfaces
677741
subIface.ProxyARP = pa
678742
}
679743

744+
if sub.Ipv4 != nil && sub.Ipv4.Neighbors != nil && len(sub.Ipv4.Neighbors.Neighbor) > 0 {
745+
for _, n := range sub.Ipv4.Neighbors.Neighbor {
746+
if n.Config == nil || n.Config.Ip == nil || n.Config.LinkLayerAddress == nil {
747+
continue
748+
}
749+
subIface.StaticARPs[*n.Config.Ip] = &dozer.SpecStaticARP{
750+
IP: *n.Config.Ip,
751+
MAC: *n.Config.LinkLayerAddress,
752+
}
753+
}
754+
}
755+
680756
if sub.Vlan != nil {
681757
if sub.Vlan.Config != nil {
682758
subIface.VLAN, err = unmarshalVLAN(sub.Vlan.Config.VlanId)
@@ -726,6 +802,17 @@ func unmarshalOCInterfaces(agent *agentapi.Agent, ocVal *oc.OpenconfigInterfaces
726802
}
727803
iface.ProxyARP = pa
728804
}
805+
if ocIface.RoutedVlan.Ipv4.Neighbors != nil && len(ocIface.RoutedVlan.Ipv4.Neighbors.Neighbor) > 0 {
806+
for _, n := range ocIface.RoutedVlan.Ipv4.Neighbors.Neighbor {
807+
if n.Config == nil || n.Config.Ip == nil || n.Config.LinkLayerAddress == nil {
808+
continue
809+
}
810+
iface.StaticARPs[*n.Config.Ip] = &dozer.SpecStaticARP{
811+
IP: *n.Config.Ip,
812+
MAC: *n.Config.LinkLayerAddress,
813+
}
814+
}
815+
}
729816
}
730817
}
731818
if vlan && !isVLAN(name) {

pkg/agent/dozer/dozer.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ type SpecProxyARP struct {
116116
All bool `json:"all,omitempty"`
117117
}
118118

119+
type SpecStaticARP struct {
120+
IP string `json:"ip,omitempty"`
121+
MAC string `json:"mac,omitempty"`
122+
}
123+
119124
type SpecInterface struct {
120125
Description *string `json:"description,omitempty"`
121126
Enabled *bool `json:"enabled,omitempty"`
@@ -129,6 +134,7 @@ type SpecInterface struct {
129134
VLANAnycastGateway []string `json:"vlanAnycastGateway,omitempty"`
130135
Subinterfaces map[uint32]*SpecSubinterface `json:"subinterfaces,omitempty"`
131136
ProxyARP *SpecProxyARP `json:"proxyARP,omitempty"`
137+
StaticARPs map[string]*SpecStaticARP `json:"staticARPs,omitempty"`
132138
}
133139

134140
type SpecInterfaceIP struct {
@@ -141,6 +147,7 @@ type SpecSubinterface struct {
141147
IPs map[string]*SpecInterfaceIP `json:"ips,omitempty"`
142148
AnycastGateways []string `json:"anycastGateways,omitempty"`
143149
ProxyARP *SpecProxyARP `json:"proxyARP,omitempty"`
150+
StaticARPs map[string]*SpecStaticARP `json:"staticARPs,omitempty"`
144151
}
145152

146153
type SpecMCLAGDomain struct {
@@ -484,6 +491,7 @@ var (
484491
_ SpecPart = (*SpecSubinterface)(nil)
485492
_ SpecPart = (*SpecInterfaceIP)(nil)
486493
_ SpecPart = (*SpecProxyARP)(nil)
494+
_ SpecPart = (*SpecStaticARP)(nil)
487495
_ SpecPart = (*SpecMCLAGDomain)(nil)
488496
_ SpecPart = (*SpecMCLAGInterface)(nil)
489497
_ SpecPart = (*SpecVRF)(nil)
@@ -564,6 +572,10 @@ func (s *SpecProxyARP) IsNil() bool {
564572
return s == nil
565573
}
566574

575+
func (s *SpecStaticARP) IsNil() bool {
576+
return s == nil
577+
}
578+
567579
func (s *SpecMCLAGInterface) IsNil() bool {
568580
return s == nil
569581
}

0 commit comments

Comments
 (0)