Skip to content

Commit a4c3d65

Browse files
committed
feat(agent): support for proxy-arp
Signed-off-by: Emanuele Di Pascale <[email protected]>
1 parent d2bf8a9 commit a4c3d65

File tree

3 files changed

+104
-1
lines changed

3 files changed

+104
-1
lines changed

pkg/agent/dozer/bcm/enforcer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ const (
7676

7777
ActionWeightCommunityListUpdate
7878

79+
ActionWeightProxyARPDelete
80+
7981
ActionWeightInterfaceBasePortChannelsUpdate
8082
ActionWeightInterfaceBaseUpdate
8183

@@ -107,6 +109,8 @@ const (
107109
ActionWeightVRFAttachedHostUpdate
108110
ActionWeightInterfaceSubinterfaceIPsUpdate
109111

112+
ActionWeightProxyARPUpdate
113+
110114
ActionWeightLLDPInterfaceUpdate
111115
ActionWeightNTP
112116
ActionWeightNTPServerUpdate

pkg/agent/dozer/bcm/spec_interface.go

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ var specInterfaceEnforcer = &DefaultValueEnforcer[string, *dozer.SpecInterface]{
7676
return errors.Wrap(err, "failed to handle interface base")
7777
}
7878

79+
if err := specInterfaceVLANProxyARPEnforcer.Handle(basePath, name, actual, desired, actions); err != nil {
80+
return errors.Wrap(err, "failed to handle interface VLAN Proxy ARP")
81+
}
82+
7983
actualIPs, desiredIPs := ValueOrNil(actual, desired,
8084
func(value *dozer.SpecInterface) map[string]*dozer.SpecInterfaceIP { return value.VLANIPs })
8185
if err := specInterfaceVLANIPsEnforcer.Handle(basePath, actualIPs, desiredIPs, actions); err != nil {
@@ -224,6 +228,56 @@ var specInterfaceVLANIPEnforcer = &DefaultValueEnforcer[string, *dozer.SpecInter
224228
},
225229
}
226230

231+
var specInterfaceVLANProxyARPEnforcer = &DefaultValueEnforcer[string, *dozer.SpecInterface]{
232+
Summary: "Interface VLAN Proxy-ARP",
233+
Path: "/routed-vlan/ipv4/proxy-arp/config",
234+
UpdateWeight: ActionWeightProxyARPUpdate,
235+
DeleteWeight: ActionWeightProxyARPDelete,
236+
RecreateOnUpdate: true,
237+
Getter: func(key string, value *dozer.SpecInterface) any { return value.ProxyARP },
238+
Marshal: func(_ string, value *dozer.SpecInterface) (ygot.ValidatedGoStruct, error) {
239+
mode := oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_DISABLE
240+
if value != nil && value.ProxyARP != nil {
241+
if value.ProxyARP.All {
242+
mode = oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_ALL
243+
} else {
244+
mode = oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_REMOTE_ONLY
245+
}
246+
}
247+
248+
return &oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp{
249+
Config: &oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config{
250+
Mode: mode,
251+
},
252+
}, nil
253+
},
254+
}
255+
256+
var specInterfaceSubinterfaceProxyARPEnforcer = &DefaultValueEnforcer[uint32, *dozer.SpecSubinterface]{
257+
Summary: "Subinterface %d Proxy-ARP",
258+
Path: "/ipv4/proxy-arp/config",
259+
UpdateWeight: ActionWeightProxyARPUpdate,
260+
DeleteWeight: ActionWeightProxyARPDelete,
261+
RecreateOnUpdate: true,
262+
Getter: func(idx uint32, value *dozer.SpecSubinterface) any { return value.ProxyARP },
263+
Marshal: func(_ uint32, value *dozer.SpecSubinterface) (ygot.ValidatedGoStruct, error) {
264+
mode := oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_DISABLE
265+
if value != nil && value.ProxyARP != nil {
266+
if value.ProxyARP.All {
267+
mode = oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_ALL
268+
} else {
269+
mode = oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_REMOTE_ONLY
270+
}
271+
}
272+
273+
return &oc.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface_Ipv4_ProxyArp{
274+
Config: &oc.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface_Ipv4_ProxyArp_Config{
275+
Mode: mode,
276+
},
277+
}, nil
278+
},
279+
}
280+
227281
var specInterfaceSubinterfacesEnforcer = &DefaultMapEnforcer[uint32, *dozer.SpecSubinterface]{
228282
Summary: "Subinterface %s",
229283
ValueHandler: specInterfaceSubinterfaceEnforcer,
@@ -238,6 +292,10 @@ var specInterfaceSubinterfaceEnforcer = &DefaultValueEnforcer[uint32, *dozer.Spe
238292
return errors.Wrap(err, "failed to handle subinterface base")
239293
}
240294

295+
if err := specInterfaceSubinterfaceProxyARPEnforcer.Handle(basePath, idx, actual, desired, actions); err != nil {
296+
return errors.Wrap(err, "failed to handle subinterface Proxy ARP")
297+
}
298+
241299
actualIPs, desiredIPs := ValueOrNil(actual, desired,
242300
func(value *dozer.SpecSubinterface) map[string]*dozer.SpecInterfaceIP { return value.IPs })
243301
if err := specInterfaceSubinterfaceIPsEnforcer.Handle(basePath, actualIPs, desiredIPs, actions); err != nil {
@@ -255,7 +313,6 @@ var specInterfaceSubinterfaceBaseEnforcer = &DefaultValueEnforcer[uint32, *dozer
255313
DeleteWeight: ActionWeightInterfaceSubinterfaceDelete,
256314
Marshal: func(idx uint32, value *dozer.SpecSubinterface) (ygot.ValidatedGoStruct, error) {
257315
var vlan *oc.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface_Vlan
258-
259316
if value.VLAN != nil {
260317
vlan = &oc.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface_Vlan{
261318
Config: &oc.OpenconfigInterfaces_Interfaces_Interface_Subinterfaces_Subinterface_Vlan_Config{
@@ -510,6 +567,22 @@ func loadActualInterfaces(ctx context.Context, agent *agentapi.Agent, client *gn
510567
return nil
511568
}
512569

570+
func unmarshalProxyARP(ocVal oc.E_OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode) (*dozer.SpecProxyARP, error) {
571+
var pa *dozer.SpecProxyARP
572+
switch ocVal {
573+
case oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_UNSET:
574+
case oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_DISABLE:
575+
case oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_REMOTE_ONLY:
576+
pa = &dozer.SpecProxyARP{All: false}
577+
case oc.OpenconfigInterfaces_Interfaces_Interface_RoutedVlan_Ipv4_ProxyArp_Config_Mode_ALL:
578+
pa = &dozer.SpecProxyARP{All: true}
579+
default:
580+
return nil, errors.Errorf("unknown Proxy ARP mode %v", ocVal)
581+
}
582+
583+
return pa, nil
584+
}
585+
513586
func unmarshalOCInterfaces(agent *agentapi.Agent, ocVal *oc.OpenconfigInterfaces_Interfaces) (map[string]*dozer.SpecInterface, error) {
514587
interfaces := map[string]*dozer.SpecInterface{}
515588

@@ -596,6 +669,14 @@ func unmarshalOCInterfaces(agent *agentapi.Agent, ocVal *oc.OpenconfigInterfaces
596669
subIface.AnycastGateways = sub.Ipv4.SagIpv4.Config.StaticAnycastGateway
597670
}
598671

672+
if sub.Ipv4 != nil && sub.Ipv4.ProxyArp != nil && sub.Ipv4.ProxyArp.Config != nil {
673+
pa, err := unmarshalProxyARP(sub.Ipv4.ProxyArp.Config.Mode)
674+
if err != nil {
675+
return nil, errors.Wrapf(err, "failed to unmarshal proxy-arp for %s.%d", name, id)
676+
}
677+
subIface.ProxyARP = pa
678+
}
679+
599680
if sub.Vlan != nil {
600681
if sub.Vlan.Config != nil {
601682
subIface.VLAN, err = unmarshalVLAN(sub.Vlan.Config.VlanId)
@@ -638,6 +719,13 @@ func unmarshalOCInterfaces(agent *agentapi.Agent, ocVal *oc.OpenconfigInterfaces
638719
if ocIface.RoutedVlan.Ipv4.SagIpv4 != nil && ocIface.RoutedVlan.Ipv4.SagIpv4.Config != nil {
639720
iface.VLANAnycastGateway = ocIface.RoutedVlan.Ipv4.SagIpv4.Config.StaticAnycastGateway
640721
}
722+
if ocIface.RoutedVlan.Ipv4.ProxyArp != nil && ocIface.RoutedVlan.Ipv4.ProxyArp.Config != nil {
723+
pa, err := unmarshalProxyARP(ocIface.RoutedVlan.Ipv4.ProxyArp.Config.Mode)
724+
if err != nil {
725+
return nil, errors.Wrapf(err, "failed to unmarshal proxy-arp for VLAN interface %s", name)
726+
}
727+
iface.ProxyARP = pa
728+
}
641729
}
642730
}
643731
if vlan && !isVLAN(name) {

pkg/agent/dozer/dozer.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ type SpecPortBreakout struct {
112112
Mode string `json:"mode,omitempty"`
113113
}
114114

115+
type SpecProxyARP struct {
116+
All bool `json:"all,omitempty"`
117+
}
118+
115119
type SpecInterface struct {
116120
Description *string `json:"description,omitempty"`
117121
Enabled *bool `json:"enabled,omitempty"`
@@ -124,6 +128,7 @@ type SpecInterface struct {
124128
VLANIPs map[string]*SpecInterfaceIP `json:"vlanIPs,omitempty"`
125129
VLANAnycastGateway []string `json:"vlanAnycastGateway,omitempty"`
126130
Subinterfaces map[uint32]*SpecSubinterface `json:"subinterfaces,omitempty"`
131+
ProxyARP *SpecProxyARP `json:"proxyARP,omitempty"`
127132
}
128133

129134
type SpecInterfaceIP struct {
@@ -135,6 +140,7 @@ type SpecSubinterface struct {
135140
VLAN *uint16 `json:"vlan,omitempty"`
136141
IPs map[string]*SpecInterfaceIP `json:"ips,omitempty"`
137142
AnycastGateways []string `json:"anycastGateways,omitempty"`
143+
ProxyARP *SpecProxyARP `json:"proxyARP,omitempty"`
138144
}
139145

140146
type SpecMCLAGDomain struct {
@@ -477,6 +483,7 @@ var (
477483
_ SpecPart = (*SpecInterface)(nil)
478484
_ SpecPart = (*SpecSubinterface)(nil)
479485
_ SpecPart = (*SpecInterfaceIP)(nil)
486+
_ SpecPart = (*SpecProxyARP)(nil)
480487
_ SpecPart = (*SpecMCLAGDomain)(nil)
481488
_ SpecPart = (*SpecMCLAGInterface)(nil)
482489
_ SpecPart = (*SpecVRF)(nil)
@@ -553,6 +560,10 @@ func (s *SpecInterfaceIP) IsNil() bool {
553560
return s == nil
554561
}
555562

563+
func (s *SpecProxyARP) IsNil() bool {
564+
return s == nil
565+
}
566+
556567
func (s *SpecMCLAGInterface) IsNil() bool {
557568
return s == nil
558569
}

0 commit comments

Comments
 (0)