Exemple #1
0
static inline void
nft_netdev_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
			    const struct nf_hook_ops *ops, struct sk_buff *skb,
			    const struct nf_hook_state *state)
{
	struct iphdr *iph, _iph;
	u32 len, thoff;

	nft_set_pktinfo(pkt, ops, skb, state);

	iph = skb_header_pointer(skb, skb_network_offset(skb), sizeof(*iph),
				 &_iph);
	if (!iph)
		return;

	iph = ip_hdr(skb);
	if (iph->ihl < 5 || iph->version != 4)
		return;

	len = ntohs(iph->tot_len);
	thoff = iph->ihl * 4;
	if (skb->len < len)
		return;
	else if (len < thoff)
		return;

	pkt->tprot = iph->protocol;
	pkt->xt.thoff = thoff;
	pkt->xt.fragoff = ntohs(iph->frag_off) & IP_OFFSET;
}
Exemple #2
0
static inline void nft_netdev_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
					       const struct nf_hook_ops *ops,
					       struct sk_buff *skb,
					       const struct nf_hook_state *state)
{
	nft_set_pktinfo(pkt, ops, skb, state);
	__nft_netdev_set_pktinfo_ipv6(pkt, ops, skb, state);
}
Exemple #3
0
static inline void nft_bridge_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
					       const struct nf_hook_ops *ops,
					       struct sk_buff *skb,
					       const struct nf_hook_state *state)
{
	if (nft_bridge_iphdr_validate(skb))
		nft_set_pktinfo_ipv4(pkt, ops, skb, state);
	else
		nft_set_pktinfo(pkt, ops, skb, state);
}
Exemple #4
0
static unsigned int
nft_do_chain_arp(void *priv,
		  struct sk_buff *skb,
		  const struct nf_hook_state *state)
{
	struct nft_pktinfo pkt;

	nft_set_pktinfo(&pkt, skb, state);

	return nft_do_chain(&pkt, priv);
}
Exemple #5
0
static inline void nft_bridge_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
					       const struct nf_hook_ops *ops,
					       struct sk_buff *skb,
					       const struct nf_hook_state *state)
{
#if IS_ENABLED(CONFIG_IPV6)
	if (nft_bridge_ip6hdr_validate(skb) &&
	    nft_set_pktinfo_ipv6(pkt, ops, skb, state) == 0)
		return;
#endif
	nft_set_pktinfo(pkt, ops, skb, state);
}
Exemple #6
0
static unsigned int
nft_do_chain_bridge(const struct nf_hook_ops *ops,
		    struct sk_buff *skb,
		    const struct net_device *in,
		    const struct net_device *out,
		    int (*okfn)(struct sk_buff *))
{
	struct nft_pktinfo pkt;

	nft_set_pktinfo(&pkt, ops, skb, in, out);

	return nft_do_chain(&pkt, ops);
}
Exemple #7
0
static unsigned int
nft_do_chain_netdev(const struct nf_hook_ops *ops, struct sk_buff *skb,
		    const struct nf_hook_state *state)
{
	struct nft_pktinfo pkt;

	switch (eth_hdr(skb)->h_proto) {
	case htons(ETH_P_IP):
		nft_netdev_set_pktinfo_ipv4(&pkt, ops, skb, state);
		break;
	case htons(ETH_P_IPV6):
		nft_netdev_set_pktinfo_ipv6(&pkt, ops, skb, state);
		break;
	default:
		nft_set_pktinfo(&pkt, ops, skb, state);
		break;
	}

	return nft_do_chain(&pkt, ops);
}
Exemple #8
0
static unsigned int nft_nat_do_chain(void *priv, struct sk_buff *skb,
				     const struct nf_hook_state *state)
{
	struct nft_pktinfo pkt;

	nft_set_pktinfo(&pkt, skb, state);

	switch (state->pf) {
#ifdef CONFIG_NF_TABLES_IPV4
	case NFPROTO_IPV4:
		nft_set_pktinfo_ipv4(&pkt, skb);
		break;
#endif
#ifdef CONFIG_NF_TABLES_IPV6
	case NFPROTO_IPV6:
		nft_set_pktinfo_ipv6(&pkt, skb);
		break;
#endif
	default:
		break;
	}

	return nft_do_chain(&pkt, priv);
}