Date: Fri, 5 Mar 2010 17:53:28 +0000 (UTC) From: Luigi Rizzo <luigi@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r204763 - head/sys/netinet/ipfw Message-ID: <201003051753.o25HrSHY068600@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: luigi Date: Fri Mar 5 17:53:28 2010 New Revision: 204763 URL: http://svn.freebsd.org/changeset/base/204763 Log: plug a memory leak on pipe's reconfiguration Modified: head/sys/netinet/ipfw/ip_dummynet.c Modified: head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- head/sys/netinet/ipfw/ip_dummynet.c Fri Mar 5 16:56:08 2010 (r204762) +++ head/sys/netinet/ipfw/ip_dummynet.c Fri Mar 5 17:53:28 2010 (r204763) @@ -1320,12 +1320,13 @@ config_sched(struct dn_sch *_nsch, struc struct schk_new_arg a; /* argument for schk_new */ int i; struct dn_link p; /* copy of oldlink */ - struct dn_profile *pf; /* copy of old link profile */ + struct dn_profile *pf = NULL; /* copy of old link profile */ /* Used to preserv mask parameter */ struct ipfw_flow_id new_mask; int new_buckets = 0; int new_flags = 0; int pipe_cmd; + int err = ENOMEM; a.sch = _nsch; if (a.sch->oid.len != sizeof(*a.sch)) { @@ -1341,11 +1342,6 @@ config_sched(struct dn_sch *_nsch, struc 1, dn_cfg.max_hash_size, "sched buckets"); /* XXX other sanity checks */ bzero(&p, sizeof(p)); - pf = malloc(sizeof(struct dn_profile), M_DUMMYNET, M_NOWAIT | M_ZERO); - if (pf == NULL) { - D("Error allocating profile"); - return ENOMEM; - } pipe_cmd = a.sch->flags & DN_PIPE_CMD; a.sch->flags &= ~DN_PIPE_CMD; //XXX do it even if is not set? @@ -1390,27 +1386,33 @@ again: /* run twice, for wfq and fifo */ goto again; } } else { - DN_BH_WUNLOCK(); D("invalid scheduler type %d %s", a.sch->oid.subtype, a.sch->name); - return EINVAL; + err = EINVAL; + goto error; } /* normalize name and subtype */ a.sch->oid.subtype = a.fp->type; bzero(a.sch->name, sizeof(a.sch->name)); strlcpy(a.sch->name, a.fp->name, sizeof(a.sch->name)); if (s == NULL) { - DN_BH_WUNLOCK(); D("cannot allocate scheduler %d", i); - return ENOMEM; + goto error; } /* restore existing link if any */ if (p.link_nr) { s->link = p; - if (pf->link_nr == p.link_nr) /* Restore profile */ - s->profile = pf; - else + if (!pf || pf->link_nr != p.link_nr) { /* no saved value */ s->profile = NULL; /* XXX maybe not needed */ + } else { + s->profile = malloc(sizeof(struct dn_profile), + M_DUMMYNET, M_NOWAIT | M_ZERO); + if (s->profile == NULL) { + D("cannot allocate profile"); + goto error; //XXX + } + bcopy(pf, s->profile, sizeof(*pf)); + } } p.link_nr = 0; if (s->fp == NULL) { @@ -1426,8 +1428,13 @@ again: /* run twice, for wfq and fifo */ if (s->link.link_nr == 0) D("XXX WARNING link 0 for sched %d", i); p = s->link; /* preserve link */ - if (s->profile) /* preserve profile */ - bcopy(s->profile, pf, sizeof(struct dn_profile)); + if (s->profile) {/* preserve profile */ + if (!pf) + pf = malloc(sizeof(*pf), + M_DUMMYNET, M_NOWAIT | M_ZERO); + if (pf) /* XXX should issue a warning otherwise */ + bcopy(s->profile, pf, sizeof(*pf)); + } /* remove from the hash */ dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL); /* Detach flowsets, preserve queues. */ @@ -1459,8 +1466,7 @@ again: /* run twice, for wfq and fifo */ if (!s->fs) { schk_delete_cb(s, (void *)DN_DESTROY); D("error creating internal fs for %d", i); - DN_BH_WUNLOCK(); - return ENOMEM; + goto error; } } /* call init function after the flowset is created */ @@ -1479,8 +1485,7 @@ next: /* sched config shouldn't modify the FIFO scheduler */ if (dn_ht_find(dn_cfg.schedhash, i, 0, &a) != NULL) { /* FIFO already exist, don't touch it */ - DN_BH_WUNLOCK(); - return 0; + goto error; } } a.sch->sched_nr = i; @@ -1488,8 +1493,12 @@ next: bzero(a.sch->name, sizeof(a.sch->name)); goto again; } + err = 0; +error: DN_BH_WUNLOCK(); - return 0; + if (pf) + free(pf, M_DUMMYNET); + return err; } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003051753.o25HrSHY068600>