From patchwork Tue Jul 30 11:05:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Hurley X-Patchwork-Id: 1138914 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=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="VvTsft+5"; 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 45yYqZ0NkJz9s3Z for ; Tue, 30 Jul 2019 21:14:50 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 0EC5C2AD8; Tue, 30 Jul 2019 11:13: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 DBB7A2A31 for ; Tue, 30 Jul 2019 11:06:10 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-wm1-f65.google.com (mail-wm1-f65.google.com [209.85.128.65]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 007067DB for ; Tue, 30 Jul 2019 11:06:09 +0000 (UTC) Received: by mail-wm1-f65.google.com with SMTP id l2so56223159wmg.0 for ; Tue, 30 Jul 2019 04:06:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jiHKPbdiglH0FnbYbzfXLbMB/iiNmL7GdQ1ir80glnU=; b=VvTsft+5vqbvegf+gOzAknoifAxSSR+V/Qru8eJMsb8hSGfFFITeGfQYyB6yvxEtZw bmzDbnoRnKFpzuZrnZSDyuYLCMT9asuzZAzTYPRiFZFQJ/LbUaiyAZWKU1tKkEAtSvfM B3P9BSg0pFlZBS/mnG7MR9pH5f5mJjXTkcCmR/ahVSE/myHMbqD+VsBraOlQJKuM8q3x lCdjgf/cM4BIkU4bIZI/F6ey86us8ds3teNFDHRaDuwXFKl2AEK+IHh3TJR3I/qiRm9r nc274qydOH2uiJUOfDdo45g082oz2bgOvypob5PuDRYpqSHicE/y9P0QzmvK1KAnp68t AvvA== 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=jiHKPbdiglH0FnbYbzfXLbMB/iiNmL7GdQ1ir80glnU=; b=Gy2IhUcDB9sS4m9cqGDAstvQeMH6Pw7YX2X7Q9lWxH/Xo61bMw24aT7oWKFTEBJGt9 rIIc+sJDRMy6+FDFP6o6GoUzmKs3wC1V9JKtQQQ+/Vcx72WHM5AS3QuQRLkP063e5HXG ItumsBU22l10gRVX2ttp5f9caER1mCOyH4qyHHPOKqwOc7l3zt+q/KtzccEUFZEUCW2E AZiJK4wWotnJdFEiIevfpx7yoLrrNX4ykNUak7UVwWaTzYBUfm3k8NXaGDybBsaNr3tp wlbtTN7sPZfg5FM/DWq16ufvBVNzUrUVRFRrZzuuwHuMl0Eksmbs3JcXNf9oDS2Q0A6C DC8w== X-Gm-Message-State: APjAAAVAWhzEzlVamaW9b3XipqivP1yvFK7Sy6F5vrH6YipvYgd1rc6o LoonhtQTn2B8rt9QeRu1nmTPQun84YM= X-Google-Smtp-Source: APXvYqw6J08TTiA4pKQU8fhIw6L+lxuKyCygQNn3ecM9MWTzHYs4Fh1OQtI5iCvMu2eAK3OEfkO2qQ== X-Received: by 2002:a7b:c247:: with SMTP id b7mr109152070wmj.13.1564484768117; Tue, 30 Jul 2019 04:06:08 -0700 (PDT) Received: from jhurley-Precision-Tower-3420.netronome.com ([80.76.204.157]) by smtp.gmail.com with ESMTPSA id v16sm48958021wrn.28.2019.07.30.04.06.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 30 Jul 2019 04:06:07 -0700 (PDT) From: John Hurley To: dev@openvswitch.org Date: Tue, 30 Jul 2019 12:05:16 +0100 Message-Id: <1564484717-18648-4-git-send-email-john.hurley@netronome.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1564484717-18648-1-git-send-email-john.hurley@netronome.com> References: <1564484717-18648-1-git-send-email-john.hurley@netronome.com> X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,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: fbl@sysclose.org, oss-drivers@netronome.com, simon.horman@netronome.com Subject: [ovs-dev] [PATCH OvS 3/4] ovs-tc: offload MPLS push actions to TC datapath 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 TC can now be used to push an MPLS header onto a packet. The MPLS label is the only information that needs to be passed here with the rest reverting to default values if none are supplied. OvS, however, gives the entire MPLS header to be pushed along with the MPLS protocol to use. TC can optionally accept these values so can be made replicate the OvS datapath rule. Convert OvS MPLS push datapath rules to TC format and offload to a TC datapath. Signed-off-by: John Hurley Reviewed-by: Simon Horman --- lib/netdev-offload-tc.c | 25 ++++++++++++++++++++ lib/packets.h | 24 +++++++++++++++++++ lib/tc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/tc.h | 5 ++++ 4 files changed, 115 insertions(+) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 2e282c9..03610d8 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -650,6 +650,21 @@ parse_tc_flower_to_match(struct tc_flower *flower, action->mpls.proto); } break; + case TC_ACT_MPLS_PUSH: { + struct ovs_action_push_mpls *push; + ovs_be32 mpls_lse = 0; + + flow_set_mpls_lse_label(&mpls_lse, action->mpls.label); + flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc); + flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl); + flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos); + + push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_MPLS, + sizeof *push); + push->mpls_ethertype = action->mpls.proto; + push->mpls_lse = mpls_lse; + } + break; case TC_ACT_PEDIT: { parse_flower_rewrite_to_netlink_action(buf, flower); } @@ -1333,6 +1348,16 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_VLAN) { action->type = TC_ACT_VLAN_POP; flower.action_count++; + } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_PUSH_MPLS) { + const struct ovs_action_push_mpls *mpls_push = nl_attr_get(nla); + + action->mpls.proto = mpls_push->mpls_ethertype; + action->mpls.label = mpls_lse_to_label(mpls_push->mpls_lse); + action->mpls.tc = mpls_lse_to_tc(mpls_push->mpls_lse); + action->mpls.ttl = mpls_lse_to_ttl(mpls_push->mpls_lse); + action->mpls.bos = mpls_lse_to_bos(mpls_push->mpls_lse); + action->type = TC_ACT_MPLS_PUSH; + flower.action_count++; } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_POP_MPLS) { action->mpls.proto = nl_attr_get_be16(nla); action->type = TC_ACT_MPLS_POP; diff --git a/lib/packets.h b/lib/packets.h index 4124490..a4bee38 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -574,6 +574,30 @@ mpls_lse_to_ttl(ovs_be32 mpls_lse) return (ntohl(mpls_lse) & MPLS_TTL_MASK) >> MPLS_TTL_SHIFT; } +/* Set label in mpls lse. */ +static inline void +flow_set_mpls_lse_label(ovs_be32 *mpls_lse, uint32_t label) +{ + *mpls_lse &= ~htonl(MPLS_LABEL_MASK); + *mpls_lse |= htonl(label << MPLS_LABEL_SHIFT); +} + +/* Set TC in mpls lse. */ +static inline void +flow_set_mpls_lse_tc(ovs_be32 *mpls_lse, uint8_t tc) +{ + *mpls_lse &= ~htonl(MPLS_TC_MASK); + *mpls_lse |= htonl((tc & 0x7) << MPLS_TC_SHIFT); +} + +/* Set BOS in mpls lse. */ +static inline void +flow_set_mpls_lse_bos(ovs_be32 *mpls_lse, uint8_t bos) +{ + *mpls_lse &= ~htonl(MPLS_BOS_MASK); + *mpls_lse |= htonl((bos & 0x1) << MPLS_BOS_SHIFT); +} + /* Set TTL in mpls lse. */ static inline void flow_set_mpls_lse_ttl(ovs_be32 *mpls_lse, uint8_t ttl) diff --git a/lib/tc.c b/lib/tc.c index 85aa9a1..71aa55c 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -1243,6 +1243,10 @@ static const struct nl_policy mpls_policy[] = { .min_len = sizeof(struct tc_mpls), .optional = false, }, [TCA_MPLS_PROTO] = { .type = NL_A_U16, .optional = true, }, + [TCA_MPLS_LABEL] = { .type = NL_A_U32, .optional = true, }, + [TCA_MPLS_TC] = { .type = NL_A_U8, .optional = true, }, + [TCA_MPLS_TTL] = { .type = NL_A_U8, .optional = true, }, + [TCA_MPLS_BOS] = { .type = NL_A_U8, .optional = true, }, }; static int @@ -1251,8 +1255,12 @@ nl_parse_act_mpls(struct nlattr *options, struct tc_flower *flower) struct nlattr *mpls_attrs[ARRAY_SIZE(mpls_policy)]; const struct nlattr *mpls_parms; struct nlattr *mpls_proto; + struct nlattr *mpls_label; struct tc_action *action; const struct tc_mpls *m; + struct nlattr *mpls_ttl; + struct nlattr *mpls_bos; + struct nlattr *mpls_tc; if (!nl_parse_nested(options, mpls_policy, mpls_attrs, ARRAY_SIZE(mpls_policy))) { @@ -1272,6 +1280,29 @@ nl_parse_act_mpls(struct nlattr *options, struct tc_flower *flower) } action->type = TC_ACT_MPLS_POP; break; + case TCA_MPLS_ACT_PUSH: + mpls_proto = mpls_attrs[TCA_MPLS_PROTO]; + if (mpls_proto) { + action->mpls.proto = nl_attr_get_be16(mpls_proto); + } + mpls_label = mpls_attrs[TCA_MPLS_LABEL]; + if (mpls_label) { + action->mpls.label = nl_attr_get_u32(mpls_label); + } + mpls_tc = mpls_attrs[TCA_MPLS_TC]; + if (mpls_tc) { + action->mpls.tc = nl_attr_get_u8(mpls_tc); + } + mpls_ttl = mpls_attrs[TCA_MPLS_TTL]; + if (mpls_ttl) { + action->mpls.ttl = nl_attr_get_u8(mpls_ttl); + } + mpls_bos = mpls_attrs[TCA_MPLS_BOS]; + if (mpls_bos) { + action->mpls.bos = nl_attr_get_u8(mpls_bos); + } + action->type = TC_ACT_MPLS_PUSH; + break; default: VLOG_ERR_RL(&error_rl, "unknown mpls action: %d, %d", m->action, m->m_action); @@ -1712,6 +1743,28 @@ nl_msg_put_act_pop_mpls(struct ofpbuf *request, ovs_be16 proto) } static void +nl_msg_put_act_push_mpls(struct ofpbuf *request, ovs_be16 proto, + uint32_t label, uint8_t tc, uint8_t ttl, uint8_t bos) +{ + size_t offset; + + nl_msg_put_string(request, TCA_ACT_KIND, "mpls"); + offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS | NLA_F_NESTED); + { + struct tc_mpls parm = { .action = TC_ACT_PIPE, + .m_action = TCA_MPLS_ACT_PUSH }; + + nl_msg_put_unspec(request, TCA_MPLS_PARMS, &parm, sizeof parm); + nl_msg_put_be16(request, TCA_MPLS_PROTO, proto); + nl_msg_put_u32(request, TCA_MPLS_LABEL, label); + nl_msg_put_u8(request, TCA_MPLS_TC, tc); + nl_msg_put_u8(request, TCA_MPLS_TTL, ttl); + nl_msg_put_u8(request, TCA_MPLS_BOS, bos); + } + nl_msg_end_nested(request, offset); +} + +static void nl_msg_put_act_tunnel_key_release(struct ofpbuf *request) { size_t offset; @@ -2094,6 +2147,14 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) nl_msg_end_nested(request, act_offset); } break; + case TC_ACT_MPLS_PUSH: { + act_offset = nl_msg_start_nested(request, act_index++); + nl_msg_put_act_push_mpls(request, action->mpls.proto, + action->mpls.label, action->mpls.tc, + action->mpls.ttl, action->mpls.bos); + nl_msg_end_nested(request, act_offset); + } + break; case TC_ACT_OUTPUT: { ingress = action->out.ingress; ifindex = action->out.ifindex_out; diff --git a/lib/tc.h b/lib/tc.h index 7805f69..a498a84 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -154,6 +154,7 @@ enum tc_action_type { TC_ACT_VLAN_POP, TC_ACT_VLAN_PUSH, TC_ACT_MPLS_POP, + TC_ACT_MPLS_PUSH, }; struct tc_action { @@ -171,6 +172,10 @@ struct tc_action { struct { ovs_be16 proto; + uint32_t label; + uint8_t tc; + uint8_t ttl; + uint8_t bos; } mpls; struct {