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 fecc6112c768a7aa0acf711fd89130eaf53d7fd1..f6e4325b330666b03f6049582ae80fcf762c1a75 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 f0896ba456c41eec368ef55b8854890d06b06a35..b2deeb2755a429ec5a2886522faf61fb5c6e7c19 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 b8065b72f56e8c85c29001c38f49ff3eb5bf249e..1890c5bc3c3cf9c9b54cb9efcb2affcd1b08de1e 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 97afdc0744e6dce6ba83943d136e4c6fb886fbf8..612bfd0737d519ea5db95b0a9469c738b234b368 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 ec47c12cd1379a85216675e83d562e488ebe711a..3fa7e1b22bdd40deda5079f141eafbc32faad516 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 2840a29b2e04d91c0cab54f67ba10d7d2bf30937..35fa265d1ce3d7d00961c75ba3d0d9355841f7e9 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 f5c66a7a4bf25fcdcd11edabc742c3520552550a..f2a4909815946fc355830d8b5bbb7800a208b748 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 30493beb611a1e43f3d7cb26afa14e88a935b894..fb3d49fb62fe697a892332408086e42f43b77ff2 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 d6e4ba5de916a3e57782764a4e3ac9fcf54e341d..71bac94770ddb6305a51e921cf196b021fe663ac 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 443cd306c0b0695f4e60660468d59ef64c1104f8..73fe2bd13fcfc5d68da601d24c8ec0ad03f74250 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 f2727475895e77939d48a9df72fec6017fd8de95..11d3c3b9aa18fbd5f6fa566437b79f32e71e0a45 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 403432988313567358871d5f85a5d71fc0385051..3cd127dd28959cf09f2fe8c76d4358b0572748fa 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;
        }