Skip to content

Commit

Permalink
ct-dpif, dpif-netlink: Add conntrack timeout policy support
Browse files Browse the repository at this point in the history
This patch first defines the dpif interface for a datapath to support
adding, deleting, getting and dumping conntrack timeout policy.
The timeout policy is identified by a 4 bytes unsigned integer in
datapath, and it currently support timeout for TCP, UDP, and ICMP
protocols.

Moreover, this patch provides the implementation for Linux kernel
datapath in dpif-netlink.

In Linux kernel, the timeout policy is maintained per L3/L4 protocol,
and it is identified by 32 bytes null terminated string.  On the other
hand, in vswitchd, the timeout policy is a generic one that consists of
all the supported L4 protocols.  Therefore, one of the main task in
dpif-netlink is to break down the generic timeout policy into 6
sub policies (ipv4 tcp, udp, icmp, and ipv6 tcp, udp, icmp),
and push down the configuration using the netlink API in
netlink-conntrack.c.

This patch also adds missing symbols in the windows datapath so
that the build on windows can pass.

Appveyor CI:
* https://ci.appveyor.com/project/YiHungWei/ovs/builds/26387754

Signed-off-by: Yi-Hung Wei <[email protected]>
Acked-by: Alin Gabriel Serdean <[email protected]>
Signed-off-by: Justin Pettit <[email protected]>
  • Loading branch information
YiHungWei authored and justinpettit committed Sep 26, 2019
1 parent 934f54a commit 1f16131
Show file tree
Hide file tree
Showing 14 changed files with 1,142 additions and 9 deletions.
3 changes: 2 additions & 1 deletion Documentation/faq/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ Q: Are all features available with all datapaths?
========================== ============== ============== ========= =======
Connection tracking 4.3 YES YES YES
Conntrack Fragment Reass. 4.3 YES YES YES
Conntrack Timeout Policies 5.2 YES NO NO
Conntrack Zone Limit 4.18 YES NO YES
NAT 4.6 YES YES YES
Conntrack zone limit 4.18 YES NO YES
Tunnel - LISP NO YES NO NO
Tunnel - STT NO YES NO YES
Tunnel - GRE 3.11 YES YES YES
Expand Down
114 changes: 114 additions & 0 deletions datapath-windows/include/OvsDpInterfaceCtExt.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,4 +421,118 @@ struct nf_ct_tcp_flags {
UINT8 mask;
};

/* File: nfnetlink_cttimeout.h. XXX: the following are not implemented */
enum ctnl_timeout_msg_types {
IPCTNL_MSG_TIMEOUT_NEW,
IPCTNL_MSG_TIMEOUT_GET,
IPCTNL_MSG_TIMEOUT_DELETE,
IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
IPCTNL_MSG_TIMEOUT_DEFAULT_GET,

IPCTNL_MSG_TIMEOUT_MAX
};

enum ctattr_timeout {
CTA_TIMEOUT_UNSPEC,
CTA_TIMEOUT_NAME,
CTA_TIMEOUT_L3PROTO,
CTA_TIMEOUT_L4PROTO,
CTA_TIMEOUT_DATA,
CTA_TIMEOUT_USE,
__CTA_TIMEOUT_MAX
};
#define CTA_TIMEOUT_MAX (__CTA_TIMEOUT_MAX - 1)

enum ctattr_timeout_generic {
CTA_TIMEOUT_GENERIC_UNSPEC,
CTA_TIMEOUT_GENERIC_TIMEOUT,
__CTA_TIMEOUT_GENERIC_MAX
};
#define CTA_TIMEOUT_GENERIC_MAX (__CTA_TIMEOUT_GENERIC_MAX - 1)

enum ctattr_timeout_tcp {
CTA_TIMEOUT_TCP_UNSPEC,
CTA_TIMEOUT_TCP_SYN_SENT,
CTA_TIMEOUT_TCP_SYN_RECV,
CTA_TIMEOUT_TCP_ESTABLISHED,
CTA_TIMEOUT_TCP_FIN_WAIT,
CTA_TIMEOUT_TCP_CLOSE_WAIT,
CTA_TIMEOUT_TCP_LAST_ACK,
CTA_TIMEOUT_TCP_TIME_WAIT,
CTA_TIMEOUT_TCP_CLOSE,
CTA_TIMEOUT_TCP_SYN_SENT2,
CTA_TIMEOUT_TCP_RETRANS,
CTA_TIMEOUT_TCP_UNACK,
__CTA_TIMEOUT_TCP_MAX
};
#define CTA_TIMEOUT_TCP_MAX (__CTA_TIMEOUT_TCP_MAX - 1)

enum ctattr_timeout_udp {
CTA_TIMEOUT_UDP_UNSPEC,
CTA_TIMEOUT_UDP_UNREPLIED,
CTA_TIMEOUT_UDP_REPLIED,
__CTA_TIMEOUT_UDP_MAX
};
#define CTA_TIMEOUT_UDP_MAX (__CTA_TIMEOUT_UDP_MAX - 1)

enum ctattr_timeout_udplite {
CTA_TIMEOUT_UDPLITE_UNSPEC,
CTA_TIMEOUT_UDPLITE_UNREPLIED,
CTA_TIMEOUT_UDPLITE_REPLIED,
__CTA_TIMEOUT_UDPLITE_MAX
};
#define CTA_TIMEOUT_UDPLITE_MAX (__CTA_TIMEOUT_UDPLITE_MAX - 1)

enum ctattr_timeout_icmp {
CTA_TIMEOUT_ICMP_UNSPEC,
CTA_TIMEOUT_ICMP_TIMEOUT,
__CTA_TIMEOUT_ICMP_MAX
};
#define CTA_TIMEOUT_ICMP_MAX (__CTA_TIMEOUT_ICMP_MAX - 1)

enum ctattr_timeout_dccp {
CTA_TIMEOUT_DCCP_UNSPEC,
CTA_TIMEOUT_DCCP_REQUEST,
CTA_TIMEOUT_DCCP_RESPOND,
CTA_TIMEOUT_DCCP_PARTOPEN,
CTA_TIMEOUT_DCCP_OPEN,
CTA_TIMEOUT_DCCP_CLOSEREQ,
CTA_TIMEOUT_DCCP_CLOSING,
CTA_TIMEOUT_DCCP_TIMEWAIT,
__CTA_TIMEOUT_DCCP_MAX
};
#define CTA_TIMEOUT_DCCP_MAX (__CTA_TIMEOUT_DCCP_MAX - 1)

enum ctattr_timeout_sctp {
CTA_TIMEOUT_SCTP_UNSPEC,
CTA_TIMEOUT_SCTP_CLOSED,
CTA_TIMEOUT_SCTP_COOKIE_WAIT,
CTA_TIMEOUT_SCTP_COOKIE_ECHOED,
CTA_TIMEOUT_SCTP_ESTABLISHED,
CTA_TIMEOUT_SCTP_SHUTDOWN_SENT,
CTA_TIMEOUT_SCTP_SHUTDOWN_RECD,
CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
CTA_TIMEOUT_SCTP_HEARTBEAT_SENT,
CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED,
__CTA_TIMEOUT_SCTP_MAX
};
#define CTA_TIMEOUT_SCTP_MAX (__CTA_TIMEOUT_SCTP_MAX - 1)

enum ctattr_timeout_icmpv6 {
CTA_TIMEOUT_ICMPV6_UNSPEC,
CTA_TIMEOUT_ICMPV6_TIMEOUT,
__CTA_TIMEOUT_ICMPV6_MAX
};
#define CTA_TIMEOUT_ICMPV6_MAX (__CTA_TIMEOUT_ICMPV6_MAX - 1)

enum ctattr_timeout_gre {
CTA_TIMEOUT_GRE_UNSPEC,
CTA_TIMEOUT_GRE_UNREPLIED,
CTA_TIMEOUT_GRE_REPLIED,
__CTA_TIMEOUT_GRE_MAX
};
#define CTA_TIMEOUT_GRE_MAX (__CTA_TIMEOUT_GRE_MAX - 1)

#define CTNL_TIMEOUT_NAME_MAX 32

#endif /* __OVS_DP_INTERFACE_CT_EXT_H_ */
8 changes: 6 additions & 2 deletions datapath-windows/ovsext/Netlink/NetlinkProto.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,17 @@
#define NLM_F_ACK 0x004
#define NLM_F_ECHO 0x008

/* GET request flag.*/
#define NLM_F_ROOT 0x100
#define NLM_F_MATCH 0x200
#define NLM_F_EXCL 0x200
#define NLM_F_ATOMIC 0x400
#define NLM_F_CREATE 0x400
#define NLM_F_DUMP (NLM_F_ROOT | NLM_F_MATCH)

/* NEW request flags. */
#define NLM_F_REPLACE 0x100
#define NLM_F_EXCL 0x200
#define NLM_F_CREATE 0x400

/* nlmsg_type values. */
#define NLMSG_NOOP 1
#define NLMSG_ERROR 2
Expand Down
1 change: 1 addition & 0 deletions include/windows/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ noinst_HEADERS += \
include/windows/linux/netfilter/nf_conntrack_tcp.h \
include/windows/linux/netfilter/nfnetlink.h \
include/windows/linux/netfilter/nfnetlink_conntrack.h \
include/windows/linux/netfilter/nfnetlink_cttimeout.h \
include/windows/linux/pkt_sched.h \
include/windows/linux/types.h \
include/windows/net/if.h \
Expand Down
Empty file.
102 changes: 102 additions & 0 deletions lib/ct-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,3 +776,105 @@ ct_dpif_format_zone_limits(uint32_t default_limit,
ds_put_format(ds, ",count=%"PRIu32, zone_limit->count);
}
}

static const char *const ct_dpif_tp_attr_string[] = {
#define CT_DPIF_TP_TCP_ATTR(ATTR) \
[CT_DPIF_TP_ATTR_TCP_##ATTR] = "TCP_"#ATTR,
CT_DPIF_TP_TCP_ATTRS
#undef CT_DPIF_TP_TCP_ATTR
#define CT_DPIF_TP_UDP_ATTR(ATTR) \
[CT_DPIF_TP_ATTR_UDP_##ATTR] = "UDP_"#ATTR,
CT_DPIF_TP_UDP_ATTRS
#undef CT_DPIF_TP_UDP_ATTR
#define CT_DPIF_TP_ICMP_ATTR(ATTR) \
[CT_DPIF_TP_ATTR_ICMP_##ATTR] = "ICMP_"#ATTR,
CT_DPIF_TP_ICMP_ATTRS
#undef CT_DPIF_TP_ICMP_ATTR
};

static bool
ct_dpif_set_timeout_policy_attr(struct ct_dpif_timeout_policy *tp,
uint32_t attr, uint32_t value)
{
if (tp->present & (1 << attr) && tp->attrs[attr] == value) {
return false;
}
tp->attrs[attr] = value;
tp->present |= 1 << attr;
return true;
}

/* Sets a timeout value identified by '*name' to 'value'.
* Returns true if the attribute is changed */
bool
ct_dpif_set_timeout_policy_attr_by_name(struct ct_dpif_timeout_policy *tp,
const char *name, uint32_t value)
{
for (uint32_t i = 0; i < CT_DPIF_TP_ATTR_MAX; ++i) {
if (!strcasecmp(name, ct_dpif_tp_attr_string[i])) {
return ct_dpif_set_timeout_policy_attr(tp, i, value);
}
}
return false;
}

bool
ct_dpif_timeout_policy_support_ipproto(uint8_t ipproto)
{
if (ipproto == IPPROTO_TCP || ipproto == IPPROTO_UDP ||
ipproto == IPPROTO_ICMP || ipproto == IPPROTO_ICMPV6) {
return true;
}
return false;
}

int
ct_dpif_set_timeout_policy(struct dpif *dpif,
const struct ct_dpif_timeout_policy *tp)
{
return (dpif->dpif_class->ct_set_timeout_policy
? dpif->dpif_class->ct_set_timeout_policy(dpif, tp)
: EOPNOTSUPP);
}

int
ct_dpif_del_timeout_policy(struct dpif *dpif, uint32_t tp_id)
{
return (dpif->dpif_class->ct_del_timeout_policy
? dpif->dpif_class->ct_del_timeout_policy(dpif, tp_id)
: EOPNOTSUPP);
}

int
ct_dpif_get_timeout_policy(struct dpif *dpif, uint32_t tp_id,
struct ct_dpif_timeout_policy *tp)
{
return (dpif->dpif_class->ct_get_timeout_policy
? dpif->dpif_class->ct_get_timeout_policy(
dpif, tp_id, tp) : EOPNOTSUPP);
}

int
ct_dpif_timeout_policy_dump_start(struct dpif *dpif, void **statep)
{
return (dpif->dpif_class->ct_timeout_policy_dump_start
? dpif->dpif_class->ct_timeout_policy_dump_start(dpif, statep)
: EOPNOTSUPP);
}

int
ct_dpif_timeout_policy_dump_next(struct dpif *dpif, void *state,
struct ct_dpif_timeout_policy *tp)
{
return (dpif->dpif_class->ct_timeout_policy_dump_next
? dpif->dpif_class->ct_timeout_policy_dump_next(dpif, state, tp)
: EOPNOTSUPP);
}

int
ct_dpif_timeout_policy_dump_done(struct dpif *dpif, void *state)
{
return (dpif->dpif_class->ct_timeout_policy_dump_done
? dpif->dpif_class->ct_timeout_policy_dump_done(dpif, state)
: EOPNOTSUPP);
}
56 changes: 56 additions & 0 deletions lib/ct-dpif.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,50 @@ struct ct_dpif_zone_limit {
struct ovs_list node;
};

#define CT_DPIF_TP_TCP_ATTRS \
CT_DPIF_TP_TCP_ATTR(SYN_SENT) \
CT_DPIF_TP_TCP_ATTR(SYN_RECV) \
CT_DPIF_TP_TCP_ATTR(ESTABLISHED) \
CT_DPIF_TP_TCP_ATTR(FIN_WAIT) \
CT_DPIF_TP_TCP_ATTR(CLOSE_WAIT) \
CT_DPIF_TP_TCP_ATTR(LAST_ACK) \
CT_DPIF_TP_TCP_ATTR(TIME_WAIT) \
CT_DPIF_TP_TCP_ATTR(CLOSE) \
CT_DPIF_TP_TCP_ATTR(SYN_SENT2) \
CT_DPIF_TP_TCP_ATTR(RETRANSMIT) \
CT_DPIF_TP_TCP_ATTR(UNACK)

#define CT_DPIF_TP_UDP_ATTRS \
CT_DPIF_TP_UDP_ATTR(FIRST) \
CT_DPIF_TP_UDP_ATTR(SINGLE) \
CT_DPIF_TP_UDP_ATTR(MULTIPLE)

#define CT_DPIF_TP_ICMP_ATTRS \
CT_DPIF_TP_ICMP_ATTR(FIRST) \
CT_DPIF_TP_ICMP_ATTR(REPLY)

enum OVS_PACKED_ENUM ct_dpif_tp_attr {
#define CT_DPIF_TP_TCP_ATTR(ATTR) CT_DPIF_TP_ATTR_TCP_##ATTR,
CT_DPIF_TP_TCP_ATTRS
#undef CT_DPIF_TP_TCP_ATTR
#define CT_DPIF_TP_UDP_ATTR(ATTR) CT_DPIF_TP_ATTR_UDP_##ATTR,
CT_DPIF_TP_UDP_ATTRS
#undef CT_DPIF_TP_UDP_ATTR
#define CT_DPIF_TP_ICMP_ATTR(ATTR) CT_DPIF_TP_ATTR_ICMP_##ATTR,
CT_DPIF_TP_ICMP_ATTRS
#undef CT_DPIF_TP_ICMP_ATTR
CT_DPIF_TP_ATTR_MAX
};

struct ct_dpif_timeout_policy {
uint32_t id; /* Unique identifier for the timeout policy in
* the datapath. */
uint32_t present; /* If a timeout attribute is present set the
* corresponding CT_DPIF_TP_ATTR_* mapping bit. */
uint32_t attrs[CT_DPIF_TP_ATTR_MAX]; /* An array that specifies
* timeout attribute values */
};

int ct_dpif_dump_start(struct dpif *, struct ct_dpif_dump_state **,
const uint16_t *zone, int *);
int ct_dpif_dump_next(struct ct_dpif_dump_state *, struct ct_dpif_entry *);
Expand Down Expand Up @@ -264,5 +308,17 @@ bool ct_dpif_parse_zone_limit_tuple(const char *s, uint16_t *pzone,
uint32_t *plimit, struct ds *);
void ct_dpif_format_zone_limits(uint32_t default_limit,
const struct ovs_list *, struct ds *);
bool ct_dpif_set_timeout_policy_attr_by_name(struct ct_dpif_timeout_policy *tp,
const char *key, uint32_t value);
bool ct_dpif_timeout_policy_support_ipproto(uint8_t ipproto);
int ct_dpif_set_timeout_policy(struct dpif *dpif,
const struct ct_dpif_timeout_policy *tp);
int ct_dpif_get_timeout_policy(struct dpif *dpif, uint32_t tp_id,
struct ct_dpif_timeout_policy *tp);
int ct_dpif_del_timeout_policy(struct dpif *dpif, uint32_t tp_id);
int ct_dpif_timeout_policy_dump_start(struct dpif *dpif, void **statep);
int ct_dpif_timeout_policy_dump_next(struct dpif *dpif, void *state,
struct ct_dpif_timeout_policy *tp);
int ct_dpif_timeout_policy_dump_done(struct dpif *dpif, void *state);

#endif /* CT_DPIF_H */
6 changes: 6 additions & 0 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -7566,6 +7566,12 @@ const struct dpif_class dpif_netdev_class = {
NULL, /* ct_set_limits */
NULL, /* ct_get_limits */
NULL, /* ct_del_limits */
NULL, /* ct_set_timeout_policy */
NULL, /* ct_get_timeout_policy */
NULL, /* ct_del_timeout_policy */
NULL, /* ct_timeout_policy_dump_start */
NULL, /* ct_timeout_policy_dump_next */
NULL, /* ct_timeout_policy_dump_done */
dpif_netdev_ipf_set_enabled,
dpif_netdev_ipf_set_min_frag,
dpif_netdev_ipf_set_max_nfrags,
Expand Down
Loading

0 comments on commit 1f16131

Please sign in to comment.