1
|
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
|
2
|
index 9660edc..bfb6e14 100644
|
3
|
--- a/sys/netinet/if_ether.c
|
4
|
+++ b/sys/netinet/if_ether.c
|
5
|
@@ -80,6 +80,8 @@ SYSCTL_DECL(_net_link_ether);
|
6
|
static SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
|
7
|
static SYSCTL_NODE(_net_link_ether, PF_ARP, arp, CTLFLAG_RW, 0, "");
|
8
|
|
9
|
+static VNET_DEFINE(int, arp_carp_mac) = 0; /* default to disabled */
|
10
|
+
|
11
|
/* timer values */
|
12
|
static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20
|
13
|
* minutes */
|
14
|
@@ -98,12 +100,16 @@ VNET_PCPUSTAT_SYSUNINIT(arpstat);
|
15
|
|
16
|
static VNET_DEFINE(int, arp_maxhold) = 1;
|
17
|
|
18
|
+#define V_arp_carp_mac VNET(arp_carp_mac)
|
19
|
#define V_arpt_keep VNET(arpt_keep)
|
20
|
#define V_arpt_down VNET(arpt_down)
|
21
|
#define V_arp_maxtries VNET(arp_maxtries)
|
22
|
#define V_arp_proxyall VNET(arp_proxyall)
|
23
|
#define V_arp_maxhold VNET(arp_maxhold)
|
24
|
|
25
|
+SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, carp_mac, CTLFLAG_RW,
|
26
|
+ &VNET_NAME(arp_carp_mac), 0,
|
27
|
+ "Send CARP mac with replies to CARP ips");
|
28
|
SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW,
|
29
|
&VNET_NAME(arpt_keep), 0,
|
30
|
"ARP entry lifetime in seconds");
|
31
|
@@ -882,6 +888,29 @@ reply:
|
32
|
/* default behaviour; never reply by broadcast. */
|
33
|
m->m_flags &= ~(M_BCAST|M_MCAST);
|
34
|
}
|
35
|
+#ifdef DEV_CARP
|
36
|
+ if (V_arp_carp_mac && carp_match) {
|
37
|
+ struct ether_header *eh = (struct ether_header *) sa.sa_data;
|
38
|
+ short type = htons(ETHERTYPE_ARP);
|
39
|
+
|
40
|
+ ah->ar_hrd = htons(ARPHRD_ETHER);
|
41
|
+
|
42
|
+ (void)memcpy(&eh->ether_type, &type,
|
43
|
+ sizeof(eh->ether_type));
|
44
|
+ (void)memcpy(eh->ether_dhost, ar_tha(ah),
|
45
|
+ sizeof (eh->ether_dhost));
|
46
|
+ (void)memcpy(eh->ether_shost, enaddr,
|
47
|
+ sizeof(eh->ether_shost));
|
48
|
+
|
49
|
+ sa.sa_family = pseudo_AF_HDRCMPLT;
|
50
|
+ sa.sa_len = sizeof(sa);
|
51
|
+ } else {
|
52
|
+#endif
|
53
|
+ sa.sa_family = AF_ARP;
|
54
|
+ sa.sa_len = 2;
|
55
|
+#ifdef DEV_CARP
|
56
|
+ }
|
57
|
+#endif
|
58
|
(void)memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln);
|
59
|
(void)memcpy(ar_spa(ah), &itaddr, ah->ar_pln);
|
60
|
ah->ar_op = htons(ARPOP_REPLY);
|
61
|
@@ -889,8 +918,6 @@ reply:
|
62
|
m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
|
63
|
m->m_pkthdr.len = m->m_len;
|
64
|
m->m_pkthdr.rcvif = NULL;
|
65
|
- sa.sa_family = AF_ARP;
|
66
|
- sa.sa_len = 2;
|
67
|
m_clrprotoflags(m); /* Avoid confusing lower layers. */
|
68
|
(*ifp->if_output)(ifp, m, &sa, NULL);
|
69
|
ARPSTAT_INC(txreplies);
|