On Sat, Feb 06, 2021 at 05:04:20PM +1000, David Gwynne wrote:
> refcnt_init starts counting at 1, while the existing code starts at 0. Do
> the crashes stop because we never fully release all the references and
> never free it now?
You are absolutely right. I was too optimistic.
Correct diff is below. It does not fix anything. Only advantage
is that carp does not access interface group internals.
bluhm
Index: net/if.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.c,v
retrieving revision 1.626
diff -u -p -r1.626 if.c
--- net/if.c 1 Feb 2021 07:43:33 -0000 1.626
+++ net/if.c 6 Feb 2021 12:16:20 -0000
@@ -2601,7 +2601,7 @@ if_creategroup(const char *groupname)
return (NULL);
strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
- ifg->ifg_refcnt = 0;
+ refcnt_init(&ifg->ifg_refcnt);
ifg->ifg_carp_demoted = 0;
TAILQ_INIT(&ifg->ifg_members);
#if NPF > 0
@@ -2642,13 +2642,17 @@ if_addgroup(struct ifnet *ifp, const cha
if (!strcmp(ifg->ifg_group, groupname))
break;
- if (ifg == NULL && (ifg = if_creategroup(groupname)) == NULL) {
+ if (ifg == NULL)
+ ifg = if_creategroup(groupname);
+ else
+ refcnt_take(&ifg->ifg_refcnt);
+
+ if (ifg == NULL) {
free(ifgl, M_TEMP, sizeof(*ifgl));
free(ifgm, M_TEMP, sizeof(*ifgm));
return (ENOMEM);
}
- ifg->ifg_refcnt++;
ifgl->ifgl_group = ifg;
ifgm->ifgm_ifp = ifp;
@@ -2692,7 +2696,7 @@ if_delgroup(struct ifnet *ifp, const cha
pfi_group_change(groupname);
#endif
- if (--ifgl->ifgl_group->ifg_refcnt == 0) {
+ if (refcnt_rele(&ifgl->ifgl_group->ifg_refcnt)) {
TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next);
#if NPF > 0
pfi_detach_ifgroup(ifgl->ifgl_group);
Index: net/if_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_var.h,v
retrieving revision 1.112
diff -u -p -r1.112 if_var.h
--- net/if_var.h 29 Jul 2020 12:09:31 -0000 1.112
+++ net/if_var.h 6 Feb 2021 12:11:35 -0000
@@ -263,7 +263,7 @@ struct ifmaddr {
struct ifg_group {
char ifg_group[IFNAMSIZ];
- u_int ifg_refcnt;
+ struct refcnt ifg_refcnt;
caddr_t ifg_pf_kif;
int ifg_carp_demoted;
TAILQ_HEAD(, ifg_member) ifg_members;
Index: netinet/ip_carp.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.351
diff -u -p -r1.351 ip_carp.c
--- netinet/ip_carp.c 21 Jan 2021 13:18:07 -0000 1.351
+++ netinet/ip_carp.c 6 Feb 2021 12:11:35 -0000
@@ -786,10 +786,7 @@ carp_sysctl(int *name, u_int namelen, vo
void
carpattach(int n)
{
- struct ifg_group *ifg;
-
- if ((ifg = if_creategroup("carp")) != NULL)
- ifg->ifg_refcnt++; /* keep around even if empty */
+ if_creategroup("carp"); /* keep around even if empty */
if_clone_attach(&carp_cloner);
carpcounters = counters_alloc(carps_ncounters);
}