| 247 | } |
| 248 | |
| 249 | int |
| 250 | pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size, |
| 251 | int *nadd, int flags) |
| 252 | { |
| 253 | struct pfr_ktable *kt, *tmpkt; |
| 254 | struct pfr_kentryworkq workq; |
| 255 | struct pfr_kentry *p, *q; |
| 256 | struct pfr_addr *ad; |
| 257 | int i, rv, xadd = 0; |
| 258 | long tzero = time_second; |
| 259 | |
| 260 | PF_RULES_WASSERT(); |
| 261 | |
| 262 | ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_FEEDBACK); |
| 263 | if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL)) |
| 264 | return (EINVAL); |
| 265 | kt = pfr_lookup_table(tbl); |
| 266 | if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) |
| 267 | return (ESRCH); |
| 268 | if (kt->pfrkt_flags & PFR_TFLAG_CONST) |
| 269 | return (EPERM); |
| 270 | tmpkt = pfr_create_ktable(&V_pfr_nulltable, 0, 0); |
| 271 | if (tmpkt == NULL) |
| 272 | return (ENOMEM); |
| 273 | SLIST_INIT(&workq); |
| 274 | for (i = 0, ad = addr; i < size; i++, ad++) { |
| 275 | if (pfr_validate_addr(ad)) |
| 276 | senderr(EINVAL); |
| 277 | p = pfr_lookup_addr(kt, ad, 1); |
| 278 | q = pfr_lookup_addr(tmpkt, ad, 1); |
| 279 | if (flags & PFR_FLAG_FEEDBACK) { |
| 280 | if (q != NULL) |
| 281 | ad->pfra_fback = PFR_FB_DUPLICATE; |
| 282 | else if (p == NULL) |
| 283 | ad->pfra_fback = PFR_FB_ADDED; |
| 284 | else if (p->pfrke_not != ad->pfra_not) |
| 285 | ad->pfra_fback = PFR_FB_CONFLICT; |
| 286 | else |
| 287 | ad->pfra_fback = PFR_FB_NONE; |
| 288 | } |
| 289 | if (p == NULL && q == NULL) { |
| 290 | p = pfr_create_kentry(ad, |
| 291 | (kt->pfrkt_flags & PFR_TFLAG_COUNTERS) != 0); |
| 292 | if (p == NULL) |
| 293 | senderr(ENOMEM); |
| 294 | if (pfr_route_kentry(tmpkt, p)) { |
| 295 | pfr_destroy_kentry(p); |
| 296 | ad->pfra_fback = PFR_FB_NONE; |
| 297 | } else { |
| 298 | SLIST_INSERT_HEAD(&workq, p, pfrke_workq); |
| 299 | xadd++; |
| 300 | } |
| 301 | } |
| 302 | } |
| 303 | pfr_clean_node_mask(tmpkt, &workq); |
| 304 | if (!(flags & PFR_FLAG_DUMMY)) |
| 305 | pfr_insert_kentries(kt, &workq, tzero); |
| 306 | else |
no test coverage detected