net: ipv6: add skbuff fraglist splitter

This patch adds the skbuff fraglist split iterator. This API provides an
iterator to transform the fraglist into single skbuff objects, it
consists of:

* ip6_fraglist_init(), that initializes the internal state of the
  fraglist iterator.
* ip6_fraglist_prepare(), that restores the IPv6 header on the fragment.
* ip6_fraglist_next(), that retrieves the fragment from the fraglist and
  updates the internal state of the iterator to point to the next
  fragment in the fraglist.

The ip6_fraglist_iter object stores the internal state of the iterator.

This code has been extracted from ip6_fragment(). Symbols are also
exported to allow to reuse this iterator from the bridge codepath to
build its own refragmentation routine by reusing the existing codebase.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Pablo Neira Ayuso
2019-05-29 13:25:32 +02:00
committed by David S. Miller
parent c8b17be0b7
commit 0feca6190f
2 changed files with 102 additions and 55 deletions

View File

@@ -154,6 +154,31 @@ struct frag_hdr {
#define IP6_MF 0x0001
#define IP6_OFFSET 0xFFF8
struct ip6_fraglist_iter {
struct ipv6hdr *tmp_hdr;
struct sk_buff *frag_list;
struct sk_buff *frag;
int offset;
unsigned int hlen;
__be32 frag_id;
u8 nexthdr;
};
int ip6_fraglist_init(struct sk_buff *skb, unsigned int hlen, u8 *prevhdr,
u8 nexthdr, __be32 frag_id,
struct ip6_fraglist_iter *iter);
void ip6_fraglist_prepare(struct sk_buff *skb, struct ip6_fraglist_iter *iter);
static inline struct sk_buff *ip6_fraglist_next(struct ip6_fraglist_iter *iter)
{
struct sk_buff *skb = iter->frag;
iter->frag = skb->next;
skb_mark_not_on_list(skb);
return skb;
}
#define IP6_REPLY_MARK(net, mark) \
((net)->ipv6.sysctl.fwmark_reflect ? (mark) : 0)