Print this page
OS-7667 IPFilter needs to keep and report state for cloud firewall logging
Portions contributed by: Mike Gerdts <mike.gerdts@joyent.com>

*** 3,13 **** * * See the IPFILTER.LICENCE file for details on licencing. * * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * ! * Copyright 2018 Joyent, Inc. */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil_solaris.c 1.7 07/22/06 (C) 1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id: ip_fil_solaris.c,v 2.62.2.19 2005/07/13 21:40:46 darrenr Exp $"; --- 3,13 ---- * * See the IPFILTER.LICENCE file for details on licencing. * * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * ! * Copyright 2019 Joyent, Inc. */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil_solaris.c 1.7 07/22/06 (C) 1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id: ip_fil_solaris.c,v 2.62.2.19 2005/07/13 21:40:46 darrenr Exp $";
*** 905,914 **** --- 905,917 ---- isp = ddi_get_soft_state(ipf_state, unit); if (isp == NULL) return ENXIO; unit = isp->ipfs_minor; + if (unit == IPL_LOGEV) + return (ipf_cfwlog_ioctl(dev, cmd, data, mode, cp, rp)); + zid = crgetzoneid(cp); if (cmd == SIOCIPFZONESET) { if (zid == GLOBAL_ZONEID) return fr_setzoneid(isp, (caddr_t) data); return EACCES;
*** 1245,1259 **** --- 1248,1280 ---- return ENXIO; if (IPL_LOGMAX < min) return ENXIO; + /* Special-case ipfev: global-zone-open only. */ + if (min == IPL_LOGEV) { + if (crgetzoneid(cred) != GLOBAL_ZONEID) + return (ENXIO); + /* + * Else enable the CFW logging of events. + * NOTE: For now, we only allow one open at a time. + * Use atomic_add to confirm/deny. And also for now, + * assume sizeof (boolean_t) == sizeof (int). + */ + if (atomic_inc_uint_nv(&ipf_cfwlog_enabled) > 1) { + atomic_dec_uint(&ipf_cfwlog_enabled); + return (EBUSY); + } + } + minor = (minor_t)(uintptr_t)vmem_alloc(ipf_minor, 1, VM_BESTFIT | VM_SLEEP); if (ddi_soft_state_zalloc(ipf_state, minor) != 0) { vmem_free(ipf_minor, (void *)(uintptr_t)minor, 1); + if (min == IPL_LOGEV) + atomic_dec_uint(&ipf_cfwlog_enabled); return ENXIO; } *devp = makedevice(getmajor(*devp), minor); isp = ddi_get_soft_state(ipf_state, minor);
*** 1271,1288 **** --- 1292,1317 ---- dev_t dev; int flags, otype; cred_t *cred; { minor_t min = getminor(dev); + ipf_devstate_t *isp; #ifdef IPFDEBUG cmn_err(CE_CONT, "iplclose(%x,%x,%x,%x)\n", dev, flags, otype, cred); #endif if (IPL_LOGMAX < min) return ENXIO; + isp = ddi_get_soft_state(ipf_state, min); + if (isp != NULL && isp->ipfs_minor == IPL_LOGEV) { + /* Disable CFW logging. */ + membar_exit(); + atomic_dec_uint(&ipf_cfwlog_enabled); + } + ddi_soft_state_free(ipf_state, min); vmem_free(ipf_minor, (void *)(uintptr_t)min, 1); return 0; }
*** 1309,1318 **** --- 1338,1350 ---- isp = ddi_get_soft_state(ipf_state, unit); if (isp == NULL) return ENXIO; unit = isp->ipfs_minor; + if (unit == IPL_LOGEV) + return (ipf_cfwlog_read(dev, uio, cp)); + /* * ipf_find_stack returns with a read lock on ifs_ipf_global */ ifs = ipf_find_stack(crgetzoneid(cp), isp); if (ifs == NULL)
*** 1360,1369 **** --- 1392,1404 ---- isp = ddi_get_soft_state(ipf_state, unit); if (isp == NULL) return ENXIO; unit = isp->ipfs_minor; + if (unit == IPL_LOGEV) + return (EIO); /* ipfev doesn't support write yet. */ + /* * ipf_find_stack returns with a read lock on ifs_ipf_global */ ifs = ipf_find_stack(crgetzoneid(cp), isp); if (ifs == NULL)