Skip to content

Commit

Permalink
conntrack: Disable algs by default.
Browse files Browse the repository at this point in the history
Presently, alg processing is enabled by default to better exercise code.
This is similar to kernels before 4.7 as well.  The recommended default
behavior in the newer kernels is to only process algs if a helper is
supplied in a conntrack rule.  The behavior is changed to match the
later kernels.

A test is extended to check that the control connection is still
created in such a case.

Signed-off-by: Darrell Ball <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
Acked-by: Aaron Conole <[email protected]>
  • Loading branch information
darball1 authored and blp committed Dec 11, 2017
1 parent bd7d93f commit 3a2a425
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
32 changes: 27 additions & 5 deletions lib/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ handle_alg_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
const struct conn *conn_for_expectation)
{
/* ALG control packet handling with expectation creation. */
if (OVS_UNLIKELY(alg_helpers[ct_alg_ctl] && conn)) {
if (OVS_UNLIKELY(alg_helpers[ct_alg_ctl] && conn && conn->alg)) {
alg_helpers[ct_alg_ctl](ct, ctx, pkt, conn_for_expectation, now,
CT_FTP_CTL_INTEREST, nat);
}
Expand Down Expand Up @@ -819,14 +819,35 @@ conn_clean(struct conntrack *ct, struct conn *conn,
}
}

static bool
ct_verify_helper(const char *helper, enum ct_alg_ctl_type ct_alg_ctl)
{
if (ct_alg_ctl == CT_ALG_CTL_NONE) {
return true;
} else if (helper) {
if ((ct_alg_ctl == CT_ALG_CTL_FTP) &&
!strncmp(helper, "ftp", strlen("ftp"))) {
return true;
} else if ((ct_alg_ctl == CT_ALG_CTL_TFTP) &&
!strncmp(helper, "tftp", strlen("tftp"))) {
return true;
} else {
return false;
}
} else {
return false;
}
}

/* This function is called with the bucket lock held. */
static struct conn *
conn_not_found(struct conntrack *ct, struct dp_packet *pkt,
struct conn_lookup_ctx *ctx, bool commit, long long now,
const struct nat_action_info_t *nat_action_info,
struct conn *conn_for_un_nat_copy,
const char *helper,
const struct alg_exp_node *alg_exp)
const struct alg_exp_node *alg_exp,
enum ct_alg_ctl_type ct_alg_ctl)
{
unsigned bucket = hash_to_bucket(ctx->hash);
struct conn *nc = NULL;
Expand Down Expand Up @@ -855,8 +876,8 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt,
nc->rev_key = nc->key;
conn_key_reverse(&nc->rev_key);

if (helper) {
nc->alg = xstrdup(helper);
if (ct_verify_helper(helper, ct_alg_ctl)) {
nc->alg = nullable_xstrdup(helper);
}

if (alg_exp) {
Expand Down Expand Up @@ -1238,7 +1259,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt,
ct_rwlock_unlock(&ct->resources_lock);

conn = conn_not_found(ct, pkt, ctx, commit, now, nat_action_info,
&conn_for_un_nat_copy, helper, alg_exp);
&conn_for_un_nat_copy, helper, alg_exp,
ct_alg_ctl);
}

write_ct_md(pkt, zone, conn, &ctx->key, alg_exp);
Expand Down
21 changes: 21 additions & 0 deletions tests/system-traffic.at
Original file line number Diff line number Diff line change
Expand Up @@ -2465,6 +2465,17 @@ table=1,in_port=2,tcp,ct_state=+trk+est,action=1
table=1,in_port=2,tcp,ct_state=+trk-new+rel,action=1
])

dnl flows3 is same as flows1, except no ALG is specified.
AT_DATA([flows3.txt], [dnl
table=0,priority=1,action=drop
table=0,priority=10,arp,action=normal
table=0,priority=10,icmp,action=normal
table=0,priority=100,in_port=1,tcp,action=ct(commit),2
table=0,priority=100,in_port=2,tcp,action=ct(table=1)
table=1,in_port=2,tcp,ct_state=+trk+est,action=1
table=1,in_port=2,tcp,ct_state=+trk+rel,action=1
])

AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows1.txt])

OVS_START_L7([at_ns0], [ftp])
Expand Down Expand Up @@ -2507,6 +2518,16 @@ AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>),helper=ftp
])

dnl Try the third set of flows, without alg specifier.
AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows3.txt])
AT_CHECK([ovs-appctl dpctl/flush-conntrack])

dnl FTP control requests from p0->p1 should work fine, but helper will not be assigned.
NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v -o wget0-3.log], [4])
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>)
])

OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP

Expand Down

0 comments on commit 3a2a425

Please sign in to comment.