[ovs-dev] [patch v1 2/4] conntrack: Refactor algs.

Darrell Ball dball at vmware.com
Wed Nov 22 09:10:10 UTC 2017



On 11/20/17, 7:17 AM, "ovs-dev-bounces at openvswitch.org on behalf of Aaron Conole" <ovs-dev-bounces at openvswitch.org on behalf of aconole at redhat.com> wrote:

    Hi Darrell,
    
    Darrell Ball <dlu998 at gmail.com> writes:
    
    > Upcoming requirements for new algs make it necessary to split out
    > alg helper more cleanly.
    >
    > Signed-off-by: Darrell Ball <dlu998 at gmail.com>
    > ---
    
    Thanks for jumping on this so quickly.
    
    I think this and 3/4 should be an independent series.  They don't have
    much to do with 1/4 or 4/4, and logically could go in (and be developed)
    independently.

That true and I was lazy

    
    >  lib/conntrack.c | 73 ++++++++++++++++++++++++++++++++++-----------------------
    >  1 file changed, 44 insertions(+), 29 deletions(-)
    >
    > diff --git a/lib/conntrack.c b/lib/conntrack.c
    > index b8d0e77..7fbcfba 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,
    > +};
    > +
    
    Any reason to hardcode these?  I think we could have a struct like:

These don’t represent specific L4 port numbers but rather services.
    
        struct ct_alg_helper {
            const char *name;
            bool (*process_dp_pkt)(struct conn *ct,
                                   const struct conn *expectation,
                                   const struct dp_packet *pkt,
                                   bool nat);
            ... /* not sure of what else would be needed, yet */;
        };


I use an array of function pointers in V2.



    
    Then we can register statically with some table.  I think it will
    simplify the way conntrack helpers are added, as well as simplify the
    code in the 'framework'/'core' area.
    
    >  static bool conn_key_extract(struct conntrack *, struct dp_packet *,
    >                               ovs_be16 dl_type, struct conn_lookup_ctx *,
    >                               uint16_t zone);
    > @@ -432,33 +438,47 @@ 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)
    > +{
    > +    return ct_alg_ctl == CT_ALG_CTL_FTP;
    > +}
    > +
    > +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_FTP is used because IPPORT_FTP in not defined in OSX,
    > -     * at least in in.h. Since this value will never change, just 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_FTP 21
    > +    enum { CT_IPPORT_FTP = 21 };
    > +    enum { CT_IPPORT_TFTP = 69 };
    >  
    > -    return (ip_proto == IPPROTO_TCP &&
    > -            (th->tcp_src == htons(CT_IPPORT_FTP) ||
    > -             th->tcp_dst == htons(CT_IPPORT_FTP)));
    > +    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 bool
    > -is_tftp_ctl(const struct dp_packet *pkt)
    > +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)
    >  {
    > -     uint8_t ip_proto = get_ip_proto(pkt);
    > -     struct udp_header *uh = 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
    > -     * the external dependency. */
    > -#define CT_IPPORT_TFTP 69
    > -    return (ip_proto == IPPROTO_UDP &&
    > -            uh->udp_dst == htons(CT_IPPORT_TFTP));
    > +    /* ALG control packet handling with expectation creation. */
    > +    if (OVS_UNLIKELY((ct_alg_ctl == CT_ALG_CTL_FTP) && conn)) {
    > +        handle_ftp_ctl(ct, ctx, pkt, conn_for_expectation,
    > +                       now, CT_FTP_CTL_INTEREST, nat);
    > +    } else if (OVS_UNLIKELY((ct_alg_ctl == CT_ALG_CTL_TFTP) && conn)) {
    > +        handle_tftp_ctl(ct, conn_for_expectation, now);
    > +    }
    >  }
    >  
    >  static void
    > @@ -1110,10 +1130,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) {
    > @@ -1173,9 +1194,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;
    >      }
    >  
    > @@ -1185,13 +1205,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
    _______________________________________________
    dev mailing list
    dev at openvswitch.org
    https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwICAg&c=uilaK90D4TOVoH58JNXRgQ&r=BVhFA09CGX7JQ5Ih-uZnsw&m=zTGUQRcnmiRHSe87JfHsdwNINRD3YAEXfTzk7Bc__-c&s=1p6L_5H-HuTZb8TOAZo7CY96y7psxyjUqlS9XT7OpOA&e=
    



More information about the dev mailing list