Commit 3d0b527b authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: conntrack: add and use nf_ct_l4proto_log_invalid

We currently pass down the l4 protocol to the conntrack ->packet()
function, but the only user of this is the debug info decision.

Same information can be derived from struct nf_conn.
Add a wrapper for the previous patch that extracs the information
from nf_conn and passes it to nf_l4proto_log_invalid().
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent c4f3db15
...@@ -149,21 +149,23 @@ int nf_ct_port_nlattr_tuple_size(void); ...@@ -149,21 +149,23 @@ int nf_ct_port_nlattr_tuple_size(void);
extern const struct nla_policy nf_ct_port_nla_policy[]; extern const struct nla_policy nf_ct_port_nla_policy[];
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
#define LOG_INVALID(net, proto) \ __printf(3, 4) __cold
((net)->ct.sysctl_log_invalid == (proto) || \ void nf_ct_l4proto_log_invalid(const struct sk_buff *skb,
(net)->ct.sysctl_log_invalid == IPPROTO_RAW) const struct nf_conn *ct,
const char *fmt, ...);
__printf(5, 6) __cold __printf(5, 6) __cold
void nf_l4proto_log_invalid(const struct sk_buff *skb, void nf_l4proto_log_invalid(const struct sk_buff *skb,
struct net *net, struct net *net,
u16 pf, u8 protonum, u16 pf, u8 protonum,
const char *fmt, ...); const char *fmt, ...);
#else #else
static inline int LOG_INVALID(struct net *net, int proto) { return 0; }
static inline __printf(5, 6) __cold static inline __printf(5, 6) __cold
void nf_l4proto_log_invalid(const struct sk_buff *skb, struct net *net, void nf_l4proto_log_invalid(const struct sk_buff *skb, struct net *net,
u16 pf, u8 protonum, const char *fmt, ...) {} u16 pf, u8 protonum, const char *fmt, ...) {}
static inline __printf(3, 4) __cold
void nf_ct_l4proto_log_invalid(const struct sk_buff *skb,
const struct nf_conn *ct,
const char *fmt, ...) { }
#endif /* CONFIG_SYSCTL */ #endif /* CONFIG_SYSCTL */
#endif /*_NF_CONNTRACK_PROTOCOL_H*/ #endif /*_NF_CONNTRACK_PROTOCOL_H*/
...@@ -87,6 +87,29 @@ void nf_l4proto_log_invalid(const struct sk_buff *skb, ...@@ -87,6 +87,29 @@ void nf_l4proto_log_invalid(const struct sk_buff *skb,
va_end(args); va_end(args);
} }
EXPORT_SYMBOL_GPL(nf_l4proto_log_invalid); EXPORT_SYMBOL_GPL(nf_l4proto_log_invalid);
__printf(3, 4)
void nf_ct_l4proto_log_invalid(const struct sk_buff *skb,
const struct nf_conn *ct,
const char *fmt, ...)
{
struct va_format vaf;
struct net *net;
va_list args;
net = nf_ct_net(ct);
if (likely(net->ct.sysctl_log_invalid == 0))
return;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
nf_l4proto_log_invalid(skb, net, nf_ct_l3num(ct),
nf_ct_protonum(ct), "%pV", &vaf);
va_end(args);
}
EXPORT_SYMBOL_GPL(nf_ct_l4proto_log_invalid);
#endif #endif
const struct nf_conntrack_l4proto * const struct nf_conntrack_l4proto *
......
...@@ -428,13 +428,13 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, ...@@ -428,13 +428,13 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
default: default:
dn = dccp_pernet(net); dn = dccp_pernet(net);
if (dn->dccp_loose == 0) { if (dn->dccp_loose == 0) {
msg = "nf_ct_dccp: not picking up existing connection "; msg = "not picking up existing connection ";
goto out_invalid; goto out_invalid;
} }
case CT_DCCP_REQUEST: case CT_DCCP_REQUEST:
break; break;
case CT_DCCP_INVALID: case CT_DCCP_INVALID:
msg = "nf_ct_dccp: invalid state transition "; msg = "invalid state transition ";
goto out_invalid; goto out_invalid;
} }
...@@ -447,9 +447,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, ...@@ -447,9 +447,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
return true; return true;
out_invalid: out_invalid:
if (LOG_INVALID(net, IPPROTO_DCCP)) nf_ct_l4proto_log_invalid(skb, ct, "%s", msg);
nf_log_packet(net, nf_ct_l3num(ct), 0, skb, NULL, NULL,
NULL, "%s", msg);
return false; return false;
} }
...@@ -472,7 +470,6 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, ...@@ -472,7 +470,6 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
u_int8_t pf, u_int8_t pf,
unsigned int *timeouts) unsigned int *timeouts)
{ {
struct net *net = nf_ct_net(ct);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
struct dccp_hdr _dh, *dh; struct dccp_hdr _dh, *dh;
u_int8_t type, old_state, new_state; u_int8_t type, old_state, new_state;
...@@ -534,15 +531,11 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, ...@@ -534,15 +531,11 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
ct->proto.dccp.last_pkt = type; ct->proto.dccp.last_pkt = type;
spin_unlock_bh(&ct->lock); spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_DCCP)) nf_ct_l4proto_log_invalid(skb, ct, "%s", "invalid packet");
nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
"nf_ct_dccp: invalid packet ignored ");
return NF_ACCEPT; return NF_ACCEPT;
case CT_DCCP_INVALID: case CT_DCCP_INVALID:
spin_unlock_bh(&ct->lock); spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_DCCP)) nf_ct_l4proto_log_invalid(skb, ct, "%s", "invalid state transition");
nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
"nf_ct_dccp: invalid state transition ");
return -NF_ACCEPT; return -NF_ACCEPT;
} }
......
...@@ -702,9 +702,9 @@ static bool tcp_in_window(const struct nf_conn *ct, ...@@ -702,9 +702,9 @@ static bool tcp_in_window(const struct nf_conn *ct,
if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
tn->tcp_be_liberal) tn->tcp_be_liberal)
res = true; res = true;
if (!res && LOG_INVALID(net, IPPROTO_TCP)) if (!res) {
nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, nf_ct_l4proto_log_invalid(skb, ct,
"nf_ct_tcp: %s ", "%s",
before(seq, sender->td_maxend + 1) ? before(seq, sender->td_maxend + 1) ?
in_recv_win ? in_recv_win ?
before(sack, receiver->td_end + 1) ? before(sack, receiver->td_end + 1) ?
...@@ -713,6 +713,7 @@ static bool tcp_in_window(const struct nf_conn *ct, ...@@ -713,6 +713,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
: "ACK is over the upper bound (ACKed data not seen yet)" : "ACK is over the upper bound (ACKed data not seen yet)"
: "SEQ is under the lower bound (already ACKed data retransmitted)" : "SEQ is under the lower bound (already ACKed data retransmitted)"
: "SEQ is over the upper bound (over the window of the receiver)"); : "SEQ is over the upper bound (over the window of the receiver)");
}
} }
pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u " pr_debug("tcp_in_window: res=%u sender end=%u maxend=%u maxwin=%u "
...@@ -937,10 +938,8 @@ static int tcp_packet(struct nf_conn *ct, ...@@ -937,10 +938,8 @@ static int tcp_packet(struct nf_conn *ct,
IP_CT_EXP_CHALLENGE_ACK; IP_CT_EXP_CHALLENGE_ACK;
} }
spin_unlock_bh(&ct->lock); spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_TCP)) nf_ct_l4proto_log_invalid(skb, ct, "invalid packet ignored in "
nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL, "state %s ", tcp_conntrack_names[old_state]);
"nf_ct_tcp: invalid packet ignored in "
"state %s ", tcp_conntrack_names[old_state]);
return NF_ACCEPT; return NF_ACCEPT;
case TCP_CONNTRACK_MAX: case TCP_CONNTRACK_MAX:
/* Special case for SYN proxy: when the SYN to the server or /* Special case for SYN proxy: when the SYN to the server or
...@@ -962,9 +961,7 @@ static int tcp_packet(struct nf_conn *ct, ...@@ -962,9 +961,7 @@ static int tcp_packet(struct nf_conn *ct,
pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n", pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
dir, get_conntrack_index(th), old_state); dir, get_conntrack_index(th), old_state);
spin_unlock_bh(&ct->lock); spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_TCP)) nf_ct_l4proto_log_invalid(skb, ct, "invalid state");
nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: invalid state ");
return -NF_ACCEPT; return -NF_ACCEPT;
case TCP_CONNTRACK_TIME_WAIT: case TCP_CONNTRACK_TIME_WAIT:
/* RFC5961 compliance cause stack to send "challenge-ACK" /* RFC5961 compliance cause stack to send "challenge-ACK"
...@@ -979,9 +976,7 @@ static int tcp_packet(struct nf_conn *ct, ...@@ -979,9 +976,7 @@ static int tcp_packet(struct nf_conn *ct,
/* Detected RFC5961 challenge ACK */ /* Detected RFC5961 challenge ACK */
ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK; ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK;
spin_unlock_bh(&ct->lock); spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_TCP)) nf_ct_l4proto_log_invalid(skb, ct, "challenge-ack ignored");
nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: challenge-ACK ignored ");
return NF_ACCEPT; /* Don't change state */ return NF_ACCEPT; /* Don't change state */
} }
break; break;
...@@ -991,9 +986,7 @@ static int tcp_packet(struct nf_conn *ct, ...@@ -991,9 +986,7 @@ static int tcp_packet(struct nf_conn *ct,
&& before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) { && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) {
/* Invalid RST */ /* Invalid RST */
spin_unlock_bh(&ct->lock); spin_unlock_bh(&ct->lock);
if (LOG_INVALID(net, IPPROTO_TCP)) nf_ct_l4proto_log_invalid(skb, ct, "invalid rst");
nf_log_packet(net, pf, 0, skb, NULL, NULL,
NULL, "nf_ct_tcp: invalid RST ");
return -NF_ACCEPT; return -NF_ACCEPT;
} }
if (index == TCP_RST_SET if (index == TCP_RST_SET
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment