Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nf_tables: extend tracing infrastructure

nft monitor mode can then decode and display this trace data.

Parts of LL/Network/Transport headers are provided as separate
attributes.

Otherwise, printing IP address data becomes virtually impossible
for userspace since in the case of the netdev family we really don't
want userspace to have to know all the possible link layer types
and/or sizes just to display/print an ip address.

We also don't want userspace to have to follow ipv6 header chains
to get the s/dport info, the kernel already did this work for us.

To avoid bloating nft_do_chain all data required for tracing is
encapsulated in nft_traceinfo.

The structure is initialized unconditionally(!) for each nft_do_chain
invocation.

This unconditionall call will be moved under a static key in a
followup patch.

With lots of help from Patrick McHardy and Pablo Neira.

Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
33d5a7b1 7ec3f7b4

+398 -19
+32
include/net/netfilter/nf_tables.h
··· 888 888 int nft_register_expr(struct nft_expr_type *); 889 889 void nft_unregister_expr(struct nft_expr_type *); 890 890 891 + int nft_verdict_dump(struct sk_buff *skb, int type, 892 + const struct nft_verdict *v); 893 + 894 + /** 895 + * struct nft_traceinfo - nft tracing information and state 896 + * 897 + * @pkt: pktinfo currently processed 898 + * @basechain: base chain currently processed 899 + * @chain: chain currently processed 900 + * @rule: rule that was evaluated 901 + * @verdict: verdict given by rule 902 + * @type: event type (enum nft_trace_types) 903 + * @packet_dumped: packet headers sent in a previous traceinfo message 904 + * @trace: other struct members are initialised 905 + */ 906 + struct nft_traceinfo { 907 + const struct nft_pktinfo *pkt; 908 + const struct nft_base_chain *basechain; 909 + const struct nft_chain *chain; 910 + const struct nft_rule *rule; 911 + const struct nft_verdict *verdict; 912 + enum nft_trace_types type; 913 + bool packet_dumped; 914 + bool trace; 915 + }; 916 + 917 + void nft_trace_init(struct nft_traceinfo *info, const struct nft_pktinfo *pkt, 918 + const struct nft_verdict *verdict, 919 + const struct nft_chain *basechain); 920 + 921 + void nft_trace_notify(struct nft_traceinfo *info); 922 + 891 923 #define nft_dereference(p) \ 892 924 nfnl_dereference(p, NFNL_SUBSYS_NFTABLES) 893 925
+52
include/uapi/linux/netfilter/nf_tables.h
··· 83 83 * @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes) 84 84 * @NFT_MSG_NEWGEN: announce a new generation, only for events (enum nft_gen_attributes) 85 85 * @NFT_MSG_GETGEN: get the rule-set generation (enum nft_gen_attributes) 86 + * @NFT_MSG_TRACE: trace event (enum nft_trace_attributes) 86 87 */ 87 88 enum nf_tables_msg_types { 88 89 NFT_MSG_NEWTABLE, ··· 103 102 NFT_MSG_DELSETELEM, 104 103 NFT_MSG_NEWGEN, 105 104 NFT_MSG_GETGEN, 105 + NFT_MSG_TRACE, 106 106 NFT_MSG_MAX, 107 107 }; 108 108 ··· 989 987 }; 990 988 #define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1) 991 989 990 + /** 991 + * enum nft_trace_attributes - nf_tables trace netlink attributes 992 + * 993 + * @NFTA_TRACE_TABLE: name of the table (NLA_STRING) 994 + * @NFTA_TRACE_CHAIN: name of the chain (NLA_STRING) 995 + * @NFTA_TRACE_RULE_HANDLE: numeric handle of the rule (NLA_U64) 996 + * @NFTA_TRACE_TYPE: type of the event (NLA_U32: nft_trace_types) 997 + * @NFTA_TRACE_VERDICT: verdict returned by hook (NLA_NESTED: nft_verdicts) 998 + * @NFTA_TRACE_ID: pseudo-id, same for each skb traced (NLA_U32) 999 + * @NFTA_TRACE_LL_HEADER: linklayer header (NLA_BINARY) 1000 + * @NFTA_TRACE_NETWORK_HEADER: network header (NLA_BINARY) 1001 + * @NFTA_TRACE_TRANSPORT_HEADER: transport header (NLA_BINARY) 1002 + * @NFTA_TRACE_IIF: indev ifindex (NLA_U32) 1003 + * @NFTA_TRACE_IIFTYPE: netdev->type of indev (NLA_U16) 1004 + * @NFTA_TRACE_OIF: outdev ifindex (NLA_U32) 1005 + * @NFTA_TRACE_OIFTYPE: netdev->type of outdev (NLA_U16) 1006 + * @NFTA_TRACE_MARK: nfmark (NLA_U32) 1007 + * @NFTA_TRACE_NFPROTO: nf protocol processed (NLA_U32) 1008 + * @NFTA_TRACE_POLICY: policy that decided fate of packet (NLA_U32) 1009 + */ 1010 + enum nft_trace_attibutes { 1011 + NFTA_TRACE_UNSPEC, 1012 + NFTA_TRACE_TABLE, 1013 + NFTA_TRACE_CHAIN, 1014 + NFTA_TRACE_RULE_HANDLE, 1015 + NFTA_TRACE_TYPE, 1016 + NFTA_TRACE_VERDICT, 1017 + NFTA_TRACE_ID, 1018 + NFTA_TRACE_LL_HEADER, 1019 + NFTA_TRACE_NETWORK_HEADER, 1020 + NFTA_TRACE_TRANSPORT_HEADER, 1021 + NFTA_TRACE_IIF, 1022 + NFTA_TRACE_IIFTYPE, 1023 + NFTA_TRACE_OIF, 1024 + NFTA_TRACE_OIFTYPE, 1025 + NFTA_TRACE_MARK, 1026 + NFTA_TRACE_NFPROTO, 1027 + NFTA_TRACE_POLICY, 1028 + __NFTA_TRACE_MAX 1029 + }; 1030 + #define NFTA_TRACE_MAX (__NFTA_TRACE_MAX - 1) 1031 + 1032 + enum nft_trace_types { 1033 + NFT_TRACETYPE_UNSPEC, 1034 + NFT_TRACETYPE_POLICY, 1035 + NFT_TRACETYPE_RETURN, 1036 + NFT_TRACETYPE_RULE, 1037 + __NFT_TRACETYPE_MAX 1038 + }; 1039 + #define NFT_TRACETYPE_MAX (__NFT_TRACETYPE_MAX - 1) 992 1040 #endif /* _LINUX_NF_TABLES_H */
+2
include/uapi/linux/netfilter/nfnetlink.h
··· 22 22 #define NFNLGRP_NFTABLES NFNLGRP_NFTABLES 23 23 NFNLGRP_ACCT_QUOTA, 24 24 #define NFNLGRP_ACCT_QUOTA NFNLGRP_ACCT_QUOTA 25 + NFNLGRP_NFTRACE, 26 + #define NFNLGRP_NFTRACE NFNLGRP_NFTRACE 25 27 __NFNLGRP_MAX, 26 28 }; 27 29 #define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
+1 -1
net/netfilter/Makefile
··· 67 67 obj-$(CONFIG_NETFILTER_SYNPROXY) += nf_synproxy_core.o 68 68 69 69 # nf_tables 70 - nf_tables-objs += nf_tables_core.o nf_tables_api.o 70 + nf_tables-objs += nf_tables_core.o nf_tables_api.o nf_tables_trace.o 71 71 nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o nft_dynset.o 72 72 nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o 73 73
+6 -6
net/netfilter/nf_tables_api.c
··· 4446 4446 } 4447 4447 } 4448 4448 4449 - static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data) 4449 + int nft_verdict_dump(struct sk_buff *skb, int type, const struct nft_verdict *v) 4450 4450 { 4451 4451 struct nlattr *nest; 4452 4452 4453 - nest = nla_nest_start(skb, NFTA_DATA_VERDICT); 4453 + nest = nla_nest_start(skb, type); 4454 4454 if (!nest) 4455 4455 goto nla_put_failure; 4456 4456 4457 - if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict.code))) 4457 + if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(v->code))) 4458 4458 goto nla_put_failure; 4459 4459 4460 - switch (data->verdict.code) { 4460 + switch (v->code) { 4461 4461 case NFT_JUMP: 4462 4462 case NFT_GOTO: 4463 4463 if (nla_put_string(skb, NFTA_VERDICT_CHAIN, 4464 - data->verdict.chain->name)) 4464 + v->chain->name)) 4465 4465 goto nla_put_failure; 4466 4466 } 4467 4467 nla_nest_end(skb, nest); ··· 4572 4572 err = nft_value_dump(skb, data, len); 4573 4573 break; 4574 4574 case NFT_DATA_VERDICT: 4575 - err = nft_verdict_dump(skb, data); 4575 + err = nft_verdict_dump(skb, NFTA_DATA_VERDICT, &data->verdict); 4576 4576 break; 4577 4577 default: 4578 4578 err = -EINVAL;
+33 -12
net/netfilter/nf_tables_core.c
··· 44 44 }, 45 45 }; 46 46 47 - static void __nft_trace_packet(const struct nft_pktinfo *pkt, 48 - const struct nft_chain *chain, 49 - int rulenum, enum nft_trace type) 47 + static noinline void __nft_trace_packet(struct nft_traceinfo *info, 48 + const struct nft_chain *chain, 49 + int rulenum, enum nft_trace type) 50 50 { 51 + const struct nft_pktinfo *pkt = info->pkt; 52 + 53 + if (!pkt->skb->nf_trace) 54 + return; 55 + 56 + info->chain = chain; 57 + info->type = type; 58 + 59 + nft_trace_notify(info); 60 + 51 61 nf_log_trace(pkt->net, pkt->pf, pkt->hook, pkt->skb, pkt->in, 52 62 pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ", 53 63 chain->table->name, chain->name, comments[type], 54 64 rulenum); 55 65 } 56 66 57 - static inline void nft_trace_packet(const struct nft_pktinfo *pkt, 67 + static inline void nft_trace_packet(struct nft_traceinfo *info, 58 68 const struct nft_chain *chain, 59 - int rulenum, enum nft_trace type) 69 + const struct nft_rule *rule, 70 + int rulenum, 71 + enum nft_trace_types type) 60 72 { 61 - if (unlikely(pkt->skb->nf_trace)) 62 - __nft_trace_packet(pkt, chain, rulenum, type); 73 + if (unlikely(info->trace)) { 74 + info->rule = rule; 75 + __nft_trace_packet(info, chain, rulenum, type); 76 + } 63 77 } 64 78 65 79 static void nft_cmp_fast_eval(const struct nft_expr *expr, ··· 135 121 struct nft_stats *stats; 136 122 int rulenum; 137 123 unsigned int gencursor = nft_genmask_cur(net); 124 + struct nft_traceinfo info; 138 125 126 + nft_trace_init(&info, pkt, &regs.verdict, basechain); 139 127 do_chain: 140 128 rulenum = 0; 141 129 rule = list_entry(&chain->rules, struct nft_rule, list); ··· 167 151 regs.verdict.code = NFT_CONTINUE; 168 152 continue; 169 153 case NFT_CONTINUE: 170 - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 154 + nft_trace_packet(&info, chain, rule, 155 + rulenum, NFT_TRACETYPE_RULE); 171 156 continue; 172 157 } 173 158 break; ··· 178 161 case NF_ACCEPT: 179 162 case NF_DROP: 180 163 case NF_QUEUE: 181 - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 164 + nft_trace_packet(&info, chain, rule, 165 + rulenum, NFT_TRACETYPE_RULE); 182 166 return regs.verdict.code; 183 167 } 184 168 ··· 192 174 stackptr++; 193 175 /* fall through */ 194 176 case NFT_GOTO: 195 - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 177 + nft_trace_packet(&info, chain, rule, 178 + rulenum, NFT_TRACETYPE_RULE); 196 179 197 180 chain = regs.verdict.chain; 198 181 goto do_chain; ··· 201 182 rulenum++; 202 183 /* fall through */ 203 184 case NFT_RETURN: 204 - nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RETURN); 185 + nft_trace_packet(&info, chain, rule, 186 + rulenum, NFT_TRACETYPE_RETURN); 205 187 break; 206 188 default: 207 189 WARN_ON(1); ··· 216 196 goto next_rule; 217 197 } 218 198 219 - nft_trace_packet(pkt, basechain, -1, NFT_TRACE_POLICY); 199 + nft_trace_packet(&info, basechain, NULL, -1, 200 + NFT_TRACETYPE_POLICY); 220 201 221 202 rcu_read_lock_bh(); 222 203 stats = this_cpu_ptr(rcu_dereference(nft_base_chain(basechain)->stats));
+271
net/netfilter/nf_tables_trace.c
··· 1 + /* 2 + * (C) 2015 Red Hat GmbH 3 + * Author: Florian Westphal <fw@strlen.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/hash.h> 12 + #include <linux/jhash.h> 13 + #include <linux/if_vlan.h> 14 + #include <linux/init.h> 15 + #include <linux/skbuff.h> 16 + #include <linux/netlink.h> 17 + #include <linux/netfilter.h> 18 + #include <linux/netfilter/nfnetlink.h> 19 + #include <linux/netfilter/nf_tables.h> 20 + #include <net/netfilter/nf_tables_core.h> 21 + #include <net/netfilter/nf_tables.h> 22 + 23 + #define NFT_TRACETYPE_LL_HSIZE 20 24 + #define NFT_TRACETYPE_NETWORK_HSIZE 40 25 + #define NFT_TRACETYPE_TRANSPORT_HSIZE 20 26 + 27 + static int trace_fill_id(struct sk_buff *nlskb, struct sk_buff *skb) 28 + { 29 + __be32 id; 30 + 31 + /* using skb address as ID results in a limited number of 32 + * values (and quick reuse). 33 + * 34 + * So we attempt to use as many skb members that will not 35 + * change while skb is with netfilter. 36 + */ 37 + id = (__be32)jhash_2words(hash32_ptr(skb), skb_get_hash(skb), 38 + skb->skb_iif); 39 + 40 + return nla_put_be32(nlskb, NFTA_TRACE_ID, id); 41 + } 42 + 43 + static int trace_fill_header(struct sk_buff *nlskb, u16 type, 44 + const struct sk_buff *skb, 45 + int off, unsigned int len) 46 + { 47 + struct nlattr *nla; 48 + 49 + if (len == 0) 50 + return 0; 51 + 52 + nla = nla_reserve(nlskb, type, len); 53 + if (!nla || skb_copy_bits(skb, off, nla_data(nla), len)) 54 + return -1; 55 + 56 + return 0; 57 + } 58 + 59 + static int nf_trace_fill_ll_header(struct sk_buff *nlskb, 60 + const struct sk_buff *skb) 61 + { 62 + struct vlan_ethhdr veth; 63 + int off; 64 + 65 + BUILD_BUG_ON(sizeof(veth) > NFT_TRACETYPE_LL_HSIZE); 66 + 67 + off = skb_mac_header(skb) - skb->data; 68 + if (off != -ETH_HLEN) 69 + return -1; 70 + 71 + if (skb_copy_bits(skb, off, &veth, ETH_HLEN)) 72 + return -1; 73 + 74 + veth.h_vlan_proto = skb->vlan_proto; 75 + veth.h_vlan_TCI = htons(skb_vlan_tag_get(skb)); 76 + veth.h_vlan_encapsulated_proto = skb->protocol; 77 + 78 + return nla_put(nlskb, NFTA_TRACE_LL_HEADER, sizeof(veth), &veth); 79 + } 80 + 81 + static int nf_trace_fill_dev_info(struct sk_buff *nlskb, 82 + const struct net_device *indev, 83 + const struct net_device *outdev) 84 + { 85 + if (indev) { 86 + if (nla_put_be32(nlskb, NFTA_TRACE_IIF, 87 + htonl(indev->ifindex))) 88 + return -1; 89 + 90 + if (nla_put_be16(nlskb, NFTA_TRACE_IIFTYPE, 91 + htons(indev->type))) 92 + return -1; 93 + } 94 + 95 + if (outdev) { 96 + if (nla_put_be32(nlskb, NFTA_TRACE_OIF, 97 + htonl(outdev->ifindex))) 98 + return -1; 99 + 100 + if (nla_put_be16(nlskb, NFTA_TRACE_OIFTYPE, 101 + htons(outdev->type))) 102 + return -1; 103 + } 104 + 105 + return 0; 106 + } 107 + 108 + static int nf_trace_fill_pkt_info(struct sk_buff *nlskb, 109 + const struct nft_pktinfo *pkt) 110 + { 111 + const struct sk_buff *skb = pkt->skb; 112 + unsigned int len = min_t(unsigned int, 113 + pkt->xt.thoff - skb_network_offset(skb), 114 + NFT_TRACETYPE_NETWORK_HSIZE); 115 + int off = skb_network_offset(skb); 116 + 117 + if (trace_fill_header(nlskb, NFTA_TRACE_NETWORK_HEADER, skb, off, len)) 118 + return -1; 119 + 120 + len = min_t(unsigned int, skb->len - pkt->xt.thoff, 121 + NFT_TRACETYPE_TRANSPORT_HSIZE); 122 + 123 + if (trace_fill_header(nlskb, NFTA_TRACE_TRANSPORT_HEADER, skb, 124 + pkt->xt.thoff, len)) 125 + return -1; 126 + 127 + if (!skb_mac_header_was_set(skb)) 128 + return 0; 129 + 130 + if (skb_vlan_tag_get(skb)) 131 + return nf_trace_fill_ll_header(nlskb, skb); 132 + 133 + off = skb_mac_header(skb) - skb->data; 134 + len = min_t(unsigned int, -off, NFT_TRACETYPE_LL_HSIZE); 135 + return trace_fill_header(nlskb, NFTA_TRACE_LL_HEADER, 136 + skb, off, len); 137 + } 138 + 139 + static int nf_trace_fill_rule_info(struct sk_buff *nlskb, 140 + const struct nft_traceinfo *info) 141 + { 142 + if (!info->rule) 143 + return 0; 144 + 145 + /* a continue verdict with ->type == RETURN means that this is 146 + * an implicit return (end of chain reached). 147 + * 148 + * Since no rule matched, the ->rule pointer is invalid. 149 + */ 150 + if (info->type == NFT_TRACETYPE_RETURN && 151 + info->verdict->code == NFT_CONTINUE) 152 + return 0; 153 + 154 + return nla_put_be64(nlskb, NFTA_TRACE_RULE_HANDLE, 155 + cpu_to_be64(info->rule->handle)); 156 + } 157 + 158 + void nft_trace_notify(struct nft_traceinfo *info) 159 + { 160 + const struct nft_pktinfo *pkt = info->pkt; 161 + struct nfgenmsg *nfmsg; 162 + struct nlmsghdr *nlh; 163 + struct sk_buff *skb; 164 + unsigned int size; 165 + int event = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_TRACE; 166 + 167 + if (!nfnetlink_has_listeners(pkt->net, NFNLGRP_NFTRACE)) 168 + return; 169 + 170 + size = nlmsg_total_size(sizeof(struct nfgenmsg)) + 171 + nla_total_size(NFT_TABLE_MAXNAMELEN) + 172 + nla_total_size(NFT_CHAIN_MAXNAMELEN) + 173 + nla_total_size(sizeof(__be64)) + /* rule handle */ 174 + nla_total_size(sizeof(__be32)) + /* trace type */ 175 + nla_total_size(0) + /* VERDICT, nested */ 176 + nla_total_size(sizeof(u32)) + /* verdict code */ 177 + nla_total_size(NFT_CHAIN_MAXNAMELEN) + /* jump target */ 178 + nla_total_size(sizeof(u32)) + /* id */ 179 + nla_total_size(NFT_TRACETYPE_LL_HSIZE) + 180 + nla_total_size(NFT_TRACETYPE_NETWORK_HSIZE) + 181 + nla_total_size(NFT_TRACETYPE_TRANSPORT_HSIZE) + 182 + nla_total_size(sizeof(u32)) + /* iif */ 183 + nla_total_size(sizeof(__be16)) + /* iiftype */ 184 + nla_total_size(sizeof(u32)) + /* oif */ 185 + nla_total_size(sizeof(__be16)) + /* oiftype */ 186 + nla_total_size(sizeof(u32)) + /* mark */ 187 + nla_total_size(sizeof(u32)) + /* nfproto */ 188 + nla_total_size(sizeof(u32)); /* policy */ 189 + 190 + skb = nlmsg_new(size, GFP_ATOMIC); 191 + if (!skb) 192 + return; 193 + 194 + nlh = nlmsg_put(skb, 0, 0, event, sizeof(struct nfgenmsg), 0); 195 + if (!nlh) 196 + goto nla_put_failure; 197 + 198 + nfmsg = nlmsg_data(nlh); 199 + nfmsg->nfgen_family = info->basechain->type->family; 200 + nfmsg->version = NFNETLINK_V0; 201 + nfmsg->res_id = 0; 202 + 203 + if (nla_put_be32(skb, NFTA_TRACE_NFPROTO, htonl(pkt->pf))) 204 + goto nla_put_failure; 205 + 206 + if (nla_put_be32(skb, NFTA_TRACE_TYPE, htonl(info->type))) 207 + goto nla_put_failure; 208 + 209 + if (trace_fill_id(skb, pkt->skb)) 210 + goto nla_put_failure; 211 + 212 + if (info->chain) { 213 + if (nla_put_string(skb, NFTA_TRACE_CHAIN, 214 + info->chain->name)) 215 + goto nla_put_failure; 216 + if (nla_put_string(skb, NFTA_TRACE_TABLE, 217 + info->chain->table->name)) 218 + goto nla_put_failure; 219 + } 220 + 221 + if (nf_trace_fill_rule_info(skb, info)) 222 + goto nla_put_failure; 223 + 224 + switch (info->type) { 225 + case NFT_TRACETYPE_UNSPEC: 226 + case __NFT_TRACETYPE_MAX: 227 + break; 228 + case NFT_TRACETYPE_RETURN: 229 + case NFT_TRACETYPE_RULE: 230 + if (nft_verdict_dump(skb, NFTA_TRACE_VERDICT, info->verdict)) 231 + goto nla_put_failure; 232 + break; 233 + case NFT_TRACETYPE_POLICY: 234 + if (nla_put_be32(skb, NFTA_TRACE_POLICY, 235 + info->basechain->policy)) 236 + goto nla_put_failure; 237 + break; 238 + } 239 + 240 + if (pkt->skb->mark && 241 + nla_put_be32(skb, NFTA_TRACE_MARK, htonl(pkt->skb->mark))) 242 + goto nla_put_failure; 243 + 244 + if (!info->packet_dumped) { 245 + if (nf_trace_fill_dev_info(skb, pkt->in, pkt->out)) 246 + goto nla_put_failure; 247 + 248 + if (nf_trace_fill_pkt_info(skb, pkt)) 249 + goto nla_put_failure; 250 + info->packet_dumped = true; 251 + } 252 + 253 + nlmsg_end(skb, nlh); 254 + nfnetlink_send(skb, pkt->net, 0, NFNLGRP_NFTRACE, 0, GFP_ATOMIC); 255 + return; 256 + 257 + nla_put_failure: 258 + WARN_ON_ONCE(1); 259 + kfree_skb(skb); 260 + } 261 + 262 + void nft_trace_init(struct nft_traceinfo *info, const struct nft_pktinfo *pkt, 263 + const struct nft_verdict *verdict, 264 + const struct nft_chain *chain) 265 + { 266 + info->basechain = nft_base_chain(chain); 267 + info->trace = true; 268 + info->packet_dumped = false; 269 + info->pkt = pkt; 270 + info->verdict = verdict; 271 + }
+1
net/netfilter/nfnetlink.c
··· 49 49 [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP, 50 50 [NFNLGRP_NFTABLES] = NFNL_SUBSYS_NFTABLES, 51 51 [NFNLGRP_ACCT_QUOTA] = NFNL_SUBSYS_ACCT, 52 + [NFNLGRP_NFTRACE] = NFNL_SUBSYS_NFTABLES, 52 53 }; 53 54 54 55 void nfnl_lock(__u8 subsys_id)