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

netfilter: conntrack: no need to pass ctinfo to error handler

It is never accessed for reading and the only places that write to it
are the icmp(6) handlers, which also set skb->nfct (and skb->nfctinfo).

The conntrack core specifically checks for attached skb->nfct after
->error() invocation and returns early in this case.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
11df4b76 10435c11

+16 -20
+1 -1
include/net/netfilter/nf_conntrack_l4proto.h
··· 55 55 void (*destroy)(struct nf_conn *ct); 56 56 57 57 int (*error)(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, 58 - unsigned int dataoff, enum ip_conntrack_info *ctinfo, 58 + unsigned int dataoff, 59 59 u_int8_t pf, unsigned int hooknum); 60 60 61 61 /* Print out the per-protocol part of the tuple. Return like seq_* */
+6 -6
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
··· 128 128 /* Returns conntrack if it dealt with ICMP, and filled in skb fields */ 129 129 static int 130 130 icmp_error_message(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, 131 - enum ip_conntrack_info *ctinfo, 132 131 unsigned int hooknum) 133 132 { 134 133 struct nf_conntrack_tuple innertuple, origtuple; 135 134 const struct nf_conntrack_l4proto *innerproto; 136 135 const struct nf_conntrack_tuple_hash *h; 137 136 const struct nf_conntrack_zone *zone; 137 + enum ip_conntrack_info ctinfo; 138 138 struct nf_conntrack_zone tmp; 139 139 140 140 NF_CT_ASSERT(skb->nfct == NULL); ··· 160 160 return -NF_ACCEPT; 161 161 } 162 162 163 - *ctinfo = IP_CT_RELATED; 163 + ctinfo = IP_CT_RELATED; 164 164 165 165 h = nf_conntrack_find_get(net, zone, &innertuple); 166 166 if (!h) { ··· 169 169 } 170 170 171 171 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) 172 - *ctinfo += IP_CT_IS_REPLY; 172 + ctinfo += IP_CT_IS_REPLY; 173 173 174 174 /* Update skb to refer to this connection */ 175 175 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general; 176 - skb->nfctinfo = *ctinfo; 176 + skb->nfctinfo = ctinfo; 177 177 return NF_ACCEPT; 178 178 } 179 179 ··· 181 181 static int 182 182 icmp_error(struct net *net, struct nf_conn *tmpl, 183 183 struct sk_buff *skb, unsigned int dataoff, 184 - enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum) 184 + u8 pf, unsigned int hooknum) 185 185 { 186 186 const struct icmphdr *icmph; 187 187 struct icmphdr _ih; ··· 225 225 icmph->type != ICMP_REDIRECT) 226 226 return NF_ACCEPT; 227 227 228 - return icmp_error_message(net, tmpl, skb, ctinfo, hooknum); 228 + return icmp_error_message(net, tmpl, skb, hooknum); 229 229 } 230 230 231 231 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
+6 -6
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
··· 145 145 icmpv6_error_message(struct net *net, struct nf_conn *tmpl, 146 146 struct sk_buff *skb, 147 147 unsigned int icmp6off, 148 - enum ip_conntrack_info *ctinfo, 149 148 unsigned int hooknum) 150 149 { 151 150 struct nf_conntrack_tuple intuple, origtuple; 152 151 const struct nf_conntrack_tuple_hash *h; 153 152 const struct nf_conntrack_l4proto *inproto; 153 + enum ip_conntrack_info ctinfo; 154 154 struct nf_conntrack_zone tmp; 155 155 156 156 NF_CT_ASSERT(skb->nfct == NULL); ··· 176 176 return -NF_ACCEPT; 177 177 } 178 178 179 - *ctinfo = IP_CT_RELATED; 179 + ctinfo = IP_CT_RELATED; 180 180 181 181 h = nf_conntrack_find_get(net, nf_ct_zone_tmpl(tmpl, skb, &tmp), 182 182 &intuple); ··· 185 185 return -NF_ACCEPT; 186 186 } else { 187 187 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) 188 - *ctinfo += IP_CT_IS_REPLY; 188 + ctinfo += IP_CT_IS_REPLY; 189 189 } 190 190 191 191 /* Update skb to refer to this connection */ 192 192 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general; 193 - skb->nfctinfo = *ctinfo; 193 + skb->nfctinfo = ctinfo; 194 194 return NF_ACCEPT; 195 195 } 196 196 197 197 static int 198 198 icmpv6_error(struct net *net, struct nf_conn *tmpl, 199 199 struct sk_buff *skb, unsigned int dataoff, 200 - enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum) 200 + u8 pf, unsigned int hooknum) 201 201 { 202 202 const struct icmp6hdr *icmp6h; 203 203 struct icmp6hdr _ih; ··· 232 232 if (icmp6h->icmp6_type >= 128) 233 233 return NF_ACCEPT; 234 234 235 - return icmpv6_error_message(net, tmpl, skb, dataoff, ctinfo, hooknum); 235 + return icmpv6_error_message(net, tmpl, skb, dataoff, hooknum); 236 236 } 237 237 238 238 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
+1 -2
net/netfilter/nf_conntrack_core.c
··· 1326 1326 * inverse of the return code tells to the netfilter 1327 1327 * core what to do with the packet. */ 1328 1328 if (l4proto->error != NULL) { 1329 - ret = l4proto->error(net, tmpl, skb, dataoff, &ctinfo, 1330 - pf, hooknum); 1329 + ret = l4proto->error(net, tmpl, skb, dataoff, pf, hooknum); 1331 1330 if (ret <= 0) { 1332 1331 NF_CT_STAT_INC_ATOMIC(net, error); 1333 1332 NF_CT_STAT_INC_ATOMIC(net, invalid);
-1
net/netfilter/nf_conntrack_proto_dccp.c
··· 561 561 562 562 static int dccp_error(struct net *net, struct nf_conn *tmpl, 563 563 struct sk_buff *skb, unsigned int dataoff, 564 - enum ip_conntrack_info *ctinfo, 565 564 u_int8_t pf, unsigned int hooknum) 566 565 { 567 566 struct dccp_hdr _dh, *dh;
+1 -1
net/netfilter/nf_conntrack_proto_sctp.c
··· 508 508 } 509 509 510 510 static int sctp_error(struct net *net, struct nf_conn *tpl, struct sk_buff *skb, 511 - unsigned int dataoff, enum ip_conntrack_info *ctinfo, 511 + unsigned int dataoff, 512 512 u8 pf, unsigned int hooknum) 513 513 { 514 514 const struct sctphdr *sh;
-1
net/netfilter/nf_conntrack_proto_tcp.c
··· 750 750 static int tcp_error(struct net *net, struct nf_conn *tmpl, 751 751 struct sk_buff *skb, 752 752 unsigned int dataoff, 753 - enum ip_conntrack_info *ctinfo, 754 753 u_int8_t pf, 755 754 unsigned int hooknum) 756 755 {
+1 -2
net/netfilter/nf_conntrack_proto_udp.c
··· 112 112 static int udplite_error(struct net *net, struct nf_conn *tmpl, 113 113 struct sk_buff *skb, 114 114 unsigned int dataoff, 115 - enum ip_conntrack_info *ctinfo, 116 115 u8 pf, unsigned int hooknum) 117 116 { 118 117 unsigned int udplen = skb->len - dataoff; ··· 161 162 #endif 162 163 163 164 static int udp_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, 164 - unsigned int dataoff, enum ip_conntrack_info *ctinfo, 165 + unsigned int dataoff, 165 166 u_int8_t pf, 166 167 unsigned int hooknum) 167 168 {