Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a4473a3 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: nf_tables: explicit nft_set_pktinfo() call from hook path



Instead of calling this function from the family specific variant, this
reduces the code size in the fast path for the netdev, bridge and inet
families. After this change, we must call nft_set_pktinfo() upfront from
the chain hook indirection.

Before:

   text    data     bss     dec     hex filename
   2145     208       0    2353     931 net/netfilter/nf_tables_netdev.o

After:

   text    data     bss     dec     hex filename
   2125     208       0    2333     91d net/netfilter/nf_tables_netdev.o

Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent fa45a760
Loading
Loading
Loading
Loading
+2 −10
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
	pkt->xt.state = state;
}

static inline void nft_set_pktinfo_proto_unspec(struct nft_pktinfo *pkt,
static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt,
					  struct sk_buff *skb)
{
	pkt->tprot_set = false;
@@ -63,14 +63,6 @@ static inline void nft_set_pktinfo_proto_unspec(struct nft_pktinfo *pkt,
	pkt->xt.fragoff = 0;
}

static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt,
					  struct sk_buff *skb,
					  const struct nf_hook_state *state)
{
	nft_set_pktinfo(pkt, skb, state);
	nft_set_pktinfo_proto_unspec(pkt, skb);
}

/**
 * 	struct nft_verdict - nf_tables verdict
 *
+8 −17
Original line number Diff line number Diff line
@@ -5,15 +5,11 @@
#include <net/netfilter/nf_tables.h>
#include <net/ip.h>

static inline void
nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
		     struct sk_buff *skb,
		     const struct nf_hook_state *state)
static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
					struct sk_buff *skb)
{
	struct iphdr *ip;

	nft_set_pktinfo(pkt, skb, state);

	ip = ip_hdr(pkt->skb);
	pkt->tprot_set = true;
	pkt->tprot = ip->protocol;
@@ -21,10 +17,8 @@ nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
	pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
}

static inline int
__nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
				struct sk_buff *skb,
				const struct nf_hook_state *state)
static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
						  struct sk_buff *skb)
{
	struct iphdr *iph, _iph;
	u32 len, thoff;
@@ -52,14 +46,11 @@ __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
	return 0;
}

static inline void
nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
			      struct sk_buff *skb,
			      const struct nf_hook_state *state)
static inline void nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt,
						 struct sk_buff *skb)
{
	nft_set_pktinfo(pkt, skb, state);
	if (__nft_set_pktinfo_ipv4_validate(pkt, skb, state) < 0)
		nft_set_pktinfo_proto_unspec(pkt, skb);
	if (__nft_set_pktinfo_ipv4_validate(pkt, skb) < 0)
		nft_set_pktinfo_unspec(pkt, skb);
}

extern struct nft_af_info nft_af_ipv4;
+9 −18
Original line number Diff line number Diff line
@@ -5,20 +5,16 @@
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <net/ipv6.h>

static inline void
nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
		     struct sk_buff *skb,
		     const struct nf_hook_state *state)
static inline void nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
					struct sk_buff *skb)
{
	unsigned int flags = IP6_FH_F_AUTH;
	int protohdr, thoff = 0;
	unsigned short frag_off;

	nft_set_pktinfo(pkt, skb, state);

	protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
	if (protohdr < 0) {
		nft_set_pktinfo_proto_unspec(pkt, skb);
		nft_set_pktinfo_unspec(pkt, skb);
		return;
	}

@@ -28,10 +24,8 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
	pkt->xt.fragoff = frag_off;
}

static inline int
__nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
				struct sk_buff *skb,
				const struct nf_hook_state *state)
static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
						  struct sk_buff *skb)
{
#if IS_ENABLED(CONFIG_IPV6)
	unsigned int flags = IP6_FH_F_AUTH;
@@ -68,14 +62,11 @@ __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
#endif
}

static inline void
nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
			      struct sk_buff *skb,
			      const struct nf_hook_state *state)
static inline void nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
						 struct sk_buff *skb)
{
	nft_set_pktinfo(pkt, skb, state);
	if (__nft_set_pktinfo_ipv6_validate(pkt, skb, state) < 0)
		nft_set_pktinfo_proto_unspec(pkt, skb);
	if (__nft_set_pktinfo_ipv6_validate(pkt, skb) < 0)
		nft_set_pktinfo_unspec(pkt, skb);
}

extern struct nft_af_info nft_af_ipv6;
+5 −3
Original line number Diff line number Diff line
@@ -25,15 +25,17 @@ nft_do_chain_bridge(void *priv,
{
	struct nft_pktinfo pkt;

	nft_set_pktinfo(&pkt, skb, state);

	switch (eth_hdr(skb)->h_proto) {
	case htons(ETH_P_IP):
		nft_set_pktinfo_ipv4_validate(&pkt, skb, state);
		nft_set_pktinfo_ipv4_validate(&pkt, skb);
		break;
	case htons(ETH_P_IPV6):
		nft_set_pktinfo_ipv6_validate(&pkt, skb, state);
		nft_set_pktinfo_ipv6_validate(&pkt, skb);
		break;
	default:
		nft_set_pktinfo_unspec(&pkt, skb, state);
		nft_set_pktinfo_unspec(&pkt, skb);
		break;
	}

+2 −1
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ nft_do_chain_arp(void *priv,
{
	struct nft_pktinfo pkt;

	nft_set_pktinfo_unspec(&pkt, skb, state);
	nft_set_pktinfo(&pkt, skb, state);
	nft_set_pktinfo_unspec(&pkt, skb);

	return nft_do_chain(&pkt, priv);
}
Loading