summaryrefslogtreecommitdiff
path: root/lib/conntrack.c
diff options
context:
space:
mode:
authorDarrell Ball <dlu998@gmail.com>2019-02-14 13:15:08 -0800
committerBen Pfaff <blp@ovn.org>2019-02-14 14:21:45 -0800
commitcda1b109c296ac7a8931ce374081bb54eee7aa10 (patch)
tree3561026c68f80e8726223716fd9781cbc1262516 /lib/conntrack.c
parent763b40b0f70251062f5f8e62b54e97041ce08a47 (diff)
downloadopenvswitch-cda1b109c296ac7a8931ce374081bb54eee7aa10.tar.gz
conntrack: Simplify 'ct_addr'.
Remove the struct wrapper and remove the unneeded union members. There may even be a portability benefit here because of the type punning. Signed-off-by: Darrell Ball <dlu998@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib/conntrack.c')
-rw-r--r--lib/conntrack.c154
1 files changed, 73 insertions, 81 deletions
diff --git a/lib/conntrack.c b/lib/conntrack.c
index 0b9627902..4d7655252 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -273,10 +273,10 @@ ct_print_conn_info(const struct conn *c, const char *log_msg,
"%"PRIu16"/%"PRIu16" zone/rev zone "
"%"PRIu16"/%"PRIu16" nw_proto/rev nw_proto "
"%"PRIu8"/%"PRIu8, log_msg,
- IP_ARGS(c->key.src.addr.ipv4_aligned),
- IP_ARGS(c->key.dst.addr.ipv4_aligned),
- IP_ARGS(c->rev_key.src.addr.ipv4_aligned),
- IP_ARGS(c->rev_key.dst.addr.ipv4_aligned),
+ IP_ARGS(c->key.src.addr.ipv4),
+ IP_ARGS(c->key.dst.addr.ipv4),
+ IP_ARGS(c->rev_key.src.addr.ipv4),
+ IP_ARGS(c->rev_key.dst.addr.ipv4),
ntohs(c->key.src.port), ntohs(c->key.dst.port),
ntohs(c->rev_key.src.port), ntohs(c->rev_key.dst.port),
c->key.zone, c->rev_key.zone, c->key.nw_proto,
@@ -423,8 +423,8 @@ write_ct_md(struct dp_packet *pkt, uint16_t zone, const struct conn *conn,
if (key) {
if (key->dl_type == htons(ETH_TYPE_IP)) {
pkt->md.ct_orig_tuple.ipv4 = (struct ovs_key_ct_tuple_ipv4) {
- key->src.addr.ipv4_aligned,
- key->dst.addr.ipv4_aligned,
+ key->src.addr.ipv4,
+ key->dst.addr.ipv4,
key->nw_proto != IPPROTO_ICMP
? key->src.port : htons(key->src.icmp_type),
key->nw_proto != IPPROTO_ICMP
@@ -434,8 +434,8 @@ write_ct_md(struct dp_packet *pkt, uint16_t zone, const struct conn *conn,
} else {
pkt->md.ct_orig_tuple_ipv6 = true;
pkt->md.ct_orig_tuple.ipv6 = (struct ovs_key_ct_tuple_ipv6) {
- key->src.addr.ipv6_aligned,
- key->dst.addr.ipv6_aligned,
+ key->src.addr.ipv6,
+ key->dst.addr.ipv6,
key->nw_proto != IPPROTO_ICMPV6
? key->src.port : htons(key->src.icmp_type),
key->nw_proto != IPPROTO_ICMPV6
@@ -559,13 +559,12 @@ nat_packet(struct dp_packet *pkt, const struct conn *conn, bool related)
if (conn->key.dl_type == htons(ETH_TYPE_IP)) {
struct ip_header *nh = dp_packet_l3(pkt);
packet_set_ipv4_addr(pkt, &nh->ip_src,
- conn->rev_key.dst.addr.ipv4_aligned);
+ conn->rev_key.dst.addr.ipv4);
} else {
struct ovs_16aligned_ip6_hdr *nh6 = dp_packet_l3(pkt);
packet_set_ipv6_addr(pkt, conn->key.nw_proto,
nh6->ip6_src.be32,
- &conn->rev_key.dst.addr.ipv6_aligned,
- true);
+ &conn->rev_key.dst.addr.ipv6, true);
}
if (!related) {
pat_packet(pkt, conn);
@@ -575,13 +574,12 @@ nat_packet(struct dp_packet *pkt, const struct conn *conn, bool related)
if (conn->key.dl_type == htons(ETH_TYPE_IP)) {
struct ip_header *nh = dp_packet_l3(pkt);
packet_set_ipv4_addr(pkt, &nh->ip_dst,
- conn->rev_key.src.addr.ipv4_aligned);
+ conn->rev_key.src.addr.ipv4);
} else {
struct ovs_16aligned_ip6_hdr *nh6 = dp_packet_l3(pkt);
packet_set_ipv6_addr(pkt, conn->key.nw_proto,
nh6->ip6_dst.be32,
- &conn->rev_key.src.addr.ipv6_aligned,
- true);
+ &conn->rev_key.src.addr.ipv6, true);
}
if (!related) {
pat_packet(pkt, conn);
@@ -658,10 +656,10 @@ reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn)
if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
packet_set_ipv4_addr(pkt, &inner_l3->ip_src,
- conn->key.src.addr.ipv4_aligned);
+ conn->key.src.addr.ipv4);
} else if (conn->nat_info->nat_action & NAT_ACTION_DST) {
packet_set_ipv4_addr(pkt, &inner_l3->ip_dst,
- conn->key.dst.addr.ipv4_aligned);
+ conn->key.dst.addr.ipv4);
}
reverse_pat_packet(pkt, conn);
@@ -681,13 +679,11 @@ reverse_nat_packet(struct dp_packet *pkt, const struct conn *conn)
if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
packet_set_ipv6_addr(pkt, conn->key.nw_proto,
inner_l3_6->ip6_src.be32,
- &conn->key.src.addr.ipv6_aligned,
- true);
+ &conn->key.src.addr.ipv6, true);
} else if (conn->nat_info->nat_action & NAT_ACTION_DST) {
packet_set_ipv6_addr(pkt, conn->key.nw_proto,
inner_l3_6->ip6_dst.be32,
- &conn->key.dst.addr.ipv6_aligned,
- true);
+ &conn->key.dst.addr.ipv6, true);
}
reverse_pat_packet(pkt, conn);
uint32_t icmp6_csum = packet_csum_pseudoheader6(nh6);
@@ -708,12 +704,12 @@ un_nat_packet(struct dp_packet *pkt, const struct conn *conn,
if (conn->key.dl_type == htons(ETH_TYPE_IP)) {
struct ip_header *nh = dp_packet_l3(pkt);
packet_set_ipv4_addr(pkt, &nh->ip_dst,
- conn->key.src.addr.ipv4_aligned);
+ conn->key.src.addr.ipv4);
} else {
struct ovs_16aligned_ip6_hdr *nh6 = dp_packet_l3(pkt);
packet_set_ipv6_addr(pkt, conn->key.nw_proto,
nh6->ip6_dst.be32,
- &conn->key.src.addr.ipv6_aligned, true);
+ &conn->key.src.addr.ipv6, true);
}
if (OVS_UNLIKELY(related)) {
@@ -726,12 +722,12 @@ un_nat_packet(struct dp_packet *pkt, const struct conn *conn,
if (conn->key.dl_type == htons(ETH_TYPE_IP)) {
struct ip_header *nh = dp_packet_l3(pkt);
packet_set_ipv4_addr(pkt, &nh->ip_src,
- conn->key.dst.addr.ipv4_aligned);
+ conn->key.dst.addr.ipv4);
} else {
struct ovs_16aligned_ip6_hdr *nh6 = dp_packet_l3(pkt);
packet_set_ipv6_addr(pkt, conn->key.nw_proto,
nh6->ip6_src.be32,
- &conn->key.dst.addr.ipv6_aligned, true);
+ &conn->key.dst.addr.ipv6, true);
}
if (OVS_UNLIKELY(related)) {
@@ -1097,8 +1093,8 @@ check_orig_tuple(struct conntrack *ct, struct dp_packet *pkt,
ctx.conn = NULL;
if (ctx_in->key.dl_type == htons(ETH_TYPE_IP)) {
- ctx.key.src.addr.ipv4_aligned = pkt->md.ct_orig_tuple.ipv4.ipv4_src;
- ctx.key.dst.addr.ipv4_aligned = pkt->md.ct_orig_tuple.ipv4.ipv4_dst;
+ ctx.key.src.addr.ipv4 = pkt->md.ct_orig_tuple.ipv4.ipv4_src;
+ ctx.key.dst.addr.ipv4 = pkt->md.ct_orig_tuple.ipv4.ipv4_dst;
if (ctx_in->key.nw_proto == IPPROTO_ICMP) {
ctx.key.src.icmp_id = ctx_in->key.src.icmp_id;
@@ -1112,8 +1108,8 @@ check_orig_tuple(struct conntrack *ct, struct dp_packet *pkt,
}
ctx.key.nw_proto = pkt->md.ct_orig_tuple.ipv4.ipv4_proto;
} else {
- ctx.key.src.addr.ipv6_aligned = pkt->md.ct_orig_tuple.ipv6.ipv6_src;
- ctx.key.dst.addr.ipv6_aligned = pkt->md.ct_orig_tuple.ipv6.ipv6_dst;
+ ctx.key.src.addr.ipv6 = pkt->md.ct_orig_tuple.ipv6.ipv6_src;
+ ctx.key.dst.addr.ipv6 = pkt->md.ct_orig_tuple.ipv6.ipv6_dst;
if (ctx_in->key.nw_proto == IPPROTO_ICMPV6) {
ctx.key.src.icmp_id = ctx_in->key.src.icmp_id;
@@ -1546,8 +1542,8 @@ extract_l3_ipv4(struct conn_key *key, const void *data, size_t size,
*new_data = (char *) data + ip_len;
}
- key->src.addr.ipv4 = ip->ip_src;
- key->dst.addr.ipv4 = ip->ip_dst;
+ key->src.addr.ipv4 = get_16aligned_be32(&ip->ip_src);
+ key->dst.addr.ipv4 = get_16aligned_be32(&ip->ip_dst);
key->nw_proto = ip->ip_proto;
return true;
@@ -1584,8 +1580,8 @@ extract_l3_ipv6(struct conn_key *key, const void *data, size_t size,
*new_data = data;
}
- key->src.addr.ipv6 = ip6->ip6_src;
- key->dst.addr.ipv6 = ip6->ip6_dst;
+ memcpy(&key->src.addr.ipv6, &ip6->ip6_src, sizeof key->src.addr);
+ memcpy(&key->dst.addr.ipv6, &ip6->ip6_dst, sizeof key->dst.addr);
key->nw_proto = nw_proto;
return true;
@@ -1769,7 +1765,7 @@ extract_l4_icmp(struct conn_key *key, const void *data, size_t size,
return false;
}
- if (inner_key.src.addr.ipv4_aligned != key->dst.addr.ipv4_aligned) {
+ if (inner_key.src.addr.ipv4 != key->dst.addr.ipv4) {
return false;
}
@@ -1855,8 +1851,8 @@ extract_l4_icmp6(struct conn_key *key, const void *data, size_t size,
}
/* pf doesn't do this, but it seems a good idea */
- if (!ipv6_addr_equals(&inner_key.src.addr.ipv6_aligned,
- &key->dst.addr.ipv6_aligned)) {
+ if (!ipv6_addr_equals(&inner_key.src.addr.ipv6,
+ &key->dst.addr.ipv6)) {
return false;
}
@@ -1998,7 +1994,7 @@ conn_key_extract(struct conntrack *ct, struct dp_packet *pkt, ovs_be16 dl_type,
}
static uint32_t
-ct_addr_hash_add(uint32_t hash, const struct ct_addr *addr)
+ct_addr_hash_add(uint32_t hash, const union ct_addr *addr)
{
BUILD_ASSERT_DECL(sizeof *addr % 4 == 0);
return hash_add_bytes32(hash, (const uint32_t *) addr, sizeof *addr);
@@ -2038,13 +2034,12 @@ conn_key_reverse(struct conn_key *key)
}
static uint32_t
-nat_ipv6_addrs_delta(struct in6_addr *ipv6_aligned_min,
- struct in6_addr *ipv6_aligned_max)
+nat_ipv6_addrs_delta(struct in6_addr *ipv6_min, struct in6_addr *ipv6_max)
{
- uint8_t *ipv6_min_hi = &ipv6_aligned_min->s6_addr[0];
- uint8_t *ipv6_min_lo = &ipv6_aligned_min->s6_addr[0] + sizeof(uint64_t);
- uint8_t *ipv6_max_hi = &ipv6_aligned_max->s6_addr[0];
- uint8_t *ipv6_max_lo = &ipv6_aligned_max->s6_addr[0] + sizeof(uint64_t);
+ uint8_t *ipv6_min_hi = &ipv6_min->s6_addr[0];
+ uint8_t *ipv6_min_lo = &ipv6_min->s6_addr[0] + sizeof(uint64_t);
+ uint8_t *ipv6_max_hi = &ipv6_max->s6_addr[0];
+ uint8_t *ipv6_max_lo = &ipv6_max->s6_addr[0] + sizeof(uint64_t);
ovs_be64 addr6_64_min_hi;
ovs_be64 addr6_64_min_lo;
@@ -2081,10 +2076,10 @@ nat_ipv6_addrs_delta(struct in6_addr *ipv6_aligned_min,
/* This function must be used in tandem with nat_ipv6_addrs_delta(), which
* restricts the input parameters. */
static void
-nat_ipv6_addr_increment(struct in6_addr *ipv6_aligned, uint32_t increment)
+nat_ipv6_addr_increment(struct in6_addr *ipv6, uint32_t increment)
{
- uint8_t *ipv6_hi = &ipv6_aligned->s6_addr[0];
- uint8_t *ipv6_lo = &ipv6_aligned->s6_addr[0] + sizeof(ovs_be64);
+ uint8_t *ipv6_hi = &ipv6->s6_addr[0];
+ uint8_t *ipv6_lo = &ipv6->s6_addr[0] + sizeof(ovs_be64);
ovs_be64 addr6_64_hi;
ovs_be64 addr6_64_lo;
memcpy(&addr6_64_hi, ipv6_hi, sizeof addr6_64_hi);
@@ -2158,30 +2153,30 @@ nat_select_range_tuple(struct conntrack *ct, const struct conn *conn,
uint32_t deltaa = 0;
uint32_t address_index;
- struct ct_addr ct_addr;
+ union ct_addr ct_addr;
memset(&ct_addr, 0, sizeof ct_addr);
- struct ct_addr max_ct_addr;
+ union ct_addr max_ct_addr;
memset(&max_ct_addr, 0, sizeof max_ct_addr);
max_ct_addr = conn->nat_info->max_addr;
if (conn->key.dl_type == htons(ETH_TYPE_IP)) {
- deltaa = ntohl(conn->nat_info->max_addr.ipv4_aligned) -
- ntohl(conn->nat_info->min_addr.ipv4_aligned);
+ deltaa = ntohl(conn->nat_info->max_addr.ipv4) -
+ ntohl(conn->nat_info->min_addr.ipv4);
address_index = hash % (deltaa + 1);
- ct_addr.ipv4_aligned = htonl(
- ntohl(conn->nat_info->min_addr.ipv4_aligned) + address_index);
+ ct_addr.ipv4 = htonl(
+ ntohl(conn->nat_info->min_addr.ipv4) + address_index);
} else {
- deltaa = nat_ipv6_addrs_delta(&conn->nat_info->min_addr.ipv6_aligned,
- &conn->nat_info->max_addr.ipv6_aligned);
+ deltaa = nat_ipv6_addrs_delta(&conn->nat_info->min_addr.ipv6,
+ &conn->nat_info->max_addr.ipv6);
/* deltaa must be within 32 bits for full hash coverage. A 64 or
* 128 bit hash is unnecessary and hence not used here. Most code
* is kept common with V4; nat_ipv6_addrs_delta() will do the
* enforcement via max_ct_addr. */
max_ct_addr = conn->nat_info->min_addr;
- nat_ipv6_addr_increment(&max_ct_addr.ipv6_aligned, deltaa);
+ nat_ipv6_addr_increment(&max_ct_addr.ipv6, deltaa);
address_index = hash % (deltaa + 1);
- ct_addr.ipv6_aligned = conn->nat_info->min_addr.ipv6_aligned;
- nat_ipv6_addr_increment(&ct_addr.ipv6_aligned, address_index);
+ ct_addr.ipv6 = conn->nat_info->min_addr.ipv6;
+ nat_ipv6_addr_increment(&ct_addr.ipv6, address_index);
}
uint16_t port = first_port;
@@ -2189,7 +2184,7 @@ nat_select_range_tuple(struct conntrack *ct, const struct conn *conn,
/* For DNAT, we don't use ephemeral ports. */
bool ephemeral_ports_tried = conn->nat_info->nat_action & NAT_ACTION_DST
? true : false;
- struct ct_addr first_addr = ct_addr;
+ union ct_addr first_addr = ct_addr;
while (true) {
if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
@@ -2225,10 +2220,9 @@ nat_select_range_tuple(struct conntrack *ct, const struct conn *conn,
} else {
if (memcmp(&ct_addr, &max_ct_addr, sizeof ct_addr)) {
if (conn->key.dl_type == htons(ETH_TYPE_IP)) {
- ct_addr.ipv4_aligned = htonl(
- ntohl(ct_addr.ipv4_aligned) + 1);
+ ct_addr.ipv4 = htonl(ntohl(ct_addr.ipv4) + 1);
} else {
- nat_ipv6_addr_increment(&ct_addr.ipv6_aligned, 1);
+ nat_ipv6_addr_increment(&ct_addr.ipv6, 1);
}
} else {
ct_addr = conn->nat_info->min_addr;
@@ -2380,14 +2374,14 @@ delete_conn(struct conn *conn)
* Note that 'dl_type' should be either "ETH_TYPE_IP" or "ETH_TYPE_IPv6"
* in network-byte order. */
static void
-ct_endpoint_to_ct_dpif_inet_addr(const struct ct_addr *a,
+ct_endpoint_to_ct_dpif_inet_addr(const union ct_addr *a,
union ct_dpif_inet_addr *b,
ovs_be16 dl_type)
{
if (dl_type == htons(ETH_TYPE_IP)) {
- b->ip = a->ipv4_aligned;
+ b->ip = a->ipv4;
} else if (dl_type == htons(ETH_TYPE_IPV6)){
- b->in6 = a->ipv6_aligned;
+ b->in6 = a->ipv6;
}
}
@@ -2397,13 +2391,12 @@ ct_endpoint_to_ct_dpif_inet_addr(const struct ct_addr *a,
* in network-byte order. */
static void
ct_dpif_inet_addr_to_ct_endpoint(const union ct_dpif_inet_addr *a,
- struct ct_addr *b,
- ovs_be16 dl_type)
+ union ct_addr *b, ovs_be16 dl_type)
{
if (dl_type == htons(ETH_TYPE_IP)) {
- b->ipv4_aligned = a->ip;
+ b->ipv4 = a->ip;
} else if (dl_type == htons(ETH_TYPE_IPV6)){
- b->ipv6_aligned = a->in6;
+ b->ipv6 = a->in6;
}
}
@@ -2723,9 +2716,9 @@ expectation_create(struct conntrack *ct, ovs_be16 dst_port,
const struct conn *master_conn, bool reply, bool src_ip_wc,
bool skip_nat)
{
- struct ct_addr src_addr;
- struct ct_addr dst_addr;
- struct ct_addr alg_nat_repl_addr;
+ union ct_addr src_addr;
+ union ct_addr dst_addr;
+ union ct_addr alg_nat_repl_addr;
struct alg_exp_node *alg_exp_node = xzalloc(sizeof *alg_exp_node);
if (reply) {
@@ -3019,12 +3012,12 @@ process_ftp_ctl_v4(struct conntrack *ct,
switch (mode) {
case CT_FTP_MODE_ACTIVE:
- *v4_addr_rep = conn_for_expectation->rev_key.dst.addr.ipv4_aligned;
- conn_ipv4_addr = conn_for_expectation->key.src.addr.ipv4_aligned;
+ *v4_addr_rep = conn_for_expectation->rev_key.dst.addr.ipv4;
+ conn_ipv4_addr = conn_for_expectation->key.src.addr.ipv4;
break;
case CT_FTP_MODE_PASSIVE:
- *v4_addr_rep = conn_for_expectation->key.dst.addr.ipv4_aligned;
- conn_ipv4_addr = conn_for_expectation->rev_key.src.addr.ipv4_aligned;
+ *v4_addr_rep = conn_for_expectation->key.dst.addr.ipv4;
+ conn_ipv4_addr = conn_for_expectation->rev_key.src.addr.ipv4;
break;
case CT_TFTP_MODE:
default:
@@ -3057,8 +3050,7 @@ static enum ftp_ctl_pkt
process_ftp_ctl_v6(struct conntrack *ct,
struct dp_packet *pkt,
const struct conn *conn_for_expectation,
- struct ct_addr *v6_addr_rep,
- char **ftp_data_start,
+ union ct_addr *v6_addr_rep, char **ftp_data_start,
size_t *addr_offset_from_ftp_data_start,
size_t *addr_size, enum ct_alg_mode *mode)
{
@@ -3128,8 +3120,8 @@ process_ftp_ctl_v6(struct conntrack *ct,
*v6_addr_rep = conn_for_expectation->rev_key.dst.addr;
/* Although most servers will block this exploit, there may be some
* less well managed. */
- if (memcmp(&ip6_addr, &v6_addr_rep->ipv6_aligned, sizeof ip6_addr) &&
- memcmp(&ip6_addr, &conn_for_expectation->key.src.addr.ipv6_aligned,
+ if (memcmp(&ip6_addr, &v6_addr_rep->ipv6, sizeof ip6_addr) &&
+ memcmp(&ip6_addr, &conn_for_expectation->key.src.addr.ipv6,
sizeof ip6_addr)) {
return CT_FTP_CTL_INVALID;
}
@@ -3148,7 +3140,7 @@ process_ftp_ctl_v6(struct conntrack *ct,
}
static int
-repl_ftp_v6_addr(struct dp_packet *pkt, struct ct_addr v6_addr_rep,
+repl_ftp_v6_addr(struct dp_packet *pkt, union ct_addr v6_addr_rep,
char *ftp_data_start,
size_t addr_offset_from_ftp_data_start,
size_t addr_size, enum ct_alg_mode mode)
@@ -3172,7 +3164,7 @@ repl_ftp_v6_addr(struct dp_packet *pkt, struct ct_addr v6_addr_rep,
}
char v6_addr_str[INET6_ADDRSTRLEN] = {0};
- ovs_assert(inet_ntop(AF_INET6, &v6_addr_rep.ipv6_aligned, v6_addr_str,
+ ovs_assert(inet_ntop(AF_INET6, &v6_addr_rep.ipv6, v6_addr_str,
sizeof v6_addr_str));
modify_packet(pkt, ftp_data_start + addr_offset_from_ftp_data_start,
addr_size, v6_addr_str, strlen(v6_addr_str),
@@ -3194,7 +3186,7 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
{
struct ip_header *l3_hdr = dp_packet_l3(pkt);
ovs_be32 v4_addr_rep = 0;
- struct ct_addr v6_addr_rep;
+ union ct_addr v6_addr_rep;
size_t addr_offset_from_ftp_data_start = 0;
size_t addr_size = 0;
char *ftp_data_start;