diff --git a/data/configd-include.json b/data/configd-include.json
index b77d48001..fc86b46e3 100644
--- a/data/configd-include.json
+++ b/data/configd-include.json
@@ -1,76 +1,77 @@
 [
+"arp.py",
 "bcast_relay.py",
 "conntrack.py",
 "conntrack_sync.py",
 "dhcp_relay.py",
 "dhcpv6_relay.py",
 "dns_forwarding.py",
 "dynamic_dns.py",
 "flow_accounting_conf.py",
 "high-availability.py",
 "host_name.py",
 "https.py",
 "igmp_proxy.py",
 "intel_qat.py",
 "interfaces-bonding.py",
 "interfaces-bridge.py",
 "interfaces-dummy.py",
 "interfaces-ethernet.py",
 "interfaces-geneve.py",
 "interfaces-l2tpv3.py",
 "interfaces-loopback.py",
 "interfaces-macsec.py",
 "interfaces-openvpn.py",
 "interfaces-pppoe.py",
 "interfaces-pseudo-ethernet.py",
 "interfaces-tunnel.py",
 "interfaces-vxlan.py",
 "interfaces-wireguard.py",
 "interfaces-wireless.py",
 "interfaces-wwan.py",
 "lldp.py",
 "nat.py",
 "nat66.py",
 "ntp.py",
 "pki.py",
 "policy.py",
 "policy-local-route.py",
 "protocols_bfd.py",
 "protocols_bgp.py",
 "protocols_igmp.py",
 "protocols_isis.py",
 "protocols_mpls.py",
 "protocols_nhrp.py",
 "protocols_ospf.py",
 "protocols_ospfv3.py",
 "protocols_pim.py",
 "protocols_rip.py",
 "protocols_ripng.py",
 "protocols_static.py",
 "protocols_static_multicast.py",
 "qos.py",
 "salt-minion.py",
 "service_console-server.py",
 "service_ids_fastnetmon.py",
 "service_ipoe-server.py",
 "service_mdns-repeater.py",
 "service_pppoe-server.py",
 "service_router-advert.py",
 "service_upnp.py",
 "ssh.py",
 "system-ip.py",
 "system-ipv6.py",
 "system-login-banner.py",
 "system-option.py",
 "system-syslog.py",
 "system-timezone.py",
 "system_console.py",
 "system_lcd.py",
 "task_scheduler.py",
 "tftp_server.py",
 "vpn_l2tp.py",
 "vpn_pptp.py",
 "vpn_sstp.py",
 "vrf.py",
 "vrf_vni.py"
 ]
diff --git a/src/conf_mode/arp.py b/src/conf_mode/arp.py
index aac07bd80..51a08bee5 100755
--- a/src/conf_mode/arp.py
+++ b/src/conf_mode/arp.py
@@ -1,104 +1,66 @@
 #!/usr/bin/env python3
 #
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2022 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-#
 
-import sys
-import os
-import re
-import syslog as sl
+from sys import exit
 
 from vyos.config import Config
+from vyos.configdict import node_changed
 from vyos.util import call
 from vyos import ConfigError
-
 from vyos import airbag
 airbag.enable()
 
-arp_cmd = '/usr/sbin/arp'
-
-def get_config():
-  c = Config()
-  if not c.exists('protocols static arp'):
-    return None
-
-  c.set_level('protocols static')
-  config_data = {}
-  
-  for ip_addr in c.list_nodes('arp'):
-    config_data.update(
-        {
-          ip_addr : c.return_value('arp ' + ip_addr + ' hwaddr')
-        }
-    )
-
-  return config_data
+def get_config(config=None):
+    if config:
+        conf = config
+    else:
+        conf = Config()
 
-def generate(c):
-  c_eff = Config()
-  c_eff.set_level('protocols static')
-  c_eff_cnf = {}
-  for ip_addr in c_eff.list_effective_nodes('arp'):
-    c_eff_cnf.update(
-        {
-          ip_addr : c_eff.return_effective_value('arp ' + ip_addr + ' hwaddr')
-        }
-    )
+    base = ['protocols', 'static', 'arp']
+    arp = conf.get_config_dict(base)
+    tmp = node_changed(conf, base)
+    if tmp: arp.update({'removed' : node_changed(conf, base)})
 
-  config_data = {
-    'remove'  : [],
-    'update'  : {}
-  }
-  ### removal
-  if c == None:
-    for ip_addr in c_eff_cnf:
-      config_data['remove'].append(ip_addr)
-  else:
-    for ip_addr in c_eff_cnf:
-      if not ip_addr in c or c[ip_addr] == None:
-        config_data['remove'].append(ip_addr)
+    return arp
 
-  ### add/update
-  if c != None:
-    for ip_addr in c:
-      if not ip_addr in c_eff_cnf:
-        config_data['update'][ip_addr] = c[ip_addr]
-      if  ip_addr in c_eff_cnf:
-        if c[ip_addr] != c_eff_cnf[ip_addr] and c[ip_addr] != None:
-          config_data['update'][ip_addr] = c[ip_addr]
+def verify(arp):
+    pass
 
-  return config_data
+def generate(arp):
+    pass
 
-def apply(c):
-  for ip_addr in c['remove']:
-    sl.syslog(sl.LOG_NOTICE, "arp -d " + ip_addr)
-    call(f'{arp_cmd} -d {ip_addr} >/dev/null 2>&1')
+def apply(arp):
+    if not arp:
+        return None
 
-  for ip_addr in c['update']:
-    sl.syslog(sl.LOG_NOTICE, "arp -s " + ip_addr + " " + c['update'][ip_addr])
-    updated = c['update'][ip_addr]
-    call(f'{arp_cmd} -s {ip_addr} {updated}')
+    if 'removed' in arp:
+        for host in arp['removed']:
+            call(f'arp --delete {host}')
 
+    if 'arp' in arp:
+        for host, host_config in arp['arp'].items():
+            mac = host_config['hwaddr']
+            call(f'arp --set {host} {mac}')
 
 if __name__ == '__main__':
-  try:
-    c = get_config()
-    ## syntax verification is done via cli
-    config = generate(c)
-    apply(config)
-  except ConfigError as e:
-    print(e)
-    sys.exit(1)
+    try:
+        c = get_config()
+        verify(c)
+        generate(c)
+        apply(c)
+    except ConfigError as e:
+        print(e)
+        exit(1)