static int __noinline npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables, prop_dictionary_t errdict) { prop_object_iterator_t it; prop_dictionary_t tbldict; int error = 0; /* Tables - array. */ if (prop_object_type(tables) != PROP_TYPE_ARRAY) { NPF_ERR_DEBUG(errdict); return EINVAL; } it = prop_array_iterator(tables); while ((tbldict = prop_object_iterator_next(it)) != NULL) { const char *name; npf_table_t *t; u_int tid; int type; /* Table - dictionary. */ if (prop_object_type(tbldict) != PROP_TYPE_DICTIONARY) { NPF_ERR_DEBUG(errdict); error = EINVAL; break; } /* Table name, ID and type. Validate them. */ if (!prop_dictionary_get_cstring_nocopy(tbldict, "name", &name)) { NPF_ERR_DEBUG(errdict); error = EINVAL; break; } prop_dictionary_get_uint32(tbldict, "id", &tid); prop_dictionary_get_int32(tbldict, "type", &type); error = npf_table_check(tblset, name, tid, type); if (error) { NPF_ERR_DEBUG(errdict); break; } /* Get the entries or binary data. */ prop_array_t ents = prop_dictionary_get(tbldict, "entries"); prop_object_t obj = prop_dictionary_get(tbldict, "data"); void *blob = prop_data_data(obj); size_t size = prop_data_size(obj); if (type == NPF_TABLE_CDB && (blob == NULL || size == 0)) { NPF_ERR_DEBUG(errdict); error = EINVAL; break; } if (type == NPF_TABLE_HASH) { size = 1024; /* XXX */ } /* Create and insert the table. */ t = npf_table_create(name, tid, type, blob, size); if (t == NULL) { NPF_ERR_DEBUG(errdict); error = ENOMEM; break; } error = npf_tableset_insert(tblset, t); KASSERT(error == 0); if (ents && (error = npf_mk_table_entries(t, ents)) != 0) { NPF_ERR_DEBUG(errdict); break; } } prop_object_iterator_release(it); /* * Note: in a case of error, caller will free the tableset. */ return error; }
static int __noinline npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables, prop_dictionary_t errdict) { prop_object_iterator_t it; prop_dictionary_t tbldict; int error = 0; /* Tables - array. */ if (prop_object_type(tables) != PROP_TYPE_ARRAY) { NPF_ERR_DEBUG(errdict); return EINVAL; } it = prop_array_iterator(tables); while ((tbldict = prop_object_iterator_next(it)) != NULL) { prop_dictionary_t ent; prop_object_iterator_t eit; prop_array_t entries; npf_table_t *t; u_int tid; int type; /* Table - dictionary. */ if (prop_object_type(tbldict) != PROP_TYPE_DICTIONARY) { NPF_ERR_DEBUG(errdict); error = EINVAL; break; } /* Table ID and type. */ prop_dictionary_get_uint32(tbldict, "id", &tid); prop_dictionary_get_int32(tbldict, "type", &type); /* Validate them, check for duplicate IDs. */ error = npf_table_check(tblset, tid, type); if (error) break; /* Create and insert the table. */ t = npf_table_create(tid, type, 1024); /* XXX */ if (t == NULL) { NPF_ERR_DEBUG(errdict); error = ENOMEM; break; } error = npf_tableset_insert(tblset, t); KASSERT(error == 0); /* Entries. */ entries = prop_dictionary_get(tbldict, "entries"); if (prop_object_type(entries) != PROP_TYPE_ARRAY) { NPF_ERR_DEBUG(errdict); error = EINVAL; break; } eit = prop_array_iterator(entries); while ((ent = prop_object_iterator_next(eit)) != NULL) { const npf_addr_t *addr; npf_netmask_t mask; int alen; /* Get address and mask. Add a table entry. */ prop_object_t obj = prop_dictionary_get(ent, "addr"); addr = (const npf_addr_t *)prop_data_data_nocopy(obj); prop_dictionary_get_uint8(ent, "mask", &mask); alen = prop_data_size(obj); error = npf_table_insert(tblset, tid, alen, addr, mask); if (error) break; } prop_object_iterator_release(eit); if (error) break; } prop_object_iterator_release(it); /* * Note: in a case of error, caller will free the tableset. */ return error; }