void skb_rshift(struct sk_buff *skb, size_t count) { assert(skb != NULL); assert(skb->data != NULL); assert(count < skb_max_size()); memmove(skb_get_data_pointner(skb->data) + count, skb_get_data_pointner(skb->data), min(skb->len, skb_max_size() - count)); skb->len += min(count, skb_max_size() - count); }
static void skb_copy_ref(struct sk_buff *to, const struct sk_buff *from) { ptrdiff_t offset; assert((to != NULL) && (to->data != NULL) && (from != NULL) && (from->data != NULL)); to->dev = from->dev; offset = skb_get_data_pointner(to->data) - skb_get_data_pointner(from->data); if (from->mac.raw != NULL) { to->mac.raw = from->mac.raw + offset; } if (from->nh.raw != NULL) { to->nh.raw = from->nh.raw + offset; } if (from->h.raw != NULL) { to->h.raw = from->h.raw + offset; } to->p_data = to->p_data_end = NULL; }
struct sk_buff * skb_realloc(size_t size, struct sk_buff *skb) { if (skb == NULL) { return skb_alloc(size); } list_del_init((struct list_head *) skb); skb->dev = NULL; skb->len = size; skb->mac.raw = skb_get_data_pointner(skb->data); skb->nh.raw = skb->h.raw = NULL; 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; }
struct sk_buff * skb_wrap_local(size_t size, struct sk_buff_data *skb_data, struct pool *pl) { ipl_t sp; struct sk_buff *skb; assert(pl != NULL); assert(size != 0); assert(skb_data != NULL); // TODO move it // if (size > skb_max_size()) { // log_error("skb_wrap: error: size is too big\n"); // return NULL; /* error: invalid argument */ // } sp = ipl_save(); { skb = pool_alloc(pl); } ipl_restore(sp); if (skb == NULL) { log_error("skb_wrap: error: no memory\n"); return NULL; /* error: no memory */ } gettimeofday(&skb->tstamp, NULL); INIT_LIST_HEAD((struct list_head * )skb); skb->dev = NULL; skb->len = size; skb->nh.raw = skb->h.raw = NULL; skb->data = skb_data; skb->mac.raw = skb_get_data_pointner(skb_data); skb->p_data = skb->p_data_end = NULL; skb->pl = pl; return skb; }
static void skb_copy_data(struct sk_buff_data *to_data, const struct sk_buff *from) { assert((to_data != NULL) && (from != NULL) && (from->data != NULL)); memcpy(skb_get_data_pointner(to_data), skb_get_data_pointner(from->data), from->len); }
void * skb_data_cast_in(struct sk_buff_data *skb_data) { assert(skb_data != NULL); return skb_get_data_pointner(skb_data); }