restricts a flow dump to a single PMD thread if set.
* New 'options:dpdk-vf-mac' field for DPDK interface of VF ports,
that allows configuring the MAC address of a VF representor.
+ * Add generic IP protocol support to conntrack. With this change, all
+ none UDP, TCP, and ICMP traffic will be treated as general L3
+ traffic, i.e. using 3 tupples.
- The environment variable OVS_UNBOUND_CONF, if set, is now used
as the DNS resolver's (unbound) configuration file.
- Linux datapath:
uint8_t nw_proto;
};
+/* Verify that nw_proto stays uint8_t as it's used to index into l4_protos[] */
+BUILD_ASSERT_DECL(MEMBER_SIZEOF(struct conn_key, nw_proto) == sizeof(uint8_t));
+
/* This is used for alg expectations; an expectation is a
* context created in preparation for establishing a data
* connection. The expectation is created by the control
static void
expectation_clean(struct conntrack *ct, const struct conn_key *parent_key);
-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 struct ct_l4_proto *l4_protos[UINT8_MAX + 1];
static void
handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
struct conntrack *
conntrack_init(void)
{
+ static struct ovsthread_once setup_l4_once = OVSTHREAD_ONCE_INITIALIZER;
struct conntrack *ct = xzalloc(sizeof *ct);
ovs_rwlock_init(&ct->resources_lock);
ct->clean_thread = ovs_thread_create("ct_clean", clean_thread_main, ct);
ct->ipf = ipf_init();
+ /* Initialize the l4 protocols. */
+ if (ovsthread_once_start(&setup_l4_once)) {
+ for (int i = 0; i < ARRAY_SIZE(l4_protos); i++) {
+ l4_protos[i] = &ct_proto_other;
+ }
+ /* IPPROTO_UDP uses ct_proto_other, so no need to initialize it. */
+ l4_protos[IPPROTO_TCP] = &ct_proto_tcp;
+ l4_protos[IPPROTO_ICMP] = &ct_proto_icmp4;
+ l4_protos[IPPROTO_ICMPV6] = &ct_proto_icmp6;
+
+ ovsthread_once_done(&setup_l4_once);
+ }
return ct;
}
return (!related || check_l4_icmp6(key, data, size, l3,
validate_checksum))
&& extract_l4_icmp6(key, data, size, related);
- } else {
- return false;
}
+
+ /* For all other protocols we do not have L4 keys, so keep them zero. */
+ return true;
}
static bool
conn->nat_info->nat_action & NAT_ACTION_SRC_PORT
? true : false;
union ct_addr first_addr = ct_addr;
- bool pat_enabled = conn->key.nw_proto != IPPROTO_ICMP &&
- conn->key.nw_proto != IPPROTO_ICMPV6;
+ bool pat_enabled = conn->key.nw_proto == IPPROTO_TCP ||
+ conn->key.nw_proto == IPPROTO_UDP;
while (true) {
if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
+AT_SETUP([conntrack - generic IP protocol])
+CHECK_CONNTRACK()
+OVS_TRAFFIC_VSWITCHD_START()
+AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg ofproto_dpif_upcall:dbg])
+
+ADD_NAMESPACES(at_ns0, at_ns1)
+
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
+ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
+
+AT_DATA([flows.txt], [dnl
+table=0, priority=1,action=drop
+table=0, priority=10,arp,action=normal
+table=0, priority=100,ip,action=ct(table=1)
+table=1, priority=100,in_port=1,ip,ct_state=+trk+new,action=ct(commit)
+table=1, priority=100,in_port=1,ct_state=+trk+est,action=normal
+])
+
+AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=01005e00001200005e000101080045c0002800000000ff7019cdc0a8001ee0000012210164010001ba52c0a800010000000000000000000000000000 actions=resubmit(,0)"])
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=192\.168\.0\.30,"], [], [dnl
+112,orig=(src=192.168.0.30,dst=224.0.0.18,sport=0,dport=0),reply=(src=224.0.0.18,dst=192.168.0.30,sport=0,dport=0)
+])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
+
AT_SETUP([conntrack - ICMP related])
AT_SKIP_IF([test $HAVE_NC = no])
CHECK_CONNTRACK()