@@ -5440,6 +5440,56 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone)
}
}
+static void
+get_capability(const char *datapath_type, struct smap *cap)
+{
+ char *str_value;
+ struct odp_support odp;
+ struct dpif_backer_support s;
+ struct dpif_backer *backer = shash_find_data(&all_dpif_backers,
+ datapath_type);
+ if (!backer) {
+ return;
+ }
+ s = backer->rt_support;
+ odp = s.odp;
+
+ /* ODP_SUPPORT_FIELDS */
+ str_value = xasprintf("%lu", odp.max_vlan_headers);
+ smap_add(cap, "max_vlan_headers", str_value);
+ free(str_value);
+
+ str_value = xasprintf("%lu", odp.max_mpls_depth);
+ smap_add(cap, "max_mpls_depth", str_value);
+ free(str_value);
+
+ smap_add(cap, "recirc", odp.recirc ? "true" : "false");
+ smap_add(cap, "ct_state", odp.ct_state ? "true" : "false");
+ smap_add(cap, "ct_zone", odp.ct_zone ? "true" : "false");
+ smap_add(cap, "ct_mark", odp.ct_mark ? "true" : "false");
+ smap_add(cap, "ct_label", odp.ct_label ? "true" : "false");
+ smap_add(cap, "ct_state_nat", odp.ct_state_nat ? "true" : "false");
+ smap_add(cap, "ct_orig_tuple", odp.ct_orig_tuple ? "true" : "false");
+ smap_add(cap, "ct_orig_tuple6", odp.ct_orig_tuple6 ? "true" : "false");
+
+ /* DPIF_SUPPORT_FIELDS */
+ smap_add(cap, "masked_set_action", s.masked_set_action ? "true" : "false");
+ smap_add(cap, "tnl_push_pop", s.tnl_push_pop ? "true" : "false");
+ smap_add(cap, "ufid", s.ufid ? "true" : "false");
+ smap_add(cap, "trunc", s.trunc ? "true" : "false");
+ smap_add(cap, "clone", s.clone ? "true" : "false");
+ smap_add(cap, "sample_nesting", s.sample_nesting ? "true" : "false");
+ smap_add(cap, "ct_eventmask", s.ct_eventmask ? "true" : "false");
+ smap_add(cap, "ct_clear", s.ct_clear ? "true" : "false");
+
+ str_value = xasprintf("%lu", s.max_hash_alg);
+ smap_add(cap, "max_hash_alg", str_value);
+ free(str_value);
+
+ smap_add(cap, "check_pkt_len", s.check_pkt_len ? "true" : "false");
+ smap_add(cap, "ct_timeout", s.ct_timeout ? "true" : "false");
+}
+
/* Gets timeout policy name in 'backer' based on 'zone', 'dl_type' and
* 'nw_proto'. Returns true if the zoned-based timeout policy is configured.
* On success, stores the timeout policy name in 'tp_name', and sets
@@ -6579,4 +6629,5 @@ const struct ofproto_class ofproto_dpif_class = {
ct_flush, /* ct_flush */
ct_set_zone_timeout_policy,
ct_del_zone_timeout_policy,
+ get_capability,
};
@@ -1890,6 +1890,8 @@ struct ofproto_class {
/* Deletes the timeout policy associated with 'zone' in datapath type
* 'dp_type'. */
void (*ct_del_zone_timeout_policy)(const char *dp_type, uint16_t zone);
+ /* Get the datapath's capabilities. */
+ void (*get_capability)(const char *dp_type, struct smap *caps);
};
extern const struct ofproto_class ofproto_dpif_class;
@@ -954,6 +954,18 @@ ofproto_get_flow_restore_wait(void)
return flow_restore_wait;
}
+/* Retrieve datapath capabilities. */
+void
+ofproto_get_capability(const char *datapath_type, struct smap *dp_cap)
+{
+ datapath_type = ofproto_normalize_type(datapath_type);
+ const struct ofproto_class *class = ofproto_class_find__(datapath_type);
+
+ if (class->get_capability) {
+ class->get_capability(datapath_type, dp_cap);
+ }
+}
+
/* Connection tracking configuration. */
void
ofproto_ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone,
@@ -371,6 +371,7 @@ void ofproto_ct_set_zone_timeout_policy(const char *datapath_type,
struct simap *timeout_policy);
void ofproto_ct_del_zone_timeout_policy(const char *datapath_type,
uint16_t zone);
+void ofproto_get_capability(const char *datapath_type, struct smap *dp_cap);
/* Configuration of ports. */
void ofproto_port_unregister(struct ofproto *, ofp_port_t ofp_port);
@@ -819,6 +819,8 @@ AT_CHECK([RUN_OVS_VSCTL([del-zone-tp netdev zone=1])])
AT_CHECK([RUN_OVS_VSCTL([--if-exists del-zone-tp netdev zone=1])])
AT_CHECK([RUN_OVS_VSCTL([list-zone-tp netdev])], [0], [Zone:2, Timeout Policies: icmp_first=2 icmp_reply=3
])
+AT_CHECK([RUN_OVS_VSCTL([list-dp-cap netdev])], [0], [
+])
OVS_VSCTL_CLEANUP
AT_CLEANUP
@@ -379,6 +379,12 @@ delete a zone that does not exist has no effect.
.IP "\fBlist\-zone\-tp \fIdatapath\fR"
Prints the timeout policies of all zones in \fIdatapath\fR.
.
+.SS "Datapath Capabilities Command"
+The command query datapath capabilities.
+.
+.IP "\fBlist\-dp\-cap \fIdatapath\fR"
+Prints the datapath's capabilities.
+.
.SS "OpenFlow Controller Connectivity"
.
\fBovs\-vswitchd\fR can perform all configured bridging and switching
@@ -1338,6 +1338,31 @@ pre_get_zone(struct ctl_context *ctx)
}
static void
+pre_get_dp_cap(struct ctl_context *ctx)
+{
+ ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_datapaths);
+ ovsdb_idl_add_column(ctx->idl, &ovsrec_datapath_col_capabilities);
+}
+
+static void
+cmd_list_dp_cap(struct ctl_context *ctx)
+{
+ struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
+ struct smap_node *node;
+
+ struct ovsrec_datapath *dp = find_datapath(vsctl_ctx, ctx->argv[1]);
+ if (!dp) {
+ ctl_fatal("datapath: %s record not found", ctx->argv[1]);
+ }
+
+ SMAP_FOR_EACH (node, &dp->capabilities) {
+ ds_put_format(&ctx->output, "%s=%s ",node->key, node->value);
+ }
+ ds_chomp(&ctx->output, ' ');
+ ds_put_char(&ctx->output, '\n');
+}
+
+static void
cmd_add_br(struct ctl_context *ctx)
{
struct vsctl_context *vsctl_ctx = vsctl_context_cast(ctx);
@@ -3087,6 +3112,9 @@ static const struct ctl_command_syntax vsctl_commands[] = {
"--if-exists", RW},
{"list-zone-tp", 1, 1, "", pre_get_zone, cmd_list_zone_tp, NULL, "", RO},
+ /* Datapath capabilities. */
+ {"list-dp-cap", 1, 1, "", pre_get_dp_cap, cmd_list_dp_cap, NULL, "", RO},
+
{NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
};
@@ -171,6 +171,7 @@ struct datapath {
struct hmap ct_zones; /* Map of 'struct ct_zone' elements, indexed
* by 'zone'. */
struct hmap_node node; /* Node in 'all_datapaths' hmap. */
+ struct smap caps; /* Capabilities. */
const struct ovsrec_datapath *dp_cfg;
unsigned int last_used; /* The last idl_seqno that this 'datapath'
* used in OVSDB. This number is used for
@@ -688,6 +689,7 @@ datapath_create(const struct ovsrec_datapath *dp_cfg, const char *type)
hmap_init(&dp->ct_zones);
hmap_insert(&all_datapaths, &dp->node, hash_string(type, 0));
+ smap_init(&dp->caps);
return dp;
}
@@ -705,6 +707,7 @@ datapath_destroy(struct datapath *dp)
hmap_remove(&all_datapaths, &dp->node);
hmap_destroy(&dp->ct_zones);
free(dp->type);
+ smap_destroy(&dp->caps);
free(dp);
}
}
@@ -774,6 +777,23 @@ reconfigure_ct_zones(struct datapath *dp)
}
static void
+reconfigure_dp_capability(struct datapath *dp)
+{
+ const struct ovsrec_datapath *dp_cfg = dp->dp_cfg;
+ struct smap_node *node;
+ struct smap cap;
+
+ smap_init(&cap);
+ ofproto_get_capability(dp->type, &cap);
+
+ SMAP_FOR_EACH (node, &cap) {
+ ovsrec_datapath_update_capabilities_setkey(dp_cfg, node->key,
+ node->value);
+ }
+ smap_destroy(&cap);
+}
+
+static void
reconfigure_datapath_cfgs(const struct ovsrec_open_vswitch *cfg)
{
struct datapath *dp;
@@ -782,6 +802,7 @@ reconfigure_datapath_cfgs(const struct ovsrec_open_vswitch *cfg)
HMAP_FOR_EACH (dp, node, &all_datapaths) {
reconfigure_ct_zones(dp);
+ reconfigure_dp_capability(dp);
}
}
@@ -1,6 +1,6 @@
{"name": "Open_vSwitch",
"version": "8.1.0",
- "cksum": "1635647160 26090",
+ "cksum": "3360805810 26219",
"tables": {
"Open_vSwitch": {
"columns": {
@@ -645,6 +645,9 @@
"value": {"type": "uuid",
"refTable": "CT_Zone"},
"min": 0, "max": "unlimited"}},
+ "capabilities": {
+ "type": {"key": "string", "value": "string",
+ "min": 0, "max": "unlimited"}},
"external_ids": {
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}}},
@@ -5628,6 +5628,82 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
connection tracking-related OpenFlow matches and actions).
</column>
+ <column name="capabilities" key="max_vlan_headers"
+ type='{"type": "integer", "minInteger": 0}'>
+ Maximum number of 802.1q VLAN headers to serialize in a mask.
+ </column>
+ <column name="capabilities" key="max_mpls_depth"
+ type='{"type": "integer", "minInteger": 0}'>
+ Maximum number of MPLS label stack entries to serialise in a mask.
+ </column>
+ <column name="capabilities" key="recirc" type='{"type": "boolean"}'>
+ If this is true, then recirculation fields will always be serialised.
+ </column>
+ <column name="capabilities" key="ct_state" type='{"type": "boolean"}'>
+ If true, datapath supports OVS_KEY_ATTR_CT_STATE.
+ </column>
+ <column name="capabilities" key="ct_zone" type='{"type": "boolean"}'>
+ If true, datapath supports OVS_KEY_ATTR_CT_ZONE.
+ </column>
+ <column name="capabilities" key="ct_mark" type='{"type": "boolean"}'>
+ If true, datapath supports OVS_KEY_ATTR_CT_MARK.
+ </column>
+ <column name="capabilities" key="ct_label" type='{"type": "boolean"}'>
+ If true, datapath supports OVS_KEY_ATTR_CT_LABEL.
+ </column>
+ <column name="capabilities" key="ct_state_nat" type='{"type": "boolean"}'>
+ If true, it means that the datapath supports the NAT bits in
+ 'ct_state'. The above 'ct_state' member must be true for this
+ to make sense.
+ </column>
+ <column name="capabilities" key="ct_orig_tuple"
+ type='{"type": "boolean"}'>
+ Conntrack original direction tuple matching * supported.
+ </column>
+ <column name="capabilities" key="ct_orig_tuple6"
+ type='{"type": "boolean"}'>
+ Conntrack original direction tuple6 matching * supported.
+ </column>
+ <column name="capabilities" key="masked_set_action"
+ type='{"type": "boolean"}'>
+ True if the datapath supports masked data in
+ OVS_ACTION_ATTR_SET actions.
+ </column>
+ <column name="capabilities" key="tnl_push_pop" type='{"type": "boolean"}'>
+ True if the datapath supports tnl_push and pop actions.
+ </column>
+ <column name="capabilities" key="ufid" type='{"type": "boolean"}'>
+ True if the datapath supports OVS_FLOW_ATTR_UFID.
+ </column>
+ <column name="capabilities" key="trunc" type='{"type": "boolean"}'>
+ True if the datapath supports OVS_ACTION_ATTR_TRUNC action.
+ </column>
+ <column name="capabilities" key="clone" type='{"type": "boolean"}'>
+ True if the datapath supports OVS_ACTION_ATTR_CLONE action.
+ </column>
+ <column name="capabilities" key="sample_nesting"
+ type='{"type": "integer", "minInteger": 0}'>
+ Maximum level of nesting allowed by OVS_ACTION_ATTR_SAMPLE action.
+ </column>
+ <column name="capabilities" key="ct_eventmask" type='{"type": "boolean"}'>
+ OVS_CT_ATTR_EVENTMASK supported by OVS_ACTION_ATTR_CT action.
+ </column>
+ <column name="capabilities" key="ct_clear" type='{"type": "boolean"}'>
+ True if the datapath supports OVS_ACTION_ATTR_CT_CLEAR action.
+ </column>
+ <column name="capabilities" key="max_hash_alg"
+ type='{"type": "integer", "minInteger": 0}'>
+ Highest supported dp_hash algorithm.
+ </column>
+ <column name="capabilities" key="check_pkt_len"
+ type='{"type": "boolean"}'>
+ True if the datapath supports OVS_ACTION_ATTR_CHECK_PKT_LEN.
+ </column>
+ <column name="capabilities" key="ct_timeout" type='{"type": "boolean"}'>
+ True if the datapath supports OVS_CT_ATTR_TIMEOUT in
+ OVS_ACTION_ATTR_CTaction.
+ </column>
+
<group title="Common Columns">
The overall purpose of these columns is described under <code>Common
Columns</code> at the beginning of this document.
The patch adds support for fetching the datapath's capabilities from the result of 'check_support()', and write the supported capability to a new database column, called 'capabilities' under Datapath table. To see how it works, run: # ovs-vsctl -- add-br br0 -- set Bridge br0 datapath_type=netdev # ovs-vsctl -- --id=@m create Datapath datapath_version=0 \ 'ct_zones={}' 'capabilities={}' \ -- set Open_vSwitch . datapaths:"netdev"=@m # ovs-vsctl list-dp-cap netdev ufid=true sample_nesting=true clone=true tnl_push_pop=true ct_orig_tuple=true ct_eventmask=true ct_state=true ct_clear=true max_vlan_headers=1 recirc=true ct_label=true max_hash_alg=1 ct_state_nat=true ct_timeout=true ct_mark=true ct_orig_tuple6=true check_pkt_len=true masked_set_action=true max_mpls_depth=3 trunc=true ct_zone=true This is based on Yi-Hung's ct timeout patchset, https://patchwork.ozlabs.org/cover/1154903/ So not applicable to the current master, mark it as RFC. Signed-off-by: William Tu <u9012063@gmail.com> --- ofproto/ofproto-dpif.c | 51 +++++++++++++++++++++++++++++++ ofproto/ofproto-provider.h | 2 ++ ofproto/ofproto.c | 12 ++++++++ ofproto/ofproto.h | 1 + tests/ovs-vsctl.at | 2 ++ utilities/ovs-vsctl.8.in | 6 ++++ utilities/ovs-vsctl.c | 28 +++++++++++++++++ vswitchd/bridge.c | 21 +++++++++++++ vswitchd/vswitch.ovsschema | 5 ++- vswitchd/vswitch.xml | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 203 insertions(+), 1 deletion(-)