On 03/05/12 22:56, mxb wrote:
I'd suggest you to experiment with the src and try to rollback if_pfsync.c to,
say rev. 1.179,
then roll forward with revisions until you can pinpoint one which breaks it.
//maxim
Ok, I've traced the problem back to r1.180 of if_pfsync.c
If I remove 1.180 and apply 1.181, 1.182, 1.183, 1.184
then everything works fine.
According to my understanding 1.180 introduces the following two problems:
1) When one firewall reboots, the other one is initiating a bulk
transfer thus demoting his carp/pfsync groups.
I don't understand why this is needed.
2) When the firewall boots it sets his demotion counter on groups
carp/pfsync to 0 (instead of 1) before his bulk transfer
is finished.
The diff bellow removes 1.180
Feel free to send me diffs to try.
regards,
Giannis
Index: sys/net/if_pfsync.c
===================================================================
RCS file: /cvs/src/sys/net/if_pfsync.c,v
retrieving revision 1.184
diff -u -p -U10 -r1.184 if_pfsync.c
--- sys/net/if_pfsync.c 11 Apr 2012 17:42:53 -0000 1.184
+++ sys/net/if_pfsync.c 4 May 2012 09:52:57 -0000
@@ -221,39 +221,36 @@ struct pfsync_softc {
int sc_bulk_tries;
struct timeout sc_bulkfail_tmo;
u_int32_t sc_ureq_received;
struct pf_state *sc_bulk_next;
struct pf_state *sc_bulk_last;
struct timeout sc_bulk_tmo;
TAILQ_HEAD(, tdb) sc_tdb_q;
- void *sc_lhcookie;
-
struct timeout sc_tmo;
};
struct pfsync_softc *pfsyncif = NULL;
struct pfsyncstats pfsyncstats;
void pfsyncattach(int);
int pfsync_clone_create(struct if_clone *, int);
int pfsync_clone_destroy(struct ifnet *);
int pfsync_alloc_scrub_memory(struct pfsync_state_peer *,
struct pf_state_peer *);
void pfsync_update_net_tdb(struct pfsync_tdb *);
int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
int pfsyncioctl(struct ifnet *, u_long, caddr_t);
void pfsyncstart(struct ifnet *);
-void pfsync_syncdev_state(void *);
struct mbuf *pfsync_if_dequeue(struct ifnet *);
void pfsync_deferred(struct pf_state *, int);
void pfsync_undefer(struct pfsync_deferral *, int);
void pfsync_defer_tmo(void *);
void pfsync_request_full_update(struct pfsync_softc *);
void pfsync_request_update(u_int32_t, u_int64_t);
void pfsync_update_state_req(struct pf_state *);
@@ -351,24 +348,20 @@ pfsync_clone_destroy(struct ifnet *ifp)
int s;
s = splsoftnet();
timeout_del(&sc->sc_bulkfail_tmo);
timeout_del(&sc->sc_bulk_tmo);
timeout_del(&sc->sc_tmo);
#if NCARP > 0
if (!pfsync_sync_ok)
carp_group_demote_adj(&sc->sc_if, -1, "pfsync destroy");
#endif
- if (sc->sc_lhcookie != NULL)
- hook_disestablish(
- sc->sc_sync_if->if_linkstatehooks,
- sc->sc_lhcookie);
if_detach(ifp);
pfsync_drop(sc);
while (sc->sc_deferred > 0) {
pd = TAILQ_FIRST(&sc->sc_deferrals);
timeout_del(&pd->pd_tmo);
pfsync_undefer(pd, 0);
}
@@ -402,51 +395,20 @@ pfsyncstart(struct ifnet *ifp)
int s;
s = splnet();
while ((m = pfsync_if_dequeue(ifp)) != NULL) {
IF_DROP(&ifp->if_snd);
m_freem(m);
}
splx(s);
}
-void
-pfsync_syncdev_state(void *arg)
-{
- struct pfsync_softc *sc = arg;
-
- if (!sc->sc_sync_if)
- return;
-
- if (sc->sc_sync_if->if_link_state == LINK_STATE_DOWN ||
- !(sc->sc_sync_if->if_flags & IFF_UP)) {
- sc->sc_if.if_flags &= ~IFF_RUNNING;
-#if NCARP > 0
- carp_group_demote_adj(&sc->sc_if, 1, "pfsyncdev");
-#endif
- /* drop everything */
- timeout_del(&sc->sc_tmo);
- pfsync_drop(sc);
-
- /* cancel bulk update */
- timeout_del(&sc->sc_bulk_tmo);
- sc->sc_bulk_next = NULL;
- sc->sc_bulk_last = NULL;
- } else {
- sc->sc_if.if_flags |= IFF_RUNNING;
- pfsync_request_full_update(sc);
-#if NCARP > 0
- carp_group_demote_adj(&sc->sc_if, -1, "pfsyncdev");
-#endif
- }
-}
-
int
pfsync_alloc_scrub_memory(struct pfsync_state_peer *s,
struct pf_state_peer *d)
{
if (s->scrub.scrub_flag && d->scrub == NULL) {
d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT | PR_ZERO);
if (d->scrub == NULL)
return (ENOMEM);
}
@@ -1325,24 +1287,20 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
if (pfsyncr.pfsyncr_maxupdates > 255) {
splx(s);
return (EINVAL);
}
sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
sc->sc_defer = pfsyncr.pfsyncr_defer;
if (pfsyncr.pfsyncr_syncdev[0] == 0) {
- if (sc->sc_lhcookie != NULL)
- hook_disestablish(
- sc->sc_sync_if->if_linkstatehooks,
- sc->sc_lhcookie);
sc->sc_sync_if = NULL;
if (imo->imo_num_memberships > 0) {
in_delmulti(imo->imo_membership[
--imo->imo_num_memberships]);
imo->imo_multicast_ifp = NULL;
}
splx(s);
break;
}
@@ -1361,37 +1319,29 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
if (imo->imo_num_memberships > 0) {
in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
imo->imo_multicast_ifp = NULL;
}
if (sc->sc_sync_if &&
sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
struct in_addr addr;
if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
- if (sc->sc_lhcookie != NULL)
- hook_disestablish(
- sc->sc_sync_if->if_linkstatehooks,
- sc->sc_lhcookie);
sc->sc_sync_if = NULL;
splx(s);
return (EADDRNOTAVAIL);
}
addr.s_addr = INADDR_PFSYNC_GROUP;
if ((imo->imo_membership[0] =
in_addmulti(&addr, sc->sc_sync_if)) == NULL) {
- if (sc->sc_lhcookie != NULL)
- hook_disestablish(
- sc->sc_sync_if->if_linkstatehooks,
- sc->sc_lhcookie);
sc->sc_sync_if = NULL;
splx(s);
return (ENOBUFS);
}
imo->imo_num_memberships++;
imo->imo_multicast_ifp = sc->sc_sync_if;
imo->imo_multicast_ttl = PFSYNC_DFLTTL;
imo->imo_multicast_loop = 0;
}
@@ -1399,24 +1349,20 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
bzero(ip, sizeof(*ip));
ip->ip_v = IPVERSION;
ip->ip_hl = sizeof(sc->sc_template) >> 2;
ip->ip_tos = IPTOS_LOWDELAY;
/* len and id are set later */
ip->ip_off = htons(IP_DF);
ip->ip_ttl = PFSYNC_DFLTTL;
ip->ip_p = IPPROTO_PFSYNC;
ip->ip_src.s_addr = INADDR_ANY;
ip->ip_dst.s_addr = sc->sc_sync_peer.s_addr;
-
- sc->sc_lhcookie =
- hook_establish(sc->sc_sync_if->if_linkstatehooks, 1,
- pfsync_syncdev_state, sc);
pfsync_request_full_update(sc);
splx(s);
break;
default:
return (ENOTTY);
}