From patchwork Tue Nov 5 22:57:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Tu X-Patchwork-Id: 1190048 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ncj0bkUb"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4774p26Qx3z9sNT for ; Wed, 6 Nov 2019 09:58:17 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 58D21D99; Tue, 5 Nov 2019 22:58:14 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id A506CD84 for ; Tue, 5 Nov 2019 22:58:13 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pl1-f196.google.com (mail-pl1-f196.google.com [209.85.214.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 92FCF27B for ; Tue, 5 Nov 2019 22:58:12 +0000 (UTC) Received: by mail-pl1-f196.google.com with SMTP id e3so8308362plt.7 for ; Tue, 05 Nov 2019 14:58:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=pVvNmGJr7SGrpOyrDPKxW/l1zsiqunTWP7tnHJz4Yzk=; b=Ncj0bkUbquL6GbHA2AGDT0J+F6tBFAKPBVxKRF58k3HihK4/k7Eekk/mfp4wQsDb+B QR2GigQjauc9FFeUnMY7d355F81CcPi09BbFdAUkUHwy1GdK5vxYpaC5unLsxgNVNmmR 7JZKQKcUHjPI8rpra1VEP60iMKzwx311ZJTRQkPq2cVhfthwSjWIa4SCoCeDiQ3KebFH ZNtuudhOuBTn+rsoc8JnZrGwhrdDQH24raHGDu/s0s36OTZIZMbRnnlXKu7h0nuY/V5U diU6QGICXqLQC4td4LkyPsvrZ3KewMBUuZnfTrnCeASh+pp1xlri7mQZIDh6CdgMGuYp 2dbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=pVvNmGJr7SGrpOyrDPKxW/l1zsiqunTWP7tnHJz4Yzk=; b=LPFLNNH0lyV9Xrh2ScG8EbvMOakCuZonvn38POfiZvtFGnD+FTIpjT3e6T8VWyZva1 xIRo9YuZyRNaDAb6Ky66+yH775SPh0GM69im0dbRUX/F4JL4722DvzzyS5J0qysdDehG cnYp2SzKJq/6go+Dy6yh9ja+jiSkZ+HJRCp32h3Zz1KNM9ZQMS2TQW51siVunM5wqfHd kWDcR097Bqf0GH4KCB8qjY8wgpCh+Ncxe2viFGrQgaWix5GbSj8OGz8FAfcYUvloQ4EF JA1cIdfdmKN6txTmMeLg9xrnhXmQwBG+clK2Dn+oXG2lv+zkXXDuxekdwSdFeoaIpHCy KzCg== X-Gm-Message-State: APjAAAW/LhYl53xirOWIyyZSHx8m0mkWY7v6d/rB6H2kYg1Wx4x7ZBNz hWORbKDHhdOkjO3mfvNCxHwKpFYQY6I= X-Google-Smtp-Source: APXvYqykMVSoivHEA4j2j/zur0ODwyCrpsUDrhUqapZGUEKFh9S407O5osP/fd6dkVm6yDO8hupVoA== X-Received: by 2002:a17:902:9343:: with SMTP id g3mr15435246plp.278.1572994691395; Tue, 05 Nov 2019 14:58:11 -0800 (PST) Received: from sc9-mailhost2.vmware.com ([66.170.99.95]) by smtp.gmail.com with ESMTPSA id j23sm9055637pfe.95.2019.11.05.14.58.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Nov 2019 14:58:10 -0800 (PST) From: William Tu To: dev@openvswitch.org Date: Tue, 5 Nov 2019 14:57:46 -0800 Message-Id: <1572994666-26627-1-git-send-email-u9012063@gmail.com> X-Mailer: git-send-email 2.7.4 X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCHv4] ofproto-dpif: Expose datapath capability to ovsdb. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org 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 Signed-off-by: William Tu Tested-by: Greg Rose Reviewed-by: Greg Rose --- v4: rebase to master v3: fix 32-bit build, reported by Greg travis: https://travis-ci.org/williamtu/ovs-travis/builds/599276267 v2: rebase to master --- ofproto/ofproto-dpif.c | 51 +++++++++++++++++++++++++++++++ ofproto/ofproto-provider.h | 2 ++ ofproto/ofproto.c | 12 ++++++++ ofproto/ofproto.h | 2 ++ tests/ovs-vsctl.at | 10 ++++++ 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, 212 insertions(+), 1 deletion(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index c35ec3e61592..fa73d06a82f4 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -5444,6 +5444,56 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id) } } +static void +get_datapath_cap(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("%"PRIuSIZE, odp.max_vlan_headers); + smap_add(cap, "max_vlan_headers", str_value); + free(str_value); + + str_value = xasprintf("%"PRIuSIZE, 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("%"PRIuSIZE, 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 zone-based timeout policy is configured. * On success, stores the timeout policy name in 'tp_name', and sets @@ -6585,4 +6635,5 @@ const struct ofproto_class ofproto_dpif_class = { ct_flush, /* ct_flush */ ct_set_zone_timeout_policy, ct_del_zone_timeout_policy, + get_datapath_cap, }; diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index c980e6bffff5..80c4fee06d01 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -1889,6 +1889,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_datapath_cap)(const char *dp_type, struct smap *caps); }; extern const struct ofproto_class ofproto_dpif_class; diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 3aaa45a9b3af..7535ba176b74 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -954,6 +954,18 @@ ofproto_get_flow_restore_wait(void) return flow_restore_wait; } +/* Retrieve datapath capabilities. */ +void +ofproto_get_datapath_cap(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_datapath_cap) { + class->get_datapath_cap(datapath_type, dp_cap); + } +} + /* Connection tracking configuration. */ void ofproto_ct_set_zone_timeout_policy(const char *datapath_type, uint16_t zone_id, diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 033c4cf93e94..48a9d602c214 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -372,6 +372,8 @@ 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_datapath_cap(const char *datapath_type, + struct smap *dp_cap); /* Configuration of ports. */ void ofproto_port_unregister(struct ofproto *, ofp_port_t ofp_port); diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at index 4d55f89e4ae3..18b9cd7c89a5 100644 --- a/tests/ovs-vsctl.at +++ b/tests/ovs-vsctl.at @@ -819,6 +819,10 @@ 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([-- --id=@m create Datapath datapath_version=0 'capabilities={recirc=true}' -- set Open_vSwitch . datapaths:"system"=@m])], [0], [stdout]) +AT_CHECK([RUN_OVS_VSCTL([list-dp-cap system])], [0], [recirc=true +]) OVS_VSCTL_CLEANUP AT_CLEANUP @@ -962,6 +966,12 @@ AT_CHECK([RUN_OVS_VSCTL([del-zone-tp netdev zone=11])], ]) 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([-- --id=@m create Datapath datapath_version=0 'capabilities={recirc=true}' -- set Open_vSwitch . datapaths:"system"=@m])], [0], [stdout]) +AT_CHECK([RUN_OVS_VSCTL([list-dp-cap nosystem])], + [1], [], [ovs-vsctl: datapath "nosystem" record not found +]) + OVS_VSCTL_CLEANUP AT_CLEANUP diff --git a/utilities/ovs-vsctl.8.in b/utilities/ovs-vsctl.8.in index 14a8aa4a48ac..ff97922dd0c6 100644 --- a/utilities/ovs-vsctl.8.in +++ b/utilities/ovs-vsctl.8.in @@ -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 diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index 7232471e68b9..bd3972636e66 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -1363,6 +1363,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); @@ -3112,6 +3137,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}, }; diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 9095ebf5d5e9..d402e39bdc68 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -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. */ unsigned int last_used; /* The last idl_seqno that this 'datapath' * used in OVSDB. This number is used for * garbage collection. */ @@ -700,6 +701,7 @@ datapath_create(const char *type) dp->type = xstrdup(type); hmap_init(&dp->ct_zones); hmap_insert(&all_datapaths, &dp->node, hash_string(type, 0)); + smap_init(&dp->caps); return dp; } @@ -716,6 +718,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); } } @@ -759,6 +762,23 @@ ct_zones_reconfigure(struct datapath *dp, struct ovsrec_datapath *dp_cfg) } static void +dp_capability_reconfigure(struct datapath *dp, + struct ovsrec_datapath *dp_cfg) +{ + struct smap_node *node; + struct smap cap; + + smap_init(&cap); + ofproto_get_datapath_cap(dp->type, &cap); + + SMAP_FOR_EACH (node, &cap) { + ovsrec_datapath_update_capabilities_setkey(dp_cfg, node->key, + node->value); + } + smap_destroy(&cap); +} + +static void datapath_reconfigure(const struct ovsrec_open_vswitch *cfg) { struct datapath *dp, *next; @@ -771,6 +791,7 @@ datapath_reconfigure(const struct ovsrec_open_vswitch *cfg) dp = datapath_lookup(dp_name); if (!dp) { dp = datapath_create(dp_name); + dp_capability_reconfigure(dp, dp_cfg); } dp->last_used = idl_seqno; ct_zones_reconfigure(dp, dp_cfg); diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema index 02be5ddeec97..0666c8c76446 100644 --- a/vswitchd/vswitch.ovsschema +++ b/vswitchd/vswitch.ovsschema @@ -1,6 +1,6 @@ {"name": "Open_vSwitch", "version": "8.2.0", - "cksum": "4076590391 26298", + "cksum": "1076640191 26427", "tables": { "Open_vSwitch": { "columns": { @@ -650,6 +650,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"}}}}, diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 00c6bd2d4ac2..8d86a5c5016b 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -5662,6 +5662,82 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ connection tracking-related OpenFlow matches and actions). + + Maximum number of 802.1q VLAN headers to serialize in a mask. + + + Maximum number of MPLS label stack entries to serialise in a mask. + + + If this is true, then recirculation fields will always be serialised. + + + If true, datapath supports OVS_KEY_ATTR_CT_STATE. + + + If true, datapath supports OVS_KEY_ATTR_CT_ZONE. + + + If true, datapath supports OVS_KEY_ATTR_CT_MARK. + + + If true, datapath supports OVS_KEY_ATTR_CT_LABEL. + + + 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. + + + Conntrack original direction tuple matching * supported. + + + Conntrack original direction tuple6 matching * supported. + + + True if the datapath supports masked data in + OVS_ACTION_ATTR_SET actions. + + + True if the datapath supports tnl_push and pop actions. + + + True if the datapath supports OVS_FLOW_ATTR_UFID. + + + True if the datapath supports OVS_ACTION_ATTR_TRUNC action. + + + True if the datapath supports OVS_ACTION_ATTR_CLONE action. + + + Maximum level of nesting allowed by OVS_ACTION_ATTR_SAMPLE action. + + + OVS_CT_ATTR_EVENTMASK supported by OVS_ACTION_ATTR_CT action. + + + True if the datapath supports OVS_ACTION_ATTR_CT_CLEAR action. + + + Highest supported dp_hash algorithm. + + + True if the datapath supports OVS_ACTION_ATTR_CHECK_PKT_LEN. + + + True if the datapath supports OVS_CT_ATTR_TIMEOUT in + OVS_ACTION_ATTR_CTaction. + + The overall purpose of these columns is described under Common Columns at the beginning of this document.