summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrell Ball <dlu998@gmail.com>2017-08-06 10:51:15 -0700
committerBen Pfaff <blp@ovn.org>2017-08-07 11:17:42 -0700
commit7be77cb0d3378a71a18b0d1d0f3513da16f071c6 (patch)
treede8fe7fba8d34d1d2533cea89020069ec0ce1b31
parentbd5e81a0e596dd012d11824cce69b7c80ae107c5 (diff)
downloadopenvswitch-7be77cb0d3378a71a18b0d1d0f3513da16f071c6.tar.gz
Userspace Datapath: Add TFTP support.
Both ipv4 and ipv6 are supported. Also, NAT support is included. Signed-off-by: Darrell Ball <dlu998@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
-rw-r--r--include/sparse/netinet/in.h3
-rw-r--r--lib/conntrack.c39
2 files changed, 40 insertions, 2 deletions
diff --git a/include/sparse/netinet/in.h b/include/sparse/netinet/in.h
index 8a5b887bd..c28158ca0 100644
--- a/include/sparse/netinet/in.h
+++ b/include/sparse/netinet/in.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, 2014, 2015 Nicira, Inc.
+ * Copyright (c) 2011, 2013, 2014, 2015, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,6 +75,7 @@ struct sockaddr_in6 {
#define IPPROTO_SCTP 132
#define IPPORT_FTP 21
+#define IPPORT_TFTP 69
/* All the IP options documented in Linux ip(7). */
#define IP_ADD_MEMBERSHIP 35
diff --git a/lib/conntrack.c b/lib/conntrack.c
index 6c593b3ec..1c0e02351 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -64,6 +64,7 @@ enum ftp_ctl_pkt {
enum ct_alg_mode {
CT_FTP_MODE_ACTIVE,
CT_FTP_MODE_PASSIVE,
+ CT_TFTP_MODE,
};
static bool conn_key_extract(struct conntrack *, struct dp_packet *,
@@ -142,6 +143,11 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
const struct conn *conn_for_expectation,
long long now, enum ftp_ctl_pkt ftp_ctl, bool nat);
+static void
+handle_tftp_ctl(struct conntrack *ct,
+ 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,
@@ -384,6 +390,21 @@ is_ftp_ctl(const struct dp_packet *pkt)
}
+static bool
+is_tftp_ctl(const struct dp_packet *pkt)
+{
+ 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));
+
+}
+
static void
alg_exp_init_expiration(struct conntrack *ct,
struct alg_exp_node *alg_exp_node,
@@ -1080,8 +1101,9 @@ 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 (conn && ftp_ctl) {
+ if (conn && (ftp_ctl || tftp_ctl)) {
conn_for_expectation = *conn;
}
@@ -1095,6 +1117,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt,
if (OVS_UNLIKELY(conn && ftp_ctl)) {
handle_ftp_ctl(ct, ctx, pkt, &conn_for_expectation,
now, CT_FTP_CTL_INTEREST, !!nat_action_info);
+ } else if (OVS_UNLIKELY(conn && tftp_ctl)) {
+ handle_tftp_ctl(ct, &conn_for_expectation, now);
}
}
@@ -2399,6 +2423,7 @@ expectation_create(struct conntrack *ct,
switch (mode) {
case CT_FTP_MODE_ACTIVE:
+ case CT_TFTP_MODE:
src_addr = master_conn->rev_key.src.addr;
dst_addr = master_conn->rev_key.dst.addr;
alg_nat_repl_addr = master_conn->key.src.addr;
@@ -2691,6 +2716,7 @@ process_ftp_ctl_v4(struct conntrack *ct,
*v4_addr_rep = conn_for_expectation->key.dst.addr.ipv4_aligned;
conn_ipv4_addr = conn_for_expectation->rev_key.src.addr.ipv4_aligned;
break;
+ case CT_TFTP_MODE:
default:
OVS_NOT_REACHED();
}
@@ -2801,6 +2827,7 @@ process_ftp_ctl_v6(struct conntrack *ct,
case CT_FTP_MODE_PASSIVE:
*v6_addr_rep = conn_for_expectation->key.dst.addr;
break;
+ case CT_TFTP_MODE:
default:
OVS_NOT_REACHED();
}
@@ -2978,3 +3005,13 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
csum_continue(tcp_csum, th, tail - (char *) th - pad));
return;
}
+
+static void
+handle_tftp_ctl(struct conntrack *ct,
+ const struct conn *conn_for_expectation,
+ long long now)
+{
+ expectation_create(ct, conn_for_expectation->key.src.port, now,
+ CT_TFTP_MODE, conn_for_expectation);
+ return;
+}