| 1150 | } |
| 1151 | |
| 1152 | int |
| 1153 | pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags) |
| 1154 | { |
| 1155 | struct pfr_ktableworkq addq, changeq; |
| 1156 | struct pfr_ktable *p, *q, *r, key; |
| 1157 | int i, rv, xadd = 0; |
| 1158 | long tzero = time_second; |
| 1159 | |
| 1160 | ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY); |
| 1161 | SLIST_INIT(&addq); |
| 1162 | SLIST_INIT(&changeq); |
| 1163 | for (i = 0; i < size; i++) { |
| 1164 | bcopy(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t)); |
| 1165 | if (pfr_validate_table(&key.pfrkt_t, PFR_TFLAG_USRMASK, |
| 1166 | flags & PFR_FLAG_USERIOCTL)) |
| 1167 | senderr(EINVAL); |
| 1168 | key.pfrkt_flags |= PFR_TFLAG_ACTIVE; |
| 1169 | p = RB_FIND(pfr_ktablehead, &V_pfr_ktables, &key); |
| 1170 | if (p == NULL) { |
| 1171 | p = pfr_create_ktable(&key.pfrkt_t, tzero, 1); |
| 1172 | if (p == NULL) |
| 1173 | senderr(ENOMEM); |
| 1174 | SLIST_FOREACH(q, &addq, pfrkt_workq) { |
| 1175 | if (!pfr_ktable_compare(p, q)) { |
| 1176 | pfr_destroy_ktable(p, 0); |
| 1177 | goto _skip; |
| 1178 | } |
| 1179 | } |
| 1180 | SLIST_INSERT_HEAD(&addq, p, pfrkt_workq); |
| 1181 | xadd++; |
| 1182 | if (!key.pfrkt_anchor[0]) |
| 1183 | goto _skip; |
| 1184 | |
| 1185 | /* find or create root table */ |
| 1186 | bzero(key.pfrkt_anchor, sizeof(key.pfrkt_anchor)); |
| 1187 | r = RB_FIND(pfr_ktablehead, &V_pfr_ktables, &key); |
| 1188 | if (r != NULL) { |
| 1189 | p->pfrkt_root = r; |
| 1190 | goto _skip; |
| 1191 | } |
| 1192 | SLIST_FOREACH(q, &addq, pfrkt_workq) { |
| 1193 | if (!pfr_ktable_compare(&key, q)) { |
| 1194 | p->pfrkt_root = q; |
| 1195 | goto _skip; |
| 1196 | } |
| 1197 | } |
| 1198 | key.pfrkt_flags = 0; |
| 1199 | r = pfr_create_ktable(&key.pfrkt_t, 0, 1); |
| 1200 | if (r == NULL) |
| 1201 | senderr(ENOMEM); |
| 1202 | SLIST_INSERT_HEAD(&addq, r, pfrkt_workq); |
| 1203 | p->pfrkt_root = r; |
| 1204 | } else if (!(p->pfrkt_flags & PFR_TFLAG_ACTIVE)) { |
| 1205 | SLIST_FOREACH(q, &changeq, pfrkt_workq) |
| 1206 | if (!pfr_ktable_compare(&key, q)) |
| 1207 | goto _skip; |
| 1208 | p->pfrkt_nflags = (p->pfrkt_flags & |
| 1209 | ~PFR_TFLAG_USRMASK) | key.pfrkt_flags; |
no test coverage detected