From patchwork Mon Dec 14 02:20:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tonghao Zhang X-Patchwork-Id: 1415731 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.166.136; helo=silver.osuosl.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.a=rsa-sha256 header.s=20161025 header.b=rrqWhNcZ; dkim-atps=neutral Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CvQCn0Y9bz9sTc for ; Mon, 14 Dec 2020 13:23:01 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 8A39A2047B; Mon, 14 Dec 2020 02:22:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Q-Jcbj7UG5fu; Mon, 14 Dec 2020 02:22:43 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by silver.osuosl.org (Postfix) with ESMTP id 6AF7120498; Mon, 14 Dec 2020 02:22:28 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 23942C1833; Mon, 14 Dec 2020 02:22:28 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id CA702C088E for ; Mon, 14 Dec 2020 02:22:26 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id B92F385BF2 for ; Mon, 14 Dec 2020 02:22:26 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Vna28Vz3N9nv for ; Mon, 14 Dec 2020 02:22:26 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f195.google.com (mail-pg1-f195.google.com [209.85.215.195]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 09F3F85A74 for ; Mon, 14 Dec 2020 02:22:26 +0000 (UTC) Received: by mail-pg1-f195.google.com with SMTP id n10so3451234pgl.10 for ; Sun, 13 Dec 2020 18:22:26 -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:in-reply-to:references; bh=TiyRHsBcNAmXi+1bMSyi1GARAIyD0JhRVloxU+Ey0dw=; b=rrqWhNcZxTSMJ00KcjaUvtmCO6+kowP+LtdGCXKGqbYnPOSg2S5KiWIghqZtfWS2+8 MhMnY3Xf0UhwcCeMkXvf95AZpPob1V3LRgPHoPZO39VGCWnWJwrUiOA7VbJ25a3+dwlJ DCHe0hfdFL9XyeeBQfim4SNmx9M669gr8vJWOkOoSpscvRvgNnepg76iX4qx/2AtfW6u 9X2Pmtfm1GdIJWAfZOZMLET6V3lQpKsZBTnnE6pUFudo49pRRtqM/xtD+h5LTdI7Ly9b VWcZWjPbGBUKMo8C5TK+dtD5UlH5VNQwRAtIsfD5l+GzYl+B4ueA4d/OxQ3n9EyqVPZb 4zqQ== 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; bh=TiyRHsBcNAmXi+1bMSyi1GARAIyD0JhRVloxU+Ey0dw=; b=PF+QLjZ4QZcf7LVgkRDHrn4UZWYNVjSANpSM1TXPor8NnEbSc/W0ukTeMUSBsSARke dZcUXho5sqoMFLqWaQ7OvDF9JQL45B0KRUrSUu+Ul2xQXV7ZYoZlozhVFJas9rZT1XXO ErBM6EkMVgP/NEsYknwCCSP7oIBH6tl/I1BI9KxwHhgcygPFgou5SBiYf2w9sT4D/RWJ KhAQH50yO0K0+SmVtoCiOUCK4EZGXlflMHrJxrB9LQLKJbwcNxI1iNEi5wpYbnmFdiEm +DLLFsyi7oDLKlw/DOr7mm+br4nYVwViTXb00WEq0btEZtNMKKb1MrfNBnr45q7fyhcM 5QkA== X-Gm-Message-State: AOAM531kgp00COD+t/jTjBki0rHPjSjGz9R1z1k+XCCvmVAdhucSw6yc eLAFMqwtgPByOfSV9WtQByk= X-Google-Smtp-Source: ABdhPJxZQkmW6yMyu6ANOdbkuLkU9fsRHqLHL96nyJY10NRjKMhTei5kCUcoE0OPgG1pqJJrCHmwiQ== X-Received: by 2002:aa7:8d19:0:b029:1a3:82bd:908a with SMTP id j25-20020aa78d190000b02901a382bd908amr7730293pfe.58.1607912545687; Sun, 13 Dec 2020 18:22:25 -0800 (PST) Received: from localhost.localdomain ([50.236.19.102]) by smtp.gmail.com with ESMTPSA id z7sm18019540pfq.193.2020.12.13.18.22.22 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 13 Dec 2020 18:22:25 -0800 (PST) From: xiangxia.m.yue@gmail.com To: blp@ovn.org, i.maximets@ovn.org, u9012063@gmail.com, elibr@nvidia.com Date: Mon, 14 Dec 2020 10:20:01 +0800 Message-Id: <20201214022001.84273-5-xiangxia.m.yue@gmail.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> References: <20201214022001.84273-1-xiangxia.m.yue@gmail.com> Cc: dev@openvswitch.org Subject: [ovs-dev] [PATCH ovs v1 4/4] ovs-router: Allow openvswitch installing fake routes. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Tonghao Zhang Now we can only add route entries which are on the same subnet with openvswitch bridges. With this patch, users can add "fake" route entries to openvswich which can use them to encapsulate packets. Signed-off-by: Tonghao Zhang --- lib/ovs-router.c | 121 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 46 deletions(-) diff --git a/lib/ovs-router.c b/lib/ovs-router.c index 09b81c6e5..9cb9b3540 100644 --- a/lib/ovs-router.c +++ b/lib/ovs-router.c @@ -47,6 +47,9 @@ #include "unaligned.h" #include "openvswitch/vlog.h" +#define PRIO_USER(plen) ((plen) + 32) +#define PRIO_LOCAL(plen) ((plen) + 64) + VLOG_DEFINE_THIS_MODULE(ovs_router); static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -216,7 +219,8 @@ static int ovs_router_insert__(uint32_t mark, uint8_t priority, bool local, const struct in6_addr *ip6_dst, uint8_t plen, const char output_bridge[], - const struct in6_addr *gw) + const struct in6_addr *gw, + const struct in6_addr *ip6_src) { const struct cls_rule *cr; struct ovs_router_entry *p; @@ -235,19 +239,24 @@ ovs_router_insert__(uint32_t mark, uint8_t priority, bool local, p->plen = plen; p->local = local; p->priority = priority; - err = get_src_addr(ip6_dst, output_bridge, &p->src_addr); - if (err && ipv6_addr_is_set(gw)) { - err = get_src_addr(gw, output_bridge, &p->src_addr); + if (!ip6_src || !ipv6_addr_is_set(ip6_src)) { + err = get_src_addr(ip6_dst, output_bridge, &p->src_addr); + if (err && ipv6_addr_is_set(gw)) { + err = get_src_addr(gw, output_bridge, &p->src_addr); + } + if (err) { + struct ds ds = DS_EMPTY_INITIALIZER; + + ipv6_format_mapped(ip6_dst, &ds); + VLOG_DBG_RL(&rl, "src addr not available for route %s", ds_cstr(&ds)); + free(p); + ds_destroy(&ds); + return err; + } + } else { + p->src_addr = *ip6_src; } - if (err) { - struct ds ds = DS_EMPTY_INITIALIZER; - ipv6_format_mapped(ip6_dst, &ds); - VLOG_DBG_RL(&rl, "src addr not available for route %s", ds_cstr(&ds)); - free(p); - ds_destroy(&ds); - return err; - } /* Longest prefix matches first. */ cls_rule_init(&p->cr, &match, priority); @@ -270,8 +279,9 @@ ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst, uint8_t plen, const struct in6_addr *gw) { if (use_system_routing_table) { - uint8_t priority = local ? plen + 64 : plen; - ovs_router_insert__(mark, priority, local, ip_dst, plen, output_bridge, gw); + uint8_t priority = local ? PRIO_LOCAL(plen) : plen; + ovs_router_insert__(mark, priority, local, ip_dst, plen, + output_bridge, gw, NULL); } } @@ -338,48 +348,64 @@ static void ovs_router_add(struct unixctl_conn *conn, int argc, const char *argv[], void *aux OVS_UNUSED) { + struct in6_addr src6 = in6addr_any; struct in6_addr gw6 = in6addr_any; struct in6_addr ip6; - uint32_t mark = 0; - unsigned int plen; + ovs_be32 src = 0; + ovs_be32 gw = 0; ovs_be32 ip; + bool ipv4_route_entry = true; + bool ipv4_local = false; + uint32_t lastargc = 0; + uint32_t mark = 0; + uint32_t plen; int err; - if (scan_ipv4_route(argv[1], &ip, &plen)) { - ovs_be32 gw = 0; + if (!scan_ipv4_route(argv[1], &ip, &plen)) { + if (!scan_ipv6_route(argv[1], &ip6, &plen)) { + unixctl_command_reply_error(conn, "Invalid parameters"); + return; + } + ipv4_route_entry = false; + } - if (argc > 3) { - if (!ovs_scan(argv[3], "pkt_mark=%"SCNi32, &mark) && - !ip_parse(argv[3], &gw)) { - unixctl_command_reply_error(conn, "Invalid pkt_mark or gateway"); - return; - } + while (argc > 3 && lastargc != argc) { + lastargc = argc; + + if (!strncmp(argv[argc - 1], "pkt_mark=", 9)) { + err = !ovs_scan(argv[--argc] + 9, "pkt_mark=%"SCNi32, &mark); + } else if (!strncmp(argv[argc - 1], "src_addr=", 9)) { + err = ipv4_route_entry ? + !ip_parse(argv[--argc] + 9, &src) : + !ipv6_parse(argv[--argc] + 9, &src6); + } else { + err = ipv4_route_entry ? + !ip_parse(argv[--argc], &gw) : + !ipv6_parse(argv[--argc], &gw6); + } + + if (err) { + unixctl_command_reply_error(conn, "Invalid pkt_mark, src_addr or gateway"); + return; } + } + + if (ipv4_route_entry) { in6_addr_set_mapped_ipv4(&ip6, ip); if (gw) { in6_addr_set_mapped_ipv4(&gw6, gw); } - plen += 96; - } else if (scan_ipv6_route(argv[1], &ip6, &plen)) { - if (argc > 3) { - if (!ovs_scan(argv[3], "pkt_mark=%"SCNi32, &mark) && - !ipv6_parse(argv[3], &gw6)) { - unixctl_command_reply_error(conn, "Invalid pkt_mark or IPv6 gateway"); - return; - } + if (src) { + in6_addr_set_mapped_ipv4(&src6, src); } - } else { - unixctl_command_reply_error(conn, "Invalid parameters"); - return; - } - if (argc > 4) { - if (!ovs_scan(argv[4], "pkt_mark=%"SCNi32, &mark)) { - unixctl_command_reply_error(conn, "Invalid pkt_mark"); - return; + if (plen == 32) { + ipv4_local = true; } + plen += 96; } - err = ovs_router_insert__(mark, plen + 32, false, &ip6, plen, argv[2], &gw6); + err = ovs_router_insert__(mark, PRIO_USER(plen), ipv4_local, &ip6, plen, + argv[2], &gw6, &src6); if (err) { unixctl_command_reply_error(conn, "Error while inserting route."); } else { @@ -410,7 +436,7 @@ ovs_router_del(struct unixctl_conn *conn, int argc OVS_UNUSED, } } - if (rt_entry_delete(mark, plen + 32, &ip6, plen)) { + if (rt_entry_delete(mark, PRIO_USER(plen), &ip6, plen)) { unixctl_command_reply(conn, "OK"); seq_change(tnl_conf_seq); } else { @@ -428,7 +454,8 @@ ovs_router_show(struct unixctl_conn *conn, int argc OVS_UNUSED, ds_put_format(&ds, "Route Table:\n"); CLS_FOR_EACH(rt, cr, &cls) { uint8_t plen; - if (rt->priority == rt->plen || rt->local) { + if (rt->priority == rt->plen || + (rt->local && rt->priority == PRIO_LOCAL(rt->plen))) { ds_put_format(&ds, "Cached: "); } else { ds_put_format(&ds, "User: "); @@ -505,7 +532,8 @@ ovs_router_flush(void) ovs_mutex_lock(&mutex); classifier_defer(&cls); CLS_FOR_EACH(rt, cr, &cls) { - if (rt->priority == rt->plen || rt->local) { + if (rt->priority == rt->plen || + (rt->local && rt->priority == PRIO_LOCAL(rt->plen))) { rt_entry_delete__(&rt->cr); } } @@ -530,8 +558,9 @@ ovs_router_init(void) classifier_init(&cls, NULL); unixctl_command_register("ovs/route/add", "ip_addr/prefix_len out_br_name [gw] " - "[pkt_mark=mark]", - 2, 4, ovs_router_add, NULL); + "[pkt_mark=mark]" + "[src_addr=src]", + 2, 5, ovs_router_add, NULL); unixctl_command_register("ovs/route/show", "", 0, 0, ovs_router_show, NULL); unixctl_command_register("ovs/route/del", "ip_addr/prefix_len "