static void lka_submit(struct lka_session *lks, struct rule *rule, struct expandnode *xn) { union lookup lk; struct envelope *ep; struct expandnode *xn2; int r; ep = xmemdup(&lks->envelope, sizeof *ep, "lka_submit"); ep->expire = rule->r_qexpire; switch (rule->r_action) { case A_RELAY: case A_RELAYVIA: if (xn->type != EXPAND_ADDRESS) fatalx("lka_deliver: expect address"); ep->type = D_MTA; ep->dest = xn->u.mailaddr; ep->agent.mta.relay = rule->r_value.relayhost; /* only rewrite if not a bounce */ if (ep->sender.user[0] && rule->r_as && rule->r_as->user[0]) (void)strlcpy(ep->sender.user, rule->r_as->user, sizeof ep->sender.user); if (ep->sender.user[0] && rule->r_as && rule->r_as->domain[0]) (void)strlcpy(ep->sender.domain, rule->r_as->domain, sizeof ep->sender.domain); break; case A_NONE: case A_MBOX: case A_MAILDIR: case A_FILENAME: case A_MDA: case A_LMTP: ep->type = D_MDA; ep->dest = lka_find_ancestor(xn, EXPAND_ADDRESS)->u.mailaddr; /* set username */ if ((xn->type == EXPAND_FILTER || xn->type == EXPAND_FILENAME) && xn->alias) { (void)strlcpy(ep->agent.mda.username, SMTPD_USER, sizeof(ep->agent.mda.username)); } else { xn2 = lka_find_ancestor(xn, EXPAND_USERNAME); (void)strlcpy(ep->agent.mda.username, xn2->u.user, sizeof(ep->agent.mda.username)); } r = table_lookup(rule->r_userbase, ep->agent.mda.username, K_USERINFO, &lk); if (r <= 0) { lks->error = (r == -1) ? LKA_TEMPFAIL : LKA_PERMFAIL; free(ep); return; } (void)strlcpy(ep->agent.mda.usertable, rule->r_userbase->t_name, sizeof ep->agent.mda.usertable); (void)strlcpy(ep->agent.mda.username, lk.userinfo.username, sizeof ep->agent.mda.username); if (xn->type == EXPAND_FILENAME) { ep->agent.mda.method = A_FILENAME; (void)strlcpy(ep->agent.mda.buffer, xn->u.buffer, sizeof ep->agent.mda.buffer); } else if (xn->type == EXPAND_FILTER) { ep->agent.mda.method = A_MDA; (void)strlcpy(ep->agent.mda.buffer, xn->u.buffer, sizeof ep->agent.mda.buffer); } else if (xn->type == EXPAND_USERNAME) { ep->agent.mda.method = rule->r_action; (void)strlcpy(ep->agent.mda.buffer, rule->r_value.buffer, sizeof ep->agent.mda.buffer); } else fatalx("lka_deliver: bad node type"); r = lka_expand_format(ep->agent.mda.buffer, sizeof(ep->agent.mda.buffer), ep, &lk.userinfo); if (!r) { lks->error = LKA_TEMPFAIL; log_warnx("warn: format string error while" " expanding for user %s", ep->agent.mda.username); free(ep); return; } break; default: fatalx("lka_submit: bad rule action"); } TAILQ_INSERT_TAIL(&lks->deliverylist, ep, entry); }
/* Create a new connection, storing it in the list of clients. */ ship_client_t *client_create_connection(int sock, int version, int type, struct client_queue *clients, ship_t *ship, block_t *block, struct sockaddr *ip, socklen_t size) { ship_client_t *rv = (ship_client_t *)malloc(sizeof(ship_client_t)); uint32_t client_seed_dc, server_seed_dc; uint8_t client_seed_bb[48], server_seed_bb[48]; int i; pthread_mutexattr_t attr; struct mt19937_state *rng; if(!rv) { perror("malloc"); return NULL; } memset(rv, 0, sizeof(ship_client_t)); if(type == CLIENT_TYPE_BLOCK) { rv->pl = (player_t *)malloc(sizeof(player_t)); if(!rv->pl) { perror("malloc"); free(rv); close(sock); return NULL; } memset(rv->pl, 0, sizeof(player_t)); if(!(rv->enemy_kills = (uint32_t *)malloc(sizeof(uint32_t) * 0x60))) { perror("malloc"); free(rv->pl); free(rv); close(sock); return NULL; } if(version == CLIENT_VERSION_BB) { rv->bb_pl = (sylverant_bb_db_char_t *)malloc(sizeof(sylverant_bb_db_char_t)); if(!rv->bb_pl) { perror("malloc"); free(rv->pl); free(rv); close(sock); return NULL; } rv->bb_opts = (sylverant_bb_db_opts_t *)malloc(sizeof(sylverant_bb_db_opts_t)); if(!rv->bb_opts) { perror("malloc"); free(rv->bb_pl); free(rv->pl); free(rv); close(sock); return NULL; } memset(rv->bb_pl, 0, sizeof(sylverant_bb_db_char_t)); memset(rv->bb_opts, 0, sizeof(sylverant_bb_db_opts_t)); } } /* Store basic parameters in the client structure. */ rv->sock = sock; rv->version = version; rv->cur_block = block; rv->arrow = 1; rv->last_message = rv->login_time = time(NULL); rv->hdr_size = 4; /* Create the mutex */ pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&rv->mutex, &attr); pthread_mutexattr_destroy(&attr); memcpy(&rv->ip_addr, ip, size); if(ip->sa_family == AF_INET6) { rv->flags |= CLIENT_FLAG_IPV6; } /* Make sure any packets sent early bail... */ rv->ckey.type = 0xFF; rv->skey.type = 0xFF; if(type == CLIENT_TYPE_SHIP) { rv->flags |= CLIENT_FLAG_TYPE_SHIP; rng = &ship->rng; } else { rng = &block->rng; } #ifdef HAVE_PYTHON rv->pyobj = client_pyobj_create(rv); if(!rv->pyobj) { goto err; } if(type == CLIENT_TYPE_SHIP) { script_execute(ScriptActionClientShipLogin, rv->pyobj, NULL); } else { script_execute(ScriptActionClientBlockLogin, rv->pyobj, NULL); } #endif switch(version) { case CLIENT_VERSION_DCV1: case CLIENT_VERSION_DCV2: case CLIENT_VERSION_PC: /* Generate the encryption keys for the client and server. */ client_seed_dc = mt19937_genrand_int32(rng); server_seed_dc = mt19937_genrand_int32(rng); CRYPT_CreateKeys(&rv->skey, &server_seed_dc, CRYPT_PC); CRYPT_CreateKeys(&rv->ckey, &client_seed_dc, CRYPT_PC); /* Send the client the welcome packet, or die trying. */ if(send_dc_welcome(rv, server_seed_dc, client_seed_dc)) { goto err; } break; case CLIENT_VERSION_GC: case CLIENT_VERSION_EP3: /* Generate the encryption keys for the client and server. */ client_seed_dc = mt19937_genrand_int32(rng); server_seed_dc = mt19937_genrand_int32(rng); CRYPT_CreateKeys(&rv->skey, &server_seed_dc, CRYPT_GAMECUBE); CRYPT_CreateKeys(&rv->ckey, &client_seed_dc, CRYPT_GAMECUBE); /* Send the client the welcome packet, or die trying. */ if(send_dc_welcome(rv, server_seed_dc, client_seed_dc)) { goto err; } break; case CLIENT_VERSION_BB: /* Generate the encryption keys for the client and server. */ for(i = 0; i < 48; i += 4) { client_seed_dc = mt19937_genrand_int32(rng); server_seed_dc = mt19937_genrand_int32(rng); client_seed_bb[i + 0] = (uint8_t)(client_seed_dc >> 0); client_seed_bb[i + 1] = (uint8_t)(client_seed_dc >> 8); client_seed_bb[i + 2] = (uint8_t)(client_seed_dc >> 16); client_seed_bb[i + 3] = (uint8_t)(client_seed_dc >> 24); server_seed_bb[i + 0] = (uint8_t)(server_seed_dc >> 0); server_seed_bb[i + 1] = (uint8_t)(server_seed_dc >> 8); server_seed_bb[i + 2] = (uint8_t)(server_seed_dc >> 16); server_seed_bb[i + 3] = (uint8_t)(server_seed_dc >> 24); } CRYPT_CreateKeys(&rv->skey, server_seed_bb, CRYPT_BLUEBURST); CRYPT_CreateKeys(&rv->ckey, client_seed_bb, CRYPT_BLUEBURST); rv->hdr_size = 8; /* Send the client the welcome packet, or die trying. */ if(send_bb_welcome(rv, server_seed_bb, client_seed_bb)) { goto err; } break; } /* Insert it at the end of our list, and we're done. */ if(type == CLIENT_TYPE_BLOCK) { pthread_rwlock_wrlock(&block->lock); TAILQ_INSERT_TAIL(clients, rv, qentry); ++block->num_clients; pthread_rwlock_unlock(&block->lock); } else { TAILQ_INSERT_TAIL(clients, rv, qentry); } ship_inc_clients(ship); return rv; err: close(sock); if(type == CLIENT_TYPE_BLOCK) { free(rv->enemy_kills); free(rv->pl); } #ifdef HAVE_PYTHON client_pyobj_invalidate(rv); Py_XDECREF(rv->pyobj); #endif pthread_mutex_destroy(&rv->mutex); free(rv); return NULL; }
/* * If blocks are contiguous on disk, use this to provide clustered * read ahead. We will read as many blocks as possible sequentially * and then parcel them up into logical blocks in the buffer hash table. */ static struct buf * cluster_rbuild(struct vnode *vp, u_quad_t filesize, daddr_t lbn, daddr_t blkno, long size, int run, int gbflags, struct buf *fbp) { struct bufobj *bo; struct buf *bp, *tbp; daddr_t bn; off_t off; long tinc, tsize; int i, inc, j, toff; KASSERT(size == vp->v_mount->mnt_stat.f_iosize, ("cluster_rbuild: size %ld != filesize %jd\n", size, (intmax_t)vp->v_mount->mnt_stat.f_iosize)); /* * avoid a division */ while ((u_quad_t) size * (lbn + run) > filesize) { --run; } if (fbp) { tbp = fbp; tbp->b_iocmd = BIO_READ; } else { tbp = getblk(vp, lbn, size, 0, 0, gbflags); if (tbp->b_flags & B_CACHE) return tbp; tbp->b_flags |= B_ASYNC | B_RAM; tbp->b_iocmd = BIO_READ; } tbp->b_blkno = blkno; if( (tbp->b_flags & B_MALLOC) || ((tbp->b_flags & B_VMIO) == 0) || (run <= 1) ) return tbp; bp = trypbuf(&cluster_pbuf_freecnt); if (bp == 0) return tbp; /* * We are synthesizing a buffer out of vm_page_t's, but * if the block size is not page aligned then the starting * address may not be either. Inherit the b_data offset * from the original buffer. */ bp->b_flags = B_ASYNC | B_CLUSTER | B_VMIO; if ((gbflags & GB_UNMAPPED) != 0) { bp->b_flags |= B_UNMAPPED; bp->b_data = unmapped_buf; } else { bp->b_data = (char *)((vm_offset_t)bp->b_data | ((vm_offset_t)tbp->b_data & PAGE_MASK)); } bp->b_iocmd = BIO_READ; bp->b_iodone = cluster_callback; bp->b_blkno = blkno; bp->b_lblkno = lbn; bp->b_offset = tbp->b_offset; KASSERT(bp->b_offset != NOOFFSET, ("cluster_rbuild: no buffer offset")); pbgetvp(vp, bp); TAILQ_INIT(&bp->b_cluster.cluster_head); bp->b_bcount = 0; bp->b_bufsize = 0; bp->b_npages = 0; inc = btodb(size); bo = &vp->v_bufobj; for (bn = blkno, i = 0; i < run; ++i, bn += inc) { if (i != 0) { if ((bp->b_npages * PAGE_SIZE) + round_page(size) > vp->v_mount->mnt_iosize_max) { break; } tbp = getblk(vp, lbn + i, size, 0, 0, GB_LOCK_NOWAIT | (gbflags & GB_UNMAPPED)); /* Don't wait around for locked bufs. */ if (tbp == NULL) break; /* * Stop scanning if the buffer is fully valid * (marked B_CACHE), or locked (may be doing a * background write), or if the buffer is not * VMIO backed. The clustering code can only deal * with VMIO-backed buffers. */ BO_LOCK(bo); if ((tbp->b_vflags & BV_BKGRDINPROG) || (tbp->b_flags & B_CACHE) || (tbp->b_flags & B_VMIO) == 0) { BO_UNLOCK(bo); bqrelse(tbp); break; } BO_UNLOCK(bo); /* * The buffer must be completely invalid in order to * take part in the cluster. If it is partially valid * then we stop. */ off = tbp->b_offset; tsize = size; VM_OBJECT_LOCK(tbp->b_bufobj->bo_object); for (j = 0; tsize > 0; j++) { toff = off & PAGE_MASK; tinc = tsize; if (toff + tinc > PAGE_SIZE) tinc = PAGE_SIZE - toff; VM_OBJECT_LOCK_ASSERT(tbp->b_pages[j]->object, MA_OWNED); if ((tbp->b_pages[j]->valid & vm_page_bits(toff, tinc)) != 0) break; off += tinc; tsize -= tinc; } VM_OBJECT_UNLOCK(tbp->b_bufobj->bo_object); if (tsize > 0) { bqrelse(tbp); break; } /* * Set a read-ahead mark as appropriate */ if ((fbp && (i == 1)) || (i == (run - 1))) tbp->b_flags |= B_RAM; /* * Set the buffer up for an async read (XXX should * we do this only if we do not wind up brelse()ing?). * Set the block number if it isn't set, otherwise * if it is make sure it matches the block number we * expect. */ tbp->b_flags |= B_ASYNC; tbp->b_iocmd = BIO_READ; if (tbp->b_blkno == tbp->b_lblkno) { tbp->b_blkno = bn; } else if (tbp->b_blkno != bn) { brelse(tbp); break; } } /* * XXX fbp from caller may not be B_ASYNC, but we are going * to biodone() it in cluster_callback() anyway */ BUF_KERNPROC(tbp); TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head, tbp, b_cluster.cluster_entry); VM_OBJECT_LOCK(tbp->b_bufobj->bo_object); for (j = 0; j < tbp->b_npages; j += 1) { vm_page_t m; m = tbp->b_pages[j]; vm_page_io_start(m); vm_object_pip_add(m->object, 1); if ((bp->b_npages == 0) || (bp->b_pages[bp->b_npages-1] != m)) { bp->b_pages[bp->b_npages] = m; bp->b_npages++; } if (m->valid == VM_PAGE_BITS_ALL) tbp->b_pages[j] = bogus_page; } VM_OBJECT_UNLOCK(tbp->b_bufobj->bo_object); /* * Don't inherit tbp->b_bufsize as it may be larger due to * a non-page-aligned size. Instead just aggregate using * 'size'. */ if (tbp->b_bcount != size) printf("warning: tbp->b_bcount wrong %ld vs %ld\n", tbp->b_bcount, size); if (tbp->b_bufsize != size) printf("warning: tbp->b_bufsize wrong %ld vs %ld\n", tbp->b_bufsize, size); bp->b_bcount += size; bp->b_bufsize += size; } /* * Fully valid pages in the cluster are already good and do not need * to be re-read from disk. Replace the page with bogus_page */ VM_OBJECT_LOCK(bp->b_bufobj->bo_object); for (j = 0; j < bp->b_npages; j++) { VM_OBJECT_LOCK_ASSERT(bp->b_pages[j]->object, MA_OWNED); if (bp->b_pages[j]->valid == VM_PAGE_BITS_ALL) bp->b_pages[j] = bogus_page; } VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); if (bp->b_bufsize > bp->b_kvasize) panic("cluster_rbuild: b_bufsize(%ld) > b_kvasize(%d)\n", bp->b_bufsize, bp->b_kvasize); bp->b_kvasize = bp->b_bufsize; if ((bp->b_flags & B_UNMAPPED) == 0) { pmap_qenter(trunc_page((vm_offset_t) bp->b_data), (vm_page_t *)bp->b_pages, bp->b_npages); } return (bp); }
int main(int argc, char **argv) { int ch, error=0; lpkg_head_t pkgs; setprogname(argv[0]); while ((ch = getopt(argc, argv, Options)) != -1) { switch (ch) { case 'A': Automatic = TRUE; break; case 'C': config_file = optarg; case 'P': Destdir = optarg; break; case 'f': Force = TRUE; ForceDepends = TRUE; break; case 'I': NoInstall = TRUE; break; case 'K': pkgdb_set_dir(optarg, 3); break; case 'L': NoView = TRUE; break; case 'R': NoRecord = TRUE; break; case 'm': OverrideMachine = optarg; break; case 'n': Fake = TRUE; Verbose = TRUE; break; case 'p': Prefix = optarg; break; case 'U': ReplaceSame = 1; Replace = 1; break; case 'u': Replace = 1; break; case 'V': show_version(); /* NOTREACHED */ case 'v': Verbose = TRUE; break; case 'W': Viewbase = optarg; break; case 'w': View = optarg; break; case 'h': case '?': default: usage(); break; } } argc -= optind; argv += optind; pkg_install_config(); if (Destdir != NULL) { char *pkgdbdir; pkgdbdir = xasprintf("%s/%s", Destdir, config_pkg_dbdir); pkgdb_set_dir(pkgdbdir, 4); free(pkgdbdir); } process_pkg_path(); TAILQ_INIT(&pkgs); if (argc == 0) { /* If no packages, yelp */ warnx("missing package name(s)"); usage(); } if (strcasecmp(do_license_check, "no") == 0) LicenseCheck = 0; else if (strcasecmp(do_license_check, "yes") == 0) LicenseCheck = 1; else if (strcasecmp(do_license_check, "always") == 0) LicenseCheck = 2; else errx(1, "Unknown value of the configuration variable" "CHECK_LICENSE"); if (LicenseCheck) load_license_lists(); /* Get all the remaining package names, if any */ for (; argc > 0; --argc, ++argv) { lpkg_t *lpp; if (IS_STDIN(*argv)) lpp = alloc_lpkg("-"); else lpp = alloc_lpkg(*argv); TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link); } error += pkg_perform(&pkgs); if (error != 0) { warnx("%d package addition%s failed", error, error == 1 ? "" : "s"); exit(1); } exit(0); }
ssize_t usdf_msg_sendmsg(struct fid_ep *fep, const struct fi_msg *msg, uint64_t flags) { size_t i; struct usdf_ep *ep; struct usdf_tx *tx; struct usdf_msg_qe *wqe; struct usdf_domain *udp; size_t tot_len; const struct iovec *iov; ep = ep_ftou(fep); tx = ep->ep_tx; udp = ep->ep_domain; iov = msg->msg_iov; if (flags & ~USDF_MSG_SUPP_SENDMSG_FLAGS) { USDF_DBG_SYS(EP_DATA, "one or more flags in %#" PRIx64 " not supported\n", flags); return -FI_EOPNOTSUPP; } /* check for inject overrun before acquiring lock and allocating wqe, * easier to unwind this way */ if (flags & FI_INJECT) { iov = msg->msg_iov; tot_len = 0; for (i = 0; i < msg->iov_count; ++i) { tot_len += iov[i].iov_len; if (tot_len > USDF_MSG_MAX_INJECT_SIZE) { USDF_DBG_SYS(EP_DATA, "max inject len exceeded (%zu)\n", tot_len); return -FI_EINVAL; } } } if (TAILQ_EMPTY(&tx->t.msg.tx_free_wqe)) { return -FI_EAGAIN; } pthread_spin_lock(&udp->dom_progress_lock); wqe = usdf_msg_get_tx_wqe(tx); wqe->ms_context = msg->context; if (flags & FI_INJECT) { tot_len = 0; for (i = 0; i < msg->iov_count; ++i) { assert(tot_len + iov[i].iov_len <= USDF_MSG_MAX_INJECT_SIZE); memcpy(&wqe->ms_inject_buf[tot_len], iov[i].iov_base, iov[i].iov_len); tot_len += iov[i].iov_len; } wqe->ms_iov[0].iov_base = wqe->ms_inject_buf; wqe->ms_iov[0].iov_len = tot_len; wqe->ms_last_iov = 0; } else { tot_len = 0; for (i = 0; i < msg->iov_count; ++i) { wqe->ms_iov[i].iov_base = (void *)iov[i].iov_base; wqe->ms_iov[i].iov_len = iov[i].iov_len; tot_len += iov[i].iov_len; } wqe->ms_last_iov = msg->iov_count - 1; } wqe->ms_cur_iov = 0; wqe->ms_resid = tot_len; wqe->ms_length = tot_len; wqe->ms_cur_ptr = iov[0].iov_base; wqe->ms_iov_resid = iov[0].iov_len; wqe->ms_signal_comp = ep->ep_tx_dflt_signal_comp || (flags & FI_COMPLETION) ? 1 : 0; /* add send to EP, and add EP to TX list if not present */ TAILQ_INSERT_TAIL(&ep->e.msg.ep_posted_wqe, wqe, ms_link); usdf_msg_ep_ready(ep); pthread_spin_unlock(&udp->dom_progress_lock); usdf_domain_progress(udp); return 0; }
/* Get CACHE from free list or evict */ NVMED_CACHE* nvmed_get_cache(NVMED_HANDLE* nvmed_handle) { NVMED* nvmed = HtoD(nvmed_handle); NVMED_CACHE *cache = nvmed->free_head.tqh_first; NVMED_CACHE *__cache; NVMED_CACHE *ret_cache; int i; unsigned int start_lpaddr, end_lpaddr; TAILQ_HEAD(cache_list, nvmed_cache) temp_head; pthread_rwlock_wrlock(&nvmed->cache_radix_lock); pthread_spin_lock(&nvmed->cache_list_lock); if(cache==NULL) { //HEAD -> LRU, //TAIL -> MRU //EVICT - LRU cache = nvmed->lru_head.tqh_first; if(!FLAG_ISSET(cache, CACHE_DIRTY)) { TAILQ_REMOVE(&nvmed->lru_head, cache, cache_list); LIST_REMOVE(cache, handle_cache_list); radix_tree_delete(&nvmed->cache_root, cache->lpaddr); FLAG_SET_FORCE(cache, 0); ret_cache = cache; } else { TAILQ_INIT(&temp_head); while(FLAG_ISSET_SYNC(cache, CACHE_LOCKED) || cache->ref != 0) { usleep(1); } start_lpaddr = cache->lpaddr; end_lpaddr = cache->lpaddr; __cache = cache->cache_list.tqe_next; TAILQ_REMOVE(&nvmed->lru_head, cache, cache_list); radix_tree_delete(&nvmed->cache_root, cache->lpaddr); TAILQ_INSERT_HEAD(&temp_head, cache, cache_list); for(i=1; i<NVMED_CACHE_FORCE_EVICT_MAX; i++) { cache = __cache; if(FLAG_ISSET_SYNC(cache, CACHE_LOCKED)) break; if(!FLAG_ISSET(cache, CACHE_DIRTY)) break; if(start_lpaddr != 0 && cache->lpaddr == start_lpaddr-1 ) { //front_merge start_lpaddr--; __cache = cache->cache_list.tqe_next; TAILQ_REMOVE(&nvmed->lru_head, cache, cache_list); radix_tree_delete(&nvmed->cache_root, cache->lpaddr); TAILQ_INSERT_HEAD(&temp_head, cache, cache_list); continue; } else if(cache->lpaddr == end_lpaddr+1) { //back_merge end_lpaddr++; __cache = cache->cache_list.tqe_next; TAILQ_REMOVE(&nvmed->lru_head, cache, cache_list); radix_tree_delete(&nvmed->cache_root, cache->lpaddr); TAILQ_INSERT_TAIL(&temp_head, cache, cache_list); continue; } else { break; } } if(FLAG_ISSET(cache, CACHE_DIRTY)) nvmed_cache_io_rw(nvmed_handle, nvme_cmd_write, temp_head.tqh_first, start_lpaddr * PAGE_SIZE, (end_lpaddr - start_lpaddr) * PAGE_SIZE, HANDLE_SYNC_IO); cache = temp_head.tqh_first; FLAG_SET_FORCE(cache, 0); ret_cache = cache; TAILQ_REMOVE(&temp_head, cache, cache_list); LIST_REMOVE(cache, handle_cache_list); while(temp_head.tqh_first != NULL) { TAILQ_REMOVE(&temp_head, temp_head.tqh_first, cache_list); TAILQ_INSERT_HEAD(&nvmed->free_head, temp_head.tqh_first, cache_list); nvmed->num_cache_usage--; } } } else { // Remove From Free Queue TAILQ_REMOVE(&nvmed->free_head, cache, cache_list); FLAG_UNSET_SYNC(cache, CACHE_FREE); if(FLAG_ISSET(cache, CACHE_UNINIT)) { memset(cache->ptr, 0, PAGE_SIZE); virt_to_phys(nvmed, cache->ptr, &cache->paddr, 4096); FLAG_UNSET_SYNC(cache, CACHE_UNINIT); } ret_cache = cache; } INIT_SYNC(ret_cache->ref); pthread_spin_unlock(&nvmed->cache_list_lock); pthread_rwlock_unlock(&nvmed->cache_radix_lock); return ret_cache; }
struct trigger_list * cvs_trigger_getlines(char * file, char * repo) { FILE *fp; int allow_all, lineno, match = 0; size_t len; regex_t preg; struct trigger_list *list; struct trigger_line *tline; char fpath[PATH_MAX]; char *currentline, *defaultline = NULL, *nline, *p, *q, *regex; if (strcmp(file, CVS_PATH_EDITINFO) == 0 || strcmp(file, CVS_PATH_VERIFYMSG) == 0) allow_all = 0; else allow_all = 1; (void)xsnprintf(fpath, PATH_MAX, "%s/%s", current_cvsroot->cr_dir, file); if ((fp = fopen(fpath, "r")) == NULL) { if (errno != ENOENT) cvs_log(LP_ERRNO, "cvs_trigger_getlines: %s", file); return (NULL); } list = xmalloc(sizeof(*list)); TAILQ_INIT(list); lineno = 0; nline = NULL; while ((currentline = fgetln(fp, &len)) != NULL) { if (currentline[len - 1] == '\n') { currentline[len - 1] = '\0'; } else { nline = xmalloc(len + 1); memcpy(nline, currentline, len); nline[len] = '\0'; currentline = nline; } lineno++; for (p = currentline; isspace((unsigned char)*p); p++) ; if (*p == '\0' || *p == '#') continue; for (q = p; !isspace((unsigned char)*q) && *q != '\0'; q++) ; if (*q == '\0') goto bad; *q++ = '\0'; regex = p; for (; isspace((unsigned char)*q); q++) ; if (*q == '\0') goto bad; if (strcmp(regex, "ALL") == 0 && allow_all) { tline = xmalloc(sizeof(*tline)); tline->line = xstrdup(q); TAILQ_INSERT_TAIL(list, tline, flist); } else if (defaultline == NULL && !match && strcmp(regex, "DEFAULT") == 0) { defaultline = xstrdup(q); } else if (!match) { if (regcomp(&preg, regex, REG_NOSUB|REG_EXTENDED)) goto bad; if (regexec(&preg, repo, 0, NULL, 0) != REG_NOMATCH) { match = 1; tline = xmalloc(sizeof(*tline)); tline->line = xstrdup(q); TAILQ_INSERT_HEAD(list, tline, flist); } regfree(&preg); } } free(nline); if (defaultline != NULL) { if (!match) { tline = xmalloc(sizeof(*tline)); tline->line = defaultline; TAILQ_INSERT_HEAD(list, tline, flist); } else free(defaultline); } (void)fclose(fp); if (TAILQ_EMPTY(list)) { free(list); list = NULL; } return (list); bad: cvs_log(LP_NOTICE, "%s: malformed line %d", file, lineno); free(defaultline); cvs_trigger_freelist(list); (void)fclose(fp); return (NULL); }
void tvhlogv ( const char *file, int line, int notify, int severity, const char *subsys, const char *fmt, va_list *args ) { int ok, options; size_t l; char buf[1024]; pthread_mutex_lock(&tvhlog_mutex); /* Check for full */ if (tvhlog_queue_full || !tvhlog_run) { pthread_mutex_unlock(&tvhlog_mutex); return; } /* Check debug enabled (and cache config) */ options = tvhlog_options; if (severity >= LOG_DEBUG) { ok = 0; if (severity <= tvhlog_level) { if (tvhlog_trace) { ok = htsmsg_get_u32_or_default(tvhlog_trace, "all", 0); ok = htsmsg_get_u32_or_default(tvhlog_trace, subsys, ok); } if (!ok && severity == LOG_DEBUG && tvhlog_debug) { ok = htsmsg_get_u32_or_default(tvhlog_debug, "all", 0); ok = htsmsg_get_u32_or_default(tvhlog_debug, subsys, ok); } } } else { ok = 1; } /* Ignore */ if (!ok) { pthread_mutex_unlock(&tvhlog_mutex); return; } /* FULL */ if (tvhlog_queue_size == TVHLOG_QUEUE_MAXSIZE) { tvhlog_queue_full = 1; fmt = "log buffer full"; args = NULL; severity = LOG_ERR; } /* Basic message */ l = 0; if (options & TVHLOG_OPT_THREAD) { l += snprintf(buf + l, sizeof(buf) - l, "tid %ld: ", (long)pthread_self()); } l += snprintf(buf + l, sizeof(buf) - l, "%s: ", subsys); if (options & TVHLOG_OPT_FILELINE && severity >= LOG_DEBUG) l += snprintf(buf + l, sizeof(buf) - l, "(%s:%d) ", file, line); if (args) l += vsnprintf(buf + l, sizeof(buf) - l, fmt, *args); else l += snprintf(buf + l, sizeof(buf) - l, "%s", fmt); /* Store */ tvhlog_msg_t *msg = calloc(1, sizeof(tvhlog_msg_t)); gettimeofday(&msg->time, NULL); msg->msg = strdup(buf); msg->severity = severity; msg->notify = notify; #if TVHLOG_THREAD if (tvhlog_run) { TAILQ_INSERT_TAIL(&tvhlog_queue, msg, link); tvhlog_queue_size++; pthread_cond_signal(&tvhlog_cond); } else { #endif FILE *fp = NULL; tvhlog_process(msg, tvhlog_options, &fp, tvhlog_path); if (fp) fclose(fp); #if TVHLOG_THREAD } #endif pthread_mutex_unlock(&tvhlog_mutex); }
static int hyfi_aggr_queue_pkt(struct net_hatbl_entry *ha, struct sk_buff **skb, u_int16_t seq) { u_int32_t i, idx = HYFI_AGGR_MAX_IFACES; /* Find the queue for that interface */ for (i = 0; i < ha->aggr_rx_entry->num_ifs; i++) { if (ha->aggr_rx_entry->hyfi_iface_info[i].ifindex == (*skb)->dev->ifindex) { /* Found */ idx = i; break; } } /* If no queue exists, assign an empty queue to that interface */ if (idx == HYFI_AGGR_MAX_IFACES) { for (i = 0; i < ha->aggr_rx_entry->num_ifs; i++) { if (!ha->aggr_rx_entry->hyfi_iface_info[i].ifindex) { /* Assign to the interface */ ha->aggr_rx_entry->hyfi_iface_info[i].ifindex = (*skb)->dev->ifindex; ha->aggr_rx_entry->hyfi_iface_info[i].pkt_cnt = 0; ha->aggr_rx_entry->hyfi_iface_info[i].seq_valid = 0; idx = i; break; } } } if (unlikely(idx >= HYFI_AGGR_MAX_IFACES)) { /* Defensive check, in case there is no available queue (unlikely) * we should just finish here. */ return -1; } else { struct hyfi_skb_aggr_q *skb_aggr_q; struct hyfi_aggr_skb_buffer *hyfi_aggr_skb_buffer = (struct hyfi_aggr_skb_buffer *) (*skb)->head; #ifdef HYFI_AGGR_NOISY_DEBUG /* Be careful, noisy and damages high rate flows */ DPRINTK( "%s: Queue future packet, ha = %p, iface = %s, seq = %d, next_seq = %d\n", __func__, ha, (*skb)->dev->name, (seq & 0x3FFF), ha->aggr_rx_entry->aggr_next_seq ); #endif /* Push the skb in the queue */ skb_aggr_q = &ha->aggr_rx_entry->hyfi_iface_info[idx].skb_aggr_q; hyfi_aggr_skb_buffer->pkt_seq = (seq & 0x3FFF); hyfi_aggr_skb_buffer->skb = *skb; TAILQ_INSERT_TAIL( skb_aggr_q, hyfi_aggr_skb_buffer, skb_aggr_qelem); ha->aggr_rx_entry->hyfi_iface_info[idx].pkt_cnt++; if (ha->aggr_rx_entry->hyfi_iface_info[idx].pkt_cnt == 1) { ha->aggr_rx_entry->hyfi_iface_info[idx].seq = (seq & 0x3FFF); ha->aggr_rx_entry->hyfi_iface_info[idx].seq_valid = 1; } *skb = NULL; } /* Sanity check: if we reached the maximum packets quota per queue, then * something is really off. flush everything and restart (may be blunt, could * be revisited in the future). */ if (unlikely( ha->aggr_rx_entry->hyfi_iface_info[idx].pkt_cnt > HYFI_AGGR_MAX_QUEUE_LEN)) { u_int16_t next_seq; DPRINTK( "%s: Queue %d is full, flush and recover\n", __func__, idx); hyfi_aggr_reset_queues(ha, seq); ha->aggr_rx_entry->time_stamp = jiffies; /* Handle the gap, dequeue the next available packets */ next_seq = hyfi_aggr_find_next_seq(ha); if (likely(next_seq != (u_int16_t) ~0)) { /* Update our next sequence variable to the closest * sequence number we have in the queues. */ ha->aggr_rx_entry->aggr_next_seq = next_seq; DPRINTK( "%s: Next sequence to dequeue: %d\n", __func__, next_seq); } else { ha->aggr_rx_entry->next_seq_valid = 0; DPRINTK( "%s: Next sequence is unavailable, forward current packet\n", __func__); return -1; } } return 0; }
static int pft_refresh(void) { struct pfioc_table io; struct pfr_tstats *t = NULL; struct pft_entry *e; int i, numtbls = 1; if (started && this_tick <= pf_tick) return (0); while (!TAILQ_EMPTY(&pft_table)) { e = TAILQ_FIRST(&pft_table); TAILQ_REMOVE(&pft_table, e, link); free(e); } bzero(&io, sizeof(io)); io.pfrio_esize = sizeof(struct pfr_tstats); for (;;) { t = reallocf(t, numtbls * sizeof(struct pfr_tstats)); if (t == NULL) { syslog(LOG_ERR, "pft_refresh(): reallocf() numtbls=%d: %s", numtbls, strerror(errno)); goto err2; } io.pfrio_size = numtbls; io.pfrio_buffer = t; if (ioctl(dev, DIOCRGETTSTATS, &io)) { syslog(LOG_ERR, "pft_refresh(): ioctl(): %s", strerror(errno)); goto err2; } if (numtbls >= io.pfrio_size) break; numtbls = io.pfrio_size; } for (i = 0; i < numtbls; i++) { e = malloc(sizeof(struct pft_entry)); if (e == NULL) goto err1; e->index = i + 1; memcpy(&e->pft, t+i, sizeof(struct pfr_tstats)); TAILQ_INSERT_TAIL(&pft_table, e, link); } pft_table_age = time(NULL); pft_table_count = numtbls; pf_tick = this_tick; free(t); return (0); err1: while (!TAILQ_EMPTY(&pft_table)) { e = TAILQ_FIRST(&pft_table); TAILQ_REMOVE(&pft_table, e, link); free(e); } err2: free(t); return(-1); }
static int pfa_table_addrs(u_int sidx, struct pfr_table *pt) { struct pfioc_table io; struct pfr_astats *t = NULL; struct pfa_entry *e; int i, numaddrs = 1; if (pt == NULL) return (-1); memset(&io, 0, sizeof(io)); strlcpy(io.pfrio_table.pfrt_name, pt->pfrt_name, sizeof(io.pfrio_table.pfrt_name)); for (;;) { t = reallocf(t, numaddrs * sizeof(struct pfr_astats)); if (t == NULL) { syslog(LOG_ERR, "pfa_table_addrs(): reallocf(): %s", strerror(errno)); numaddrs = -1; goto error; } memset(t, 0, sizeof(*t)); io.pfrio_size = numaddrs; io.pfrio_buffer = t; io.pfrio_esize = sizeof(struct pfr_astats); if (ioctl(dev, DIOCRGETASTATS, &io)) { syslog(LOG_ERR, "pfa_table_addrs(): ioctl() on %s: %s", pt->pfrt_name, strerror(errno)); numaddrs = -1; break; } if (numaddrs >= io.pfrio_size) break; numaddrs = io.pfrio_size; } for (i = 0; i < numaddrs; i++) { if ((t + i)->pfras_a.pfra_af != AF_INET && (t + i)->pfras_a.pfra_af != AF_INET6) { numaddrs = i; break; } e = (struct pfa_entry *)malloc(sizeof(struct pfa_entry)); if (e == NULL) { syslog(LOG_ERR, "pfa_table_addrs(): malloc(): %s", strerror(errno)); numaddrs = -1; break; } e->index = sidx + i; memcpy(&e->pfas, t + i, sizeof(struct pfr_astats)); TAILQ_INSERT_TAIL(&pfa_table, e, link); } free(t); error: return (numaddrs); }
static int pfi_refresh(void) { struct pfioc_iface io; struct pfi_kif *p = NULL; struct pfi_entry *e; int i, numifs = 1; if (started && this_tick <= pf_tick) return (0); while (!TAILQ_EMPTY(&pfi_table)) { e = TAILQ_FIRST(&pfi_table); TAILQ_REMOVE(&pfi_table, e, link); free(e); } bzero(&io, sizeof(io)); io.pfiio_esize = sizeof(struct pfi_kif); for (;;) { p = reallocf(p, numifs * sizeof(struct pfi_kif)); if (p == NULL) { syslog(LOG_ERR, "pfi_refresh(): reallocf() numifs=%d: %s", numifs, strerror(errno)); goto err2; } io.pfiio_size = numifs; io.pfiio_buffer = p; if (ioctl(dev, DIOCIGETIFACES, &io)) { syslog(LOG_ERR, "pfi_refresh(): ioctl(): %s", strerror(errno)); goto err2; } if (numifs >= io.pfiio_size) break; numifs = io.pfiio_size; } for (i = 0; i < numifs; i++) { e = malloc(sizeof(struct pfi_entry)); if (e == NULL) goto err1; e->index = i + 1; memcpy(&e->pfi, p+i, sizeof(struct pfi_kif)); TAILQ_INSERT_TAIL(&pfi_table, e, link); } pfi_table_age = time(NULL); pfi_table_count = numifs; pf_tick = this_tick; free(p); return (0); err1: while (!TAILQ_EMPTY(&pfi_table)) { e = TAILQ_FIRST(&pfi_table); TAILQ_REMOVE(&pfi_table, e, link); free(e); } err2: free(p); return(-1); }
static void parse_schedule(const char *string, int timeout) { char buffer[20]; const char *slash; int count = 0; SCHEDULEITEM *repeatat = NULL; size_t len; SCHEDULEITEM *item; if (string) for (slash = string; *slash; slash++) if (*slash == '/') count++; free_schedulelist(); if (count == 0) { item = xmalloc(sizeof(*item)); item->type = SC_SIGNAL; item->value = timeout; item->gotoitem = NULL; TAILQ_INSERT_TAIL(&schedule, item, entries); item = xmalloc(sizeof(*item)); item->type = SC_TIMEOUT; item->gotoitem = NULL; TAILQ_INSERT_TAIL(&schedule, item, entries); if (string) { if (sscanf(string, "%d", &item->value) != 1) eerrorx("%s: invalid timeout in schedule", applet); } else item->value = 5; return; } while (string != NULL) { if ((slash = strchr(string, '/'))) len = slash - string; else len = strlen(string); if (len >= (ptrdiff_t)sizeof(buffer)) eerrorx("%s: invalid schedule item, far too long", applet); memcpy(buffer, string, len); buffer[len] = 0; string = slash ? slash + 1 : NULL; item = parse_schedule_item(buffer); TAILQ_INSERT_TAIL(&schedule, item, entries); if (item->type == SC_FOREVER) { if (repeatat) eerrorx("%s: invalid schedule, `forever' " "appears more than once", applet); repeatat = item; continue; } } if (repeatat) { item = xmalloc(sizeof(*item)); item->type = SC_GOTO; item->value = 0; item->gotoitem = repeatat; TAILQ_INSERT_TAIL(&schedule, item, entries); } return; }
/* * __wt_open -- * Open a file handle. */ int __wt_open(WT_SESSION_IMPL *session, const char *name, int ok_create, int exclusive, int dio_type, WT_FH **fhp) { DWORD dwCreationDisposition; HANDLE filehandle, filehandle_secondary; WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_FH *fh, *tfh; int direct_io, f, matched, share_mode; char *path; conn = S2C(session); fh = NULL; path = NULL; filehandle = INVALID_HANDLE_VALUE; filehandle_secondary = INVALID_HANDLE_VALUE; direct_io = 0; WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: open", name)); /* Increment the reference count if we already have the file open. */ matched = 0; __wt_spin_lock(session, &conn->fh_lock); TAILQ_FOREACH(tfh, &conn->fhqh, q) if (strcmp(name, tfh->name) == 0) { ++tfh->ref; *fhp = tfh; matched = 1; break; } __wt_spin_unlock(session, &conn->fh_lock); if (matched) return (0); /* For directories, create empty file handles with invalid handles */ if (dio_type == WT_FILE_TYPE_DIRECTORY) { goto setupfh; } WT_RET(__wt_filename(session, name, &path)); share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE; /* * Security: * The application may spawn a new process, and we don't want another * process to have access to our file handles. * * TODO: Set tighter file permissions but set bInheritHandle to false * to prevent inheritance */ f = FILE_ATTRIBUTE_NORMAL; dwCreationDisposition = 0; if (ok_create) { dwCreationDisposition = CREATE_NEW; if (exclusive) dwCreationDisposition = CREATE_ALWAYS; } else dwCreationDisposition = OPEN_EXISTING; if (dio_type && FLD_ISSET(conn->direct_io, dio_type)) { f |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; direct_io = 1; } if (dio_type == WT_FILE_TYPE_LOG && FLD_ISSET(conn->txn_logsync, WT_LOG_DSYNC)) { f |= FILE_FLAG_WRITE_THROUGH; } /* Disable read-ahead on trees: it slows down random read workloads. */ if (dio_type == WT_FILE_TYPE_DATA || dio_type == WT_FILE_TYPE_CHECKPOINT) f |= FILE_FLAG_RANDOM_ACCESS; filehandle = CreateFileA(path, (GENERIC_READ | GENERIC_WRITE), share_mode, NULL, dwCreationDisposition, f, NULL); if (filehandle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_EXISTS && ok_create) filehandle = CreateFileA(path, (GENERIC_READ | GENERIC_WRITE), share_mode, NULL, OPEN_EXISTING, f, NULL); if (filehandle == INVALID_HANDLE_VALUE) WT_ERR_MSG(session, __wt_errno(), direct_io ? "%s: open failed with direct I/O configured, some " "filesystem types do not support direct I/O" : "%s", path); } /* * Open a second handle to file to support allocation/truncation * concurrently with reads on the file. Writes would also move the file * pointer. */ filehandle_secondary = CreateFileA(path, (GENERIC_READ | GENERIC_WRITE), share_mode, NULL, OPEN_EXISTING, f, NULL); if (filehandle == INVALID_HANDLE_VALUE) WT_ERR_MSG(session, __wt_errno(), "open failed for secondary handle: %s", path); setupfh: WT_ERR(__wt_calloc(session, 1, sizeof(WT_FH), &fh)); WT_ERR(__wt_strdup(session, name, &fh->name)); fh->filehandle = filehandle; fh->filehandle_secondary = filehandle_secondary; fh->ref = 1; fh->direct_io = direct_io; /* Set the file's size. */ if (dio_type != WT_FILE_TYPE_DIRECTORY) WT_ERR(__wt_filesize(session, fh, &fh->size)); /* Configure file extension. */ if (dio_type == WT_FILE_TYPE_DATA || dio_type == WT_FILE_TYPE_CHECKPOINT) fh->extend_len = conn->data_extend_len; /* Configure fallocate/posix_fallocate calls. */ __wt_fallocate_config(session, fh); /* * Repeat the check for a match, but then link onto the database's list * of files. */ matched = 0; __wt_spin_lock(session, &conn->fh_lock); TAILQ_FOREACH(tfh, &conn->fhqh, q) if (strcmp(name, tfh->name) == 0) { ++tfh->ref; *fhp = tfh; matched = 1; break; } if (!matched) { TAILQ_INSERT_TAIL(&conn->fhqh, fh, q); WT_STAT_FAST_CONN_INCR(session, file_open); *fhp = fh; } __wt_spin_unlock(session, &conn->fh_lock); if (matched) { err: if (fh != NULL) { __wt_free(session, fh->name); __wt_free(session, fh); } if (filehandle != INVALID_HANDLE_VALUE) (void)CloseHandle(filehandle); if (filehandle_secondary != INVALID_HANDLE_VALUE) (void)CloseHandle(filehandle_secondary); } __wt_free(session, path); return (ret); }
/* * Mount null layer */ static int nullfs_mount(struct mount *mp) { int error = 0; struct vnode *lowerrootvp, *vp; struct vnode *nullm_rootvp; struct null_mount *xmp; struct thread *td = curthread; char *target; int isvnunlocked = 0, len; struct nameidata nd, *ndp = &nd; NULLFSDEBUG("nullfs_mount(mp = %p)\n", (void *)mp); if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_NULLFS)) return (EPERM); if (mp->mnt_flag & MNT_ROOTFS) return (EOPNOTSUPP); /* * Update is a no-op */ if (mp->mnt_flag & MNT_UPDATE) { /* * Only support update mounts for NFS export. */ if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) return (0); else return (EOPNOTSUPP); } /* * Get argument */ error = vfs_getopt(mp->mnt_optnew, "target", (void **)&target, &len); if (error || target[len - 1] != '\0') return (EINVAL); /* * Unlock lower node to avoid possible deadlock. */ if ((mp->mnt_vnodecovered->v_op == &null_vnodeops) && VOP_ISLOCKED(mp->mnt_vnodecovered) == LK_EXCLUSIVE) { VOP_UNLOCK(mp->mnt_vnodecovered, 0); isvnunlocked = 1; } /* * Find lower node */ NDINIT(ndp, LOOKUP, FOLLOW|LOCKLEAF, UIO_SYSSPACE, target, curthread); error = namei(ndp); /* * Re-lock vnode. * XXXKIB This is deadlock-prone as well. */ if (isvnunlocked) vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY); if (error) return (error); NDFREE(ndp, NDF_ONLY_PNBUF); /* * Sanity check on lower vnode */ lowerrootvp = ndp->ni_vp; /* * Check multi null mount to avoid `lock against myself' panic. */ if (lowerrootvp == VTONULL(mp->mnt_vnodecovered)->null_lowervp) { NULLFSDEBUG("nullfs_mount: multi null mount?\n"); vput(lowerrootvp); return (EDEADLK); } xmp = (struct null_mount *) malloc(sizeof(struct null_mount), M_NULLFSMNT, M_WAITOK | M_ZERO); /* * Save reference to underlying FS */ xmp->nullm_vfs = lowerrootvp->v_mount; /* * Save reference. Each mount also holds * a reference on the root vnode. */ error = null_nodeget(mp, lowerrootvp, &vp); /* * Make sure the node alias worked */ if (error) { free(xmp, M_NULLFSMNT); return (error); } /* * Keep a held reference to the root vnode. * It is vrele'd in nullfs_unmount. */ nullm_rootvp = vp; nullm_rootvp->v_vflag |= VV_ROOT; xmp->nullm_rootvp = nullm_rootvp; /* * Unlock the node (either the lower or the alias) */ VOP_UNLOCK(vp, 0); if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) { MNT_ILOCK(mp); mp->mnt_flag |= MNT_LOCAL; MNT_IUNLOCK(mp); } xmp->nullm_flags |= NULLM_CACHE; if (vfs_getopt(mp->mnt_optnew, "nocache", NULL, NULL) == 0) xmp->nullm_flags &= ~NULLM_CACHE; MNT_ILOCK(mp); if ((xmp->nullm_flags & NULLM_CACHE) != 0) { mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag & (MNTK_SHARED_WRITES | MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED); } mp->mnt_kern_flag |= MNTK_LOOKUP_EXCL_DOTDOT; mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag & (MNTK_SUSPENDABLE | MNTK_USES_BCACHE); MNT_IUNLOCK(mp); mp->mnt_data = xmp; vfs_getnewfsid(mp); if ((xmp->nullm_flags & NULLM_CACHE) != 0) { MNT_ILOCK(xmp->nullm_vfs); TAILQ_INSERT_TAIL(&xmp->nullm_vfs->mnt_uppers, mp, mnt_upper_link); MNT_IUNLOCK(xmp->nullm_vfs); } vfs_mountedfrom(mp, target); NULLFSDEBUG("nullfs_mount: lower %s, alias at %s\n", mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname); return (0); }
short trans_cb(int fd, pid_t pid, int policynr, const char *name, int code, const char *emulation, void *args, int argsize, struct intercept_replace *repl, struct intercept_tlq *tls, void *cbarg) { short action, future; struct policy *policy; struct intercept_pid *ipid; struct intercept_tlq alitls; struct intercept_translate alitl[SYSTRACE_MAXALIAS]; struct systrace_alias *alias = NULL; struct filterq *pflq = NULL; const char *binname = NULL; char output[_POSIX2_LINE_MAX]; pid_t ppid; int done = 0, dolog = 0; action = ICPOLICY_PERMIT; if (policynr == -1) goto out; if ((policy = systrace_findpolnr(policynr)) == NULL) errx(1, "%s:%d: find %d", __func__, __LINE__, policynr); ipid = intercept_getpid(pid); ipid->uflags = 0; binname = ipid->name != NULL ? ipid->name : policy->name; ppid = ipid->ppid; /* Required to set up replacements */ do { make_output(output, sizeof(output), binname, pid, ppid, policynr, policy->name, policy->nfilters, emulation, name, code, tls, repl); /* Fast-path checking */ if ((action = policy->kerneltable[code]) != ICPOLICY_ASK) goto out; pflq = systrace_policyflq(policy, emulation, name); if (pflq == NULL) errx(1, "%s:%d: no filter queue", __func__, __LINE__); action = filter_evaluate(tls, pflq, ipid); if (action != ICPOLICY_ASK) goto done; /* Do aliasing here */ if (!noalias) alias = systrace_find_alias(emulation, name); if (alias != NULL) { int i; /* Set up variables for further filter actions */ tls = &alitls; emulation = alias->aemul; name = alias->aname; /* Create an aliased list for filter_evaluate */ TAILQ_INIT(tls); for (i = 0; i < alias->nargs; i++) { memcpy(&alitl[i], alias->arguments[i], sizeof(struct intercept_translate)); TAILQ_INSERT_TAIL(tls, &alitl[i], next); } if ((pflq = systrace_policyflq(policy, alias->aemul, alias->aname)) == NULL) errx(1, "%s:%d: no filter queue", __func__, __LINE__); action = filter_evaluate(tls, pflq, ipid); if (action != ICPOLICY_ASK) goto done; make_output(output, sizeof(output), binname, pid, ppid, policynr, policy->name, policy->nfilters, alias->aemul, alias->aname, code, tls, NULL); } /* * At this point, we have to ask the user, but we may check * if the policy has been updated in the meanwhile. */ if (systrace_updatepolicy(fd, policy) == -1) done = 1; } while (!done); if (policy->flags & POLICY_UNSUPERVISED) { action = ICPOLICY_NEVER; dolog = 1; goto out; } action = filter_ask(fd, tls, pflq, policynr, emulation, name, output, &future, ipid); if (future != ICPOLICY_ASK) filter_modifypolicy(fd, policynr, emulation, name, future); if (policy->flags & POLICY_DETACHED) { if (intercept_detach(fd, pid) == -1) err(1, "intercept_detach"); return (action); } else if (action == ICPOLICY_KILL) { kill(pid, SIGKILL); return (ICPOLICY_NEVER); } done: if (ipid->uflags & SYSCALL_LOG) dolog = 1; out: if (dolog) log_msg(LOG_WARNING, "%s user: %s, prog: %s", action < ICPOLICY_NEVER ? "permit" : "deny", ipid->username, output); /* Argument replacement in intercept might still fail */ return (action); }
int __rpc_getbroadifs(int af, int proto, int socktype, broadlist_t *list) { int count = 0; struct broadif *bip; struct ifaddrs *ifap, *ifp; #ifdef INET6 struct sockaddr_in6 *sin6; #endif struct sockaddr_in *sin; struct addrinfo hints, *res; if (getifaddrs(&ifp) < 0) return 0; memset(&hints, 0, sizeof hints); hints.ai_family = af; hints.ai_protocol = proto; hints.ai_socktype = socktype; if (getaddrinfo(NULL, "sunrpc", &hints, &res) != 0) { freeifaddrs(ifp); return 0; } for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) { if (ifap->ifa_addr->sa_family != af || !(ifap->ifa_flags & IFF_UP)) continue; bip = (struct broadif *)malloc(sizeof *bip); if (bip == NULL) break; bip->index = if_nametoindex(ifap->ifa_name); if ( #ifdef INET6 af != AF_INET6 && #endif (ifap->ifa_flags & IFF_BROADCAST) && ifap->ifa_broadaddr) { memcpy(&bip->broadaddr, ifap->ifa_broadaddr, (size_t)ifap->ifa_broadaddr->sa_len); sin = (struct sockaddr_in *)(void *)&bip->broadaddr; sin->sin_port = ((struct sockaddr_in *) (void *)res->ai_addr)->sin_port; } else #ifdef INET6 if (af == AF_INET6 && (ifap->ifa_flags & IFF_MULTICAST)) { sin6 = (struct sockaddr_in6 *)(void *)&bip->broadaddr; inet_pton(af, RPCB_MULTICAST_ADDR, &sin6->sin6_addr); sin6->sin6_family = af; sin6->sin6_len = sizeof *sin6; sin6->sin6_port = ((struct sockaddr_in6 *) (void *)res->ai_addr)->sin6_port; sin6->sin6_scope_id = bip->index; } else #endif { free(bip); continue; } TAILQ_INSERT_TAIL(list, bip, link); count++; } freeifaddrs(ifp); freeaddrinfo(res); return count; }
/* * Craft a temporary node suitable for sending a management frame * to the specified station. We craft only as much state as we * need to do the work since the node will be immediately reclaimed * once the send completes, and the temporary node will NOT be put * into node table. */ struct ieee80211_node * ieee80211_tmp_node(struct ieee80211vap *vap, const u_int8_t *macaddr) { struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node *ni; int i; /* * if vap is being deleted, do not allow new allocations. */ if (ieee80211_vap_deleted_is_set(vap)) { return NULL; } ni = ic->ic_node_alloc(&ic->ic_sta, vap, TRUE /* temp node */); if (ni == NULL) { vap->iv_stats.is_rx_nodealloc++; return NULL; } #ifdef IEEE80211_DEBUG_NODELEAK do { rwlock_state_t lock_state; OS_RWLOCK_WRITE_LOCK(&ic->ic_nodelock,&lock_state); TAILQ_INSERT_TAIL(&ic->ic_nodes, ni, ni_alloc_list); OS_RWLOCK_WRITE_UNLOCK(&ic->ic_nodelock,&lock_state); } while(0); #endif ni->ni_flags |= IEEE80211_NODE_TEMP; /* useful for debugging */ ieee80211_ref_node(ni); /* mark referenced */ IEEE80211_VAP_LOCK(vap); vap->iv_node_count++; IEEE80211_VAP_UNLOCK(vap); ni->ni_bss_node = ieee80211_ref_bss_node(vap); ni->ni_vap = vap; ni->ni_ic = ic; ni->ni_table = NULL; /* copy some default variables from parent */ IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr); ni->ni_intval = ic->ic_intval; /* default beacon interval */ /* set default rate and channel */ ieee80211_node_set_chan(ni); ni->ni_txpower = ic->ic_txpowlimit; /* max power */ /* init our unicast / receive key state */ ieee80211_crypto_resetkey(vap, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE); ieee80211_crypto_resetkey(vap, &ni->ni_persta.nips_hwkey, IEEE80211_KEYIX_NONE); for (i = 0; i < IEEE80211_WEP_NKID; i++) { ieee80211_crypto_resetkey(vap, &ni->ni_persta.nips_swkey[i], IEEE80211_KEYIX_NONE); } ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY; /* IBSS-only: mark as unassociated by default. */ ni->ni_assoc_state = IEEE80211_NODE_ADHOC_STATE_UNAUTH_UNASSOC; /* 11n */ ni->ni_chwidth = ic->ic_cwm_get_width(ic); IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_bss->ni_bssid); return ni; }
void audit_commit(struct kaudit_record *ar, int error, int retval) { au_event_t event; au_class_t class; au_id_t auid; int sorf; struct au_mask *aumask; if (ar == NULL) return; /* * Decide whether to commit the audit record by checking the error * value from the system call and using the appropriate audit mask. */ if (ar->k_ar.ar_subj_auid == AU_DEFAUDITID) aumask = &audit_nae_mask; else aumask = &ar->k_ar.ar_subj_amask; if (error) sorf = AU_PRS_FAILURE; else sorf = AU_PRS_SUCCESS; /* * syscalls.master sometimes contains a prototype event number, which * we will transform into a more specific event number now that we * have more complete information gathered during the system call. */ switch(ar->k_ar.ar_event) { case AUE_OPEN_RWTC: ar->k_ar.ar_event = audit_flags_and_error_to_openevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_OPENAT_RWTC: ar->k_ar.ar_event = audit_flags_and_error_to_openatevent( ar->k_ar.ar_arg_fflags, error); break; case AUE_SYSCTL: ar->k_ar.ar_event = audit_ctlname_to_sysctlevent( ar->k_ar.ar_arg_ctlname, ar->k_ar.ar_valid_arg); break; case AUE_AUDITON: /* Convert the auditon() command to an event. */ ar->k_ar.ar_event = auditon_command_event(ar->k_ar.ar_arg_cmd); break; } auid = ar->k_ar.ar_subj_auid; event = ar->k_ar.ar_event; class = au_event_class(event); ar->k_ar_commit |= AR_COMMIT_KERNEL; if (au_preselect(event, class, aumask, sorf) != 0) ar->k_ar_commit |= AR_PRESELECT_TRAIL; if (audit_pipe_preselect(auid, event, class, sorf, ar->k_ar_commit & AR_PRESELECT_TRAIL) != 0) ar->k_ar_commit |= AR_PRESELECT_PIPE; if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE | AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE)) == 0) { mtx_lock(&audit_mtx); audit_pre_q_len--; mtx_unlock(&audit_mtx); audit_free(ar); return; } ar->k_ar.ar_errno = error; ar->k_ar.ar_retval = retval; nanotime(&ar->k_ar.ar_endtime); /* * Note: it could be that some records initiated while audit was * enabled should still be committed? */ mtx_lock(&audit_mtx); if (audit_suspended || !audit_enabled) { audit_pre_q_len--; mtx_unlock(&audit_mtx); audit_free(ar); return; } /* * Constrain the number of committed audit records based on the * configurable parameter. */ while (audit_q_len >= audit_qctrl.aq_hiwater) cv_wait(&audit_watermark_cv, &audit_mtx); TAILQ_INSERT_TAIL(&audit_q, ar, k_q); audit_q_len++; audit_pre_q_len--; cv_signal(&audit_worker_cv); mtx_unlock(&audit_mtx); }
int nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct) { int r,_status; int i; char *orig = 0; char *str; char *component_id; char *connection_address; unsigned int port; in_addr_t addr; char *ice_option_tag; for(i=0;i<attr_ct;i++){ orig = str = attrs[i]; component_id = 0; connection_address = 0; ice_option_tag = 0; if (!strncasecmp(str, "remote-candidates:", 18)) { fast_forward(&str, 18); skip_whitespace(&str); while (*str != '\0') { if ((r=grab_token(&str, &component_id))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &connection_address))) ABORT(r); if (*str == '\0') ABORT(R_BAD_DATA); addr = inet_addr(connection_address); if (addr == INADDR_NONE) ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if (sscanf(str, "%u", &port) != 1) ABORT(R_BAD_DATA); if (port < 1 || port > 0x0FFFF) ABORT(R_BAD_DATA); skip_to_past_space(&str); #if 0 /* TODO: !nn! just drop on the floor for now, later put somewhere */ /* Assume v4 for now */ if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&candidate->base)) ABORT(r); TAILQ_INSERT_TAIL(head, elm, field); #endif component_id = 0; /* prevent free */ RFREE(connection_address); connection_address = 0; /* prevent free */ } } else if (!strncasecmp(str, "ice-lite", 8)) { pctx->peer_lite = 1; fast_forward(&str, 8); } else if (!strncasecmp(str, "ice-mismatch", 12)) { pctx->peer_ice_mismatch = 1; fast_forward(&str, 12); } else if (!strncasecmp(str, "ice-ufrag:", 10)) { fast_forward(&str, 10); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &pctx->peer_ufrag))) ABORT(r); } else if (!strncasecmp(str, "ice-pwd:", 8)) { fast_forward(&str, 8); if (*str == '\0') ABORT(R_BAD_DATA); skip_whitespace(&str); if (*str == '\0') ABORT(R_BAD_DATA); if ((r=grab_token(&str, &pctx->peer_pwd))) ABORT(r); } else if (!strncasecmp(str, "ice-options:", 12)) { fast_forward(&str, 12); skip_whitespace(&str); while (*str != '\0') { if ((r=grab_token(&str, &ice_option_tag))) ABORT(r); skip_whitespace(&str); #if 0 //TODO: !nn! for now, just drop on the floor, later put somewhere #endif ice_option_tag = 0; /* prevent free */ } } else { ABORT(R_BAD_DATA); } skip_whitespace(&str); /* it's expected to be at EOD at this point */ assert(strlen(str) == 0); } _status=0; abort: if (_status) { if (orig) r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig); } RFREE(connection_address); RFREE(component_id); RFREE(ice_option_tag); return(_status); }
static int parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, int opt, const char *arg, struct dhcp_opt **ldop, struct dhcp_opt **edop) { int i, l, t; unsigned int u; char *p = NULL, *fp, *np, **nconf; ssize_t s; struct in_addr addr, addr2; in_addr_t *naddr; struct rt *rt; const struct dhcp_opt *d; uint8_t *request, *require, *no; struct dhcp_opt **dop, *ndop; size_t *dop_len, dl; struct vivco *vivco; struct token *token; #ifdef INET6 size_t sl; struct if_ia *ia; uint8_t iaid[4]; struct if_sla *sla, *slap; #endif dop = NULL; dop_len = NULL; #ifdef INET6 i = 0; #endif switch(opt) { case 'f': /* FALLTHROUGH */ case 'g': /* FALLTHROUGH */ case 'n': /* FALLTHROUGH */ case 'x': /* FALLTHROUGH */ case 'T': /* FALLTHROUGH */ case 'U': /* FALLTHROUGH */ case 'V': /* We need to handle non interface options */ break; case 'b': ifo->options |= DHCPCD_BACKGROUND; break; case 'c': free(ifo->script); ifo->script = strdup(arg); if (ifo->script == NULL) syslog(LOG_ERR, "%s: %m", __func__); break; case 'd': ifo->options |= DHCPCD_DEBUG; break; case 'e': add_environ(ifo, arg, 1); break; case 'h': if (!arg) { ifo->options |= DHCPCD_HOSTNAME; break; } s = parse_string(ifo->hostname, HOSTNAME_MAX_LEN, arg); if (s == -1) { syslog(LOG_ERR, "hostname: %m"); return -1; } if (s != 0 && ifo->hostname[0] == '.') { syslog(LOG_ERR, "hostname cannot begin with ."); return -1; } ifo->hostname[s] = '\0'; if (ifo->hostname[0] == '\0') ifo->options &= ~DHCPCD_HOSTNAME; else ifo->options |= DHCPCD_HOSTNAME; break; case 'i': if (arg) s = parse_string((char *)ifo->vendorclassid + 1, VENDORCLASSID_MAX_LEN, arg); else s = 0; if (s == -1) { syslog(LOG_ERR, "vendorclassid: %m"); return -1; } *ifo->vendorclassid = (uint8_t)s; break; case 'k': ifo->options |= DHCPCD_RELEASE; break; case 'l': if (*arg == '-') { syslog(LOG_ERR, "leasetime must be a positive value"); return -1; } errno = 0; ifo->leasetime = (uint32_t)strtoul(arg, NULL, 0); if (errno == EINVAL || errno == ERANGE) { syslog(LOG_ERR, "`%s' out of range", arg); return -1; } break; case 'm': ifo->metric = atoint(arg); if (ifo->metric < 0) { syslog(LOG_ERR, "metric must be a positive value"); return -1; } break; case 'o': arg = set_option_space(ctx, arg, &d, &dl, ifo, &request, &require, &no); if (make_option_mask(d, dl, request, arg, 1) != 0) { syslog(LOG_ERR, "unknown option `%s'", arg); return -1; } break; case 'p': ifo->options |= DHCPCD_PERSISTENT; break; case 'q': ifo->options |= DHCPCD_QUIET; break; case 'r': if (parse_addr(&ifo->req_addr, NULL, arg) != 0) return -1; ifo->options |= DHCPCD_REQUEST; ifo->req_mask.s_addr = 0; break; case 's': if (ifo->options & DHCPCD_IPV6 && !(ifo->options & DHCPCD_IPV4)) { ifo->options |= DHCPCD_INFORM; break; } if (arg && *arg != '\0') { if (parse_addr(&ifo->req_addr, &ifo->req_mask, arg) != 0) return -1; } else { ifo->req_addr.s_addr = 0; ifo->req_mask.s_addr = 0; } ifo->options |= DHCPCD_INFORM | DHCPCD_PERSISTENT; ifo->options &= ~(DHCPCD_ARP | DHCPCD_STATIC); break; case 't': ifo->timeout = atoint(arg); if (ifo->timeout < 0) { syslog(LOG_ERR, "timeout must be a positive value"); return -1; } break; case 'u': s = USERCLASS_MAX_LEN - ifo->userclass[0] - 1; s = parse_string((char *)ifo->userclass + ifo->userclass[0] + 2, s, arg); if (s == -1) { syslog(LOG_ERR, "userclass: %m"); return -1; } if (s != 0) { ifo->userclass[ifo->userclass[0] + 1] = s; ifo->userclass[0] += s + 1; } break; case 'v': p = strchr(arg, ','); if (!p || !p[1]) { syslog(LOG_ERR, "invalid vendor format: %s", arg); return -1; } /* If vendor starts with , then it is not encapsulated */ if (p == arg) { arg++; s = parse_string((char *)ifo->vendor + 1, VENDOR_MAX_LEN, arg); if (s == -1) { syslog(LOG_ERR, "vendor: %m"); return -1; } ifo->vendor[0] = (uint8_t)s; ifo->options |= DHCPCD_VENDORRAW; break; } /* Encapsulated vendor options */ if (ifo->options & DHCPCD_VENDORRAW) { ifo->options &= ~DHCPCD_VENDORRAW; ifo->vendor[0] = 0; } /* No need to strip the comma */ i = atoint(arg); if (i < 1 || i > 254) { syslog(LOG_ERR, "vendor option should be between" " 1 and 254 inclusive"); return -1; } arg = p + 1; s = VENDOR_MAX_LEN - ifo->vendor[0] - 2; if (inet_aton(arg, &addr) == 1) { if (s < 6) { s = -1; errno = ENOBUFS; } else { memcpy(ifo->vendor + ifo->vendor[0] + 3, &addr.s_addr, sizeof(addr.s_addr)); s = sizeof(addr.s_addr); } } else { s = parse_string((char *)ifo->vendor + ifo->vendor[0] + 3, s, arg); } if (s == -1) { syslog(LOG_ERR, "vendor: %m"); return -1; } if (s != 0) { ifo->vendor[ifo->vendor[0] + 1] = i; ifo->vendor[ifo->vendor[0] + 2] = s; ifo->vendor[0] += s + 2; } break; case 'w': ifo->options |= DHCPCD_WAITIP; if (arg != NULL && arg[0] != '\0') { if (arg[0] == '4' || arg[1] == '4') ifo->options |= DHCPCD_WAITIP4; if (arg[0] == '6' || arg[1] == '6') ifo->options |= DHCPCD_WAITIP6; } break; case 'y': ifo->reboot = atoint(arg); if (ifo->reboot < 0) { syslog(LOG_ERR, "reboot must be a positive value"); return -1; } break; case 'z': if (ifname == NULL) ctx->ifav = splitv(&ctx->ifac, ctx->ifav, arg); break; case 'A': ifo->options &= ~DHCPCD_ARP; /* IPv4LL requires ARP */ ifo->options &= ~DHCPCD_IPV4LL; break; case 'B': ifo->options &= ~DHCPCD_DAEMONISE; break; case 'C': /* Commas to spaces for shell */ while ((p = strchr(arg, ','))) *p = ' '; s = strlen("skip_hooks=") + strlen(arg) + 1; p = malloc(sizeof(char) * s); if (p == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } snprintf(p, s, "skip_hooks=%s", arg); add_environ(ifo, p, 0); free(p); break; case 'D': ifo->options |= DHCPCD_CLIENTID | DHCPCD_DUID; break; case 'E': ifo->options |= DHCPCD_LASTLEASE; break; case 'F': if (!arg) { ifo->fqdn = FQDN_BOTH; break; } if (strcmp(arg, "none") == 0) ifo->fqdn = FQDN_NONE; else if (strcmp(arg, "ptr") == 0) ifo->fqdn = FQDN_PTR; else if (strcmp(arg, "both") == 0) ifo->fqdn = FQDN_BOTH; else if (strcmp(arg, "disable") == 0) ifo->fqdn = FQDN_DISABLE; else { syslog(LOG_ERR, "invalid value `%s' for FQDN", arg); return -1; } break; case 'G': ifo->options &= ~DHCPCD_GATEWAY; break; case 'H': ifo->options |= DHCPCD_XID_HWADDR; break; case 'I': /* Strings have a type of 0 */; ifo->clientid[1] = 0; if (arg) s = parse_string_hwaddr((char *)ifo->clientid + 1, CLIENTID_MAX_LEN, arg, 1); else s = 0; if (s == -1) { syslog(LOG_ERR, "clientid: %m"); return -1; } ifo->options |= DHCPCD_CLIENTID; ifo->clientid[0] = (uint8_t)s; break; case 'J': ifo->options |= DHCPCD_BROADCAST; break; case 'K': ifo->options &= ~DHCPCD_LINK; break; case 'L': ifo->options &= ~DHCPCD_IPV4LL; break; case 'M': ifo->options |= DHCPCD_MASTER; break; case 'O': arg = set_option_space(ctx, arg, &d, &dl, ifo, &request, &require, &no); if (make_option_mask(d, dl, request, arg, -1) != 0 || make_option_mask(d, dl, require, arg, -1) != 0 || make_option_mask(d, dl, no, arg, 1) != 0) { syslog(LOG_ERR, "unknown option `%s'", arg); return -1; } break; case 'Q': arg = set_option_space(ctx, arg, &d, &dl, ifo, &request, &require, &no); if (make_option_mask(d, dl, require, arg, 1) != 0 || make_option_mask(d, dl, request, arg, 1) != 0) { syslog(LOG_ERR, "unknown option `%s'", arg); return -1; } break; case 'S': p = strchr(arg, '='); if (p == NULL) { syslog(LOG_ERR, "static assignment required"); return -1; } p++; if (strncmp(arg, "ip_address=", strlen("ip_address=")) == 0) { if (parse_addr(&ifo->req_addr, ifo->req_mask.s_addr == 0 ? &ifo->req_mask : NULL, p) != 0) return -1; ifo->options |= DHCPCD_STATIC; ifo->options &= ~DHCPCD_INFORM; } else if (strncmp(arg, "subnet_mask=", strlen("subnet_mask=")) == 0) { if (parse_addr(&ifo->req_mask, NULL, p) != 0) return -1; } else if (strncmp(arg, "routes=", strlen("routes=")) == 0 || strncmp(arg, "static_routes=", strlen("static_routes=")) == 0 || strncmp(arg, "classless_static_routes=", strlen("classless_static_routes=")) == 0 || strncmp(arg, "ms_classless_static_routes=", strlen("ms_classless_static_routes=")) == 0) { fp = np = strwhite(p); if (np == NULL) { syslog(LOG_ERR, "all routes need a gateway"); return -1; } *np++ = '\0'; np = strskipwhite(np); if (ifo->routes == NULL) { ifo->routes = malloc(sizeof(*ifo->routes)); if (ifo->routes == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } TAILQ_INIT(ifo->routes); } rt = malloc(sizeof(*rt)); if (rt == NULL) { syslog(LOG_ERR, "%s: %m", __func__); *fp = ' '; return -1; } if (parse_addr(&rt->dest, &rt->net, p) == -1 || parse_addr(&rt->gate, NULL, np) == -1) { free(rt); *fp = ' '; return -1; } TAILQ_INSERT_TAIL(ifo->routes, rt, next); *fp = ' '; } else if (strncmp(arg, "routers=", strlen("routers=")) == 0) { if (ifo->routes == NULL) { ifo->routes = malloc(sizeof(*ifo->routes)); if (ifo->routes == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } TAILQ_INIT(ifo->routes); } rt = malloc(sizeof(*rt)); if (rt == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } rt->dest.s_addr = INADDR_ANY; rt->net.s_addr = INADDR_ANY; if (parse_addr(&rt->gate, NULL, p) == -1) { free(rt); return -1; } TAILQ_INSERT_TAIL(ifo->routes, rt, next); } else { s = 0; if (ifo->config != NULL) { while (ifo->config[s] != NULL) { if (strncmp(ifo->config[s], arg, p - arg) == 0) { p = strdup(arg); if (p == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } free(ifo->config[s]); ifo->config[s] = p; return 1; } s++; } } p = strdup(arg); if (p == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } nconf = realloc(ifo->config, sizeof(char *) * (s + 2)); if (nconf == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->config = nconf; ifo->config[s] = p; ifo->config[s + 1] = NULL; } break; case 'W': if (parse_addr(&addr, &addr2, arg) != 0) return -1; if (strchr(arg, '/') == NULL) addr2.s_addr = INADDR_BROADCAST; naddr = realloc(ifo->whitelist, sizeof(in_addr_t) * (ifo->whitelist_len + 2)); if (naddr == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->whitelist = naddr; ifo->whitelist[ifo->whitelist_len++] = addr.s_addr; ifo->whitelist[ifo->whitelist_len++] = addr2.s_addr; break; case 'X': if (parse_addr(&addr, &addr2, arg) != 0) return -1; if (strchr(arg, '/') == NULL) addr2.s_addr = INADDR_BROADCAST; naddr = realloc(ifo->blacklist, sizeof(in_addr_t) * (ifo->blacklist_len + 2)); if (naddr == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->blacklist = naddr; ifo->blacklist[ifo->blacklist_len++] = addr.s_addr; ifo->blacklist[ifo->blacklist_len++] = addr2.s_addr; break; case 'Z': if (ifname == NULL) ctx->ifdv = splitv(&ctx->ifdc, ctx->ifdv, arg); break; case '4': ifo->options &= ~DHCPCD_IPV6; ifo->options |= DHCPCD_IPV4; break; case '6': ifo->options &= ~DHCPCD_IPV4; ifo->options |= DHCPCD_IPV6; break; case O_NOIPV4: ifo->options &= ~DHCPCD_IPV4; break; case O_NOIPV6: ifo->options &= ~DHCPCD_IPV6; break; #ifdef INET case O_ARPING: while (arg && *arg != '\0') { fp = strwhite(arg); if (fp) *fp++ = '\0'; if (parse_addr(&addr, NULL, arg) != 0) return -1; naddr = realloc(ifo->arping, sizeof(in_addr_t) * (ifo->arping_len + 1)); if (naddr == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->arping = naddr; ifo->arping[ifo->arping_len++] = addr.s_addr; arg = strskipwhite(fp); } break; case O_DESTINATION: if (make_option_mask(ctx->dhcp_opts, ctx->dhcp_opts_len, ifo->dstmask, arg, 2) != 0) { if (errno == EINVAL) syslog(LOG_ERR, "option `%s' does not take" " an IPv4 address", arg); else syslog(LOG_ERR, "unknown option `%s'", arg); return -1; } break; case O_FALLBACK: free(ifo->fallback); ifo->fallback = strdup(arg); if (ifo->fallback == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } break; #endif case O_IAID: if (ifname == NULL) { syslog(LOG_ERR, "IAID must belong in an interface block"); return -1; } if (parse_iaid(ifo->iaid, arg, sizeof(ifo->iaid)) == -1) return -1; ifo->options |= DHCPCD_IAID; break; case O_IPV6RS: ifo->options |= DHCPCD_IPV6RS; break; case O_NOIPV6RS: ifo->options &= ~DHCPCD_IPV6RS; break; case O_IPV6RA_FORK: ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS; break; case O_IPV6RA_OWN: ifo->options |= DHCPCD_IPV6RA_OWN; break; case O_IPV6RA_OWN_D: ifo->options |= DHCPCD_IPV6RA_OWN_DEFAULT; break; case O_NOALIAS: ifo->options |= DHCPCD_NOALIAS; break; #ifdef INET6 case O_IA_NA: i = D6_OPTION_IA_NA; /* FALLTHROUGH */ case O_IA_TA: if (i == 0) i = D6_OPTION_IA_TA; /* FALLTHROUGH */ case O_IA_PD: if (i == 0) { if (ifname == NULL) { syslog(LOG_ERR, "IA PD must belong in an interface block"); return -1; } i = D6_OPTION_IA_PD; } if (arg != NULL && ifname == NULL) { syslog(LOG_ERR, "IA with IAID must belong in an interface block"); return -1; } ifo->options |= DHCPCD_IA_FORCED; if (ifo->ia_type != 0 && ifo->ia_type != i) { syslog(LOG_ERR, "cannot specify a different IA type"); return -1; } ifo->ia_type = i; if (arg == NULL) break; fp = strwhite(arg); if (fp) *fp++ = '\0'; if (parse_iaid(iaid, arg, sizeof(iaid)) == -1) return -1; ia = NULL; for (sl = 0; sl < ifo->ia_len; sl++) { if (ifo->ia[sl].iaid[0] == iaid[0] && ifo->ia[sl].iaid[1] == iaid[1] && ifo->ia[sl].iaid[2] == iaid[2] && ifo->ia[sl].iaid[3] == iaid[3]) { ia = &ifo->ia[sl]; break; } } if (ia == NULL) { ia = realloc(ifo->ia, sizeof(*ifo->ia) * (ifo->ia_len + 1)); if (ia == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->ia = ia; ia = &ifo->ia[ifo->ia_len++]; ia->iaid[0] = iaid[0]; ia->iaid[1] = iaid[1]; ia->iaid[2] = iaid[2]; ia->iaid[3] = iaid[3]; ia->sla = NULL; ia->sla_len = 0; } if (ifo->ia_type != D6_OPTION_IA_PD) break; for (p = fp; p; p = fp) { fp = strwhite(p); if (fp) { *fp++ = '\0'; fp = strskipwhite(fp); } sla = realloc(ia->sla, sizeof(*ia->sla) * (ia->sla_len + 1)); if (sla == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ia->sla = sla; sla = &ia->sla[ia->sla_len++]; np = strchr(p, '/'); if (np) *np++ = '\0'; if (strcmp(ifname, p) == 0) { syslog(LOG_ERR, "%s: cannot assign IA_PD to itself", ifname); return -1; } if (strlcpy(sla->ifname, p, sizeof(sla->ifname)) >= sizeof(sla->ifname)) { syslog(LOG_ERR, "%s: interface name too long", arg); return -1; } p = np; if (p) { np = strchr(p, '/'); if (np) *np++ = '\0'; if (*p == '\0') sla->sla_set = 0; else { errno = 0; sla->sla = atoint(p); sla->sla_set = 1; if (errno) return -1; } if (np) { sla->prefix_len = atoint(np); if (sla->prefix_len < 0 || sla->prefix_len > 128) return -1; } else sla->prefix_len = 64; } else { sla->sla_set = 0; /* Sanity - check there are no more * unspecified SLA's */ for (sl = 0; sl < ia->sla_len - 1; sl++) { slap = &ia->sla[sl]; if (slap->sla_set == 0 && strcmp(slap->ifname, sla->ifname) == 0) { syslog(LOG_WARNING, "%s: cannot specify the " "same interface twice with " "an automatic SLA", sla->ifname); ia->sla_len--; break; } } } } #endif break; case O_HOSTNAME_SHORT: ifo->options |= DHCPCD_HOSTNAME | DHCPCD_HOSTNAME_SHORT; break; case O_DEV: #ifdef PLUGIN_DEV if (ctx->dev_load) free(ctx->dev_load); ctx->dev_load = strdup(arg); #endif break; case O_NODEV: ifo->options &= ~DHCPCD_DEV; break; case O_DEFINE: dop = &ifo->dhcp_override; dop_len = &ifo->dhcp_override_len; /* FALLTHROUGH */ case O_DEFINE6: if (dop == NULL) { dop = &ifo->dhcp6_override; dop_len = &ifo->dhcp6_override_len; } /* FALLTHROUGH */ case O_VENDOPT: if (dop == NULL) { dop = &ifo->vivso_override; dop_len = &ifo->vivso_override_len; } *edop = *ldop = NULL; /* FALLTHROUGH */ case O_EMBED: if (dop == NULL) { if (*edop) { dop = &(*edop)->embopts; dop_len = &(*edop)->embopts_len; } else if (ldop) { dop = &(*ldop)->embopts; dop_len = &(*ldop)->embopts_len; } else { syslog(LOG_ERR, "embed must be after a define or encap"); return -1; } } /* FALLTHROUGH */ case O_ENCAP: if (dop == NULL) { if (*ldop == NULL) { syslog(LOG_ERR, "encap must be after a define"); return -1; } dop = &(*ldop)->encopts; dop_len = &(*ldop)->encopts_len; } /* Shared code for define, define6, embed and encap */ /* code */ if (opt == O_EMBED) /* Embedded options don't have codes */ u = 0; else { fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "invalid syntax: %s", arg); return -1; } *fp++ = '\0'; errno = 0; u = strtoul(arg, &np, 0); if (u > UINT32_MAX || errno != 0 || *np != '\0') { syslog(LOG_ERR, "invalid code: %s", arg); return -1; } arg = strskipwhite(fp); if (arg == NULL) { syslog(LOG_ERR, "invalid syntax"); return -1; } } /* type */ fp = strwhite(arg); if (fp) *fp++ = '\0'; np = strchr(arg, ':'); /* length */ if (np) { *np++ = '\0'; if ((l = atoint(np)) == -1) return -1; } else l = 0; t = 0; if (strcasecmp(arg, "request") == 0) { t |= REQUEST; arg = strskipwhite(fp); fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "incomplete request type"); return -1; } *fp++ = '\0'; } else if (strcasecmp(arg, "norequest") == 0) { t |= NOREQ; arg = strskipwhite(fp); fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "incomplete request type"); return -1; } *fp++ = '\0'; } if (strcasecmp(arg, "index") == 0) { t |= INDEX; arg = strskipwhite(fp); fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "incomplete index type"); return -1; } *fp++ = '\0'; } if (strcasecmp(arg, "array") == 0) { t |= ARRAY; arg = strskipwhite(fp); fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "incomplete array type"); return -1; } *fp++ = '\0'; } if (strcasecmp(arg, "ipaddress") == 0) t |= ADDRIPV4; else if (strcasecmp(arg, "ip6address") == 0) t |= ADDRIPV6; else if (strcasecmp(arg, "string") == 0) t |= STRING; else if (strcasecmp(arg, "byte") == 0) t |= UINT8; else if (strcasecmp(arg, "uint16") == 0) t |= UINT16; else if (strcasecmp(arg, "int16") == 0) t |= SINT16; else if (strcasecmp(arg, "uint32") == 0) t |= UINT32; else if (strcasecmp(arg, "int32") == 0) t |= SINT32; else if (strcasecmp(arg, "flag") == 0) t |= FLAG; else if (strcasecmp(arg, "domain") == 0) t |= STRING | RFC3397; else if (strcasecmp(arg, "binhex") == 0) t |= BINHEX; else if (strcasecmp(arg, "embed") == 0) t |= EMBED; else if (strcasecmp(arg, "encap") == 0) t |= ENCAP; else if (strcasecmp(arg, "rfc3361") ==0) t |= STRING | RFC3361; else if (strcasecmp(arg, "rfc3442") ==0) t |= STRING | RFC3442; else if (strcasecmp(arg, "rfc5969") == 0) t |= STRING | RFC5969; else if (strcasecmp(arg, "option") == 0) t |= OPTION; else { syslog(LOG_ERR, "unknown type: %s", arg); return -1; } if (l && !(t & (STRING | BINHEX))) { syslog(LOG_WARNING, "ignoring length for type `%s'", arg); l = 0; } if (t & ARRAY && t & (STRING | BINHEX)) { syslog(LOG_WARNING, "ignoring array for strings"); t &= ~ARRAY; } /* variable */ if (!fp) { if (!(t & OPTION)) { syslog(LOG_ERR, "type %s requires a variable name", arg); return -1; } np = NULL; } else { arg = strskipwhite(fp); fp = strwhite(arg); if (fp) *fp++ = '\0'; np = strdup(arg); if (np == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } } if (opt != O_EMBED) { for (dl = 0, ndop = *dop; dl < *dop_len; dl++, ndop++) { /* type 0 seems freshly malloced struct * for us to use */ if (ndop->option == u || ndop->type == 0) break; } if (dl == *dop_len) ndop = NULL; } else ndop = NULL; if (ndop == NULL) { if ((ndop = realloc(*dop, sizeof(**dop) * ((*dop_len) + 1))) == NULL) { syslog(LOG_ERR, "%s: %m", __func__); free(np); return -1; } *dop = ndop; ndop = &(*dop)[(*dop_len)++]; ndop->embopts = NULL; ndop->embopts_len = 0; ndop->encopts = NULL; ndop->encopts_len = 0; } else free_dhcp_opt_embenc(ndop); ndop->option = u; /* could have been 0 */ ndop->type = t; ndop->len = l; ndop->var = np; /* Save the define for embed and encap options */ if (opt == O_DEFINE || opt == O_DEFINE6 || opt == O_VENDOPT) *ldop = ndop; else if (opt == O_ENCAP) *edop = ndop; break; case O_VENDCLASS: fp = strwhite(arg); if (fp) *fp++ = '\0'; errno = 0; u = strtoul(arg, &np, 0); if (u > UINT32_MAX || errno != 0 || *np != '\0') { syslog(LOG_ERR, "invalid code: %s", arg); return -1; } if (fp) { s = parse_string(NULL, 0, fp); if (s == -1) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } if (s + (sizeof(uint16_t) * 2) > UINT16_MAX) { syslog(LOG_ERR, "vendor class is too big"); return -1; } np = malloc(s); if (np == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } parse_string(np, s, fp); } else { s = 0; np = NULL; } vivco = realloc(ifo->vivco, sizeof(*ifo->vivco) * (ifo->vivco_len + 1)); if (vivco == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->vivco = vivco; ifo->vivco_en = u; vivco = &ifo->vivco[ifo->vivco_len++]; vivco->len = s; vivco->data = (uint8_t *)np; break; case O_AUTHPROTOCOL: fp = strwhite(arg); if (fp) *fp++ = '\0'; if (strcasecmp(arg, "token") == 0) ifo->auth.protocol = AUTH_PROTO_TOKEN; else if (strcasecmp(arg, "delayed") == 0) ifo->auth.protocol = AUTH_PROTO_DELAYED; else if (strcasecmp(arg, "delayedrealm") == 0) ifo->auth.protocol = AUTH_PROTO_DELAYEDREALM; else { syslog(LOG_ERR, "%s: unsupported protocol", arg); return -1; } arg = strskipwhite(fp); fp = strwhite(arg); if (arg == NULL) { ifo->auth.options |= DHCPCD_AUTH_SEND; ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; ifo->auth.rdm = AUTH_RDM_MONOTONIC; break; } if (fp) *fp++ = '\0'; if (strcasecmp(arg, "hmacmd5") == 0 || strcasecmp(arg, "hmac-md5") == 0) ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; else { syslog(LOG_ERR, "%s: unsupported algorithm", arg); return 1; } arg = fp; if (arg == NULL) { ifo->auth.options |= DHCPCD_AUTH_SEND; ifo->auth.rdm = AUTH_RDM_MONOTONIC; break; } if (strcasecmp(arg, "monocounter") == 0) { ifo->auth.rdm = AUTH_RDM_MONOTONIC; ifo->auth.options |= DHCPCD_AUTH_RDM_COUNTER; } else if (strcasecmp(arg, "monotonic") ==0 || strcasecmp(arg, "monotime") == 0) ifo->auth.rdm = AUTH_RDM_MONOTONIC; else { syslog(LOG_ERR, "%s: unsupported RDM", arg); return -1; } ifo->auth.options |= DHCPCD_AUTH_SEND; break; case O_AUTHTOKEN: fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "authtoken requires a realm"); return -1; } *fp++ = '\0'; token = malloc(sizeof(*token)); if (token == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } if (parse_uint32(&token->secretid, arg) == -1) { syslog(LOG_ERR, "%s: not a number", arg); free(token); return -1; } arg = fp; fp = strend(arg); if (fp == NULL) { syslog(LOG_ERR, "authtoken requies an a key"); free(token); return -1; } *fp++ = '\0'; token->realm_len = parse_string(NULL, 0, arg); if (token->realm_len) { token->realm = malloc(token->realm_len); if (token->realm == NULL) { free(token); syslog(LOG_ERR, "%s: %m", __func__); return -1; } parse_string((char *)token->realm, token->realm_len, arg); } arg = fp; fp = strend(arg); if (fp == NULL) { syslog(LOG_ERR, "authtoken requies an an expiry date"); free(token->realm); free(token); return -1; } *fp++ = '\0'; if (*arg == '"') { arg++; np = strchr(arg, '"'); if (np) *np = '\0'; } if (strcmp(arg, "0") == 0 || strcasecmp(arg, "forever") == 0) token->expire =0; else { struct tm tm; memset(&tm, 0, sizeof(tm)); if (strptime(arg, "%Y-%m-%d %H:%M", &tm) == NULL) { syslog(LOG_ERR, "%s: invalid date time", arg); free(token->realm); free(token); return -1; } if ((token->expire = mktime(&tm)) == (time_t)-1) { syslog(LOG_ERR, "%s: mktime: %m", __func__); free(token->realm); free(token); return -1; } } arg = fp; token->key_len = parse_string(NULL, 0, arg); if (token->key_len == 0) { syslog(LOG_ERR, "authtoken needs a key"); free(token->realm); free(token); return -1; } token->key = malloc(token->key_len); parse_string((char *)token->key, token->key_len, arg); TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next); break; case O_AUTHNOTREQUIRED: ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; break; case O_NODHCP: ifo->options &= ~DHCPCD_DHCP; break; case O_NODHCP6: ifo->options &= ~DHCPCD_DHCP6; break; default: return 0; } return 1; }
struct tte * tsb_tte_enter(pmap_t pm, vm_page_t m, vm_offset_t va, u_long sz, u_long data) { struct tte *bucket; struct tte *rtp; struct tte *tp; vm_offset_t ova; int b0; int i; if (DCACHE_COLOR(VM_PAGE_TO_PHYS(m)) != DCACHE_COLOR(va)) { CTR5(KTR_SPARE2, "tsb_tte_enter: off colour va=%#lx pa=%#lx o=%p ot=%d pi=%#lx", va, VM_PAGE_TO_PHYS(m), m->object, m->object ? m->object->type : -1, m->pindex); if (pm == kernel_pmap) PMAP_STATS_INC(tsb_nenter_k_oc); else PMAP_STATS_INC(tsb_nenter_u_oc); } rw_assert(&tte_list_global_lock, RA_WLOCKED); PMAP_LOCK_ASSERT(pm, MA_OWNED); if (pm == kernel_pmap) { PMAP_STATS_INC(tsb_nenter_k); tp = tsb_kvtotte(va); KASSERT((tp->tte_data & TD_V) == 0, ("tsb_tte_enter: replacing valid kernel mapping")); goto enter; } PMAP_STATS_INC(tsb_nenter_u); bucket = tsb_vtobucket(pm, sz, va); tp = NULL; rtp = NULL; b0 = rd(tick) & (TSB_BUCKET_SIZE - 1); i = b0; do { if ((bucket[i].tte_data & TD_V) == 0) { tp = &bucket[i]; break; } if (tp == NULL) { if ((bucket[i].tte_data & TD_REF) == 0) tp = &bucket[i]; else if (rtp == NULL) rtp = &bucket[i]; } } while ((i = (i + 1) & (TSB_BUCKET_SIZE - 1)) != b0); if (tp == NULL) tp = rtp; if ((tp->tte_data & TD_V) != 0) { PMAP_STATS_INC(tsb_nrepl); ova = TTE_GET_VA(tp); pmap_remove_tte(pm, NULL, tp, ova); tlb_page_demap(pm, ova); } enter: if ((m->flags & PG_FICTITIOUS) == 0) { data |= TD_CP; if ((m->oflags & VPO_UNMANAGED) == 0) { pm->pm_stats.resident_count++; data |= TD_PV; } if (pmap_cache_enter(m, va) != 0) data |= TD_CV; TAILQ_INSERT_TAIL(&m->md.tte_list, tp, tte_link); } else data |= TD_FAKE | TD_E; tp->tte_vpn = TV_VPN(va, sz); tp->tte_data = data; return (tp); }
void add_test_command(struct test_command *t) { TAILQ_INSERT_TAIL(&commands_list, t, next); }
// create netifs for a list of interfaces uint16_t netif_fetch(int ifc, char *ifl[], struct my_sysinfo *sysinfo, struct nhead *netifs) { struct ifaddrs *ifaddrs, *ifaddr = NULL; struct ifreq ifr; int count = 0; int type, enabled; uint32_t index; struct parent_req mreq = {}; #ifdef AF_PACKET struct sockaddr_ll saddrll; #elif defined(AF_LINK) struct sockaddr_dl saddrdl; #endif // netifs struct netif *n_netif, *netif = NULL; if (sockfd == -1) my_fatal("please call netif_init first"); if (getifaddrs(&ifaddrs) < 0) { my_loge(CRIT, "address detection failed"); return(0); } // zero count = 0; // unset all but CAP_HOST and CAP_ROUTER sysinfo->cap &= (CAP_HOST|CAP_ROUTER); sysinfo->cap_active &= (CAP_HOST|CAP_ROUTER); // reset counter sysinfo->physif_count = 0; // mark all interfaces TAILQ_FOREACH(netif, netifs, entries) { netif->type = NETIF_OLD; } for (ifaddr = ifaddrs; ifaddr != NULL; ifaddr = ifaddr->ifa_next) { // skip interfaces without addresses if (ifaddr->ifa_addr == NULL) { my_log(INFO, "skipping interface %s", ifaddr->ifa_name); continue; } // only handle datalink addresses if (ifaddr->ifa_addr->sa_family != NETIF_AF) continue; // prepare ifr struct memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifaddr->ifa_name, sizeof(ifr.ifr_name)); // skip non-ethernet interfaces #ifdef AF_PACKET memcpy(&saddrll, ifaddr->ifa_addr, sizeof(saddrll)); if (saddrll.sll_hatype != ARPHRD_ETHER) { my_log(INFO, "skipping interface %s", ifaddr->ifa_name); continue; } index = saddrll.sll_ifindex; #elif defined(AF_LINK) memcpy(&saddrdl, ifaddr->ifa_addr, sizeof(saddrdl)); #ifdef IFT_BRIDGE if ((saddrdl.sdl_type != IFT_BRIDGE) && (saddrdl.sdl_type != IFT_ETHER)) { #else if (saddrdl.sdl_type != IFT_ETHER) { #endif my_log(INFO, "skipping interface %s", ifaddr->ifa_name); continue; } index = saddrdl.sdl_index; #endif // check for interfaces that are down enabled = 0; if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t)&ifr) >= 0) enabled = (ifr.ifr_flags & IFF_UP); // detect interface type type = netif_type(sockfd, index, ifaddr, &ifr); if (type == NETIF_REGULAR) { my_log(INFO, "found ethernet interface %s", ifaddr->ifa_name); sysinfo->physif_count++; } else if (type == NETIF_WIRELESS) { my_log(INFO, "found wireless interface %s", ifaddr->ifa_name); sysinfo->cap |= CAP_WLAN; sysinfo->cap_active |= (enabled == 1) ? CAP_WLAN : 0; } else if (type == NETIF_TAP) { my_log(INFO, "found tun/tap interface %s", ifaddr->ifa_name); } else if (type == NETIF_TEAMING) { my_log(INFO, "found teaming interface %s", ifaddr->ifa_name); } else if (type == NETIF_BONDING) { my_log(INFO, "found bond interface %s", ifaddr->ifa_name); } else if (type == NETIF_BRIDGE) { my_log(INFO, "found bridge interface %s", ifaddr->ifa_name); sysinfo->cap |= CAP_BRIDGE; sysinfo->cap_active |= (enabled == 1) ? CAP_BRIDGE : 0; } else if (type == NETIF_VLAN) { my_log(INFO, "found vlan interface %s", ifaddr->ifa_name); } else if (type == NETIF_INVALID) { my_log(INFO, "skipping interface %s", ifaddr->ifa_name); continue; } // skip interfaces that are down if (enabled == 0) { my_log(INFO, "skipping interface %s (down)", ifaddr->ifa_name); continue; } my_log(INFO, "adding interface %s", ifaddr->ifa_name); // fetch / create netif if ((netif = netif_byindex(netifs, index)) == NULL) { netif = my_malloc(sizeof(struct netif)); TAILQ_INSERT_TAIL(netifs, netif, entries); } else { // reset everything up to the tailq_entry but keep protos uint16_t protos = netif->protos; memset(netif, 0, offsetof(struct netif, entries)); netif->protos = protos; } // copy name, index and type netif->index = index; strlcpy(netif->name, ifaddr->ifa_name, sizeof(netif->name)); netif->type = type; #ifdef HAVE_SYSFS mreq.op = PARENT_ALIAS; mreq.index = netif->index; if (my_mreq(&mreq)) strlcpy(netif->description, mreq.buf, IFDESCRSIZE); #elif defined(SIOCGIFDESCR) #ifndef __FreeBSD__ ifr.ifr_data = (caddr_t)&netif->description; #else ifr.ifr_buffer.buffer = &netif->description; ifr.ifr_buffer.length = IFDESCRSIZE; #endif ioctl(sockfd, SIOCGIFDESCR, &ifr); #endif if (sysinfo->mifname && (strcmp(netif->name, sysinfo->mifname) == 0)) sysinfo->mnetif = netif; // update counters count++; } // remove old interfaces TAILQ_FOREACH_SAFE(netif, netifs, entries, n_netif) { if (netif->type != NETIF_OLD) continue; my_log(INFO, "removing old interface %s", netif->name); mreq.op = PARENT_CLOSE; mreq.index = netif->index; my_mreq(&mreq); TAILQ_REMOVE(netifs, netif, entries); if (sysinfo->mnetif == netif) sysinfo->mnetif = NULL; free(netif); } // add child subif lists to each bond/bridge // detect vlan interface settings TAILQ_FOREACH(netif, netifs, entries) { my_log(INFO, "detecting %s settings", netif->name); switch(netif->type) { #ifdef HAVE_LIBTEAM case NETIF_TEAMING: netif_team(sockfd, netifs, netif, &ifr); break; #endif /* HAVE_LIBTEAM */ case NETIF_BONDING: netif_bond(sockfd, netifs, netif, &ifr); break; case NETIF_BRIDGE: netif_bridge(sockfd, netifs, netif, &ifr); break; case NETIF_VLAN: netif_vlan(sockfd, netifs, netif, &ifr); break; case NETIF_REGULAR: netif_device_id(sockfd, netif, &ifr); break; default: break; } } // add addresses to netifs my_log(INFO, "fetching addresses for all interfaces"); netif_addrs(ifaddrs, netifs, sysinfo); // use the first mac as chassis id if ((netif = TAILQ_FIRST(netifs)) != NULL) memcpy(&sysinfo->hwaddr, &netif->hwaddr, ETHER_ADDR_LEN); // validate detected interfaces if (ifc > 0) { count = 0; for (int j = 0; j < ifc; j++) { netif = netif_byname(netifs, ifl[j]); if (netif == NULL) { my_log(CRIT, "interface %s is invalid", ifl[j]); } else if (netif->type == NETIF_VLAN) { my_log(CRIT, "vlan interface %s is not supported", ifl[j]); } else { netif->argv = 1; count++; } } if (count != ifc) count = 0; } else if (count == 0) { my_log(CRIT, "no valid interface found"); } if ((options & OPT_MNETIF) && !sysinfo->mnetif) my_log(CRIT, "could not detect the specified management interface"); // cleanup freeifaddrs(ifaddrs); return(count); };
/* * wiredtiger_open -- * Main library entry point: open a new connection to a WiredTiger * database. */ int wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, const char *config, WT_CONNECTION **wt_connp) { static WT_CONNECTION stdc = { __conn_close, __conn_reconfigure, __conn_get_home, __conn_is_new, __conn_open_session, __conn_load_extension, __conn_add_data_source, __conn_add_collator, __conn_add_compressor, __conn_add_extractor }; static struct { const char *name; uint32_t flag; } *ft, directio_types[] = { { "data", WT_DIRECTIO_DATA }, { "log", WT_DIRECTIO_LOG }, { NULL, 0 } }; WT_CONFIG subconfig; WT_CONFIG_ITEM cval, skey, sval; WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_ITEM *cbuf, expath, exconfig; WT_SESSION_IMPL *session; const char *cfg[] = { __wt_confdfl_wiredtiger_open, config, NULL, NULL, NULL }; int exist; *wt_connp = NULL; session = NULL; cbuf = NULL; WT_CLEAR(expath); WT_CLEAR(exconfig); WT_RET(__wt_library_init()); WT_RET(__wt_calloc_def(NULL, 1, &conn)); conn->iface = stdc; /* * Immediately link the structure into the connection structure list: * the only thing ever looked at on that list is the database name, * and a NULL value is fine. */ __wt_spin_lock(NULL, &__wt_process.spinlock); TAILQ_INSERT_TAIL(&__wt_process.connqh, conn, q); __wt_spin_unlock(NULL, &__wt_process.spinlock); session = conn->default_session = &conn->dummy_session; session->iface.connection = &conn->iface; session->name = "wiredtiger_open"; __wt_event_handler_set(session, event_handler); /* Remaining basic initialization of the connection structure. */ WT_ERR(__wt_connection_init(conn)); /* Check the configuration strings. */ WT_ERR(__wt_config_check( session, __wt_confchk_wiredtiger_open, config, 0)); /* Get the database home. */ WT_ERR(__conn_home(session, home, cfg)); /* Make sure no other thread of control already owns this database. */ WT_ERR(__conn_single(session, cfg)); /* Read the database-home configuration file. */ WT_ERR(__conn_config_file(session, cfg, &cbuf)); /* Read the environment variable configuration. */ WT_ERR(__conn_config_env(session, cfg)); WT_ERR(__wt_config_gets(session, cfg, "hazard_max", &cval)); conn->hazard_max = (uint32_t)cval.val; WT_ERR(__wt_config_gets(session, cfg, "session_max", &cval)); conn->session_size = (uint32_t)cval.val + WT_NUM_INTERNAL_SESSIONS; WT_ERR(__wt_config_gets(session, cfg, "lsm_merge", &cval)); if (cval.val) F_SET(conn, WT_CONN_LSM_MERGE); WT_ERR(__wt_config_gets(session, cfg, "sync", &cval)); if (cval.val) F_SET(conn, WT_CONN_SYNC); WT_ERR(__wt_config_gets(session, cfg, "transactional", &cval)); if (cval.val) F_SET(conn, WT_CONN_TRANSACTIONAL); /* Configure verbose flags. */ WT_ERR(__conn_verbose_config(session, cfg)); WT_ERR(__wt_conn_cache_pool_config(session, cfg)); WT_ERR(__wt_config_gets(session, cfg, "logging", &cval)); if (cval.val != 0) WT_ERR(__wt_open( session, WT_LOG_FILENAME, 1, 0, 0, &conn->log_fh)); /* Configure direct I/O and buffer alignment. */ WT_ERR(__wt_config_gets(session, cfg, "buffer_alignment", &cval)); if (cval.val == -1) conn->buffer_alignment = WT_BUFFER_ALIGNMENT_DEFAULT; else conn->buffer_alignment = (size_t)cval.val; #ifndef HAVE_POSIX_MEMALIGN if (conn->buffer_alignment != 0) WT_ERR_MSG(session, EINVAL, "buffer_alignment requires posix_memalign"); #endif /* * Configuration: direct_io, mmap, statistics. */ WT_ERR(__wt_config_gets(session, cfg, "direct_io", &cval)); for (ft = directio_types; ft->name != NULL; ft++) { ret = __wt_config_subgets(session, &cval, ft->name, &sval); if (ret == 0) { if (sval.val) FLD_SET(conn->direct_io, ft->flag); } else if (ret != WT_NOTFOUND) goto err; } WT_ERR(__wt_config_gets(session, cfg, "mmap", &cval)); conn->mmap = cval.val == 0 ? 0 : 1; WT_ERR(__wt_config_gets(session, cfg, "statistics", &cval)); conn->statistics = cval.val == 0 ? 0 : 1; /* Load any extensions referenced in the config. */ WT_ERR(__wt_config_gets(session, cfg, "extensions", &cval)); WT_ERR(__wt_config_subinit(session, &subconfig, &cval)); while ((ret = __wt_config_next(&subconfig, &skey, &sval)) == 0) { WT_ERR(__wt_buf_fmt( session, &expath, "%.*s", (int)skey.len, skey.str)); if (sval.len > 0) WT_ERR(__wt_buf_fmt(session, &exconfig, "entry=%.*s\n", (int)sval.len, sval.str)); WT_ERR(conn->iface.load_extension(&conn->iface, expath.data, (sval.len > 0) ? exconfig.data : NULL)); } WT_ERR_NOTFOUND_OK(ret); /* * Open the connection; if that fails, the connection handle has been * destroyed by the time the open function returns. */ if ((ret = __wt_connection_open(conn, cfg)) != 0) { conn = NULL; WT_ERR(ret); } /* Open the default session. */ WT_ERR(__wt_open_session(conn, 1, NULL, NULL, &conn->default_session)); session = conn->default_session; /* * Check on the turtle and metadata files, creating them if necessary * (which avoids application threads racing to create the metadata file * later). */ WT_ERR(__wt_meta_turtle_init(session, &exist)); if (!exist) { /* * We're single-threaded, but acquire the schema lock * regardless: the lower level code checks that it is * appropriately synchronized. */ WT_WITH_SCHEMA_LOCK(session, ret = __wt_schema_create(session, WT_METADATA_URI, NULL)); WT_ERR(ret); } WT_ERR(__wt_metadata_open(session)); /* If there's a hot-backup file, load it. */ WT_ERR(__wt_metadata_load_backup(session)); /* * XXX LSM initialization. * This is structured so that it could be moved to an extension. */ WT_ERR(__wt_lsm_init(&conn->iface, NULL)); STATIC_ASSERT(offsetof(WT_CONNECTION_IMPL, iface) == 0); *wt_connp = &conn->iface; /* * Destroying the connection on error will destroy our session handle, * cleanup using the session handle first, then discard the connection. */ err: if (cbuf != NULL) __wt_buf_free(session, cbuf); __wt_buf_free(session, &expath); __wt_buf_free(session, &exconfig); if (ret != 0 && conn != NULL) WT_TRET(__wt_connection_destroy(conn)); /* Let the server threads proceed. */ if (ret == 0) conn->connection_initialized = 1; return (ret); }
/* * Register the chosen transform XF into SA. As a side effect set PROTOP * to point at the corresponding proto structure. INITIATOR is true if we * are the initiator. */ int sa_add_transform(struct sa *sa, struct payload *xf, int initiator, struct proto **protop) { struct proto *proto; struct payload *prop = xf->context; *protop = 0; if (!initiator) { proto = calloc(1, sizeof *proto); if (!proto) log_error("sa_add_transform: calloc (1, %lu) failed", (unsigned long)sizeof *proto); } else { /* * RFC 2408, section 4.2 states the responder SHOULD use the * proposal number from the initiator (i.e us), in it's * selected proposal to make this lookup easier. Most vendors * follow this. One noted exception is the CiscoPIX (and * perhaps other Cisco products). * * We start by matching on the proposal number, as before. */ for (proto = TAILQ_FIRST(&sa->protos); proto && proto->no != GET_ISAKMP_PROP_NO(prop->p); proto = TAILQ_NEXT(proto, link)) ; /* * If we did not find a match, search through all proposals * and xforms. */ if (!proto || sa_validate_proto_xf(proto, xf, sa->phase) != 0) for (proto = TAILQ_FIRST(&sa->protos); proto && sa_validate_proto_xf(proto, xf, sa->phase) != 0; proto = TAILQ_NEXT(proto, link)) ; } if (!proto) return -1; *protop = proto; /* Allocate DOI-specific part. */ if (!initiator) { proto->data = calloc(1, sa->doi->proto_size); if (!proto->data) { log_error("sa_add_transform: calloc (1, %lu) failed", (unsigned long)sa->doi->proto_size); goto cleanup; } } proto->no = GET_ISAKMP_PROP_NO(prop->p); proto->proto = GET_ISAKMP_PROP_PROTO(prop->p); proto->spi_sz[0] = GET_ISAKMP_PROP_SPI_SZ(prop->p); if (proto->spi_sz[0]) { proto->spi[0] = malloc(proto->spi_sz[0]); if (!proto->spi[0]) goto cleanup; memcpy(proto->spi[0], prop->p + ISAKMP_PROP_SPI_OFF, proto->spi_sz[0]); } proto->chosen = xf; proto->sa = sa; proto->id = GET_ISAKMP_TRANSFORM_ID(xf->p); if (!initiator) TAILQ_INSERT_TAIL(&sa->protos, proto, link); /* Let the DOI get at proto for initializing its own data. */ if (sa->doi->proto_init) sa->doi->proto_init(proto, 0); LOG_DBG((LOG_SA, 80, "sa_add_transform: " "proto %p no %d proto %d chosen %p sa %p id %d", proto, proto->no, proto->proto, proto->chosen, proto->sa, proto->id)); return 0; cleanup: if (!initiator) { free(proto->data); free(proto); } *protop = 0; return -1; }
struct ifinfo * update_ifinfo(struct ifilist_head_t *ifi_head, int ifindex) { struct if_msghdr *ifm; struct ifinfo *ifi = NULL; struct sockaddr *sa; struct sockaddr *rti_info[RTAX_MAX]; char *msg; size_t len; char *lim; int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_IFLIST, 0 }; int error; syslog(LOG_DEBUG, "<%s> enter", __func__); if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), NULL, &len, NULL, 0) < 0) { syslog(LOG_ERR, "<%s> sysctl: NET_RT_IFLIST size get failed", __func__); exit(1); } if ((msg = malloc(len)) == NULL) { syslog(LOG_ERR, "<%s> malloc failed", __func__); exit(1); } if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), msg, &len, NULL, 0) < 0) { syslog(LOG_ERR, "<%s> sysctl: NET_RT_IFLIST get failed", __func__); exit(1); } lim = msg + len; for (ifm = (struct if_msghdr *)msg; ifm != NULL && ifm < (struct if_msghdr *)lim; ifm = get_next_msghdr(ifm,(struct if_msghdr *)lim)) { int ifi_new; syslog(LOG_DEBUG, "<%s> ifm = %p, lim = %p, diff = %zu", __func__, ifm, lim, (char *)lim - (char *)ifm); if (ifm->ifm_version != RTM_VERSION) { syslog(LOG_ERR, "<%s> ifm_vesrion mismatch", __func__); exit(1); } if (ifm->ifm_msglen == 0) { syslog(LOG_WARNING, "<%s> ifm_msglen is 0", __func__); free(msg); return (NULL); } ifi_new = 0; if (ifm->ifm_type == RTM_IFINFO) { struct ifreq ifr; int s; char ifname[IFNAMSIZ]; syslog(LOG_DEBUG, "<%s> RTM_IFINFO found. " "ifm_index = %d, ifindex = %d", __func__, ifm->ifm_index, ifindex); /* when ifindex is specified */ if (ifindex != UPDATE_IFINFO_ALL && ifindex != ifm->ifm_index) continue; /* ifname */ if (if_indextoname(ifm->ifm_index, ifname) == NULL) { syslog(LOG_WARNING, "<%s> ifname not found (idx=%d)", __func__, ifm->ifm_index); continue; } /* lookup an entry with the same ifindex */ TAILQ_FOREACH(ifi, ifi_head, ifi_next) { if (ifm->ifm_index == ifi->ifi_ifindex) break; if (strncmp(ifname, ifi->ifi_ifname, sizeof(ifname)) == 0) break; } if (ifi == NULL) { syslog(LOG_DEBUG, "<%s> new entry for idx=%d", __func__, ifm->ifm_index); ELM_MALLOC(ifi, exit(1)); ifi->ifi_rainfo = NULL; ifi->ifi_state = IFI_STATE_UNCONFIGURED; ifi->ifi_persist = 0; ifi_new = 1; } /* ifindex */ ifi->ifi_ifindex = ifm->ifm_index; /* ifname */ strlcpy(ifi->ifi_ifname, ifname, IFNAMSIZ); if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { syslog(LOG_ERR, "<%s> socket() failed.", __func__); if (ifi_new) free(ifi); continue; } /* MTU */ ifi->ifi_phymtu = ifm->ifm_data.ifi_mtu; if (ifi->ifi_phymtu == 0) { memset(&ifr, 0, sizeof(ifr)); ifr.ifr_addr.sa_family = AF_INET6; strlcpy(ifr.ifr_name, ifi->ifi_ifname, sizeof(ifr.ifr_name)); error = ioctl(s, SIOCGIFMTU, (caddr_t)&ifr); if (error) { close(s); syslog(LOG_ERR, "<%s> ioctl() failed.", __func__); if (ifi_new) free(ifi); continue; } ifi->ifi_phymtu = ifr.ifr_mtu; if (ifi->ifi_phymtu == 0) { syslog(LOG_WARNING, "<%s> no interface mtu info" " on %s. %d will be used.", __func__, ifi->ifi_ifname, IPV6_MMTU); ifi->ifi_phymtu = IPV6_MMTU; } } close(s); /* ND flags */ error = update_ifinfo_nd_flags(ifi); if (error) { if (ifi_new) free(ifi); continue; } /* SDL */ sa = (struct sockaddr *)(ifm + 1); get_rtaddrs(ifm->ifm_addrs, sa, rti_info); if ((sa = rti_info[RTAX_IFP]) != NULL) { if (sa->sa_family == AF_LINK) { memcpy(&ifi->ifi_sdl, (struct sockaddr_dl *)sa, sizeof(ifi->ifi_sdl)); } } else memset(&ifi->ifi_sdl, 0, sizeof(ifi->ifi_sdl)); /* flags */ ifi->ifi_flags = ifm->ifm_flags; /* type */ ifi->ifi_type = ifm->ifm_type; } else { syslog(LOG_ERR, "out of sync parsing NET_RT_IFLIST\n" "expected %d, got %d\n msglen = %d\n", RTM_IFINFO, ifm->ifm_type, ifm->ifm_msglen); exit(1); } if (ifi_new) { syslog(LOG_DEBUG, "<%s> adding %s(idx=%d) to ifilist", __func__, ifi->ifi_ifname, ifi->ifi_ifindex); TAILQ_INSERT_TAIL(ifi_head, ifi, ifi_next); } }
/* * Find the correct table entry for the given variable. If non exists, * create one. */ static struct entry * table_find(struct tabwork *work, const struct asn_oid *var) { struct entry *e, *e1; struct work *w, *w1; u_int i, p, j; size_t len; u_char *ptr; struct asn_oid oid; /* get index */ asn_slice_oid(&oid, var, work->descr->table.len + 2, var->len); e = TAILQ_FIRST(work->table); w = TAILQ_FIRST(&work->worklist); while (e != NULL) { if (asn_compare_oid(&w->index, &oid) == 0) return (e); e = TAILQ_NEXT(e, link); w = TAILQ_NEXT(w, link); } /* Not found create new one */ if ((e = malloc(work->descr->entry_size)) == NULL) { seterr(&snmp_client, "no memory for table entry"); return (NULL); } if ((w = malloc(sizeof(*w))) == NULL) { seterr(&snmp_client, "no memory for table entry"); free(e); return (NULL); } w->index = oid; memset(e, 0, work->descr->entry_size); /* decode index */ p = work->descr->table.len + 2; for (i = 0; i < work->descr->index_size; i++) { switch (work->descr->entries[i].syntax) { case SNMP_SYNTAX_INTEGER: if (var->len < p + 1) { seterr(&snmp_client, "bad index: need integer"); goto err; } if (var->subs[p] > INT32_MAX) { seterr(&snmp_client, "bad index: integer too large"); goto err; } *(int32_t *)(void *)((u_char *)e + work->descr->entries[i].offset) = var->subs[p++]; break; case SNMP_SYNTAX_OCTETSTRING: if (var->len < p + 1) { seterr(&snmp_client, "bad index: need string length"); goto err; } len = var->subs[p++]; if (var->len < p + len) { seterr(&snmp_client, "bad index: string too short"); goto err; } if ((ptr = malloc(len + 1)) == NULL) { seterr(&snmp_client, "no memory for index string"); goto err; } for (j = 0; j < len; j++) { if (var->subs[p] > UCHAR_MAX) { seterr(&snmp_client, "bad index: char too large"); free(ptr); goto err; } ptr[j] = var->subs[p++]; } ptr[j] = '\0'; *(u_char **)(void *)((u_char *)e + work->descr->entries[i].offset) = ptr; *(size_t *)(void *)((u_char *)e + work->descr->entries[i].offset + sizeof(u_char *)) = len; break; case SNMP_SYNTAX_OID: if (var->len < p + 1) { seterr(&snmp_client, "bad index: need oid length"); goto err; } oid.len = var->subs[p++]; if (var->len < p + oid.len) { seterr(&snmp_client, "bad index: oid too short"); goto err; } for (j = 0; j < oid.len; j++) oid.subs[j] = var->subs[p++]; *(struct asn_oid *)(void *)((u_char *)e + work->descr->entries[i].offset) = oid; break; case SNMP_SYNTAX_IPADDRESS: if (var->len < p + 4) { seterr(&snmp_client, "bad index: need ip-address"); goto err; } for (j = 0; j < 4; j++) { if (var->subs[p] > 0xff) { seterr(&snmp_client, "bad index: ipaddress too large"); goto err; } ((u_char *)e + work->descr->entries[i].offset)[j] = var->subs[p++]; } break; case SNMP_SYNTAX_GAUGE: if (var->len < p + 1) { seterr(&snmp_client, "bad index: need unsigned"); goto err; } if (var->subs[p] > UINT32_MAX) { seterr(&snmp_client, "bad index: unsigned too large"); goto err; } *(uint32_t *)(void *)((u_char *)e + work->descr->entries[i].offset) = var->subs[p++]; break; case SNMP_SYNTAX_COUNTER: case SNMP_SYNTAX_TIMETICKS: case SNMP_SYNTAX_COUNTER64: case SNMP_SYNTAX_NULL: case SNMP_SYNTAX_NOSUCHOBJECT: case SNMP_SYNTAX_NOSUCHINSTANCE: case SNMP_SYNTAX_ENDOFMIBVIEW: abort(); } e->found |= (uint64_t)1 << i; } /* link into the correct place */ e1 = TAILQ_FIRST(work->table); w1 = TAILQ_FIRST(&work->worklist); while (e1 != NULL) { if (asn_compare_oid(&w1->index, &w->index) > 0) break; e1 = TAILQ_NEXT(e1, link); w1 = TAILQ_NEXT(w1, link); } if (e1 == NULL) { TAILQ_INSERT_TAIL(work->table, e, link); TAILQ_INSERT_TAIL(&work->worklist, w, link); } else { TAILQ_INSERT_BEFORE(e1, e, link); TAILQ_INSERT_BEFORE(w1, w, link); } return (e); err: /* * Error happend. Free all octet string index parts and the entry * itself. */ for (i = 0; i < work->descr->index_size; i++) { if (work->descr->entries[i].syntax == SNMP_SYNTAX_OCTETSTRING && (e->found & ((uint64_t)1 << i))) free(*(void **)(void *)((u_char *)e + work->descr->entries[i].offset)); } free(e); free(w); return (NULL); }
END_TEST #ifdef ENABLE_DOT1 /* This test case tests send and receive of all DOT1 TLVs(2005 and 2009): Port Valn ID, VLAN, Port Protocol VLAN ID, Protocol Identity, VID Usage Digest, Management VID, and 802.1ax Link Aggregation TLVs */ START_TEST (test_send_rcv_dot1_tlvs) { int n; struct lldpd_vlan *rvlan, vlan1, vlan2, vlan3; struct lldpd_ppvid ppvid, *rppvid; struct lldpd_pi pi1, pi2, *rpi; struct lldpd_chassis *nchassis = NULL; struct lldpd_port *nport = NULL; struct packet *pkt; /* Populate port and chassis */ hardware.h_lport.p_id_subtype = LLDP_PORTID_SUBTYPE_LLADDR; hardware.h_lport.p_id = macaddress; hardware.h_lport.p_id_len = ETHER_ADDR_LEN; hardware.h_lport.p_descr = "Fake port description"; hardware.h_lport.p_mfs = 1516; hardware.h_lport.p_pvid = 1500; chassis.c_id_subtype = LLDP_CHASSISID_SUBTYPE_LOCAL; chassis.c_id = "Chassis name"; chassis.c_id_len = strlen(chassis.c_id); chassis.c_name = "Second chassis"; chassis.c_descr = "Chassis description"; chassis.c_cap_available = LLDP_CAP_ROUTER | LLDP_CAP_BRIDGE; chassis.c_cap_enabled = LLDP_CAP_ROUTER; vlan1.v_name = "Voice"; vlan1.v_vid = 157; vlan2.v_name = "Data"; vlan2.v_vid = 1247; vlan3.v_name = "Control"; vlan3.v_vid = 741; TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan1, v_entries); TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan2, v_entries); TAILQ_INSERT_TAIL(&hardware.h_lport.p_vlans, &vlan3, v_entries); ppvid.p_cap_status = 3; ppvid.p_ppvid = 1500; TAILQ_INSERT_TAIL(&hardware.h_lport.p_ppvids, &ppvid, p_entries); pi1.p_pi = "IEEE Link Aggregration Control Protocol 802.3ad"; pi1.p_pi_len = strlen(pi1.p_pi); pi2.p_pi = "IEEE Link Layer Discovery Protocol 802.1ab-2005"; pi2.p_pi_len = strlen(pi2.p_pi); TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi1, p_entries); TAILQ_INSERT_TAIL(&hardware.h_lport.p_pids, &pi2, p_entries); /* Build packet */ n = lldp_send(&test_lldpd, &hardware); if (n != 0) { fail("unable to build packet"); return; } if (TAILQ_EMPTY(&pkts)) { fail("no packets sent"); return; } pkt = TAILQ_FIRST(&pkts); fail_unless(TAILQ_NEXT(pkt, next) == NULL, "more than one packet sent"); /* decode the retrieved packet calling lldp_decode() */ fail_unless(lldp_decode(NULL, pkt->data, pkt->size, &hardware, &nchassis, &nport) != -1); if (!nchassis || !nport) { fail("unable to decode packet"); return; } /* verify port values */ check_received_port(&hardware.h_lport, nport); /* verify chassis values */ check_received_chassis(&chassis, nchassis); if (TAILQ_EMPTY(&nport->p_vlans)) { fail("no VLAN"); return; } rvlan = TAILQ_FIRST(&nport->p_vlans); ck_assert_int_eq(rvlan->v_vid, vlan1.v_vid); ck_assert_str_eq(rvlan->v_name, vlan1.v_name); rvlan = TAILQ_NEXT(rvlan, v_entries); if (!rvlan) { fail("no more VLAN"); return; } ck_assert_int_eq(rvlan->v_vid, vlan2.v_vid); ck_assert_str_eq(rvlan->v_name, vlan2.v_name); rvlan = TAILQ_NEXT(rvlan, v_entries); if (!rvlan) { fail("no more VLAN"); return; } ck_assert_int_eq(rvlan->v_vid, vlan3.v_vid); ck_assert_str_eq(rvlan->v_name, vlan3.v_name); rvlan = TAILQ_NEXT(rvlan, v_entries); fail_unless(rvlan == NULL); ck_assert_int_eq(nport->p_pvid, hardware.h_lport.p_pvid); if (TAILQ_EMPTY(&nport->p_ppvids)) { fail("no Port Protocal VLAN ID"); return; } rppvid = TAILQ_FIRST(&nport->p_ppvids); ck_assert_int_eq(rppvid->p_cap_status, ppvid.p_cap_status); ck_assert_int_eq(rppvid->p_ppvid, ppvid.p_ppvid); if (TAILQ_EMPTY(&nport->p_pids)) { fail("no Protocal Identity TLV"); return; } rpi = TAILQ_FIRST(&nport->p_pids); ck_assert_int_eq(rpi->p_pi_len, pi1.p_pi_len); ck_assert_str_eq_n(rpi->p_pi, pi1.p_pi, pi1.p_pi_len); rpi = TAILQ_NEXT(rpi, p_entries); if (!rpi) { fail("no more Protocol Identity TLVs"); return; } ck_assert_int_eq(rpi->p_pi_len, pi2.p_pi_len); ck_assert_str_eq_n(rpi->p_pi, pi2.p_pi, pi2.p_pi_len); rpi = TAILQ_NEXT(rpi, p_entries); fail_unless(rpi == NULL); return; }
static int mfi_disk_attach(device_t dev) { struct mfi_disk *sc; struct mfi_ld_info *ld_info; uint64_t sectors; uint32_t secsize; char *state; sc = device_get_softc(dev); ld_info = device_get_ivars(dev); sc->ld_dev = dev; sc->ld_id = ld_info->ld_config.properties.ld.v.target_id; sc->ld_unit = device_get_unit(dev); sc->ld_info = ld_info; sc->ld_controller = device_get_softc(device_get_parent(dev)); sc->ld_flags = 0; sectors = ld_info->size; secsize = MFI_SECTOR_LEN; mtx_lock(&sc->ld_controller->mfi_io_lock); TAILQ_INSERT_TAIL(&sc->ld_controller->mfi_ld_tqh, sc, ld_link); mtx_unlock(&sc->ld_controller->mfi_io_lock); switch (ld_info->ld_config.params.state) { case MFI_LD_STATE_OFFLINE: state = "offline"; break; case MFI_LD_STATE_PARTIALLY_DEGRADED: state = "partially degraded"; break; case MFI_LD_STATE_DEGRADED: state = "degraded"; break; case MFI_LD_STATE_OPTIMAL: state = "optimal"; break; default: state = "unknown"; break; } device_printf(dev, "%juMB (%ju sectors) RAID volume '%s' is %s\n", sectors / (1024 * 1024 / secsize), sectors, ld_info->ld_config.properties.name, state); sc->ld_disk = disk_alloc(); sc->ld_disk->d_drv1 = sc; sc->ld_disk->d_maxsize = sc->ld_controller->mfi_max_io * secsize; sc->ld_disk->d_name = "mfid"; sc->ld_disk->d_open = mfi_disk_open; sc->ld_disk->d_close = mfi_disk_close; sc->ld_disk->d_strategy = mfi_disk_strategy; sc->ld_disk->d_dump = mfi_disk_dump; sc->ld_disk->d_unit = sc->ld_unit; sc->ld_disk->d_sectorsize = secsize; sc->ld_disk->d_mediasize = sectors * secsize; if (sc->ld_disk->d_mediasize >= (1 * 1024 * 1024)) { sc->ld_disk->d_fwheads = 255; sc->ld_disk->d_fwsectors = 63; } else { sc->ld_disk->d_fwheads = 64; sc->ld_disk->d_fwsectors = 32; } disk_create(sc->ld_disk, DISK_VERSION); return (0); }