Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
0ca743a5 PNA |
2 | #ifndef _NF_TABLES_IPV4_H_ |
3 | #define _NF_TABLES_IPV4_H_ | |
4 | ||
5 | #include <net/netfilter/nf_tables.h> | |
6 | #include <net/ip.h> | |
7 | ||
7a4473a3 PNA |
8 | static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt, |
9 | struct sk_buff *skb) | |
0ca743a5 PNA |
10 | { |
11 | struct iphdr *ip; | |
12 | ||
0ca743a5 | 13 | ip = ip_hdr(pkt->skb); |
beac5afa | 14 | pkt->tprot_set = true; |
4566bf27 PM |
15 | pkt->tprot = ip->protocol; |
16 | pkt->xt.thoff = ip_hdrlen(pkt->skb); | |
0ca743a5 PNA |
17 | pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET; |
18 | } | |
19 | ||
7a4473a3 PNA |
20 | static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt, |
21 | struct sk_buff *skb) | |
ddc8b602 PNA |
22 | { |
23 | struct iphdr *iph, _iph; | |
24 | u32 len, thoff; | |
25 | ||
26 | iph = skb_header_pointer(skb, skb_network_offset(skb), sizeof(*iph), | |
27 | &_iph); | |
28 | if (!iph) | |
29 | return -1; | |
30 | ||
ddc8b602 PNA |
31 | if (iph->ihl < 5 || iph->version != 4) |
32 | return -1; | |
33 | ||
34 | len = ntohs(iph->tot_len); | |
35 | thoff = iph->ihl * 4; | |
36 | if (skb->len < len) | |
37 | return -1; | |
38 | else if (len < thoff) | |
39 | return -1; | |
40 | ||
41 | pkt->tprot_set = true; | |
42 | pkt->tprot = iph->protocol; | |
43 | pkt->xt.thoff = thoff; | |
44 | pkt->xt.fragoff = ntohs(iph->frag_off) & IP_OFFSET; | |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
7a4473a3 PNA |
49 | static inline void nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt, |
50 | struct sk_buff *skb) | |
ddc8b602 | 51 | { |
7a4473a3 PNA |
52 | if (__nft_set_pktinfo_ipv4_validate(pkt, skb) < 0) |
53 | nft_set_pktinfo_unspec(pkt, skb); | |
ddc8b602 PNA |
54 | } |
55 | ||
0ca743a5 | 56 | #endif |