static inline int iptree_add(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout) { struct ip_set_iptree *map = set->data; struct ip_set_iptreeb *btree; struct ip_set_iptreec *ctree; struct ip_set_iptreed *dtree; unsigned char a,b,c,d; int ret = 0; if (!ip || map->elements >= limit) /* We could call the garbage collector * but it's probably overkill */ return -ERANGE; ABCD(a, b, c, d, &ip); DP("%u %u %u %u timeout %u", a, b, c, d, timeout); ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep); ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep); ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep); if (dtree->expires[d] && (!map->timeout || time_after(dtree->expires[d], jiffies))) ret = -EEXIST; if (map->timeout && timeout == 0) timeout = map->timeout; dtree->expires[d] = map->timeout ? (timeout * HZ + jiffies) : 1; /* Lottery: I won! */ if (dtree->expires[d] == 0) dtree->expires[d] = 1; DP("%u %lu", d, dtree->expires[d]); if (ret == 0) map->elements++; return ret; }
int main() { typedef std::unique_ptr<SingleCharPrinter> charptr; charptr A(new ACharPrinter); charptr AB(new BCharPrinter(new ACharPrinter)); charptr ABCD(new DCharPrinter(new CCharPrinter(new BCharPrinter(new ACharPrinter)))); A->draw(); std::cout << '\n'; AB->draw(); std::cout << '\n'; ABCD->draw(); std::cout << '\n'; return 0; }
static inline int iptree_test(struct ip_set *set, ip_set_ip_t ip) { struct ip_set_iptree *map = set->data; struct ip_set_iptreeb *btree; struct ip_set_iptreec *ctree; struct ip_set_iptreed *dtree; unsigned char a,b,c,d; if (!ip) return -ERANGE; ABCD(a, b, c, d, &ip); DP("%u %u %u %u timeout %u", a, b, c, d, map->timeout); TESTIP_WALK(map, a, btree); TESTIP_WALK(btree, b, ctree); TESTIP_WALK(ctree, c, dtree); DP("%lu %lu", dtree->expires[d], jiffies); return dtree->expires[d] && (!map->timeout || time_after(dtree->expires[d], jiffies)); }
static inline int iptree_del(struct ip_set *set, ip_set_ip_t ip) { struct ip_set_iptree *map = set->data; struct ip_set_iptreeb *btree; struct ip_set_iptreec *ctree; struct ip_set_iptreed *dtree; unsigned char a,b,c,d; if (!ip) return -ERANGE; ABCD(a, b, c, d, &ip); DELIP_WALK(map, a, btree); DELIP_WALK(btree, b, ctree); DELIP_WALK(ctree, c, dtree); if (dtree->expires[d]) { dtree->expires[d] = 0; map->elements--; return 0; } return -EEXIST; }