diff --git a/net/ndp-proxy-go/pkg-descr b/net/ndp-proxy-go/pkg-descr
index 73d314b14a..161f8684eb 100644
--- a/net/ndp-proxy-go/pkg-descr
+++ b/net/ndp-proxy-go/pkg-descr
@@ -9,6 +9,7 @@ Plugin Changelog
1.3
* Add ratelimit for pfctl operations
+* Add CARP failover
1.2
diff --git a/net/ndp-proxy-go/src/etc/rc.syshook.d/carp/20-ndpproxy b/net/ndp-proxy-go/src/etc/rc.syshook.d/carp/20-ndpproxy
new file mode 100755
index 0000000000..8ec0ccb33b
--- /dev/null
+++ b/net/ndp-proxy-go/src/etc/rc.syshook.d/carp/20-ndpproxy
@@ -0,0 +1,53 @@
+#!/usr/local/bin/php
+general->enabled->isEmpty() ||
+ $model->general->carp_depend_on->isEmpty()
+) {
+ exit(0);
+}
+
+$actions = [
+ 'MASTER' => 'start',
+ 'BACKUP' => 'stop',
+];
+
+mwexecfm('/usr/local/etc/rc.d/ndp-proxy-go ' . $actions[$type]);
diff --git a/net/ndp-proxy-go/src/opnsense/mvc/app/controllers/OPNsense/NdpProxy/forms/general.xml b/net/ndp-proxy-go/src/opnsense/mvc/app/controllers/OPNsense/NdpProxy/forms/general.xml
index 5d6c3372d8..596c7b1af4 100644
--- a/net/ndp-proxy-go/src/opnsense/mvc/app/controllers/OPNsense/NdpProxy/forms/general.xml
+++ b/net/ndp-proxy-go/src/opnsense/mvc/app/controllers/OPNsense/NdpProxy/forms/general.xml
@@ -9,6 +9,13 @@
checkboxEnable or disable this service.
+
+ ndpproxy.general.carp_depend_on
+
+ checkbox
+ true
+ If any CARP VHID on this node is in MASTER state the service will be started, otherwise stopped. As NDP is stateless, a short interruption of IPv6 connectivity must be expected during CARP transitions.
+ header
@@ -39,7 +46,8 @@
header
-
+
+ truendpproxy.general.cache_ttl
@@ -61,6 +69,11 @@
checkboxPersist cache to file on service stop and load it on service start. Only neighbors with a valid cache lifetime are loaded. This helps on system reboots to minimize downtime of individual clients.
+
+ header
+
+ true
+ ndpproxy.general.route_qps
@@ -82,6 +95,11 @@
50Controls CPU usage vs. NDP responsiveness. Lower values (e.g., 25 ms) minimize latency during cache refresh at the cost of more CPU. Higher values (100–250 ms) reduce CPU use but may introduce small latency spikes.
+
+ header
+
+ true
+ ndpproxy.general.debug
diff --git a/net/ndp-proxy-go/src/opnsense/mvc/app/models/OPNsense/NdpProxy/NdpProxy.xml b/net/ndp-proxy-go/src/opnsense/mvc/app/models/OPNsense/NdpProxy/NdpProxy.xml
index b71d385129..9f02e11462 100644
--- a/net/ndp-proxy-go/src/opnsense/mvc/app/models/OPNsense/NdpProxy/NdpProxy.xml
+++ b/net/ndp-proxy-go/src/opnsense/mvc/app/models/OPNsense/NdpProxy/NdpProxy.xml
@@ -1,7 +1,7 @@
//OPNsense/ndpproxyNDP Proxy model
- 1.0
+ 1.1
@@ -43,6 +43,10 @@
0Y
+
+ 0
+ Y
+
diff --git a/net/ndp-proxy-go/src/opnsense/service/templates/OPNsense/NdpProxy/ndp_proxy_go b/net/ndp-proxy-go/src/opnsense/service/templates/OPNsense/NdpProxy/ndp_proxy_go
index f5131e9af2..61b7c01f2b 100644
--- a/net/ndp-proxy-go/src/opnsense/service/templates/OPNsense/NdpProxy/ndp_proxy_go
+++ b/net/ndp-proxy-go/src/opnsense/service/templates/OPNsense/NdpProxy/ndp_proxy_go
@@ -2,6 +2,9 @@
{% set general = helpers.getNodeByTag('OPNsense.ndpproxy.general') %}
{% if general.enabled|default("0") == "1" and general.upstream and general.downstream %}
ndp_proxy_go_enable="YES"
+{% if general.carp_depend_on %}
+ndp_proxy_go_check_carp="YES"
+{% endif %}
ndp_proxy_go_upstream="{{ helpers.physical_interface(general.upstream) }}"
{% set downstream_interfaces = [] %}
{% for interface in general.downstream.split(',') %}