[PATCH 2/5] AF_RXRPC: Move generic skbuff stuff from XFRM code to generic code [try #3]
Move generic skbuff stuff from XFRM code to generic code so that AF_RXRPC can use it too. The kdoc comments I've attached to the functions needs to be checked by whoever wrote them as I had to make some guesses about the workings of these functions. Signed-Off-By: David Howells <[EMAIL PROTECTED]> --- include/linux/skbuff.h |6 ++ include/net/esp.h |2 - net/core/skbuff.c | 188 net/xfrm/xfrm_algo.c | 169 --- 4 files changed, 194 insertions(+), 171 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4ff3940..9e70270 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -83,6 +83,7 @@ */ struct net_device; +struct scatterlist; #ifdef CONFIG_NETFILTER struct nf_conntrack { @@ -363,6 +364,11 @@ extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb, int newheadroom, int newtailroom, gfp_t priority); +extern intskb_to_sgvec(struct sk_buff *skb, + struct scatterlist *sg, int offset, + int len); +extern intskb_cow_data(struct sk_buff *skb, int tailbits, + struct sk_buff **trailer); extern intskb_pad(struct sk_buff *skb, int pad); #define dev_kfree_skb(a) kfree_skb(a) extern void skb_over_panic(struct sk_buff *skb, int len, diff --git a/include/net/esp.h b/include/net/esp.h index 713d039..d05d8d2 100644 --- a/include/net/esp.h +++ b/include/net/esp.h @@ -40,8 +40,6 @@ struct esp_data } auth; }; -extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len); -extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len); static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 702fa8f..f3ed31b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -2060,6 +2061,190 @@ void __init skb_init(void) NULL, NULL); } +/** + * skb_to_sgvec - Fill a scatter-gather list from a socket buffer + * @skb: Socket buffer containing the buffers to be mapped + * @sg: The scatter-gather list to map into + * @offset: The offset into the buffer's contents to start mapping + * @len: Length of buffer space to be mapped + * + * Fill the specified scatter-gather list with mappings/pointers into a + * region of the buffer space attached to a socket buffer. + */ +int +skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) +{ + int start = skb_headlen(skb); + int i, copy = start - offset; + int elt = 0; + + if (copy > 0) { + if (copy > len) + copy = len; + sg[elt].page = virt_to_page(skb->data + offset); + sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; + sg[elt].length = copy; + elt++; + if ((len -= copy) == 0) + return elt; + offset += copy; + } + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + skb_shinfo(skb)->frags[i].size; + if ((copy = end - offset) > 0) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + if (copy > len) + copy = len; + sg[elt].page = frag->page; + sg[elt].offset = frag->page_offset+offset-start; + sg[elt].length = copy; + elt++; + if (!(len -= copy)) + return elt; + offset += copy; + } + start = end; + } + + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + elt += skb_to_sgvec(list, sg+elt, offset - start, copy); + if ((len -= copy) == 0) + return elt; +
Re: [PATCH 2/5] AF_RXRPC: Move generic skbuff stuff from XFRM code to generic code [try #2]
On Fri, Mar 16, 2007 at 12:50:21PM +, David Howells wrote: > Move generic skbuff stuff from XFRM code to generic code so that AF_RXRPC can > use it too. > > Signed-Off-By: David Howells <[EMAIL PROTECTED]> > --- > > include/linux/skbuff.h |4 + > include/net/esp.h |2 - > net/core/skbuff.c | 173 > > net/xfrm/xfrm_algo.c | 169 --- > 4 files changed, 177 insertions(+), 171 deletions(-) > --- a/include/linux/skbuff.h > +++ b/include/linux/skbuff.h > @@ -1481,5 +1481,9 @@ static inline int skb_is_gso(const struct sk_buff *skb) > return skb_shinfo(skb)->gso_size; > } > > +struct scatterlist; normally we try to put structure forward declarations at the top of the header instead of spreading it around all over. > +extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int > offset, int len); > +extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff > **trailer); please make sure no line is longer than 80 characters. Also shouldn't prototypes normally be above inlines? Or at least grouped into logical areas? > +/* > + * fill a scatter-gather list with pointers into a part of a socket buffer > + * chain > + */ This could probably use a kdoc comment now that it's a public symbol. > +/* > + * Check that skb data bits are writable. If they are not, copy data > + * to newly created private area. If "tailbits" is given, make sure that > + * tailbits bytes beyond current end of skb are writable. > + * > + * Returns amount of elements of scatterlist to load for subsequent > + * transformations and pointer to writable trailer skb. > + */ Same here. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/5] AF_RXRPC: Move generic skbuff stuff from XFRM code to generic code [try #2]
Move generic skbuff stuff from XFRM code to generic code so that AF_RXRPC can use it too. Signed-Off-By: David Howells <[EMAIL PROTECTED]> --- include/linux/skbuff.h |4 + include/net/esp.h |2 - net/core/skbuff.c | 173 net/xfrm/xfrm_algo.c | 169 --- 4 files changed, 177 insertions(+), 171 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4ff3940..8701b12 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1481,5 +1481,9 @@ static inline int skb_is_gso(const struct sk_buff *skb) return skb_shinfo(skb)->gso_size; } +struct scatterlist; +extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len); +extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); + #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/include/net/esp.h b/include/net/esp.h index 713d039..d05d8d2 100644 --- a/include/net/esp.h +++ b/include/net/esp.h @@ -40,8 +40,6 @@ struct esp_data } auth; }; -extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len); -extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len); static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 820761f..a70c152 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -2059,6 +2060,175 @@ void __init skb_init(void) NULL, NULL); } +/* + * fill a scatter-gather list with pointers into a part of a socket buffer + * chain + */ +int +skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) +{ + int start = skb_headlen(skb); + int i, copy = start - offset; + int elt = 0; + + if (copy > 0) { + if (copy > len) + copy = len; + sg[elt].page = virt_to_page(skb->data + offset); + sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; + sg[elt].length = copy; + elt++; + if ((len -= copy) == 0) + return elt; + offset += copy; + } + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + skb_shinfo(skb)->frags[i].size; + if ((copy = end - offset) > 0) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + if (copy > len) + copy = len; + sg[elt].page = frag->page; + sg[elt].offset = frag->page_offset+offset-start; + sg[elt].length = copy; + elt++; + if (!(len -= copy)) + return elt; + offset += copy; + } + start = end; + } + + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + elt += skb_to_sgvec(list, sg+elt, offset - start, copy); + if ((len -= copy) == 0) + return elt; + offset += copy; + } + start = end; + } + } + BUG_ON(len); + return elt; +} + +/* + * Check that skb data bits are writable. If they are not, copy data + * to newly created private area. If "tailbits" is given, make sure that + * tailbits bytes beyond current end of skb are writable. + * + * Returns amount of elements of scatterlist to load for subsequent + * transformations and pointer to writable trailer skb. + */ +int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) +{ + int copyflag; + int elt; + struct sk_buff *skb1, **skb_p; + + /* If skb is cloned or its head is paged, reallocate +* head pulling out all the pages (pages are considered not writable +* at the moment even if they are anonymous). +*/ + if ((skb_cloned(skb) || skb_shinfo(skb)->nr_frags) && + __pskb_pull_tail(skb, skb_pagelen(skb)-skb_headlen(skb)) == NULL)
[PATCH 2/5] AF_RXRPC: Move generic skbuff stuff from XFRM code to generic code
Move generic skbuff stuff from XFRM code to generic code so that AF_RXRPC can use it too. Signed-Off-By: David Howells <[EMAIL PROTECTED]> --- include/linux/skbuff.h |4 + include/net/esp.h |2 - net/core/skbuff.c | 173 net/xfrm/xfrm_algo.c | 169 --- 4 files changed, 177 insertions(+), 171 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4ff3940..8701b12 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1481,5 +1481,9 @@ static inline int skb_is_gso(const struct sk_buff *skb) return skb_shinfo(skb)->gso_size; } +struct scatterlist; +extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len); +extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); + #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/include/net/esp.h b/include/net/esp.h index 713d039..d05d8d2 100644 --- a/include/net/esp.h +++ b/include/net/esp.h @@ -40,8 +40,6 @@ struct esp_data } auth; }; -extern int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len); -extern int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len); static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 820761f..a70c152 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -2059,6 +2060,175 @@ void __init skb_init(void) NULL, NULL); } +/* + * fill a scatter-gather list with pointers into a part of a socket buffer + * chain + */ +int +skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) +{ + int start = skb_headlen(skb); + int i, copy = start - offset; + int elt = 0; + + if (copy > 0) { + if (copy > len) + copy = len; + sg[elt].page = virt_to_page(skb->data + offset); + sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; + sg[elt].length = copy; + elt++; + if ((len -= copy) == 0) + return elt; + offset += copy; + } + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + skb_shinfo(skb)->frags[i].size; + if ((copy = end - offset) > 0) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + if (copy > len) + copy = len; + sg[elt].page = frag->page; + sg[elt].offset = frag->page_offset+offset-start; + sg[elt].length = copy; + elt++; + if (!(len -= copy)) + return elt; + offset += copy; + } + start = end; + } + + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + BUG_TRAP(start <= offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + elt += skb_to_sgvec(list, sg+elt, offset - start, copy); + if ((len -= copy) == 0) + return elt; + offset += copy; + } + start = end; + } + } + BUG_ON(len); + return elt; +} + +/* + * Check that skb data bits are writable. If they are not, copy data + * to newly created private area. If "tailbits" is given, make sure that + * tailbits bytes beyond current end of skb are writable. + * + * Returns amount of elements of scatterlist to load for subsequent + * transformations and pointer to writable trailer skb. + */ +int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) +{ + int copyflag; + int elt; + struct sk_buff *skb1, **skb_p; + + /* If skb is cloned or its head is paged, reallocate +* head pulling out all the pages (pages are considered not writable +* at the moment even if they are anonymous). +*/ + if ((skb_cloned(skb) || skb_shinfo(skb)->nr_frags) && + __pskb_pull_tail(skb, skb_pagelen(skb)-skb_headlen(skb)) == NULL)