1c58794deSPawel Jakub Dawidek /*- 2c58794deSPawel Jakub Dawidek * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3c58794deSPawel Jakub Dawidek * All rights reserved. 4c58794deSPawel Jakub Dawidek * 5c58794deSPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without 6c58794deSPawel Jakub Dawidek * modification, are permitted provided that the following conditions 7c58794deSPawel Jakub Dawidek * are met: 8c58794deSPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright 9c58794deSPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer. 10c58794deSPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright 11c58794deSPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the 12c58794deSPawel Jakub Dawidek * documentation and/or other materials provided with the distribution. 13c58794deSPawel Jakub Dawidek * 14c58794deSPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15c58794deSPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16c58794deSPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17c58794deSPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18c58794deSPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19c58794deSPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20c58794deSPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21c58794deSPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22c58794deSPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23c58794deSPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24c58794deSPawel Jakub Dawidek * SUCH DAMAGE. 25c58794deSPawel Jakub Dawidek */ 26c58794deSPawel Jakub Dawidek 27c58794deSPawel Jakub Dawidek #include <sys/cdefs.h> 28c58794deSPawel Jakub Dawidek __FBSDID("$FreeBSD$"); 29c58794deSPawel Jakub Dawidek 30c58794deSPawel Jakub Dawidek #include <sys/param.h> 31c58794deSPawel Jakub Dawidek #include <sys/systm.h> 32c58794deSPawel Jakub Dawidek #include <sys/kernel.h> 33c58794deSPawel Jakub Dawidek #include <sys/module.h> 34c58794deSPawel Jakub Dawidek #include <sys/lock.h> 35c58794deSPawel Jakub Dawidek #include <sys/mutex.h> 36c58794deSPawel Jakub Dawidek #include <sys/bio.h> 37c58794deSPawel Jakub Dawidek #include <sys/sysctl.h> 38c58794deSPawel Jakub Dawidek #include <sys/malloc.h> 39c58794deSPawel Jakub Dawidek #include <sys/kthread.h> 40c58794deSPawel Jakub Dawidek #include <sys/proc.h> 41c58794deSPawel Jakub Dawidek #include <sys/sched.h> 42c58794deSPawel Jakub Dawidek #include <sys/uio.h> 43c58794deSPawel Jakub Dawidek 44c58794deSPawel Jakub Dawidek #include <vm/uma.h> 45c58794deSPawel Jakub Dawidek 46c58794deSPawel Jakub Dawidek #include <geom/geom.h> 47c58794deSPawel Jakub Dawidek #include <geom/eli/g_eli.h> 48c58794deSPawel Jakub Dawidek 49c58794deSPawel Jakub Dawidek 50c58794deSPawel Jakub Dawidek MALLOC_DECLARE(M_ELI); 51c58794deSPawel Jakub Dawidek 52c58794deSPawel Jakub Dawidek 53c58794deSPawel Jakub Dawidek static void 54c58794deSPawel Jakub Dawidek g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp) 55c58794deSPawel Jakub Dawidek { 56c58794deSPawel Jakub Dawidek struct g_eli_metadata md; 57c58794deSPawel Jakub Dawidek struct g_provider *pp; 58c58794deSPawel Jakub Dawidek const char *name; 59c58794deSPawel Jakub Dawidek u_char *key, mkey[G_ELI_DATAIVKEYLEN]; 60c58794deSPawel Jakub Dawidek int *nargs, *detach; 61c58794deSPawel Jakub Dawidek int keysize, error; 62c58794deSPawel Jakub Dawidek u_int nkey; 63c58794deSPawel Jakub Dawidek 64c58794deSPawel Jakub Dawidek g_topology_assert(); 65c58794deSPawel Jakub Dawidek 66c58794deSPawel Jakub Dawidek nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 67c58794deSPawel Jakub Dawidek if (nargs == NULL) { 68c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "nargs"); 69c58794deSPawel Jakub Dawidek return; 70c58794deSPawel Jakub Dawidek } 71c58794deSPawel Jakub Dawidek if (*nargs != 1) { 72c58794deSPawel Jakub Dawidek gctl_error(req, "Invalid number of arguments."); 73c58794deSPawel Jakub Dawidek return; 74c58794deSPawel Jakub Dawidek } 75c58794deSPawel Jakub Dawidek 76c58794deSPawel Jakub Dawidek detach = gctl_get_paraml(req, "detach", sizeof(*detach)); 77c58794deSPawel Jakub Dawidek if (detach == NULL) { 78c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "detach"); 79c58794deSPawel Jakub Dawidek return; 80c58794deSPawel Jakub Dawidek } 81c58794deSPawel Jakub Dawidek 82c58794deSPawel Jakub Dawidek name = gctl_get_asciiparam(req, "arg0"); 83c58794deSPawel Jakub Dawidek if (name == NULL) { 84c58794deSPawel Jakub Dawidek gctl_error(req, "No 'arg%u' argument.", 0); 85c58794deSPawel Jakub Dawidek return; 86c58794deSPawel Jakub Dawidek } 87c58794deSPawel Jakub Dawidek if (strncmp(name, "/dev/", strlen("/dev/")) == 0) 88c58794deSPawel Jakub Dawidek name += strlen("/dev/"); 89c58794deSPawel Jakub Dawidek pp = g_provider_by_name(name); 90c58794deSPawel Jakub Dawidek if (pp == NULL) { 91c58794deSPawel Jakub Dawidek gctl_error(req, "Provider %s is invalid.", name); 92c58794deSPawel Jakub Dawidek return; 93c58794deSPawel Jakub Dawidek } 94c58794deSPawel Jakub Dawidek error = g_eli_read_metadata(mp, pp, &md); 95c58794deSPawel Jakub Dawidek if (error != 0) { 96c58794deSPawel Jakub Dawidek gctl_error(req, "Cannot read metadata from %s (error=%d).", 97c58794deSPawel Jakub Dawidek name, error); 98c58794deSPawel Jakub Dawidek return; 99c58794deSPawel Jakub Dawidek } 100c58794deSPawel Jakub Dawidek if (md.md_keys == 0x00) { 101c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 102c58794deSPawel Jakub Dawidek gctl_error(req, "No valid keys on %s.", pp->name); 103c58794deSPawel Jakub Dawidek return; 104c58794deSPawel Jakub Dawidek } 105c58794deSPawel Jakub Dawidek 106c58794deSPawel Jakub Dawidek key = gctl_get_param(req, "key", &keysize); 107c58794deSPawel Jakub Dawidek if (key == NULL || keysize != G_ELI_USERKEYLEN) { 108c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 109c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "key"); 110c58794deSPawel Jakub Dawidek return; 111c58794deSPawel Jakub Dawidek } 112c58794deSPawel Jakub Dawidek 113c58794deSPawel Jakub Dawidek error = g_eli_mkey_decrypt(&md, key, mkey, &nkey); 114c58794deSPawel Jakub Dawidek bzero(key, keysize); 115c58794deSPawel Jakub Dawidek if (error == -1) { 116c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 117c58794deSPawel Jakub Dawidek gctl_error(req, "Wrong key for %s.", pp->name); 118c58794deSPawel Jakub Dawidek return; 119c58794deSPawel Jakub Dawidek } else if (error > 0) { 120c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 121c58794deSPawel Jakub Dawidek gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).", 122c58794deSPawel Jakub Dawidek pp->name, error); 123c58794deSPawel Jakub Dawidek return; 124c58794deSPawel Jakub Dawidek } 125c58794deSPawel Jakub Dawidek G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name); 126c58794deSPawel Jakub Dawidek 127c58794deSPawel Jakub Dawidek if (*detach) 128c58794deSPawel Jakub Dawidek md.md_flags |= G_ELI_FLAG_WO_DETACH; 129c58794deSPawel Jakub Dawidek g_eli_create(req, mp, pp, &md, mkey, nkey); 130c58794deSPawel Jakub Dawidek bzero(mkey, sizeof(mkey)); 131c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 132c58794deSPawel Jakub Dawidek } 133c58794deSPawel Jakub Dawidek 134c58794deSPawel Jakub Dawidek static struct g_eli_softc * 135c58794deSPawel Jakub Dawidek g_eli_find_device(struct g_class *mp, const char *prov) 136c58794deSPawel Jakub Dawidek { 137c58794deSPawel Jakub Dawidek struct g_eli_softc *sc; 138c58794deSPawel Jakub Dawidek struct g_geom *gp; 139c58794deSPawel Jakub Dawidek struct g_provider *pp; 140c58794deSPawel Jakub Dawidek struct g_consumer *cp; 141c58794deSPawel Jakub Dawidek 142c58794deSPawel Jakub Dawidek if (strncmp(prov, "/dev/", strlen("/dev/")) == 0) 143c58794deSPawel Jakub Dawidek prov += strlen("/dev/"); 144c58794deSPawel Jakub Dawidek LIST_FOREACH(gp, &mp->geom, geom) { 145c58794deSPawel Jakub Dawidek sc = gp->softc; 146c58794deSPawel Jakub Dawidek if (sc == NULL) 147c58794deSPawel Jakub Dawidek continue; 148c58794deSPawel Jakub Dawidek pp = LIST_FIRST(&gp->provider); 149c58794deSPawel Jakub Dawidek if (pp != NULL && strcmp(pp->name, prov) == 0) 150c58794deSPawel Jakub Dawidek return (sc); 151c58794deSPawel Jakub Dawidek cp = LIST_FIRST(&gp->consumer); 152c58794deSPawel Jakub Dawidek if (cp != NULL && cp->provider != NULL && 153c58794deSPawel Jakub Dawidek strcmp(cp->provider->name, prov) == 0) { 154c58794deSPawel Jakub Dawidek return (sc); 155c58794deSPawel Jakub Dawidek } 156c58794deSPawel Jakub Dawidek } 157c58794deSPawel Jakub Dawidek return (NULL); 158c58794deSPawel Jakub Dawidek } 159c58794deSPawel Jakub Dawidek 160c58794deSPawel Jakub Dawidek static void 161c58794deSPawel Jakub Dawidek g_eli_ctl_detach(struct gctl_req *req, struct g_class *mp) 162c58794deSPawel Jakub Dawidek { 163c58794deSPawel Jakub Dawidek struct g_eli_softc *sc; 164c58794deSPawel Jakub Dawidek int *force, *last, *nargs, error; 165c58794deSPawel Jakub Dawidek const char *prov; 166c58794deSPawel Jakub Dawidek char param[16]; 1677d54b385SPawel Jakub Dawidek int i; 168c58794deSPawel Jakub Dawidek 169c58794deSPawel Jakub Dawidek g_topology_assert(); 170c58794deSPawel Jakub Dawidek 171c58794deSPawel Jakub Dawidek nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 172c58794deSPawel Jakub Dawidek if (nargs == NULL) { 173c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "nargs"); 174c58794deSPawel Jakub Dawidek return; 175c58794deSPawel Jakub Dawidek } 176c58794deSPawel Jakub Dawidek if (*nargs <= 0) { 177c58794deSPawel Jakub Dawidek gctl_error(req, "Missing device(s)."); 178c58794deSPawel Jakub Dawidek return; 179c58794deSPawel Jakub Dawidek } 180c58794deSPawel Jakub Dawidek force = gctl_get_paraml(req, "force", sizeof(*force)); 181c58794deSPawel Jakub Dawidek if (force == NULL) { 182c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "force"); 183c58794deSPawel Jakub Dawidek return; 184c58794deSPawel Jakub Dawidek } 185c58794deSPawel Jakub Dawidek last = gctl_get_paraml(req, "last", sizeof(*last)); 186c58794deSPawel Jakub Dawidek if (last == NULL) { 187c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "last"); 188c58794deSPawel Jakub Dawidek return; 189c58794deSPawel Jakub Dawidek } 190c58794deSPawel Jakub Dawidek 1917d54b385SPawel Jakub Dawidek for (i = 0; i < *nargs; i++) { 1927d54b385SPawel Jakub Dawidek snprintf(param, sizeof(param), "arg%d", i); 193c58794deSPawel Jakub Dawidek prov = gctl_get_asciiparam(req, param); 194c58794deSPawel Jakub Dawidek if (prov == NULL) { 1957d54b385SPawel Jakub Dawidek gctl_error(req, "No 'arg%d' argument.", i); 196c58794deSPawel Jakub Dawidek return; 197c58794deSPawel Jakub Dawidek } 198c58794deSPawel Jakub Dawidek sc = g_eli_find_device(mp, prov); 199c58794deSPawel Jakub Dawidek if (sc == NULL) { 200c58794deSPawel Jakub Dawidek gctl_error(req, "No such device: %s.", prov); 201c58794deSPawel Jakub Dawidek return; 202c58794deSPawel Jakub Dawidek } 203c58794deSPawel Jakub Dawidek if (*last) { 204c58794deSPawel Jakub Dawidek sc->sc_flags |= G_ELI_FLAG_RW_DETACH; 205c58794deSPawel Jakub Dawidek sc->sc_geom->access = g_eli_access; 206c58794deSPawel Jakub Dawidek } else { 207c58794deSPawel Jakub Dawidek error = g_eli_destroy(sc, *force); 208c58794deSPawel Jakub Dawidek if (error != 0) { 209c58794deSPawel Jakub Dawidek gctl_error(req, 210c58794deSPawel Jakub Dawidek "Cannot destroy device %s (error=%d).", 211c58794deSPawel Jakub Dawidek sc->sc_name, error); 212c58794deSPawel Jakub Dawidek return; 213c58794deSPawel Jakub Dawidek } 214c58794deSPawel Jakub Dawidek } 215c58794deSPawel Jakub Dawidek } 216c58794deSPawel Jakub Dawidek } 217c58794deSPawel Jakub Dawidek 218c58794deSPawel Jakub Dawidek static void 219c58794deSPawel Jakub Dawidek g_eli_ctl_onetime(struct gctl_req *req, struct g_class *mp) 220c58794deSPawel Jakub Dawidek { 221c58794deSPawel Jakub Dawidek struct g_eli_metadata md; 222c58794deSPawel Jakub Dawidek struct g_provider *pp; 223c58794deSPawel Jakub Dawidek const char *name; 224c58794deSPawel Jakub Dawidek intmax_t *keylen, *sectorsize; 225c58794deSPawel Jakub Dawidek u_char mkey[G_ELI_DATAIVKEYLEN]; 226c58794deSPawel Jakub Dawidek int *nargs, *detach; 227c58794deSPawel Jakub Dawidek 228c58794deSPawel Jakub Dawidek g_topology_assert(); 229c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 230c58794deSPawel Jakub Dawidek 231c58794deSPawel Jakub Dawidek nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 232c58794deSPawel Jakub Dawidek if (nargs == NULL) { 233c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "nargs"); 234c58794deSPawel Jakub Dawidek return; 235c58794deSPawel Jakub Dawidek } 236c58794deSPawel Jakub Dawidek if (*nargs != 1) { 237c58794deSPawel Jakub Dawidek gctl_error(req, "Invalid number of arguments."); 238c58794deSPawel Jakub Dawidek return; 239c58794deSPawel Jakub Dawidek } 240c58794deSPawel Jakub Dawidek 241c58794deSPawel Jakub Dawidek detach = gctl_get_paraml(req, "detach", sizeof(*detach)); 242c58794deSPawel Jakub Dawidek if (detach == NULL) { 243c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "detach"); 244c58794deSPawel Jakub Dawidek return; 245c58794deSPawel Jakub Dawidek } 246c58794deSPawel Jakub Dawidek 247c58794deSPawel Jakub Dawidek strlcpy(md.md_magic, G_ELI_MAGIC, sizeof(md.md_magic)); 248c58794deSPawel Jakub Dawidek md.md_version = G_ELI_VERSION; 249c58794deSPawel Jakub Dawidek md.md_flags |= G_ELI_FLAG_ONETIME; 250c58794deSPawel Jakub Dawidek if (*detach) 251c58794deSPawel Jakub Dawidek md.md_flags |= G_ELI_FLAG_WO_DETACH; 252c58794deSPawel Jakub Dawidek 253eaa3b919SPawel Jakub Dawidek name = gctl_get_asciiparam(req, "aalgo"); 254c58794deSPawel Jakub Dawidek if (name == NULL) { 255eaa3b919SPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "aalgo"); 256c58794deSPawel Jakub Dawidek return; 257c58794deSPawel Jakub Dawidek } 258eaa3b919SPawel Jakub Dawidek if (strcmp(name, "none") != 0) { 259eaa3b919SPawel Jakub Dawidek md.md_aalgo = g_eli_str2aalgo(name); 260eaa3b919SPawel Jakub Dawidek if (md.md_aalgo < CRYPTO_ALGORITHM_MIN || 261eaa3b919SPawel Jakub Dawidek md.md_aalgo > CRYPTO_ALGORITHM_MAX) { 262eaa3b919SPawel Jakub Dawidek gctl_error(req, "Invalid authentication algorithm."); 263eaa3b919SPawel Jakub Dawidek return; 264eaa3b919SPawel Jakub Dawidek } 265eaa3b919SPawel Jakub Dawidek md.md_flags |= G_ELI_FLAG_AUTH; 266eaa3b919SPawel Jakub Dawidek } 267eaa3b919SPawel Jakub Dawidek 268eaa3b919SPawel Jakub Dawidek name = gctl_get_asciiparam(req, "ealgo"); 269eaa3b919SPawel Jakub Dawidek if (name == NULL) { 270eaa3b919SPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "ealgo"); 271eaa3b919SPawel Jakub Dawidek return; 272eaa3b919SPawel Jakub Dawidek } 273eaa3b919SPawel Jakub Dawidek md.md_ealgo = g_eli_str2ealgo(name); 274eaa3b919SPawel Jakub Dawidek if (md.md_ealgo < CRYPTO_ALGORITHM_MIN || 275eaa3b919SPawel Jakub Dawidek md.md_ealgo > CRYPTO_ALGORITHM_MAX) { 276eaa3b919SPawel Jakub Dawidek gctl_error(req, "Invalid encryption algorithm."); 277c58794deSPawel Jakub Dawidek return; 278c58794deSPawel Jakub Dawidek } 279c58794deSPawel Jakub Dawidek 280c58794deSPawel Jakub Dawidek keylen = gctl_get_paraml(req, "keylen", sizeof(*keylen)); 281c58794deSPawel Jakub Dawidek if (keylen == NULL) { 282c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "keylen"); 283c58794deSPawel Jakub Dawidek return; 284c58794deSPawel Jakub Dawidek } 285eaa3b919SPawel Jakub Dawidek md.md_keylen = g_eli_keylen(md.md_ealgo, *keylen); 286c58794deSPawel Jakub Dawidek if (md.md_keylen == 0) { 287c58794deSPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument.", "keylen"); 288c58794deSPawel Jakub Dawidek return; 289c58794deSPawel Jakub Dawidek } 290c58794deSPawel Jakub Dawidek 291c58794deSPawel Jakub Dawidek /* Not important here. */ 292c58794deSPawel Jakub Dawidek md.md_provsize = 0; 293c58794deSPawel Jakub Dawidek /* Not important here. */ 294c58794deSPawel Jakub Dawidek bzero(md.md_salt, sizeof(md.md_salt)); 295c58794deSPawel Jakub Dawidek 296c58794deSPawel Jakub Dawidek md.md_keys = 0x01; 297c58794deSPawel Jakub Dawidek arc4rand(mkey, sizeof(mkey), 0); 298c58794deSPawel Jakub Dawidek 299c58794deSPawel Jakub Dawidek /* Not important here. */ 300c58794deSPawel Jakub Dawidek bzero(md.md_hash, sizeof(md.md_hash)); 301c58794deSPawel Jakub Dawidek 302c58794deSPawel Jakub Dawidek name = gctl_get_asciiparam(req, "arg0"); 303c58794deSPawel Jakub Dawidek if (name == NULL) { 304c58794deSPawel Jakub Dawidek gctl_error(req, "No 'arg%u' argument.", 0); 305c58794deSPawel Jakub Dawidek return; 306c58794deSPawel Jakub Dawidek } 307c58794deSPawel Jakub Dawidek if (strncmp(name, "/dev/", strlen("/dev/")) == 0) 308c58794deSPawel Jakub Dawidek name += strlen("/dev/"); 309c58794deSPawel Jakub Dawidek pp = g_provider_by_name(name); 310c58794deSPawel Jakub Dawidek if (pp == NULL) { 311c58794deSPawel Jakub Dawidek gctl_error(req, "Provider %s is invalid.", name); 312c58794deSPawel Jakub Dawidek return; 313c58794deSPawel Jakub Dawidek } 314c58794deSPawel Jakub Dawidek 315c58794deSPawel Jakub Dawidek sectorsize = gctl_get_paraml(req, "sectorsize", sizeof(*sectorsize)); 316c58794deSPawel Jakub Dawidek if (sectorsize == NULL) { 317c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "sectorsize"); 318c58794deSPawel Jakub Dawidek return; 319c58794deSPawel Jakub Dawidek } 320c58794deSPawel Jakub Dawidek if (*sectorsize == 0) 321c58794deSPawel Jakub Dawidek md.md_sectorsize = pp->sectorsize; 322c58794deSPawel Jakub Dawidek else { 323c58794deSPawel Jakub Dawidek if (*sectorsize < 0 || (*sectorsize % pp->sectorsize) != 0) { 324c58794deSPawel Jakub Dawidek gctl_error(req, "Invalid sector size."); 325c58794deSPawel Jakub Dawidek return; 326c58794deSPawel Jakub Dawidek } 327c58794deSPawel Jakub Dawidek md.md_sectorsize = *sectorsize; 328c58794deSPawel Jakub Dawidek } 329c58794deSPawel Jakub Dawidek 330c58794deSPawel Jakub Dawidek g_eli_create(req, mp, pp, &md, mkey, -1); 331c58794deSPawel Jakub Dawidek bzero(mkey, sizeof(mkey)); 332c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 333c58794deSPawel Jakub Dawidek } 334c58794deSPawel Jakub Dawidek 335c58794deSPawel Jakub Dawidek static void 336c58794deSPawel Jakub Dawidek g_eli_ctl_setkey(struct gctl_req *req, struct g_class *mp) 337c58794deSPawel Jakub Dawidek { 338c58794deSPawel Jakub Dawidek struct g_eli_softc *sc; 339c58794deSPawel Jakub Dawidek struct g_eli_metadata md; 340c58794deSPawel Jakub Dawidek struct g_provider *pp; 341c58794deSPawel Jakub Dawidek struct g_consumer *cp; 342c58794deSPawel Jakub Dawidek const char *name; 343c58794deSPawel Jakub Dawidek u_char *key, *mkeydst, *sector; 344c58794deSPawel Jakub Dawidek intmax_t *valp; 3457a5c26fcSPawel Jakub Dawidek int keysize, nkey, error; 346c58794deSPawel Jakub Dawidek 347c58794deSPawel Jakub Dawidek g_topology_assert(); 348c58794deSPawel Jakub Dawidek 349c58794deSPawel Jakub Dawidek name = gctl_get_asciiparam(req, "arg0"); 350c58794deSPawel Jakub Dawidek if (name == NULL) { 351c58794deSPawel Jakub Dawidek gctl_error(req, "No 'arg%u' argument.", 0); 352c58794deSPawel Jakub Dawidek return; 353c58794deSPawel Jakub Dawidek } 354c58794deSPawel Jakub Dawidek sc = g_eli_find_device(mp, name); 355c58794deSPawel Jakub Dawidek if (sc == NULL) { 356c58794deSPawel Jakub Dawidek gctl_error(req, "Provider %s is invalid.", name); 357c58794deSPawel Jakub Dawidek return; 358c58794deSPawel Jakub Dawidek } 359c58794deSPawel Jakub Dawidek cp = LIST_FIRST(&sc->sc_geom->consumer); 360c58794deSPawel Jakub Dawidek pp = cp->provider; 361c58794deSPawel Jakub Dawidek 362c58794deSPawel Jakub Dawidek error = g_eli_read_metadata(mp, pp, &md); 363c58794deSPawel Jakub Dawidek if (error != 0) { 364c58794deSPawel Jakub Dawidek gctl_error(req, "Cannot read metadata from %s (error=%d).", 365c58794deSPawel Jakub Dawidek name, error); 366c58794deSPawel Jakub Dawidek return; 367c58794deSPawel Jakub Dawidek } 368c58794deSPawel Jakub Dawidek 369c58794deSPawel Jakub Dawidek valp = gctl_get_paraml(req, "keyno", sizeof(*valp)); 370c58794deSPawel Jakub Dawidek if (valp == NULL) { 371c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "keyno"); 372c58794deSPawel Jakub Dawidek return; 373c58794deSPawel Jakub Dawidek } 374c58794deSPawel Jakub Dawidek if (*valp != -1) 375c58794deSPawel Jakub Dawidek nkey = *valp; 376c58794deSPawel Jakub Dawidek else 377c58794deSPawel Jakub Dawidek nkey = sc->sc_nkey; 378c58794deSPawel Jakub Dawidek if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) { 379c58794deSPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument.", "keyno"); 380c58794deSPawel Jakub Dawidek return; 381c58794deSPawel Jakub Dawidek } 382c58794deSPawel Jakub Dawidek 3837a5c26fcSPawel Jakub Dawidek valp = gctl_get_paraml(req, "iterations", sizeof(*valp)); 3847a5c26fcSPawel Jakub Dawidek if (valp == NULL) { 3857a5c26fcSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "iterations"); 3867a5c26fcSPawel Jakub Dawidek return; 3877a5c26fcSPawel Jakub Dawidek } 3887a5c26fcSPawel Jakub Dawidek /* Check if iterations number should and can be changed. */ 3897a5c26fcSPawel Jakub Dawidek if (*valp != -1) { 3907a5c26fcSPawel Jakub Dawidek if (bitcount32(md.md_keys) != 1) { 3917a5c26fcSPawel Jakub Dawidek gctl_error(req, "To be able to use '-i' option, only " 3927a5c26fcSPawel Jakub Dawidek "one key can be defined."); 3937a5c26fcSPawel Jakub Dawidek return; 3947a5c26fcSPawel Jakub Dawidek } 3957a5c26fcSPawel Jakub Dawidek if (md.md_keys != (1 << nkey)) { 3967a5c26fcSPawel Jakub Dawidek gctl_error(req, "Only already defined key can be " 3977a5c26fcSPawel Jakub Dawidek "changed when '-i' option is used."); 3987a5c26fcSPawel Jakub Dawidek return; 3997a5c26fcSPawel Jakub Dawidek } 4007a5c26fcSPawel Jakub Dawidek md.md_iterations = *valp; 4017a5c26fcSPawel Jakub Dawidek } 4027a5c26fcSPawel Jakub Dawidek 403c58794deSPawel Jakub Dawidek key = gctl_get_param(req, "key", &keysize); 404c58794deSPawel Jakub Dawidek if (key == NULL || keysize != G_ELI_USERKEYLEN) { 405c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 406c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "key"); 407c58794deSPawel Jakub Dawidek return; 408c58794deSPawel Jakub Dawidek } 409c58794deSPawel Jakub Dawidek 410c58794deSPawel Jakub Dawidek mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN; 411c58794deSPawel Jakub Dawidek md.md_keys |= (1 << nkey); 412c58794deSPawel Jakub Dawidek 413eaa3b919SPawel Jakub Dawidek bcopy(sc->sc_mkey, mkeydst, sizeof(sc->sc_mkey)); 414c58794deSPawel Jakub Dawidek 415c58794deSPawel Jakub Dawidek /* Encrypt Master Key with the new key. */ 416eaa3b919SPawel Jakub Dawidek error = g_eli_mkey_encrypt(md.md_ealgo, key, md.md_keylen, mkeydst); 417c58794deSPawel Jakub Dawidek bzero(key, sizeof(key)); 418c58794deSPawel Jakub Dawidek if (error != 0) { 419c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 420c58794deSPawel Jakub Dawidek gctl_error(req, "Cannot encrypt Master Key (error=%d).", error); 421c58794deSPawel Jakub Dawidek return; 422c58794deSPawel Jakub Dawidek } 423c58794deSPawel Jakub Dawidek 424c58794deSPawel Jakub Dawidek sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO); 425c58794deSPawel Jakub Dawidek /* Store metadata with fresh key. */ 426c58794deSPawel Jakub Dawidek eli_metadata_encode(&md, sector); 427c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 428c58794deSPawel Jakub Dawidek error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector, 429c58794deSPawel Jakub Dawidek pp->sectorsize); 430c58794deSPawel Jakub Dawidek bzero(sector, sizeof(sector)); 431c58794deSPawel Jakub Dawidek free(sector, M_ELI); 432c58794deSPawel Jakub Dawidek if (error != 0) { 433c58794deSPawel Jakub Dawidek gctl_error(req, "Cannot store metadata on %s (error=%d).", 434c58794deSPawel Jakub Dawidek pp->name, error); 435c58794deSPawel Jakub Dawidek return; 436c58794deSPawel Jakub Dawidek } 437c58794deSPawel Jakub Dawidek G_ELI_DEBUG(1, "Key %u changed on %s.", nkey, pp->name); 438c58794deSPawel Jakub Dawidek } 439c58794deSPawel Jakub Dawidek 440c58794deSPawel Jakub Dawidek static void 441c58794deSPawel Jakub Dawidek g_eli_ctl_delkey(struct gctl_req *req, struct g_class *mp) 442c58794deSPawel Jakub Dawidek { 443c58794deSPawel Jakub Dawidek struct g_eli_softc *sc; 444c58794deSPawel Jakub Dawidek struct g_eli_metadata md; 445c58794deSPawel Jakub Dawidek struct g_provider *pp; 446c58794deSPawel Jakub Dawidek struct g_consumer *cp; 447c58794deSPawel Jakub Dawidek const char *name; 448c58794deSPawel Jakub Dawidek u_char *mkeydst, *sector; 449c58794deSPawel Jakub Dawidek intmax_t *valp; 450c58794deSPawel Jakub Dawidek size_t keysize; 451c58794deSPawel Jakub Dawidek int error, nkey, *all, *force; 452c58794deSPawel Jakub Dawidek u_int i; 453c58794deSPawel Jakub Dawidek 454c58794deSPawel Jakub Dawidek g_topology_assert(); 455c58794deSPawel Jakub Dawidek 456c58794deSPawel Jakub Dawidek nkey = 0; /* fixes causeless gcc warning */ 457c58794deSPawel Jakub Dawidek 458c58794deSPawel Jakub Dawidek name = gctl_get_asciiparam(req, "arg0"); 459c58794deSPawel Jakub Dawidek if (name == NULL) { 460c58794deSPawel Jakub Dawidek gctl_error(req, "No 'arg%u' argument.", 0); 461c58794deSPawel Jakub Dawidek return; 462c58794deSPawel Jakub Dawidek } 463c58794deSPawel Jakub Dawidek sc = g_eli_find_device(mp, name); 464c58794deSPawel Jakub Dawidek if (sc == NULL) { 465c58794deSPawel Jakub Dawidek gctl_error(req, "Provider %s is invalid.", name); 466c58794deSPawel Jakub Dawidek return; 467c58794deSPawel Jakub Dawidek } 468c58794deSPawel Jakub Dawidek cp = LIST_FIRST(&sc->sc_geom->consumer); 469c58794deSPawel Jakub Dawidek pp = cp->provider; 470c58794deSPawel Jakub Dawidek 471c58794deSPawel Jakub Dawidek error = g_eli_read_metadata(mp, pp, &md); 472c58794deSPawel Jakub Dawidek if (error != 0) { 473c58794deSPawel Jakub Dawidek gctl_error(req, "Cannot read metadata from %s (error=%d).", 474c58794deSPawel Jakub Dawidek name, error); 475c58794deSPawel Jakub Dawidek return; 476c58794deSPawel Jakub Dawidek } 477c58794deSPawel Jakub Dawidek 478c58794deSPawel Jakub Dawidek all = gctl_get_paraml(req, "all", sizeof(*all)); 479c58794deSPawel Jakub Dawidek if (all == NULL) { 480c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "all"); 481c58794deSPawel Jakub Dawidek return; 482c58794deSPawel Jakub Dawidek } 483c58794deSPawel Jakub Dawidek 484c58794deSPawel Jakub Dawidek if (*all) { 485c58794deSPawel Jakub Dawidek mkeydst = md.md_mkeys; 486c58794deSPawel Jakub Dawidek keysize = sizeof(md.md_mkeys); 487c58794deSPawel Jakub Dawidek } else { 488c58794deSPawel Jakub Dawidek force = gctl_get_paraml(req, "force", sizeof(*force)); 489c58794deSPawel Jakub Dawidek if (force == NULL) { 490c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "force"); 491c58794deSPawel Jakub Dawidek return; 492c58794deSPawel Jakub Dawidek } 493c58794deSPawel Jakub Dawidek 494c58794deSPawel Jakub Dawidek valp = gctl_get_paraml(req, "keyno", sizeof(*valp)); 495c58794deSPawel Jakub Dawidek if (valp == NULL) { 496c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "keyno"); 497c58794deSPawel Jakub Dawidek return; 498c58794deSPawel Jakub Dawidek } 499c58794deSPawel Jakub Dawidek if (*valp != -1) 500c58794deSPawel Jakub Dawidek nkey = *valp; 501c58794deSPawel Jakub Dawidek else 502c58794deSPawel Jakub Dawidek nkey = sc->sc_nkey; 503c58794deSPawel Jakub Dawidek if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) { 504c58794deSPawel Jakub Dawidek gctl_error(req, "Invalid '%s' argument.", "keyno"); 505c58794deSPawel Jakub Dawidek return; 506c58794deSPawel Jakub Dawidek } 507c58794deSPawel Jakub Dawidek if (!(md.md_keys & (1 << nkey)) && !*force) { 508c58794deSPawel Jakub Dawidek gctl_error(req, "Master Key %u is not set.", nkey); 509c58794deSPawel Jakub Dawidek return; 510c58794deSPawel Jakub Dawidek } 511c58794deSPawel Jakub Dawidek md.md_keys &= ~(1 << nkey); 512c58794deSPawel Jakub Dawidek if (md.md_keys == 0 && !*force) { 513c58794deSPawel Jakub Dawidek gctl_error(req, "This is the last Master Key. Use '-f' " 514c58794deSPawel Jakub Dawidek "flag if you really want to remove it."); 515c58794deSPawel Jakub Dawidek return; 516c58794deSPawel Jakub Dawidek } 517c58794deSPawel Jakub Dawidek mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN; 518c58794deSPawel Jakub Dawidek keysize = G_ELI_MKEYLEN; 519c58794deSPawel Jakub Dawidek } 520c58794deSPawel Jakub Dawidek 521c58794deSPawel Jakub Dawidek sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO); 522c58794deSPawel Jakub Dawidek for (i = 0; i <= g_eli_overwrites; i++) { 523c58794deSPawel Jakub Dawidek if (i == g_eli_overwrites) 524c58794deSPawel Jakub Dawidek bzero(mkeydst, keysize); 525c58794deSPawel Jakub Dawidek else 526c58794deSPawel Jakub Dawidek arc4rand(mkeydst, keysize, 0); 527c58794deSPawel Jakub Dawidek /* Store metadata with destroyed key. */ 528c58794deSPawel Jakub Dawidek eli_metadata_encode(&md, sector); 529c58794deSPawel Jakub Dawidek error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector, 530c58794deSPawel Jakub Dawidek pp->sectorsize); 531c58794deSPawel Jakub Dawidek if (error != 0) { 532c58794deSPawel Jakub Dawidek G_ELI_DEBUG(0, "Cannot store metadata on %s " 533c58794deSPawel Jakub Dawidek "(error=%d).", pp->name, error); 534c58794deSPawel Jakub Dawidek } 535c58794deSPawel Jakub Dawidek } 536c58794deSPawel Jakub Dawidek bzero(&md, sizeof(md)); 537c58794deSPawel Jakub Dawidek bzero(sector, sizeof(sector)); 538c58794deSPawel Jakub Dawidek free(sector, M_ELI); 539c58794deSPawel Jakub Dawidek if (*all) 540c58794deSPawel Jakub Dawidek G_ELI_DEBUG(1, "All keys removed from %s.", pp->name); 541c58794deSPawel Jakub Dawidek else 542c58794deSPawel Jakub Dawidek G_ELI_DEBUG(1, "Key %d removed from %s.", nkey, pp->name); 543c58794deSPawel Jakub Dawidek } 544c58794deSPawel Jakub Dawidek 545c58794deSPawel Jakub Dawidek static int 546c58794deSPawel Jakub Dawidek g_eli_kill_one(struct g_eli_softc *sc) 547c58794deSPawel Jakub Dawidek { 548c58794deSPawel Jakub Dawidek struct g_provider *pp; 549c58794deSPawel Jakub Dawidek struct g_consumer *cp; 550c58794deSPawel Jakub Dawidek u_char *sector; 551c58794deSPawel Jakub Dawidek int err, error = 0; 552c58794deSPawel Jakub Dawidek u_int i; 553c58794deSPawel Jakub Dawidek 554c58794deSPawel Jakub Dawidek g_topology_assert(); 555c58794deSPawel Jakub Dawidek 556c58794deSPawel Jakub Dawidek if (sc == NULL) 557c58794deSPawel Jakub Dawidek return (ENOENT); 558c58794deSPawel Jakub Dawidek 559c58794deSPawel Jakub Dawidek pp = LIST_FIRST(&sc->sc_geom->provider); 560c58794deSPawel Jakub Dawidek g_error_provider(pp, ENXIO); 561c58794deSPawel Jakub Dawidek 562c58794deSPawel Jakub Dawidek cp = LIST_FIRST(&sc->sc_geom->consumer); 563c58794deSPawel Jakub Dawidek pp = cp->provider; 564c58794deSPawel Jakub Dawidek 565c58794deSPawel Jakub Dawidek sector = malloc(pp->sectorsize, M_ELI, M_WAITOK); 566c58794deSPawel Jakub Dawidek for (i = 0; i <= g_eli_overwrites; i++) { 567c58794deSPawel Jakub Dawidek if (i == g_eli_overwrites) 568c58794deSPawel Jakub Dawidek bzero(sector, pp->sectorsize); 569c58794deSPawel Jakub Dawidek else 570c58794deSPawel Jakub Dawidek arc4rand(sector, pp->sectorsize, 0); 571c58794deSPawel Jakub Dawidek err = g_write_data(cp, pp->mediasize - pp->sectorsize, sector, 572c58794deSPawel Jakub Dawidek pp->sectorsize); 573c58794deSPawel Jakub Dawidek if (err != 0) { 574c58794deSPawel Jakub Dawidek G_ELI_DEBUG(0, "Cannot erase metadata on %s " 575c58794deSPawel Jakub Dawidek "(error=%d).", pp->name, err); 576c58794deSPawel Jakub Dawidek if (error == 0) 577c58794deSPawel Jakub Dawidek error = err; 578c58794deSPawel Jakub Dawidek } 579c58794deSPawel Jakub Dawidek } 580c58794deSPawel Jakub Dawidek free(sector, M_ELI); 581c58794deSPawel Jakub Dawidek if (error == 0) 582c58794deSPawel Jakub Dawidek G_ELI_DEBUG(0, "%s has been killed.", pp->name); 583c58794deSPawel Jakub Dawidek g_eli_destroy(sc, 1); 584c58794deSPawel Jakub Dawidek return (error); 585c58794deSPawel Jakub Dawidek } 586c58794deSPawel Jakub Dawidek 587c58794deSPawel Jakub Dawidek static void 588c58794deSPawel Jakub Dawidek g_eli_ctl_kill(struct gctl_req *req, struct g_class *mp) 589c58794deSPawel Jakub Dawidek { 590c58794deSPawel Jakub Dawidek int *all, *nargs; 591c58794deSPawel Jakub Dawidek int error; 592c58794deSPawel Jakub Dawidek 593c58794deSPawel Jakub Dawidek g_topology_assert(); 594c58794deSPawel Jakub Dawidek 595c58794deSPawel Jakub Dawidek nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 596c58794deSPawel Jakub Dawidek if (nargs == NULL) { 597c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "nargs"); 598c58794deSPawel Jakub Dawidek return; 599c58794deSPawel Jakub Dawidek } 600c58794deSPawel Jakub Dawidek all = gctl_get_paraml(req, "all", sizeof(*all)); 601c58794deSPawel Jakub Dawidek if (all == NULL) { 602c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "all"); 603c58794deSPawel Jakub Dawidek return; 604c58794deSPawel Jakub Dawidek } 605c58794deSPawel Jakub Dawidek if (!*all && *nargs == 0) { 606c58794deSPawel Jakub Dawidek gctl_error(req, "Too few arguments."); 607c58794deSPawel Jakub Dawidek return; 608c58794deSPawel Jakub Dawidek } 609c58794deSPawel Jakub Dawidek 610c58794deSPawel Jakub Dawidek if (*all) { 611c58794deSPawel Jakub Dawidek struct g_geom *gp, *gp2; 612c58794deSPawel Jakub Dawidek 613c58794deSPawel Jakub Dawidek LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { 614c58794deSPawel Jakub Dawidek error = g_eli_kill_one(gp->softc); 615c58794deSPawel Jakub Dawidek if (error != 0) 616c58794deSPawel Jakub Dawidek gctl_error(req, "Not fully done."); 617c58794deSPawel Jakub Dawidek } 618c58794deSPawel Jakub Dawidek } else { 619c58794deSPawel Jakub Dawidek struct g_eli_softc *sc; 620c58794deSPawel Jakub Dawidek const char *prov; 621c58794deSPawel Jakub Dawidek char param[16]; 622c58794deSPawel Jakub Dawidek int i; 623c58794deSPawel Jakub Dawidek 624c58794deSPawel Jakub Dawidek for (i = 0; i < *nargs; i++) { 6257d54b385SPawel Jakub Dawidek snprintf(param, sizeof(param), "arg%d", i); 626c58794deSPawel Jakub Dawidek prov = gctl_get_asciiparam(req, param); 627b5f30223SPawel Jakub Dawidek if (prov == NULL) { 628b5f30223SPawel Jakub Dawidek G_ELI_DEBUG(0, "No 'arg%d' argument.", i); 629b5f30223SPawel Jakub Dawidek continue; 630b5f30223SPawel Jakub Dawidek } 631c58794deSPawel Jakub Dawidek 632c58794deSPawel Jakub Dawidek sc = g_eli_find_device(mp, prov); 633c58794deSPawel Jakub Dawidek if (sc == NULL) { 6347d54b385SPawel Jakub Dawidek G_ELI_DEBUG(0, "No such provider: %s.", prov); 635c58794deSPawel Jakub Dawidek continue; 636c58794deSPawel Jakub Dawidek } 637c58794deSPawel Jakub Dawidek error = g_eli_kill_one(sc); 638c58794deSPawel Jakub Dawidek if (error != 0) 639c58794deSPawel Jakub Dawidek gctl_error(req, "Not fully done."); 640c58794deSPawel Jakub Dawidek } 641c58794deSPawel Jakub Dawidek } 642c58794deSPawel Jakub Dawidek } 643c58794deSPawel Jakub Dawidek 644c58794deSPawel Jakub Dawidek void 645c58794deSPawel Jakub Dawidek g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb) 646c58794deSPawel Jakub Dawidek { 647c58794deSPawel Jakub Dawidek uint32_t *version; 648c58794deSPawel Jakub Dawidek 649c58794deSPawel Jakub Dawidek g_topology_assert(); 650c58794deSPawel Jakub Dawidek 651c58794deSPawel Jakub Dawidek version = gctl_get_paraml(req, "version", sizeof(*version)); 652c58794deSPawel Jakub Dawidek if (version == NULL) { 653c58794deSPawel Jakub Dawidek gctl_error(req, "No '%s' argument.", "version"); 654c58794deSPawel Jakub Dawidek return; 655c58794deSPawel Jakub Dawidek } 656c58794deSPawel Jakub Dawidek if (*version != G_ELI_VERSION) { 657c58794deSPawel Jakub Dawidek gctl_error(req, "Userland and kernel parts are out of sync."); 658c58794deSPawel Jakub Dawidek return; 659c58794deSPawel Jakub Dawidek } 660c58794deSPawel Jakub Dawidek 661c58794deSPawel Jakub Dawidek if (strcmp(verb, "attach") == 0) 662c58794deSPawel Jakub Dawidek g_eli_ctl_attach(req, mp); 663c58794deSPawel Jakub Dawidek else if (strcmp(verb, "detach") == 0 || strcmp(verb, "stop") == 0) 664c58794deSPawel Jakub Dawidek g_eli_ctl_detach(req, mp); 665c58794deSPawel Jakub Dawidek else if (strcmp(verb, "onetime") == 0) 666c58794deSPawel Jakub Dawidek g_eli_ctl_onetime(req, mp); 667c58794deSPawel Jakub Dawidek else if (strcmp(verb, "setkey") == 0) 668c58794deSPawel Jakub Dawidek g_eli_ctl_setkey(req, mp); 669c58794deSPawel Jakub Dawidek else if (strcmp(verb, "delkey") == 0) 670c58794deSPawel Jakub Dawidek g_eli_ctl_delkey(req, mp); 671c58794deSPawel Jakub Dawidek else if (strcmp(verb, "kill") == 0) 672c58794deSPawel Jakub Dawidek g_eli_ctl_kill(req, mp); 673c58794deSPawel Jakub Dawidek else 674c58794deSPawel Jakub Dawidek gctl_error(req, "Unknown verb."); 675c58794deSPawel Jakub Dawidek } 676