summaryrefslogtreecommitdiffstats
path: root/sys/netinet/if_ether.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r--sys/netinet/if_ether.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index c99c465..4631be5 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -80,6 +80,8 @@ SYSCTL_DECL(_net_link_ether);
static SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
static SYSCTL_NODE(_net_link_ether, PF_ARP, arp, CTLFLAG_RW, 0, "");
+static VNET_DEFINE(int, arp_carp_mac) = 0; /* default to disabled */
+
/* timer values */
static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20
* minutes */
@@ -98,12 +100,16 @@ VNET_PCPUSTAT_SYSUNINIT(arpstat);
static VNET_DEFINE(int, arp_maxhold) = 1;
+#define V_arp_carp_mac VNET(arp_carp_mac)
#define V_arpt_keep VNET(arpt_keep)
#define V_arpt_down VNET(arpt_down)
#define V_arp_maxtries VNET(arp_maxtries)
#define V_arp_proxyall VNET(arp_proxyall)
#define V_arp_maxhold VNET(arp_maxhold)
+SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, carp_mac, CTLFLAG_RW,
+ &VNET_NAME(arp_carp_mac), 0,
+ "Send CARP mac with replies to CARP ips");
SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW,
&VNET_NAME(arpt_keep), 0,
"ARP entry lifetime in seconds");
@@ -931,6 +937,29 @@ reply:
/* default behaviour; never reply by broadcast. */
m->m_flags &= ~(M_BCAST|M_MCAST);
}
+#ifdef DEV_CARP
+ if (V_arp_carp_mac && carp_match) {
+ struct ether_header *eh = (struct ether_header *) sa.sa_data;
+ short type = htons(ETHERTYPE_ARP);
+
+ ah->ar_hrd = htons(ARPHRD_ETHER);
+
+ (void)memcpy(&eh->ether_type, &type,
+ sizeof(eh->ether_type));
+ (void)memcpy(eh->ether_dhost, ar_tha(ah),
+ sizeof (eh->ether_dhost));
+ (void)memcpy(eh->ether_shost, enaddr,
+ sizeof(eh->ether_shost));
+
+ sa.sa_family = pseudo_AF_HDRCMPLT;
+ sa.sa_len = sizeof(sa);
+ } else {
+#endif
+ sa.sa_family = AF_ARP;
+ sa.sa_len = 2;
+#ifdef DEV_CARP
+ }
+#endif
(void)memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln);
(void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln);
ah->ar_op = htons(ARPOP_REPLY);
@@ -938,8 +967,6 @@ reply:
m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
m->m_pkthdr.len = m->m_len;
m->m_pkthdr.rcvif = NULL;
- sa.sa_family = AF_ARP;
- sa.sa_len = 2;
m_clrprotoflags(m); /* Avoid confusing lower layers. */
(*ifp->if_output)(ifp, m, &sa, NULL);
ARPSTAT_INC(txreplies);
OpenPOWER on IntegriCloud