From patchwork Fri Feb 2 06:08:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wenxu X-Patchwork-Id: 868518 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=) 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 3zXmlM1HG5z9s7F for ; Fri, 2 Feb 2018 17:09:02 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 3B8F1DE7; Fri, 2 Feb 2018 06:08:59 +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 34240DE6 for ; Fri, 2 Feb 2018 06:08:58 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from m97138.mail.qiye.163.com (m97138.mail.qiye.163.com [220.181.97.138]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 3DDFA14F for ; Fri, 2 Feb 2018 06:08:55 +0000 (UTC) Received: from localhost.localdomain (unknown [123.59.132.129]) by smtp9 (Coremail) with SMTP id u+CowAD3_yN1AHRaFy9UAA--.35S2; Fri, 02 Feb 2018 14:08:53 +0800 (CST) From: wenxu@ucloud.cn To: dev@openvswitch.org Date: Fri, 2 Feb 2018 14:08:52 +0800 Message-Id: <1517551732-592-1-git-send-email-wenxu@ucloud.cn> X-Mailer: git-send-email 1.8.3.1 X-CM-TRANSID: u+CowAD3_yN1AHRaFy9UAA--.35S2 X-Coremail-Antispam: 1Uf129KBjvJXoW3XF1DuF4xZF13uFyrXr1fZwb_yoW3AFykpF 4Dtry3Jr4rtFy3X347tw42vw1agw4vkanrKryxWw4ayFsrX34qqFyUKF1j9F4rJrW5CrZI qFn8trWUAan3WaDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0Jba3kZUUUUU= X-Originating-IP: [123.59.132.129] X-CM-SenderInfo: xzhq53w6xfz0lxgou0/1tbicRXgKFlZtoHozwAAs8 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: frank.zeng@ucloud.cn Subject: [ovs-dev] [PATCH] ofproto-dpif-xlate: native tunnel using valid tun_src specified by flow or port options 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 From: wenxu native tunnel build tunnel with tun_src only from the route src and not care about the options:local_ip. Sometimes an virtual IP using for tun_src dpdk-br: inet 10.1.1.7/24 brd 10.1.1.255 scope global dpdk-br inet 10.1.1.254/32 scope global dpdk-br Interface: gre options: {key=flow, local_ip="10.1.1.254", remote_ip=flow} the native tunnel always using 10.1.1.7 as the tunnel_src but not 10.1.1.254. This patch made valid tun_src specified by flow-action or gre port options can be used for tunnel_src of packet. It stores the rtm_type for each route and improve the priority RTN_LOCAL type(higher then userdef route). Like the kernel space when lookup the route, if there are tun_src specified by flow-action or port options. Check the tun_src wheather is a local address, then lookup the route. Signed-off-by: wenxu Signed-off-by: frank.zeng --- lib/ovs-router.c | 38 +++++++++++++++++++++++++++++++------- lib/ovs-router.h | 2 +- lib/route-table.c | 10 ++++++++-- ofproto/ofproto-dpif-sflow.c | 2 +- ofproto/ofproto-dpif-xlate.c | 4 ++++ 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/lib/ovs-router.c b/lib/ovs-router.c index 0f1103b..e1375a3 100644 --- a/lib/ovs-router.c +++ b/lib/ovs-router.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "classifier.h" #include "command-line.h" @@ -61,6 +62,7 @@ struct ovs_router_entry { struct in6_addr nw_addr; struct in6_addr src_addr; uint8_t plen; + uint8_t rtm_type; uint8_t priority; uint32_t mark; }; @@ -97,13 +99,28 @@ ovs_router_lookup(uint32_t mark, const struct in6_addr *ip6_dst, const struct cls_rule *cr; struct flow flow = {.ipv6_dst = *ip6_dst, .pkt_mark = mark}; + if (src && ipv6_addr_is_set(src)) { + const struct cls_rule *cr_src; + struct flow flow_src = {.ipv6_dst = *src, .pkt_mark = mark}; + + cr_src = classifier_lookup(&cls, OVS_VERSION_MAX, &flow_src, NULL); + if (cr_src) { + struct ovs_router_entry *p_src = ovs_router_entry_cast(cr_src); + if (p_src->rtm_type != RTN_LOCAL) { + return false; + } + } else { + return false; + } + } + cr = classifier_lookup(&cls, OVS_VERSION_MAX, &flow, NULL); if (cr) { struct ovs_router_entry *p = ovs_router_entry_cast(cr); ovs_strlcpy(output_bridge, p->output_bridge, IFNAMSIZ); *gw = p->gw; - if (src) { + if (src && !ipv6_addr_is_set(src)) { *src = p->src_addr; } return true; @@ -184,7 +201,7 @@ out: } static int -ovs_router_insert__(uint32_t mark, uint8_t priority, +ovs_router_insert__(uint32_t mark, uint8_t priority, uint8_t rtm_type, const struct in6_addr *ip6_dst, uint8_t plen, const char output_bridge[], const struct in6_addr *gw) @@ -204,6 +221,7 @@ ovs_router_insert__(uint32_t mark, uint8_t priority, p->mark = mark; p->nw_addr = match.flow.ipv6_dst; p->plen = plen; + p->rtm_type = rtm_type; p->priority = priority; err = get_src_addr(ip6_dst, output_bridge, &p->src_addr); if (err && ipv6_addr_is_set(gw)) { @@ -236,9 +254,10 @@ ovs_router_insert__(uint32_t mark, uint8_t priority, void ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst, uint8_t plen, - const char output_bridge[], const struct in6_addr *gw) + uint8_t rtm_type, const char output_bridge[], + const struct in6_addr *gw) { - ovs_router_insert__(mark, plen, ip_dst, plen, output_bridge, gw); + ovs_router_insert__(mark, plen, rtm_type, ip_dst, plen, output_bridge, gw); } static void @@ -345,7 +364,7 @@ ovs_router_add(struct unixctl_conn *conn, int argc, } } - err = ovs_router_insert__(mark, plen + 32, &ip6, plen, argv[2], &gw6); + err = ovs_router_insert__(mark, plen + 32, RTN_UNICAST, &ip6, plen, argv[2], &gw6); if (err) { unixctl_command_reply_error(conn, "Error while inserting route."); } else { @@ -402,7 +421,12 @@ ovs_router_show(struct unixctl_conn *conn, int argc OVS_UNUSED, ipv6_format_mapped(&rt->nw_addr, &ds); plen = rt->plen; if (IN6_IS_ADDR_V4MAPPED(&rt->nw_addr)) { - plen -= 96; + uint8_t plen_off = 96; + + if (rt->rtm_type == RTN_LOCAL) { + plen_off += 64; + } + plen -= plen_off; } ds_put_format(&ds, "/%"PRIu8, plen); if (rt->mark) { @@ -426,7 +450,7 @@ static void ovs_router_lookup_cmd(struct unixctl_conn *conn, int argc, const char *argv[], void *aux OVS_UNUSED) { - struct in6_addr gw, src; + struct in6_addr gw, src = in6addr_any; char iface[IFNAMSIZ]; struct in6_addr ip6; unsigned int plen; diff --git a/lib/ovs-router.h b/lib/ovs-router.h index b55b1a5..f41771b 100644 --- a/lib/ovs-router.h +++ b/lib/ovs-router.h @@ -31,7 +31,7 @@ bool ovs_router_lookup(uint32_t mark, const struct in6_addr *ip_dst, struct in6_addr *src, struct in6_addr *gw); void ovs_router_init(void); void ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst, - uint8_t plen, + uint8_t plen, uint8_t rtm_type, const char output_bridge[], const struct in6_addr *gw); void ovs_router_flush(void); #ifdef __cplusplus diff --git a/lib/route-table.c b/lib/route-table.c index 97a0be5..e75d24e 100644 --- a/lib/route-table.c +++ b/lib/route-table.c @@ -47,6 +47,7 @@ VLOG_DEFINE_THIS_MODULE(route_table); struct route_data { /* Copied from struct rtmsg. */ unsigned char rtm_dst_len; + unsigned char rtm_type; /* Extracted from Netlink attributes. */ struct in6_addr rta_dst; /* 0 if missing. */ @@ -228,6 +229,7 @@ route_table_parse(struct ofpbuf *buf, struct route_table_msg *change) if (parsed) { const struct nlmsghdr *nlmsg; int rta_oif; /* Output interface index. */ + uint8_t dst_len_off = 96; nlmsg = buf->data; @@ -243,7 +245,11 @@ route_table_parse(struct ofpbuf *buf, struct route_table_msg *change) change->relevant = false; } change->nlmsg_type = nlmsg->nlmsg_type; - change->rd.rtm_dst_len = rtm->rtm_dst_len + (ipv4 ? 96 : 0); + if (rtm->rtm_type == RTN_LOCAL) { + dst_len_off += 64; + } + change->rd.rtm_dst_len = rtm->rtm_dst_len + (ipv4 ? dst_len_off : 0); + change->rd.rtm_type = rtm->rtm_type; if (attrs[RTA_OIF]) { rta_oif = nl_attr_get_u32(attrs[RTA_OIF]); @@ -306,7 +312,7 @@ route_table_handle_msg(const struct route_table_msg *change) const struct route_data *rd = &change->rd; ovs_router_insert(rd->mark, &rd->rta_dst, rd->rtm_dst_len, - rd->ifname, &rd->rta_gw); + rd->rtm_type, rd->ifname, &rd->rta_gw); } } diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index 60e1b4e..0a79623 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -467,7 +467,7 @@ sflow_choose_agent_address(const char *agent_device, if (inet_parse_active(target, SFL_DEFAULT_COLLECTOR_PORT, &sa.ss) && sa.ss.ss_family == AF_INET) { - struct in6_addr addr6, src, gw; + struct in6_addr addr6, gw, src = in6addr_any; in6_addr_set_mapped_ipv4(&addr6, sa.sin.sin_addr.s_addr); /* sFlow only supports target in default routing table with diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index cc450a8..4e62dab 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3319,6 +3319,10 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, memcpy(&old_base_flow, &ctx->base_flow, sizeof old_base_flow); memcpy(&old_flow, &ctx->xin->flow, sizeof old_flow); + if (flow->tunnel.ip_src) { + in6_addr_set_mapped_ipv4(&s_ip6, flow->tunnel.ip_src); + } + err = tnl_route_lookup_flow(ctx, flow, &d_ip6, &s_ip6, &out_dev); if (err) { xlate_report(ctx, OFT_WARN, "native tunnel routing failed");