From patchwork Mon Oct 22 22:24:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mary Manohar X-Patchwork-Id: 987964 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) 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=nutanix.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=nutanix.com header.i=@nutanix.com header.b="RMQ7feeF"; 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 42fB0j4Wcfz9sMx for ; Tue, 23 Oct 2018 09:25:09 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id ACD2BB0B; Mon, 22 Oct 2018 22:24:13 +0000 (UTC) X-Original-To: ovs-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 BC0A1A91 for ; Mon, 22 Oct 2018 22:24:11 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx0b-002c1b01.pphosted.com (mx0b-002c1b01.pphosted.com [148.163.155.12]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id A212B833 for ; Mon, 22 Oct 2018 22:24:10 +0000 (UTC) Received: from pps.filterd (m0127843.ppops.net [127.0.0.1]) by mx0b-002c1b01.pphosted.com (8.16.0.23/8.16.0.23) with SMTP id w9MMK3Ew008312 for ; Mon, 22 Oct 2018 15:24:09 -0700 Received: from nam05-co1-obe.outbound.protection.outlook.com (mail-co1nam05lp0087.outbound.protection.outlook.com [216.32.181.87]) by mx0b-002c1b01.pphosted.com with ESMTP id 2n82fg45tx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Mon, 22 Oct 2018 15:24:09 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=e0cxZmyMCrXbGQ1Hz+Zy11iUboi+JfjrPeAt0gfo9yE=; b=RMQ7feeFu1ONdzQjLW45RD+bbOI10gWtjbBpkaGnQgqIs0Oi0n6b2SfVw3W5EVgrABKNb7+BezhtsIE3luDXpOIjinvU05fpeHCViFet0sOGDPlbbV7N9y+dzjsXMTaKyCHGjFL3bKjZuOOXDMvJIwOnf6365W0ewmKg0WHZuS0= Received: from SN6PR02MB3933.namprd02.prod.outlook.com (52.135.69.14) by SN6PR02MB5135.namprd02.prod.outlook.com (52.135.99.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1228.26; Mon, 22 Oct 2018 22:24:07 +0000 Received: from SN6PR02MB3933.namprd02.prod.outlook.com ([fe80::3cf5:568:99f2:f27]) by SN6PR02MB3933.namprd02.prod.outlook.com ([fe80::3cf5:568:99f2:f27%3]) with mapi id 15.20.1250.028; Mon, 22 Oct 2018 22:24:07 +0000 From: Mary Manohar To: "ovs-dev@openvswitch.org" Thread-Topic: [PATCH v1 2/3] [2/3] Routing policies, add routing-policies in ovn-nbctl Thread-Index: AQHUalXyumoXrgVnKkWpKpT7K2xdHg== Date: Mon, 22 Oct 2018 22:24:07 +0000 Message-ID: <1540247132-167477-3-git-send-email-mary.manohar@nutanix.com> References: <1540247132-167477-1-git-send-email-mary.manohar@nutanix.com> In-Reply-To: <1540247132-167477-1-git-send-email-mary.manohar@nutanix.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR05CA0104.namprd05.prod.outlook.com (2603:10b6:a03:e0::45) To SN6PR02MB3933.namprd02.prod.outlook.com (2603:10b6:805:2b::14) x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [205.209.132.11] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; SN6PR02MB5135; 6:c0jzQjDs6nax64Kk+kfydq2Fr0FwKBOybpp9C5fRIM30sBhbqOdG/qg2hNLElpEFTtyud2R5wHPpchujt65GT/e/+SdD+hRfvYc3I6W81SRg5G9XwVENoTRj82UwO5W+0vcRektSHbIOMpo75u2o0khDfCEAsW9+RNf9hgHhsjQUMUAG0ncmwEjQxMqXVuigl2oT6n1SCCr4RQEESscWhh/b1doZoLdZrp4T9OiCIlgcMh9kDBetqtpUrO6lB6X3J1Pv6GwCXjvWtNCBQnYi0h5TUhnGIud9rY23PCqD+S9DL1LM3668VcM3IZGw0xZ4GM8ZAxHPrEPDrphtqKj6KR/GvZfXcj2gsf+cIVBxZ8Utj71b/cdI3321XG5vIqVhi1q3oYALK7RKDB63VpB9o7pJjslkAY1jxWFY1fjR6r2mDSx/SDJgi7Kr/rZcTmNIb7lZ3VD1UfJhksDP1gejgA==; 5:Hliod+Th8ZEo4/RSni4y0PcTFBF+sE/Q3rMvPMKYLvYJS/foH7pixl+Iw8Y47Wl4s6xRJHV8sLSYdxyqX91KDCAY09CxrDGVO8Q48nWz9zyySo/nEedwr7zSb/rjETviWsvq+1VsIhf2b11YZWX4252mRw4pMrDoj+vVaiu81kg=; 7:U1IbilOCMO5oVG1xWMj/gvx8VNs2GybQGLyS9ohklYlzTUdkZHjMxp/UwfjY4OqZxUxSGhuf+cnXil6KnZoqu2F64O06YnT3A6kY9tp2olEjE1+2YHNroz/I3Ib629AM6UEnGQVp4cedcrskinDYPpYTLS6RizstYyJE9agaDXiMcLE18/ySHZMn/WRAXBKce1R0gkp0tSpDn8fR9nPgonzbXV0L3PFi9+3rggkCSZ3gWJjRyQJE8QMKGkFbNjLf x-ms-office365-filtering-correlation-id: f6952927-4f33-471f-7f66-08d6386d14c8 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(7168020)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7167020)(7153060)(7193020); SRVR:SN6PR02MB5135; x-ms-traffictypediagnostic: SN6PR02MB5135: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(8121501046)(5005006)(10201501046)(3002001)(3231355)(944501410)(52105095)(93006095)(93001095)(148016)(149066)(150057)(6041310)(20161123560045)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:SN6PR02MB5135; BCL:0; PCL:0; RULEID:; SRVR:SN6PR02MB5135; x-forefront-prvs: 08331F819E x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(39860400002)(366004)(396003)(376002)(136003)(346002)(199004)(189003)(44832011)(68736007)(6506007)(55236004)(102836004)(107886003)(186003)(8676002)(386003)(14454004)(86362001)(2906002)(6512007)(478600001)(6916009)(25786009)(36756003)(6116002)(3846002)(316002)(53936002)(2900100001)(5250100002)(5660300001)(11346002)(2501003)(6486002)(446003)(2616005)(476003)(97736004)(486006)(2351001)(256004)(105586002)(81156014)(14444005)(71190400001)(99286004)(305945005)(106356001)(8936002)(81166006)(76176011)(52116002)(26005)(71200400001)(6436002)(66066001)(7736002)(4326008)(5640700003)(64030200001); DIR:OUT; SFP:1102; SCL:1; SRVR:SN6PR02MB5135; H:SN6PR02MB3933.namprd02.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: nutanix.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: Av5w8wPRCKxwxJ/sa8qO1acX2pawT/KuxE5ft9qBm7S5kjvbcsCtQzRlGI9uWHL6pokFJ1NJVjtSc8I3ZfVCsacUaWMfuNLBNjTWvcqRM/L6XgmW2y541U9nQQi+gsd684v7NABvyKHgveU4AIGOLROty2j6Ll8OJvvACEYaQoddNbccKlE+crl6gXzxle75XXg/IoNR01Pmz+CjuhTqak43YQ77ReyuuakwM3t8c8a+ymuhXfCazUeZfnkZ4lWzWTvoWHmEhipNrD6CUknScXQoVDSXlDr/UBC9EibYLCEljIACXEZBA7JZWO8AaOq842+EoNp1jZU4bgWWaxPSGv5nuvl3T+lurF/rPJ+X0UI= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: f6952927-4f33-471f-7f66-08d6386d14c8 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Oct 2018 22:24:07.4931 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: bb047546-786f-4de1-bd75-24e5b6f79043 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR02MB5135 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-10-22_11:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1810220188 X-Spam-Status: No, score=-0.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, KHOP_DYNAMIC, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Mary Manohar Subject: [ovs-dev] [PATCH v1 2/3] [2/3] Routing policies, add routing-policies in ovn-nbctl 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: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This Series: Policy-Based Routing This patch: Add commands to ovn-nbctl to add/delete/list routing policies. Routing-policy commands: lr-policy-add ROUTER PRIORITY MATCH ACTION [NEXTHOP] add a policy to router lr-policy-del ROUTER [PRIORITY [MATCH]] lr-policy-list ROUTER print policies for ROUTER lr-policy-add : A policy is uniquely identified by priority and match. Multiple policies can have the same priority. lr-policy-del : takes priority and match as optional parameters. If priority is not specified, all the rules would be deleted. If priority is specified, all rules with that priority are deleted. If priority and match are specified, the policy with the given priority and match is deleted. lr-policy-list : mandates ROUTER parameter. Sample CLI: ovn-nbctl lr-policy-add lr1 10 "ip4.src == 1.1.1.0/24" drop ovn-nbctl lr-policy-del lr1 10 ovn-nbctl lr-policy-list lr1 --- ovn/utilities/ovn-nbctl.c | 196 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c index 798c972..920024b 100644 --- a/ovn/utilities/ovn-nbctl.c +++ b/ovn/utilities/ovn-nbctl.c @@ -642,6 +642,13 @@ Route commands:\n\ remove routes from ROUTER\n\ lr-route-list ROUTER print routes for ROUTER\n\ \n\ +Policy commands:\n\ + lr-policy-add ROUTER PRIORITY MATCH ACTION [NEXTHOP]\n\ + add a policy to router\n\ + lr-policy-del ROUTER [PRIORITY [MATCH]]\n\ + remove policies from ROUTER\n\ + lr-policy-list ROUTER print policies for ROUTER\n\ +\n\ NAT commands:\n\ lr-nat-add ROUTER TYPE EXTERNAL_IP LOGICAL_IP [LOGICAL_PORT EXTERNAL_MAC]\n\ add a NAT to ROUTER\n\ @@ -3395,6 +3402,187 @@ normalize_prefix_str(const char *orig_prefix) return normalize_ipv6_prefix(ipv6, plen); } } + +static void +nbctl_lr_policy_add(struct ctl_context *ctx) +{ + const struct nbrec_logical_router *lr; + int64_t priority = 0; + char *error = lr_by_name_or_uuid(ctx, ctx->argv[1], true, &lr); + if (error) { + ctx->error = error; + return; + } + error = parse_priority(ctx->argv[2], &priority); + if (error) { + ctx->error = error; + return; + } + const char *action = ctx->argv[4]; + char *next_hop = NULL; + /* Validate action. */ + if (strcmp(action, "allow") && strcmp(action, "drop") + && strcmp(action, "reroute")) { + ctl_error(ctx, "%s: action must be one of \"allow\", \"drop\", " + "and \"reroute\"", action); + } + if (!strcmp(action, "reroute")) { + if (ctx->argc < 6) { + ctl_error(ctx, "Nexthop is not specified when action is reroute."); + } + } + /* Check if same routing policy already exists. + * A policy is uniquely identified by priority and match */ + for (int i = 0; i < lr->n_policies; i++) { + const struct nbrec_logical_router_policy *policy = lr->policies[i]; + if ((policy->priority == priority) && + (!strcmp(policy->match, ctx->argv[3]))) { + ctl_error(ctx, "Same routing policy already existed on the " + "logical router %s.", ctx->argv[1]); + } + } + if (ctx->argc == 6) { + next_hop = normalize_prefix_str(ctx->argv[5]); + if (!next_hop) { + ctl_error(ctx, "bad next hop argument: %s", ctx->argv[5]); + } + } + struct nbrec_logical_router_policy *policy; + policy = nbrec_logical_router_policy_insert(ctx->txn); + nbrec_logical_router_policy_set_priority(policy, priority); + nbrec_logical_router_policy_set_match(policy, ctx->argv[3]); + nbrec_logical_router_policy_set_action(policy, action); + if (ctx->argc == 6) { + nbrec_logical_router_policy_set_nexthop(policy, next_hop); + } + nbrec_logical_router_verify_policies(lr); + struct nbrec_logical_router_policy **new_policies + = xmalloc(sizeof *new_policies * (lr->n_policies + 1)); + memcpy(new_policies, lr->policies, + sizeof *new_policies * lr->n_policies); + new_policies[lr->n_policies] = policy; + nbrec_logical_router_set_policies(lr, new_policies, + lr->n_policies + 1); + free(new_policies); + if (next_hop != NULL) + free(next_hop); +} + +static void +nbctl_lr_policy_del(struct ctl_context *ctx) +{ + const struct nbrec_logical_router *lr; + int64_t priority = 0; + char *error = lr_by_name_or_uuid(ctx, ctx->argv[1], true, &lr); + if (error) { + ctx->error = error; + return; + } + if (ctx->argc == 2) { + /* If a priority is not specified, delete all policies. */ + nbrec_logical_router_set_policies(lr, NULL, 0); + return; + } + error = parse_priority(ctx->argv[2], &priority); + if (error) { + ctx->error = error; + return; + } + /* If match is not specified, delete all routing policies with the + * specified priority. */ + if (ctx->argc == 3) { + struct nbrec_logical_router_policy **new_policies + = xmemdup(lr->policies, + sizeof *new_policies * lr->n_policies); + int n_policies = 0; + for (int i = 0; i < lr->n_policies; i++) { + if (priority != lr->policies[i]->priority) { + new_policies[n_policies++] = lr->policies[i]; + } + } + nbrec_logical_router_verify_policies(lr); + nbrec_logical_router_set_policies(lr, new_policies, n_policies); + free(new_policies); + return; + } + /* Delete policy that has the same priority and match string */ + for (int i = 0; i < lr->n_policies; i++) { + struct nbrec_logical_router_policy *routing_policy = lr->policies[i]; + if (priority == routing_policy->priority && + !strcmp(ctx->argv[3], routing_policy->match)) { + struct nbrec_logical_router_policy **new_policies + = xmemdup(lr->policies, + sizeof *new_policies * lr->n_policies); + new_policies[i] = lr->policies[lr->n_policies - 1]; + nbrec_logical_router_verify_policies(lr); + nbrec_logical_router_set_policies(lr, new_policies, + lr->n_policies - 1); + free(new_policies); + return; + } + } +} + + struct routing_policy { + int priority; + char *match; + const struct nbrec_logical_router_policy *policy; +}; + +static int +routing_policy_cmp(const void *policy1_, const void *policy2_) +{ + const struct routing_policy *policy1p = policy1_; + const struct routing_policy *policy2p = policy2_; + if (policy1p->priority != policy2p->priority) { + return policy1p->priority > policy2p->priority ? -1 : 1; + } else { + return strcmp(policy1p->match, policy2p->match); + } +} + +static void +print_routing_policy(const struct nbrec_logical_router_policy *policy, struct ds *s) +{ + if (policy->nexthop != NULL) { + char *next_hop = normalize_prefix_str(policy->nexthop); + ds_put_format(s, "%10ld %50s %15s %25s", policy->priority, policy->match, + policy->action, next_hop); + free(next_hop); + } else + ds_put_format(s, "%10ld %50s %15s", policy->priority, policy->match, policy->action); + ds_put_char(s, '\n'); +} + +static void +nbctl_lr_policy_list(struct ctl_context *ctx) +{ + const struct nbrec_logical_router *lr; + struct routing_policy *policies; + size_t n_policies = 0; + char *error = lr_by_name_or_uuid(ctx, ctx->argv[1], true, &lr); + if (error) { + ctx->error = error; + return; + } + policies = xmalloc(sizeof *policies * lr->n_policies); + for (int i = 0; i < lr->n_policies; i++) { + const struct nbrec_logical_router_policy *policy + = lr->policies[i]; + policies[n_policies].priority = policy->priority; + policies[n_policies].match = policy->match; + policies[n_policies].policy = policy; + n_policies++; + } + qsort(policies, n_policies, sizeof *policies, routing_policy_cmp); + if (n_policies) { + ds_put_cstr(&ctx->output, "Routing Policies\n"); + } + for (int i = 0; i < n_policies; i++) { + print_routing_policy(policies[i].policy, &ctx->output); + } + free(policies); +} static void nbctl_lr_route_add(struct ctl_context *ctx) @@ -5143,6 +5331,14 @@ static const struct ctl_command_syntax nbctl_commands[] = { { "lr-route-list", 1, 1, "ROUTER", NULL, nbctl_lr_route_list, NULL, "", RO }, + /* Policy commands */ + { "lr-policy-add", 4, 5, "ROUTER PRIORITY MATCH ACTION [NEXTHOP]", NULL, + nbctl_lr_policy_add, NULL, "", RW }, + { "lr-policy-del", 1, 3, "ROUTER [PRIORITY [MATCH]]", NULL, + nbctl_lr_policy_del, NULL, "", RW }, + { "lr-policy-list", 1, 1, "ROUTER", NULL, nbctl_lr_policy_list, NULL, + "", RO }, + /* NAT commands. */ { "lr-nat-add", 4, 6, "ROUTER TYPE EXTERNAL_IP LOGICAL_IP [LOGICAL_PORT EXTERNAL_MAC]", NULL,