From patchwork Fri Apr 14 19:46:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Zhou X-Patchwork-Id: 750948 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3w4Ss953n9z9s7F for ; Sat, 15 Apr 2017 05:49:01 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 8964AC56; Fri, 14 Apr 2017 19:46:57 +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 69773C46 for ; Fri, 14 Apr 2017 19:46:54 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg0-f66.google.com (mail-pg0-f66.google.com [74.125.83.66]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 048BE168 for ; Fri, 14 Apr 2017 19:46:53 +0000 (UTC) Received: by mail-pg0-f66.google.com with SMTP id 63so4592528pgh.0 for ; Fri, 14 Apr 2017 12:46:53 -0700 (PDT) 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:in-reply-to :references:content-transfer-encoding; bh=bmXo6190WI/AoXuKGDv/OLjhVC6X2T+VV5biTqvgriQ=; b=P+efIo9/y4BnNzYC3mol+rP6HuL2x+yCyvqa2g5pCGO0w7HI1yqJXssIFKDkbS8req KPUL/+tF7vrxbM+IfQUvL5i3caj7V5u52imYOYrSAJoPgt4yICdofGzoeUaWD4oTww6O NaYkipeERaGhiDLug6VUi4cISJ4gt5xUUWqBYRtg6WDEI5vKo4R6AUo+r4LJdkFV6oVf tJZJtKayTzHBVs6v+0vCu1PXMP+5ZkUjIWYE+XucZUvdZU/VN+9laLz0Y3Cwx5norUe4 99JGbe6LMrplS0BViRLep9kcD+Juhri7yQbiaM0dpYNGJpb/7ZdjPuqqLay5Re9OxV6U FDVQ== X-Gm-Message-State: AN3rC/5g5heqSqk6oEHNoDabH04ffx0KY1QPeRDgSIKuyg0R382aGzyE ccWezQxOj99h1f1U X-Received: by 10.99.164.26 with SMTP id c26mr8803526pgf.89.1492199213461; Fri, 14 Apr 2017 12:46:53 -0700 (PDT) Received: from centos.eng.vmware.com ([208.91.1.34]) by smtp.gmail.com with ESMTPSA id p68sm4661584pfp.104.2017.04.14.12.46.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 14 Apr 2017 12:46:52 -0700 (PDT) From: Andy Zhou To: dev@openvswitch.org Date: Fri, 14 Apr 2017 12:46:20 -0700 Message-Id: <1492199182-4479-4-git-send-email-azhou@ovn.org> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1492199182-4479-1-git-send-email-azhou@ovn.org> References: <1492199182-4479-1-git-send-email-azhou@ovn.org> X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM 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] [action upcall meters 3/5] ofproto: Support action upcall meters 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 Allow action upcall meters, i.e. slowpath and controller meters, to be added and displayed. Keep track of datapath meter ID of those action upcall meters in ofproto to aid action translation. Later patches will make use of them. Signed-off-by: Andy Zhou Acked-by: Jarno Rajahalme --- lib/ofp-print.c | 33 ++++++++++++++++++++++++++--- ofproto/ofproto-provider.h | 4 ++++ ofproto/ofproto.c | 52 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/lib/ofp-print.c b/lib/ofp-print.c index a8cdfcbf20b1..140af05950b7 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -1333,11 +1333,36 @@ ofp_print_meter_band(struct ds *s, uint16_t flags, } static void +ofp_print_meter_id(struct ds *s, uint32_t meter_id, char seperator) +{ + if (meter_id <= OFPM13_MAX) { + ds_put_format(s, "meter%c%"PRIu32, seperator, meter_id); + } else { + const char *name; + switch (meter_id) { + case OFPM13_SLOWPATH: + name = "slowpath"; + break; + case OFPM13_CONTROLLER: + name = "controller"; + break; + case OFPM13_ALL: + name = "ALL"; + break; + default: + name = "unknown"; + } + ds_put_format(s, "meter%c%s", seperator, name); + } +} + +static void ofp_print_meter_stats(struct ds *s, const struct ofputil_meter_stats *ms) { uint16_t i; - ds_put_format(s, "meter:%"PRIu32" ", ms->meter_id); + ofp_print_meter_id(s, ms->meter_id, ':'); + ds_put_char(s, ' '); ds_put_format(s, "flow_count:%"PRIu32" ", ms->flow_count); ds_put_format(s, "packet_in_count:%"PRIu64" ", ms->packet_in_count); ds_put_format(s, "byte_in_count:%"PRIu64" ", ms->byte_in_count); @@ -1358,7 +1383,8 @@ ofp_print_meter_config(struct ds *s, const struct ofputil_meter_config *mc) { uint16_t i; - ds_put_format(s, "meter=%"PRIu32" ", mc->meter_id); + ofp_print_meter_id(s, mc->meter_id, '='); + ds_put_char(s, ' '); ofp_print_meter_flags(s, mc->flags); @@ -1412,8 +1438,9 @@ ofp_print_meter_stats_request(struct ds *s, const struct ofp_header *oh) uint32_t meter_id; ofputil_decode_meter_request(oh, &meter_id); + ds_put_char(s, ' '); - ds_put_format(s, " meter=%"PRIu32, meter_id); + ofp_print_meter_id(s, meter_id, '='); } static const char * diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 000326d7f79d..688a9e5d32eb 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -112,6 +112,10 @@ struct ofproto { /* Meter table. */ struct ofputil_meter_features meter_features; struct hmap meters; /* uint32_t indexed 'struct meter *'. */ + uint32_t slowpath_meter_id; /* Datapath slowpath meter. UINT32_MAX + if not defined. */ + uint32_t controller_meter_id; /* Datapath controller meter. UINT32_MAX + if not defined. */ /* OpenFlow connections. */ struct connmgr *connmgr; diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 8c4c7e67f213..abbb849a384b 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -568,6 +568,8 @@ ofproto_create(const char *datapath_name, const char *datapath_type, memset(&ofproto->meter_features, 0, sizeof ofproto->meter_features); } hmap_init(&ofproto->meters); + ofproto->slowpath_meter_id = UINT32_MAX; + ofproto->controller_meter_id = UINT32_MAX; /* Set the initial tables version. */ ofproto_bump_tables_version(ofproto); @@ -6232,9 +6234,33 @@ ofproto_get_meter(const struct ofproto *ofproto, uint32_t meter_id) return NULL; } +static uint32_t * +ofproto_upcall_meter_ptr(struct ofproto *ofproto, uint32_t meter_id) +{ + switch(meter_id) { + case OFPM13_SLOWPATH: + return &ofproto->slowpath_meter_id; + break; + case OFPM13_CONTROLLER: + return &ofproto->controller_meter_id; + break; + case OFPM13_ALL: + OVS_NOT_REACHED(); + default: + return NULL; + } +} + static void ofproto_add_meter(struct ofproto *ofproto, struct meter *meter) { + uint32_t *upcall_meter_ptr = ofproto_upcall_meter_ptr(ofproto, meter->id); + + /* Cache datapath meter IDs of special meters. */ + if (upcall_meter_ptr) { + *upcall_meter_ptr = meter->provider_meter_id.uint32; + } + hmap_insert(&ofproto->meters, &meter->node, hash_int(meter->id, 0)); } @@ -6248,7 +6274,7 @@ static bool ofproto_fix_meter_action(const struct ofproto *ofproto, struct ofpact_meter *ma) { - if (ma->meter_id && ma->meter_id <= ofproto->meter_features.max_meters) { + if (ma->meter_id) { const struct meter *meter = ofproto_get_meter(ofproto, ma->meter_id); if (meter && meter->provider_meter_id.uint32 != UINT32_MAX) { @@ -6306,6 +6332,12 @@ static void meter_destroy(struct ofproto *ofproto, struct meter *meter) OVS_REQUIRES(ofproto_mutex) { + uint32_t *upcall_meter_ptr; + upcall_meter_ptr = ofproto_upcall_meter_ptr(ofproto, meter->id); + if (upcall_meter_ptr) { + *upcall_meter_ptr = UINT32_MAX; + } + if (!ovs_list_is_empty(&meter->rules)) { struct rule_collection rules; struct rule *rule; @@ -6438,12 +6470,24 @@ handle_meter_mod(struct ofconn *ofconn, const struct ofp_header *oh) if (mm.command != OFPMC13_DELETE) { /* Fails also when meters are not implemented by the provider. */ - if (meter_id == 0 || meter_id > OFPM13_MAX) { + if (ofproto->meter_features.max_meters == 0) { error = OFPERR_OFPMMFC_INVALID_METER; goto exit_free_bands; - } else if (meter_id > ofproto->meter_features.max_meters) { - error = OFPERR_OFPMMFC_OUT_OF_METERS; + } + + if (meter_id == 0) { + error = OFPERR_OFPMMFC_INVALID_METER; goto exit_free_bands; + } else if (meter_id > OFPM13_MAX) { + switch(meter_id) { + case OFPM13_SLOWPATH: + case OFPM13_CONTROLLER: + break; + case OFPM13_ALL: + default: + error = OFPERR_OFPMMFC_INVALID_METER; + goto exit_free_bands; + } } if (mm.meter.n_bands > ofproto->meter_features.max_bands) { error = OFPERR_OFPMMFC_OUT_OF_BANDS;