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

netfilter: conntrack: pass hook state to log functions

The packet logger backend is unable to provide the incoming (or
outgoing) interface name because that information isn't available.

Pass the hook state, it contains the network namespace, the protocol
family, the network interfaces and other things.

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
62eec0d7 836382dc

+47 -44
+12 -8
include/net/netfilter/nf_conntrack_l4proto.h
··· 159 159 extern const struct nla_policy nf_ct_port_nla_policy[]; 160 160 161 161 #ifdef CONFIG_SYSCTL 162 - __printf(3, 4) __cold 162 + __printf(4, 5) __cold 163 163 void nf_ct_l4proto_log_invalid(const struct sk_buff *skb, 164 164 const struct nf_conn *ct, 165 + const struct nf_hook_state *state, 165 166 const char *fmt, ...); 166 - __printf(5, 6) __cold 167 + __printf(4, 5) __cold 167 168 void nf_l4proto_log_invalid(const struct sk_buff *skb, 168 - struct net *net, 169 - u16 pf, u8 protonum, 169 + const struct nf_hook_state *state, 170 + u8 protonum, 170 171 const char *fmt, ...); 171 172 #else 172 - static inline __printf(5, 6) __cold 173 - void nf_l4proto_log_invalid(const struct sk_buff *skb, struct net *net, 174 - u16 pf, u8 protonum, const char *fmt, ...) {} 175 - static inline __printf(3, 4) __cold 173 + static inline __printf(4, 5) __cold 174 + void nf_l4proto_log_invalid(const struct sk_buff *skb, 175 + const struct nf_hook_state *state, 176 + u8 protonum, 177 + const char *fmt, ...) {} 178 + static inline __printf(4, 5) __cold 176 179 void nf_ct_l4proto_log_invalid(const struct sk_buff *skb, 177 180 const struct nf_conn *ct, 181 + const struct nf_hook_state *state, 178 182 const char *fmt, ...) { } 179 183 #endif /* CONFIG_SYSCTL */ 180 184
+9 -7
net/netfilter/nf_conntrack_proto.c
··· 45 45 static DEFINE_MUTEX(nf_ct_proto_mutex); 46 46 47 47 #ifdef CONFIG_SYSCTL 48 - __printf(5, 6) 48 + __printf(4, 5) 49 49 void nf_l4proto_log_invalid(const struct sk_buff *skb, 50 - struct net *net, 51 - u16 pf, u8 protonum, 50 + const struct nf_hook_state *state, 51 + u8 protonum, 52 52 const char *fmt, ...) 53 53 { 54 + struct net *net = state->net; 54 55 struct va_format vaf; 55 56 va_list args; 56 57 ··· 63 62 vaf.fmt = fmt; 64 63 vaf.va = &args; 65 64 66 - nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, 67 - "nf_ct_proto_%d: %pV ", protonum, &vaf); 65 + nf_log_packet(net, state->pf, 0, skb, state->in, state->out, 66 + NULL, "nf_ct_proto_%d: %pV ", protonum, &vaf); 68 67 va_end(args); 69 68 } 70 69 EXPORT_SYMBOL_GPL(nf_l4proto_log_invalid); 71 70 72 - __printf(3, 4) 71 + __printf(4, 5) 73 72 void nf_ct_l4proto_log_invalid(const struct sk_buff *skb, 74 73 const struct nf_conn *ct, 74 + const struct nf_hook_state *state, 75 75 const char *fmt, ...) 76 76 { 77 77 struct va_format vaf; ··· 87 85 vaf.fmt = fmt; 88 86 vaf.va = &args; 89 87 90 - nf_l4proto_log_invalid(skb, net, nf_ct_l3num(ct), 88 + nf_l4proto_log_invalid(skb, state, 91 89 nf_ct_protonum(ct), "%pV", &vaf); 92 90 va_end(args); 93 91 }
+7 -7
net/netfilter/nf_conntrack_proto_dccp.c
··· 382 382 383 383 static noinline bool 384 384 dccp_new(struct nf_conn *ct, const struct sk_buff *skb, 385 - const struct dccp_hdr *dh) 385 + const struct dccp_hdr *dh, 386 + const struct nf_hook_state *hook_state) 386 387 { 387 388 struct net *net = nf_ct_net(ct); 388 389 struct nf_dccp_net *dn; ··· 415 414 return true; 416 415 417 416 out_invalid: 418 - nf_ct_l4proto_log_invalid(skb, ct, "%s", msg); 417 + nf_ct_l4proto_log_invalid(skb, ct, hook_state, "%s", msg); 419 418 return false; 420 419 } 421 420 ··· 465 464 } 466 465 return false; 467 466 out_invalid: 468 - nf_l4proto_log_invalid(skb, state->net, state->pf, 469 - IPPROTO_DCCP, "%s", msg); 467 + nf_l4proto_log_invalid(skb, state, IPPROTO_DCCP, "%s", msg); 470 468 return true; 471 469 } 472 470 ··· 488 488 return -NF_ACCEPT; 489 489 490 490 type = dh->dccph_type; 491 - if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh)) 491 + if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh, state)) 492 492 return -NF_ACCEPT; 493 493 494 494 if (type == DCCP_PKT_RESET && ··· 543 543 ct->proto.dccp.last_pkt = type; 544 544 545 545 spin_unlock_bh(&ct->lock); 546 - nf_ct_l4proto_log_invalid(skb, ct, "%s", "invalid packet"); 546 + nf_ct_l4proto_log_invalid(skb, ct, state, "%s", "invalid packet"); 547 547 return NF_ACCEPT; 548 548 case CT_DCCP_INVALID: 549 549 spin_unlock_bh(&ct->lock); 550 - nf_ct_l4proto_log_invalid(skb, ct, "%s", "invalid state transition"); 550 + nf_ct_l4proto_log_invalid(skb, ct, state, "%s", "invalid state transition"); 551 551 return -NF_ACCEPT; 552 552 } 553 553
+3 -4
net/netfilter/nf_conntrack_proto_icmp.c
··· 170 170 ct_daddr = &ct->tuplehash[dir].tuple.dst.u3; 171 171 if (!nf_inet_addr_cmp(outer_daddr, ct_daddr)) { 172 172 if (state->pf == AF_INET) { 173 - nf_l4proto_log_invalid(skb, state->net, state->pf, 173 + nf_l4proto_log_invalid(skb, state, 174 174 l4proto, 175 175 "outer daddr %pI4 != inner %pI4", 176 176 &outer_daddr->ip, &ct_daddr->ip); 177 177 } else if (state->pf == AF_INET6) { 178 - nf_l4proto_log_invalid(skb, state->net, state->pf, 178 + nf_l4proto_log_invalid(skb, state, 179 179 l4proto, 180 180 "outer daddr %pI6 != inner %pI6", 181 181 &outer_daddr->ip6, &ct_daddr->ip6); ··· 197 197 const struct nf_hook_state *state, 198 198 const char *msg) 199 199 { 200 - nf_l4proto_log_invalid(skb, state->net, state->pf, 201 - IPPROTO_ICMP, "%s", msg); 200 + nf_l4proto_log_invalid(skb, state, IPPROTO_ICMP, "%s", msg); 202 201 } 203 202 204 203 /* Small and modified version of icmp_rcv */
+1 -2
net/netfilter/nf_conntrack_proto_icmpv6.c
··· 126 126 const struct nf_hook_state *state, 127 127 const char *msg) 128 128 { 129 - nf_l4proto_log_invalid(skb, state->net, state->pf, 130 - IPPROTO_ICMPV6, "%s", msg); 129 + nf_l4proto_log_invalid(skb, state, IPPROTO_ICMPV6, "%s", msg); 131 130 } 132 131 133 132 int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
+1 -1
net/netfilter/nf_conntrack_proto_sctp.c
··· 351 351 } 352 352 return false; 353 353 out_invalid: 354 - nf_l4proto_log_invalid(skb, state->net, state->pf, IPPROTO_SCTP, "%s", logmsg); 354 + nf_l4proto_log_invalid(skb, state, IPPROTO_SCTP, "%s", logmsg); 355 355 return true; 356 356 } 357 357
+12 -11
net/netfilter/nf_conntrack_proto_tcp.c
··· 446 446 } 447 447 } 448 448 449 - static bool tcp_in_window(const struct nf_conn *ct, 450 - struct ip_ct_tcp *state, 449 + static bool tcp_in_window(struct nf_conn *ct, 451 450 enum ip_conntrack_dir dir, 452 451 unsigned int index, 453 452 const struct sk_buff *skb, 454 453 unsigned int dataoff, 455 - const struct tcphdr *tcph) 454 + const struct tcphdr *tcph, 455 + const struct nf_hook_state *hook_state) 456 456 { 457 + struct ip_ct_tcp *state = &ct->proto.tcp; 457 458 struct net *net = nf_ct_net(ct); 458 459 struct nf_tcp_net *tn = nf_tcp_pernet(net); 459 460 struct ip_ct_tcp_state *sender = &state->seen[dir]; ··· 671 670 tn->tcp_be_liberal) 672 671 res = true; 673 672 if (!res) { 674 - nf_ct_l4proto_log_invalid(skb, ct, 673 + nf_ct_l4proto_log_invalid(skb, ct, hook_state, 675 674 "%s", 676 675 before(seq, sender->td_maxend + 1) ? 677 676 in_recv_win ? ··· 711 710 const struct nf_hook_state *state, 712 711 const char *msg) 713 712 { 714 - nf_l4proto_log_invalid(skb, state->net, state->pf, IPPROTO_TCP, "%s", msg); 713 + nf_l4proto_log_invalid(skb, state, IPPROTO_TCP, "%s", msg); 715 714 } 716 715 717 716 /* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */ ··· 971 970 IP_CT_EXP_CHALLENGE_ACK; 972 971 } 973 972 spin_unlock_bh(&ct->lock); 974 - nf_ct_l4proto_log_invalid(skb, ct, 973 + nf_ct_l4proto_log_invalid(skb, ct, state, 975 974 "packet (index %d) in dir %d ignored, state %s", 976 975 index, dir, 977 976 tcp_conntrack_names[old_state]); ··· 996 995 pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n", 997 996 dir, get_conntrack_index(th), old_state); 998 997 spin_unlock_bh(&ct->lock); 999 - nf_ct_l4proto_log_invalid(skb, ct, "invalid state"); 998 + nf_ct_l4proto_log_invalid(skb, ct, state, "invalid state"); 1000 999 return -NF_ACCEPT; 1001 1000 case TCP_CONNTRACK_TIME_WAIT: 1002 1001 /* RFC5961 compliance cause stack to send "challenge-ACK" ··· 1011 1010 /* Detected RFC5961 challenge ACK */ 1012 1011 ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK; 1013 1012 spin_unlock_bh(&ct->lock); 1014 - nf_ct_l4proto_log_invalid(skb, ct, "challenge-ack ignored"); 1013 + nf_ct_l4proto_log_invalid(skb, ct, state, "challenge-ack ignored"); 1015 1014 return NF_ACCEPT; /* Don't change state */ 1016 1015 } 1017 1016 break; ··· 1036 1035 if (before(seq, ct->proto.tcp.seen[!dir].td_maxack)) { 1037 1036 /* Invalid RST */ 1038 1037 spin_unlock_bh(&ct->lock); 1039 - nf_ct_l4proto_log_invalid(skb, ct, "invalid rst"); 1038 + nf_ct_l4proto_log_invalid(skb, ct, state, "invalid rst"); 1040 1039 return -NF_ACCEPT; 1041 1040 } 1042 1041 ··· 1080 1079 break; 1081 1080 } 1082 1081 1083 - if (!tcp_in_window(ct, &ct->proto.tcp, dir, index, 1084 - skb, dataoff, th)) { 1082 + if (!tcp_in_window(ct, dir, index, 1083 + skb, dataoff, th, state)) { 1085 1084 spin_unlock_bh(&ct->lock); 1086 1085 return -NF_ACCEPT; 1087 1086 }
+2 -4
net/netfilter/nf_conntrack_proto_udp.c
··· 38 38 const struct nf_hook_state *state, 39 39 const char *msg) 40 40 { 41 - nf_l4proto_log_invalid(skb, state->net, state->pf, 42 - IPPROTO_UDP, "%s", msg); 41 + nf_l4proto_log_invalid(skb, state, IPPROTO_UDP, "%s", msg); 43 42 } 44 43 45 44 static bool udp_error(struct sk_buff *skb, ··· 129 130 const struct nf_hook_state *state, 130 131 const char *msg) 131 132 { 132 - nf_l4proto_log_invalid(skb, state->net, state->pf, 133 - IPPROTO_UDPLITE, "%s", msg); 133 + nf_l4proto_log_invalid(skb, state, IPPROTO_UDPLITE, "%s", msg); 134 134 } 135 135 136 136 static bool udplite_error(struct sk_buff *skb,