void skb_free(struct sk_buff *skb) { ipl_t sp; if (!skb) { return; } skb_data_free(skb->data); sp = ipl_save(); { assert((skb->lnk.prev != NULL) && (skb->lnk.next != NULL)); list_del((struct list_head *) skb); pool_free(&skb_pool, skb); } ipl_restore(sp); }
struct sk_buff * skb_alloc_local(size_t size, struct pool *pl) { struct sk_buff *skb; struct sk_buff_data *skb_data; skb_data = skb_data_alloc(size); if (skb_data == NULL) { return NULL; /* error: no memory */ } skb = skb_wrap_local(size, skb_data, pl); if (skb == NULL) { skb_data_free(skb_data); return NULL; /* error: no memory */ } return skb; }
struct sk_buff * skb_clone(const struct sk_buff *skb) { struct sk_buff *cloned; struct sk_buff_data *cloned_data; assert(skb != NULL); cloned_data = skb_data_clone(skb->data); if (cloned_data == NULL) { return NULL; /* error: no memory */ } cloned = skb_wrap(skb->len, cloned_data); if (cloned == NULL) { skb_data_free(cloned_data); return NULL; /* error: no memory */ } skb_copy_ref(cloned, skb); return cloned; }
struct sk_buff * skb_alloc(size_t size) { struct sk_buff *skb; struct sk_buff_data *skb_data; if (skb_data_pool.obj_size >= size) { skb_data = skb_data_alloc(); } else { skb_data = skb_data_alloc_dynamic(size); } if (skb_data == NULL) { return NULL; /* error: no memory */ } skb = skb_wrap(size, skb_data); if (skb == NULL) { skb_data_free(skb_data); return NULL; /* error: no memory */ } return skb; }
struct sk_buff * skb_declone(struct sk_buff *skb) { struct sk_buff_data *decloned_data; assert(skb != NULL); if (!skb_data_cloned(skb->data)) { return skb; } decloned_data = skb_data_alloc(); if (decloned_data == NULL) { return NULL; /* error: no memory */ } skb_shift_ref(skb, skb_get_data_pointner(decloned_data) - skb_get_data_pointner(skb->data)); skb_copy_data(decloned_data, skb); skb_data_free(skb->data); skb->data = decloned_data; return skb; }