1
|
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
|
2
|
index 0a3607e..2d73edb 100644
|
3
|
--- a/sys/netinet/ip_carp.c
|
4
|
+++ b/sys/netinet/ip_carp.c
|
5
|
@@ -115,7 +115,6 @@ struct carp_softc {
|
6
|
int sc_sendad_success;
|
7
|
#define CARP_SENDAD_MIN_SUCCESS 3
|
8
|
|
9
|
- int sc_init_counter;
|
10
|
uint64_t sc_counter;
|
11
|
|
12
|
/* authentication */
|
13
|
@@ -579,7 +578,6 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
|
14
|
struct ifnet *ifp = m->m_pkthdr.rcvif;
|
15
|
struct ifaddr *ifa;
|
16
|
struct carp_softc *sc;
|
17
|
- uint64_t tmp_counter;
|
18
|
struct timeval sc_tv, ch_tv;
|
19
|
|
20
|
/* verify that the VHID is valid on the receiving interface */
|
21
|
@@ -619,14 +617,20 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
|
22
|
goto out;
|
23
|
}
|
24
|
|
25
|
- tmp_counter = ntohl(ch->carp_counter[0]);
|
26
|
- tmp_counter = tmp_counter<<32;
|
27
|
- tmp_counter += ntohl(ch->carp_counter[1]);
|
28
|
-
|
29
|
- /* XXX Replay protection goes here */
|
30
|
-
|
31
|
- sc->sc_init_counter = 0;
|
32
|
- sc->sc_counter = tmp_counter;
|
33
|
+ if (!bcmp(&sc->sc_counter, ch->carp_counter,
|
34
|
+ sizeof(ch->carp_counter))) {
|
35
|
+ /* Do not log duplicates from non simplex interfaces */
|
36
|
+ if (sc->sc_carpdev->if_flags & IFF_SIMPLEX) {
|
37
|
+ CARPSTATS_INC(carps_badauth);
|
38
|
+ ifp->if_ierrors++;
|
39
|
+ CARP_UNLOCK(sc);
|
40
|
+ CARP_LOG("%s, replay or network loop detected.\n",
|
41
|
+ ifp->if_xname);
|
42
|
+ } else
|
43
|
+ CARP_UNLOCK(sc);
|
44
|
+ m_freem(m);
|
45
|
+ return;
|
46
|
+ }
|
47
|
|
48
|
sc_tv.tv_sec = sc->sc_advbase;
|
49
|
sc_tv.tv_usec = DEMOTE_ADVSKEW(sc) * 1000000 / 256;
|
50
|
@@ -700,13 +704,12 @@ carp_prepare_ad(struct mbuf *m, struct carp_softc *sc, struct carp_header *ch)
|
51
|
{
|
52
|
struct m_tag *mtag;
|
53
|
|
54
|
- if (sc->sc_init_counter) {
|
55
|
+ if (!sc->sc_counter) {
|
56
|
/* this could also be seconds since unix epoch */
|
57
|
sc->sc_counter = arc4random();
|
58
|
sc->sc_counter = sc->sc_counter << 32;
|
59
|
sc->sc_counter += arc4random();
|
60
|
- } else
|
61
|
- sc->sc_counter++;
|
62
|
+ }
|
63
|
|
64
|
ch->carp_counter[0] = htonl((sc->sc_counter>>32)&0xffffffff);
|
65
|
ch->carp_counter[1] = htonl(sc->sc_counter&0xffffffff);
|
66
|
@@ -1490,9 +1493,9 @@ carp_alloc(struct ifnet *ifp)
|
67
|
|
68
|
sc = malloc(sizeof(*sc), M_CARP, M_WAITOK|M_ZERO);
|
69
|
|
70
|
+ sc->sc_counter = 0;
|
71
|
sc->sc_advbase = CARP_DFLTINTV;
|
72
|
sc->sc_vhid = -1; /* required setting */
|
73
|
- sc->sc_init_counter = 1;
|
74
|
sc->sc_state = INIT;
|
75
|
|
76
|
sc->sc_ifasiz = sizeof(struct ifaddr *);
|