/* The tdb table better be locked before it is handed in, or races might happen */ int ipsec_sa_delchain(struct ipsec_sa *ips) { struct ipsec_sa *tdbdel; int error = 0; char sa[SATOA_BUF]; size_t sa_len; if(!ips) { KLIPS_PRINT(debug_xform, "klips_error:deltdbchain: " "null pointer passed in!\n"); return -ENODATA; } sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); KLIPS_PRINT(debug_xform, "klips_debug:deltdbchain: " "passed SA:%s\n", sa_len ? sa : " (error)"); while(ips->ips_onext) { ips = ips->ips_onext; } while(ips) { /* XXX send a pfkey message up to advise of deleted TDB */ sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); KLIPS_PRINT(debug_xform, "klips_debug:deltdbchain: " "unlinking and delting SA:%s", sa_len ? sa : " (error)"); tdbdel = ips; ips = ips->ips_inext; if(ips) { sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); KLIPS_PRINT(debug_xform, ", inext=%s", sa_len ? sa : " (error)"); tdbdel->ips_inext = NULL; ips->ips_onext = NULL; } KLIPS_PRINT(debug_xform, ".\n"); if((error = ipsec_sa_del(tdbdel))) { KLIPS_PRINT(debug_xform, "klips_debug:deltdbchain: " "deltdb returned error %d.\n", -error); return error; } if((error = ipsec_sa_wipe(tdbdel))) { KLIPS_PRINT(debug_xform, "klips_debug:deltdbchain: " "ipsec_tdbwipe returned error %d.\n", -error); return error; } } return error; }
struct ipsec_sa *__ipsec_sa_get(struct ipsec_sa *ips, const char *func, int line, int type) { if (ips == NULL) return NULL; if (debug_xform) { char sa[SATOT_BUF]; size_t sa_len; sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa)); KLIPS_PRINT(debug_xform, "ipsec_sa_get: " "ipsec_sa %p SA:%s, ref:%d reference count (%d++) incremented by %s:%d.\n", ips, sa_len ? sa : " (error)", ips->ips_ref, atomic_read(&ips->ips_refcount), func, line); } atomic_inc(&ips->ips_refcount); #ifdef IPSEC_SA_RECOUNT_DEBUG if (type >= 0 && type < sizeof(ips->ips_track)) { unsigned long flags; local_irq_save(flags); if (ips->ips_track[type] == 255) printk("ipsec_sa_get: OVERFLOW for %d @ %s %d\n", type, func, line); else ips->ips_track[type]++; local_irq_restore(flags); } else { printk("BAD BAD BAD @ %s %d\n", func, line); } #endif #if 0 /* * DAVIDM: if we include this code it means the SA is freed immediately * on creation and then reused ! Not sure why it is here. */ if (atomic_dec_and_test(&ips->ips_refcount)) { KLIPS_PRINT(debug_xform, "ipsec_sa_get: freeing %p\n", ips); /* it was zero */ ipsec_sa_wipe(ips); } #endif return ips; }
void __ipsec_sa_put(struct ipsec_sa *ips, const char *func, int line, int type) { if (ips == NULL) { KLIPS_PRINT(debug_xform, "ipsec_sa_put: " "null pointer passed in!\n"); return; } if (debug_xform) { char sa[SATOT_BUF]; size_t sa_len; sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa)); KLIPS_PRINT(debug_xform, "ipsec_sa_put: " "ipsec_sa %p SA:%s, ref:%d reference count (%d--) decremented by %s:%d.\n", ips, sa_len ? sa : " (error)", ips->ips_ref, atomic_read(&ips->ips_refcount), func, line); } #ifdef IPSEC_SA_RECOUNT_DEBUG if (type >= 0 && type < sizeof(ips->ips_track)) { unsigned long flags; local_irq_save(flags); if (ips->ips_track[type] == 0) printk("ipsec_sa_put: UNDERFLOW for %d @ %s %d\n", type, func, line); else ips->ips_track[type]--; local_irq_restore(flags); } else { printk("BAD BAD BAD @ %s %d\n", func, line); } #endif if (atomic_dec_and_test(&ips->ips_refcount)) { KLIPS_PRINT(debug_xform, "ipsec_sa_put: freeing %p\n", ips); /* it was zero */ ipsec_sa_wipe(ips); } return; }
void __ipsec_sa_put(struct ipsec_sa *ips, const char *func, int line) { if(ips == NULL) { KLIPS_PRINT(debug_xform, "ipsec_sa_put: " "null pointer passed in!\n"); return; } #ifdef CONFIG_KLIPS_DEBUG if(debug_xform) { char sa[SATOT_BUF]; size_t sa_len; sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa)); KLIPS_PRINT(debug_xform, "ipsec_sa_put: " "ipsec_sa %p SA:%s, ref:%d reference count (%d--) decremented by %s:%d.\n", ips, sa_len ? sa : " (error)", ips->ips_ref, atomic_read(&ips->ips_refcount), func, line); } #endif if(atomic_dec_and_test(&ips->ips_refcount)) { KLIPS_PRINT(debug_xform, "ipsec_sa_put: freeing %p\n", ips); /* it was zero */ ipsec_sa_wipe(ips); } return; }