Upcoming requirements for new algs make it desirable to split out alg helper more cleanly.
Signed-off-by: Darrell Ball <[email protected]> --- lib/conntrack.c | 108 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 39 deletions(-) diff --git a/lib/conntrack.c b/lib/conntrack.c index f5a3aa9..e397941 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -67,6 +67,12 @@ enum ct_alg_mode { CT_TFTP_MODE, }; +enum ct_alg_ctl_type { + CT_ALG_CTL_NONE, + CT_ALG_CTL_FTP, + CT_ALG_CTL_TFTP, +}; + static bool conn_key_extract(struct conntrack *, struct dp_packet *, ovs_be16 dl_type, struct conn_lookup_ctx *, uint16_t zone); @@ -142,6 +148,13 @@ static enum ftp_ctl_pkt detect_ftp_ctl_type(const struct conn_lookup_ctx *ctx, struct dp_packet *pkt); +static struct ct_l4_proto *l4_protos[] = { + [IPPROTO_TCP] = &ct_proto_tcp, + [IPPROTO_UDP] = &ct_proto_other, + [IPPROTO_ICMP] = &ct_proto_icmp4, + [IPPROTO_ICMPV6] = &ct_proto_icmp6, +}; + static void handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, struct dp_packet *pkt, @@ -150,14 +163,23 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, static void handle_tftp_ctl(struct conntrack *ct, + const struct conn_lookup_ctx *ctx OVS_UNUSED, + struct dp_packet *pkt OVS_UNUSED, const struct conn *conn_for_expectation, - long long now); - -static struct ct_l4_proto *l4_protos[] = { - [IPPROTO_TCP] = &ct_proto_tcp, - [IPPROTO_UDP] = &ct_proto_other, - [IPPROTO_ICMP] = &ct_proto_icmp4, - [IPPROTO_ICMPV6] = &ct_proto_icmp6, + long long now, enum ftp_ctl_pkt ftp_ctl OVS_UNUSED, + bool nat OVS_UNUSED); + +typedef void (*alg_helper)(struct conntrack *ct, + const struct conn_lookup_ctx *ctx, + struct dp_packet *pkt, + const struct conn *conn_for_expectation, + long long now, enum ftp_ctl_pkt ftp_ctl, + bool nat); + +static alg_helper alg_helpers[] = { + [CT_ALG_CTL_NONE] = NULL, + [CT_ALG_CTL_FTP] = handle_ftp_ctl, + [CT_ALG_CTL_TFTP] = handle_tftp_ctl, }; long long ct_timeout_val[] = { @@ -434,35 +456,45 @@ get_ip_proto(const struct dp_packet *pkt) } static bool -is_ftp_ctl(const struct dp_packet *pkt) +is_ftp_ctl(const enum ct_alg_ctl_type ct_alg_ctl) { - uint8_t ip_proto = get_ip_proto(pkt); - struct tcp_header *th = dp_packet_l4(pkt); - - /* CT_IPPORT_FTP is used because IPPORT_FTP in not defined in OSX, - * at least in in.h. Since this value will never change, just remove - * the external dependency. */ -#define CT_IPPORT_FTP 21 - - return (ip_proto == IPPROTO_TCP && - (th->tcp_src == htons(CT_IPPORT_FTP) || - th->tcp_dst == htons(CT_IPPORT_FTP))); - + return ct_alg_ctl == CT_ALG_CTL_FTP; } -static bool -is_tftp_ctl(const struct dp_packet *pkt) +static enum ct_alg_ctl_type +get_alg_ctl_type(const struct dp_packet *pkt) { uint8_t ip_proto = get_ip_proto(pkt); struct udp_header *uh = dp_packet_l4(pkt); + struct tcp_header *th = dp_packet_l4(pkt); - /* CT_IPPORT_TFTP is used because IPPORT_TFTP in not defined in OSX, - * at least in in.h. Since this value will never change, remove + /* CT_IPPORT_FTP/TFTP is used because IPPORT_FTP/TFTP in not defined + * in OSX, at least in in.h. Since these values will never change, remove * the external dependency. */ -#define CT_IPPORT_TFTP 69 - return (ip_proto == IPPROTO_UDP && - uh->udp_dst == htons(CT_IPPORT_TFTP)); + enum { CT_IPPORT_FTP = 21 }; + enum { CT_IPPORT_TFTP = 69 }; + + if (ip_proto == IPPROTO_UDP && uh->udp_dst == htons(CT_IPPORT_TFTP)) { + return CT_ALG_CTL_TFTP; + } else if (ip_proto == IPPROTO_TCP && + (th->tcp_src == htons(CT_IPPORT_FTP) || + th->tcp_dst == htons(CT_IPPORT_FTP))) { + return CT_ALG_CTL_FTP; + } + return CT_ALG_CTL_NONE; +} +static void +handle_alg_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, + struct dp_packet *pkt, enum ct_alg_ctl_type ct_alg_ctl, + const struct conn *conn, long long now, bool nat, + const struct conn *conn_for_expectation) +{ + /* ALG control packet handling with expectation creation. */ + if (OVS_UNLIKELY(alg_helpers[ct_alg_ctl] && conn)) { + alg_helpers[ct_alg_ctl](ct, ctx, pkt, conn_for_expectation, now, + CT_FTP_CTL_INTEREST, nat); + } } static void @@ -1121,10 +1153,11 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, bool create_new_conn = false; struct conn conn_for_un_nat_copy; conn_for_un_nat_copy.conn_type = CT_CONN_TYPE_DEFAULT; - bool ftp_ctl = is_ftp_ctl(pkt); + + enum ct_alg_ctl_type ct_alg_ctl = get_alg_ctl_type(pkt); if (OVS_LIKELY(conn)) { - if (ftp_ctl) { + if (is_ftp_ctl(ct_alg_ctl)) { /* Keep sequence tracking in sync with the source of the * sequence skew. */ if (ctx->reply != conn->seq_skew_dir) { @@ -1187,9 +1220,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, set_label(pkt, conn, &setlabel[0], &setlabel[1]); } - bool tftp_ctl = is_tftp_ctl(pkt); struct conn conn_for_expectation; - if (OVS_UNLIKELY((ftp_ctl || tftp_ctl) && conn)) { + if (OVS_UNLIKELY((ct_alg_ctl != CT_ALG_CTL_NONE) && conn)) { conn_for_expectation = *conn; } @@ -1199,13 +1231,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, create_un_nat_conn(ct, &conn_for_un_nat_copy, now, !!alg_exp); } - /* FTP control packet handling with expectation creation. */ - if (OVS_UNLIKELY(ftp_ctl && conn)) { - handle_ftp_ctl(ct, ctx, pkt, &conn_for_expectation, - now, CT_FTP_CTL_INTEREST, !!nat_action_info); - } else if (OVS_UNLIKELY(tftp_ctl && conn)) { - handle_tftp_ctl(ct, &conn_for_expectation, now); - } + handle_alg_ctl(ct, ctx, pkt, ct_alg_ctl, conn, now, !!nat_action_info, + &conn_for_expectation); } /* Sends the packets in '*pkt_batch' through the connection tracker 'ct'. All @@ -3099,8 +3126,11 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, static void handle_tftp_ctl(struct conntrack *ct, + const struct conn_lookup_ctx *ctx OVS_UNUSED, + struct dp_packet *pkt OVS_UNUSED, const struct conn *conn_for_expectation, - long long now) + long long now, enum ftp_ctl_pkt ftp_ctl OVS_UNUSED, + bool nat OVS_UNUSED) { expectation_create(ct, conn_for_expectation->key.src.port, now, CT_TFTP_MODE, conn_for_expectation); -- 1.9.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
