OSDN Git Service

netfilter: nf_tables: explicit nft_set_pktinfo() call from hook path
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 10 Dec 2017 00:43:14 +0000 (01:43 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 8 Jan 2018 17:01:15 +0000 (18:01 +0100)
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: Pablo Neira Ayuso <pablo@netfilter.org>
12 files changed:
include/net/netfilter/nf_tables.h
include/net/netfilter/nf_tables_ipv4.h
include/net/netfilter/nf_tables_ipv6.h
net/bridge/netfilter/nf_tables_bridge.c
net/ipv4/netfilter/nf_tables_arp.c
net/ipv4/netfilter/nf_tables_ipv4.c
net/ipv4/netfilter/nft_chain_nat_ipv4.c
net/ipv4/netfilter/nft_chain_route_ipv4.c
net/ipv6/netfilter/nf_tables_ipv6.c
net/ipv6/netfilter/nft_chain_nat_ipv6.c
net/ipv6/netfilter/nft_chain_route_ipv6.c
net/netfilter/nf_tables_netdev.c

index fecc611..f6e4325 100644 (file)
@@ -54,8 +54,8 @@ 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,
-                                               struct sk_buff *skb)
+static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt,
+                                         struct sk_buff *skb)
 {
        pkt->tprot_set = false;
        pkt->tprot = 0;
@@ -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
  *
index f0896ba..b2deeb2 100644 (file)
@@ -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;
index b8065b7..1890c5b 100644 (file)
@@ -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;
index 97afdc0..612bfd0 100644 (file)
@@ -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;
        }
 
index ec47c12..3fa7e1b 100644 (file)
@@ -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);
 }
index 2840a29..35fa265 100644 (file)
@@ -24,7 +24,8 @@ static unsigned int nft_do_chain_ipv4(void *priv,
 {
        struct nft_pktinfo pkt;
 
-       nft_set_pktinfo_ipv4(&pkt, skb, state);
+       nft_set_pktinfo(&pkt, skb, state);
+       nft_set_pktinfo_ipv4(&pkt, skb);
 
        return nft_do_chain(&pkt, priv);
 }
index f5c66a7..f2a4909 100644 (file)
@@ -33,7 +33,8 @@ static unsigned int nft_nat_do_chain(void *priv,
 {
        struct nft_pktinfo pkt;
 
-       nft_set_pktinfo_ipv4(&pkt, skb, state);
+       nft_set_pktinfo(&pkt, skb, state);
+       nft_set_pktinfo_ipv4(&pkt, skb);
 
        return nft_do_chain(&pkt, priv);
 }
index 30493be..fb3d49f 100644 (file)
@@ -38,7 +38,8 @@ static unsigned int nf_route_table_hook(void *priv,
            ip_hdrlen(skb) < sizeof(struct iphdr))
                return NF_ACCEPT;
 
-       nft_set_pktinfo_ipv4(&pkt, skb, state);
+       nft_set_pktinfo(&pkt, skb, state);
+       nft_set_pktinfo_ipv4(&pkt, skb);
 
        mark = skb->mark;
        iph = ip_hdr(skb);
index d6e4ba5..71bac94 100644 (file)
@@ -22,7 +22,8 @@ static unsigned int nft_do_chain_ipv6(void *priv,
 {
        struct nft_pktinfo pkt;
 
-       nft_set_pktinfo_ipv6(&pkt, skb, state);
+       nft_set_pktinfo(&pkt, skb, state);
+       nft_set_pktinfo_ipv6(&pkt, skb);
 
        return nft_do_chain(&pkt, priv);
 }
index 443cd30..73fe2bd 100644 (file)
@@ -31,7 +31,8 @@ static unsigned int nft_nat_do_chain(void *priv,
 {
        struct nft_pktinfo pkt;
 
-       nft_set_pktinfo_ipv6(&pkt, skb, state);
+       nft_set_pktinfo(&pkt, skb, state);
+       nft_set_pktinfo_ipv6(&pkt, skb);
 
        return nft_do_chain(&pkt, priv);
 }
index f272747..11d3c3b 100644 (file)
@@ -33,7 +33,8 @@ static unsigned int nf_route_table_hook(void *priv,
        u32 mark, flowlabel;
        int err;
 
-       nft_set_pktinfo_ipv6(&pkt, skb, state);
+       nft_set_pktinfo(&pkt, skb, state);
+       nft_set_pktinfo_ipv6(&pkt, skb);
 
        /* save source/dest address, mark, hoplimit, flowlabel, priority */
        memcpy(&saddr, &ipv6_hdr(skb)->saddr, sizeof(saddr));
index 4034329..3cd127d 100644 (file)
@@ -21,15 +21,17 @@ nft_do_chain_netdev(void *priv, struct sk_buff *skb,
 {
        struct nft_pktinfo pkt;
 
+       nft_set_pktinfo(&pkt, skb, state);
+
        switch (skb->protocol) {
        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;
        }