| 1255 | } |
| 1256 | |
| 1257 | int |
| 1258 | pf_state_insert(struct pfi_kkif *kif, struct pf_state_key *skw, |
| 1259 | struct pf_state_key *sks, struct pf_state *s) |
| 1260 | { |
| 1261 | struct pf_idhash *ih; |
| 1262 | struct pf_state *cur; |
| 1263 | int error; |
| 1264 | |
| 1265 | KASSERT(TAILQ_EMPTY(&sks->states[0]) && TAILQ_EMPTY(&sks->states[1]), |
| 1266 | ("%s: sks not pristine", __func__)); |
| 1267 | KASSERT(TAILQ_EMPTY(&skw->states[0]) && TAILQ_EMPTY(&skw->states[1]), |
| 1268 | ("%s: skw not pristine", __func__)); |
| 1269 | KASSERT(s->refs == 0, ("%s: state not pristine", __func__)); |
| 1270 | |
| 1271 | s->kif = kif; |
| 1272 | |
| 1273 | if (s->id == 0 && s->creatorid == 0) { |
| 1274 | /* XXX: should be atomic, but probability of collision low */ |
| 1275 | if ((s->id = V_pf_stateid[curcpu]++) == PFID_MAXID) |
| 1276 | V_pf_stateid[curcpu] = 1; |
| 1277 | s->id |= (uint64_t )curcpu << PFID_CPUSHIFT; |
| 1278 | s->id = htobe64(s->id); |
| 1279 | s->creatorid = V_pf_status.hostid; |
| 1280 | } |
| 1281 | |
| 1282 | /* Returns with ID locked on success. */ |
| 1283 | if ((error = pf_state_key_attach(skw, sks, s)) != 0) |
| 1284 | return (error); |
| 1285 | |
| 1286 | ih = &V_pf_idhash[PF_IDHASH(s)]; |
| 1287 | PF_HASHROW_ASSERT(ih); |
| 1288 | LIST_FOREACH(cur, &ih->states, entry) |
| 1289 | if (cur->id == s->id && cur->creatorid == s->creatorid) |
| 1290 | break; |
| 1291 | |
| 1292 | if (cur != NULL) { |
| 1293 | PF_HASHROW_UNLOCK(ih); |
| 1294 | if (V_pf_status.debug >= PF_DEBUG_MISC) { |
| 1295 | printf("pf: state ID collision: " |
| 1296 | "id: %016llx creatorid: %08x\n", |
| 1297 | (unsigned long long)be64toh(s->id), |
| 1298 | ntohl(s->creatorid)); |
| 1299 | } |
| 1300 | pf_detach_state(s); |
| 1301 | return (EEXIST); |
| 1302 | } |
| 1303 | LIST_INSERT_HEAD(&ih->states, s, entry); |
| 1304 | /* One for keys, one for ID hash. */ |
| 1305 | refcount_init(&s->refs, 2); |
| 1306 | |
| 1307 | counter_u64_add(V_pf_status.fcounters[FCNT_STATE_INSERT], 1); |
| 1308 | if (V_pfsync_insert_state_ptr != NULL) |
| 1309 | V_pfsync_insert_state_ptr(s); |
| 1310 | |
| 1311 | /* Returns locked. */ |
| 1312 | return (0); |
| 1313 | } |
| 1314 |
no test coverage detected