From patchwork Mon Jul 16 10:00:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianbo Liu X-Patchwork-Id: 944274 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=mellanox.com 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 41Tf7n52Mpz9rxs for ; Mon, 16 Jul 2018 20:01:25 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 5129FC9D; Mon, 16 Jul 2018 10:00:23 +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 E9B62AF8 for ; Mon, 16 Jul 2018 10:00:20 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 0358867E for ; Mon, 16 Jul 2018 10:00:18 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jianbol@mellanox.com) with ESMTPS (AES256-SHA encrypted); 16 Jul 2018 13:03:18 +0300 Received: from r-vrt-24-60.mtr.labs.mlnx. (r-vrt-24-60.mtr.labs.mlnx [10.213.24.60]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w6GA0D4g027489; Mon, 16 Jul 2018 13:00:13 +0300 From: Jianbo Liu To: dev@openvswitch.org, simon.horman@netronome.com Date: Mon, 16 Jul 2018 10:00:00 +0000 Message-Id: <20180716100003.19174-2-jianbol@mellanox.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20180716100003.19174-1-jianbol@mellanox.com> References: <20180716100003.19174-1-jianbol@mellanox.com> X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 1/4] tc: Add VLAN tpid for push action 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 Currently we only support 802.1q, so we can offload push action without specifying any vlan type. Kernel will push 802.1q ethertype by default. But to support QinQ, we need to tell what ethertype is in push action as it could be 802.1ad. Signed-off-by: Jianbo Liu Reviewed-by: Roi Dayan --- lib/netdev-tc-offloads.c | 1 + lib/tc.c | 7 ++++++- lib/tc.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c index bdf288c..93a762d 100644 --- a/lib/netdev-tc-offloads.c +++ b/lib/netdev-tc-offloads.c @@ -1077,6 +1077,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_PUSH_VLAN) { const struct ovs_action_push_vlan *vlan_push = nl_attr_get(nla); + action->vlan.vlan_push_tpid = vlan_push->vlan_tpid; action->vlan.vlan_push_id = vlan_tci_to_vid(vlan_push->vlan_tci); action->vlan.vlan_push_prio = vlan_tci_to_pcp(vlan_push->vlan_tci); action->type = TC_ACT_VLAN_PUSH; diff --git a/lib/tc.c b/lib/tc.c index 7a71036..66234ce 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -784,9 +784,11 @@ nl_parse_act_vlan(struct nlattr *options, struct tc_flower *flower) vlan_parms = vlan_attrs[TCA_VLAN_PARMS]; v = nl_attr_get_unspec(vlan_parms, sizeof *v); if (v->v_action == TCA_VLAN_ACT_PUSH) { + struct nlattr *vlan_tpid = vlan_attrs[TCA_VLAN_PUSH_VLAN_PROTOCOL]; struct nlattr *vlan_id = vlan_attrs[TCA_VLAN_PUSH_VLAN_ID]; struct nlattr *vlan_prio = vlan_attrs[TCA_VLAN_PUSH_VLAN_PRIORITY]; + action->vlan.vlan_push_tpid = nl_attr_get_u16(vlan_tpid); action->vlan.vlan_push_id = nl_attr_get_u16(vlan_id); action->vlan.vlan_push_prio = vlan_prio ? nl_attr_get_u8(vlan_prio) : 0; action->type = TC_ACT_VLAN_PUSH; @@ -1158,7 +1160,8 @@ nl_msg_put_act_pedit(struct ofpbuf *request, struct tc_pedit *parm, } static void -nl_msg_put_act_push_vlan(struct ofpbuf *request, uint16_t vid, uint8_t prio) +nl_msg_put_act_push_vlan(struct ofpbuf *request, uint16_t tpid, + uint16_t vid, uint8_t prio) { size_t offset; @@ -1169,6 +1172,7 @@ nl_msg_put_act_push_vlan(struct ofpbuf *request, uint16_t vid, uint8_t prio) .v_action = TCA_VLAN_ACT_PUSH }; nl_msg_put_unspec(request, TCA_VLAN_PARMS, &parm, sizeof parm); + nl_msg_put_u16(request, TCA_VLAN_PUSH_VLAN_PROTOCOL, tpid); nl_msg_put_u16(request, TCA_VLAN_PUSH_VLAN_ID, vid); nl_msg_put_u8(request, TCA_VLAN_PUSH_VLAN_PRIORITY, prio); } @@ -1489,6 +1493,7 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower) case TC_ACT_VLAN_PUSH: { act_offset = nl_msg_start_nested(request, act_index++); nl_msg_put_act_push_vlan(request, + action->vlan.vlan_push_tpid, action->vlan.vlan_push_id, action->vlan.vlan_push_prio); nl_msg_end_nested(request, act_offset); diff --git a/lib/tc.h b/lib/tc.h index 80505f0..d954819 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -119,6 +119,7 @@ struct tc_action { int ifindex_out; struct { + ovs_be16 vlan_push_tpid; uint16_t vlan_push_id; uint8_t vlan_push_prio; } vlan; From patchwork Mon Jul 16 10:00:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianbo Liu X-Patchwork-Id: 944278 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=mellanox.com 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 41Tf9D1V86z9rxs for ; Mon, 16 Jul 2018 20:02:40 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 2C670C9A; Mon, 16 Jul 2018 10:00:26 +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 D3E43C7A for ; Mon, 16 Jul 2018 10:00:21 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 02202FC for ; Mon, 16 Jul 2018 10:00:18 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jianbol@mellanox.com) with ESMTPS (AES256-SHA encrypted); 16 Jul 2018 13:03:18 +0300 Received: from r-vrt-24-60.mtr.labs.mlnx. (r-vrt-24-60.mtr.labs.mlnx [10.213.24.60]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w6GA0D4h027489; Mon, 16 Jul 2018 13:00:14 +0300 From: Jianbo Liu To: dev@openvswitch.org, simon.horman@netronome.com Date: Mon, 16 Jul 2018 10:00:01 +0000 Message-Id: <20180716100003.19174-3-jianbol@mellanox.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20180716100003.19174-1-jianbol@mellanox.com> References: <20180716100003.19174-1-jianbol@mellanox.com> X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 2/4] netdev-tc-offloads: Add support to match on 802.1AD ethertype 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 Currently, we assume VLAN ethtertype is 0x8100, but it could be 0x88a8 if QinQ is supported. Signed-off-by: Jianbo Liu Reviewed-by: Roi Dayan --- lib/netdev-tc-offloads.c | 6 +++--- lib/tc.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c index 93a762d..5c15f6a 100644 --- a/lib/netdev-tc-offloads.c +++ b/lib/netdev-tc-offloads.c @@ -430,7 +430,7 @@ parse_tc_flower_to_match(struct tc_flower *flower, match_set_dl_src_masked(match, key->src_mac, mask->src_mac); match_set_dl_dst_masked(match, key->dst_mac, mask->dst_mac); - if (key->eth_type == htons(ETH_TYPE_VLAN)) { + if (eth_type_vlan(key->eth_type)) { match_set_dl_vlan(match, htons(key->vlan_id)); match_set_dl_vlan_pcp(match, key->vlan_prio); match_set_dl_type(match, key->encap_eth_type); @@ -517,7 +517,7 @@ parse_tc_flower_to_match(struct tc_flower *flower, push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_VLAN, sizeof *push); - push->vlan_tpid = htons(ETH_TYPE_VLAN); + push->vlan_tpid = action->vlan.vlan_push_tpid; push->vlan_tci = htons(action->vlan.vlan_push_id | (action->vlan.vlan_push_prio << 13) | VLAN_CFI); @@ -962,7 +962,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, VLOG_DBG_RL(&rl, "vlan_prio: %d\n", flower.key.vlan_prio); } flower.key.encap_eth_type = flower.key.eth_type; - flower.key.eth_type = htons(ETH_TYPE_VLAN); + flower.key.eth_type = key->vlans[0].tpid; } else if (mask->vlans[0].tci == htons(0xffff) && ntohs(key->vlans[0].tci) == 0) { /* exact && no vlan */ diff --git a/lib/tc.c b/lib/tc.c index 66234ce..5030399 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -332,7 +332,7 @@ nl_parse_flower_eth(struct nlattr **attrs, struct tc_flower *flower) static void nl_parse_flower_vlan(struct nlattr **attrs, struct tc_flower *flower) { - if (flower->key.eth_type != htons(ETH_TYPE_VLAN)) { + if (!eth_type_vlan(flower->key.eth_type)) { return; } @@ -1576,7 +1576,7 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) { uint16_t host_eth_type = ntohs(flower->key.eth_type); - bool is_vlan = (host_eth_type == ETH_TYPE_VLAN); + bool is_vlan = eth_type_vlan(flower->key.eth_type); int err; /* need to parse acts first as some acts require changing the matching From patchwork Mon Jul 16 10:00:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianbo Liu X-Patchwork-Id: 944271 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=mellanox.com 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 41Tf6j3YyBz9rxs for ; Mon, 16 Jul 2018 20:00:24 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id A9B99B1E; Mon, 16 Jul 2018 10:00:21 +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 43F0FAF8 for ; Mon, 16 Jul 2018 10:00:20 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 036B671F for ; Mon, 16 Jul 2018 10:00:18 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jianbol@mellanox.com) with ESMTPS (AES256-SHA encrypted); 16 Jul 2018 13:03:19 +0300 Received: from r-vrt-24-60.mtr.labs.mlnx. (r-vrt-24-60.mtr.labs.mlnx [10.213.24.60]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w6GA0D4i027489; Mon, 16 Jul 2018 13:00:14 +0300 From: Jianbo Liu To: dev@openvswitch.org, simon.horman@netronome.com Date: Mon, 16 Jul 2018 10:00:02 +0000 Message-Id: <20180716100003.19174-4-jianbol@mellanox.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20180716100003.19174-1-jianbol@mellanox.com> References: <20180716100003.19174-1-jianbol@mellanox.com> X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 3/4] flow: Refactor some of VLAN helper functions 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 By default, these function are to change the first vlan vid and pcp in the flow. Add a parameter as index for vlans if we want to handle the second ones. Signed-off-by: Jianbo Liu Reviewed-by: Roi Dayan --- include/openvswitch/match.h | 4 ++-- lib/flow.c | 14 +++++++------- lib/flow.h | 4 ++-- lib/match.c | 14 +++++++------- lib/meta-flow.c | 8 ++++---- lib/netdev-tc-offloads.c | 4 ++-- ovn/controller/physical.c | 2 +- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/openvswitch/match.h b/include/openvswitch/match.h index 49e463a..b43ecb1 100644 --- a/include/openvswitch/match.h +++ b/include/openvswitch/match.h @@ -163,11 +163,11 @@ void match_set_dl_dst_masked(struct match *, const struct eth_addr dl_dst, void match_set_dl_tci(struct match *, ovs_be16 tci); void match_set_dl_tci_masked(struct match *, ovs_be16 tci, ovs_be16 mask); void match_set_any_vid(struct match *); -void match_set_dl_vlan(struct match *, ovs_be16); +void match_set_dl_vlan(struct match *, ovs_be16, int id); void match_set_vlan_vid(struct match *, ovs_be16); void match_set_vlan_vid_masked(struct match *, ovs_be16 vid, ovs_be16 mask); void match_set_any_pcp(struct match *); -void match_set_dl_vlan_pcp(struct match *, uint8_t); +void match_set_dl_vlan_pcp(struct match *, uint8_t, int id); void match_set_any_mpls_lse(struct match *, int idx); void match_set_mpls_lse(struct match *, int idx, ovs_be32); void match_set_any_mpls_label(struct match *, int idx); diff --git a/lib/flow.c b/lib/flow.c index 76a8b9a..77ed3d9 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -2520,14 +2520,14 @@ flow_hash_in_wildcards(const struct flow *flow, * * - Other values of 'vid' should not be used. */ void -flow_set_dl_vlan(struct flow *flow, ovs_be16 vid) +flow_set_dl_vlan(struct flow *flow, ovs_be16 vid, int id) { if (vid == htons(OFP10_VLAN_NONE)) { - flow->vlans[0].tci = htons(0); + flow->vlans[id].tci = htons(0); } else { vid &= htons(VLAN_VID_MASK); - flow->vlans[0].tci &= ~htons(VLAN_VID_MASK); - flow->vlans[0].tci |= htons(VLAN_CFI) | vid; + flow->vlans[id].tci &= ~htons(VLAN_VID_MASK); + flow->vlans[id].tci |= htons(VLAN_CFI) | vid; } } @@ -2560,11 +2560,11 @@ flow_set_vlan_vid(struct flow *flow, ovs_be16 vid) * After calling this function, 'flow' will not match packets without a VLAN * header. */ void -flow_set_vlan_pcp(struct flow *flow, uint8_t pcp) +flow_set_vlan_pcp(struct flow *flow, uint8_t pcp, int id) { pcp &= 0x07; - flow->vlans[0].tci &= ~htons(VLAN_PCP_MASK); - flow->vlans[0].tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI); + flow->vlans[id].tci &= ~htons(VLAN_PCP_MASK); + flow->vlans[id].tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI); } /* Counts the number of VLAN headers. */ diff --git a/lib/flow.h b/lib/flow.h index af7b5e9..d03f1ba 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -99,10 +99,10 @@ static inline int flow_compare_3way(const struct flow *, const struct flow *); static inline bool flow_equal(const struct flow *, const struct flow *); static inline size_t flow_hash(const struct flow *, uint32_t basis); -void flow_set_dl_vlan(struct flow *, ovs_be16 vid); +void flow_set_dl_vlan(struct flow *, ovs_be16 vid, int id); void flow_fix_vlan_tpid(struct flow *); void flow_set_vlan_vid(struct flow *, ovs_be16 vid); -void flow_set_vlan_pcp(struct flow *, uint8_t pcp); +void flow_set_vlan_pcp(struct flow *, uint8_t pcp, int id); void flow_limit_vlans(int vlan_limit); int flow_count_vlan_headers(const struct flow *); diff --git a/lib/match.c b/lib/match.c index bf7e636..2281fa0 100644 --- a/lib/match.c +++ b/lib/match.c @@ -705,13 +705,13 @@ match_set_any_vid(struct match *match) * VID equals the low 12 bits of 'dl_vlan'. */ void -match_set_dl_vlan(struct match *match, ovs_be16 dl_vlan) +match_set_dl_vlan(struct match *match, ovs_be16 dl_vlan, int id) { - flow_set_dl_vlan(&match->flow, dl_vlan); + flow_set_dl_vlan(&match->flow, dl_vlan, id); if (dl_vlan == htons(OFP10_VLAN_NONE)) { - match->wc.masks.vlans[0].tci = OVS_BE16_MAX; + match->wc.masks.vlans[id].tci = OVS_BE16_MAX; } else { - match->wc.masks.vlans[0].tci |= htons(VLAN_VID_MASK | VLAN_CFI); + match->wc.masks.vlans[id].tci |= htons(VLAN_VID_MASK | VLAN_CFI); } } @@ -757,10 +757,10 @@ match_set_any_pcp(struct match *match) /* Modifies 'match' so that it matches only packets with an 802.1Q header whose * PCP equals the low 3 bits of 'dl_vlan_pcp'. */ void -match_set_dl_vlan_pcp(struct match *match, uint8_t dl_vlan_pcp) +match_set_dl_vlan_pcp(struct match *match, uint8_t dl_vlan_pcp, int id) { - flow_set_vlan_pcp(&match->flow, dl_vlan_pcp); - match->wc.masks.vlans[0].tci |= htons(VLAN_CFI | VLAN_PCP_MASK); + flow_set_vlan_pcp(&match->flow, dl_vlan_pcp, id); + match->wc.masks.vlans[id].tci |= htons(VLAN_CFI | VLAN_PCP_MASK); } /* Modifies 'match' so that the MPLS label 'idx' matches 'lse' exactly. */ diff --git a/lib/meta-flow.c b/lib/meta-flow.c index db0abb3..fd8f3c6 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -1136,7 +1136,7 @@ mf_set_value(const struct mf_field *mf, break; case MFF_DL_VLAN: - match_set_dl_vlan(match, value->be16); + match_set_dl_vlan(match, value->be16, 0); break; case MFF_VLAN_VID: match_set_vlan_vid(match, value->be16); @@ -1144,7 +1144,7 @@ mf_set_value(const struct mf_field *mf, case MFF_DL_VLAN_PCP: case MFF_VLAN_PCP: - match_set_dl_vlan_pcp(match, value->u8); + match_set_dl_vlan_pcp(match, value->u8, 0); break; case MFF_MPLS_LABEL: @@ -1538,7 +1538,7 @@ mf_set_flow_value(const struct mf_field *mf, break; case MFF_DL_VLAN: - flow_set_dl_vlan(flow, value->be16); + flow_set_dl_vlan(flow, value->be16, 0); flow_fix_vlan_tpid(flow); break; @@ -1549,7 +1549,7 @@ mf_set_flow_value(const struct mf_field *mf, case MFF_DL_VLAN_PCP: case MFF_VLAN_PCP: - flow_set_vlan_pcp(flow, value->u8); + flow_set_vlan_pcp(flow, value->u8, 0); flow_fix_vlan_tpid(flow); break; diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c index 5c15f6a..3405458 100644 --- a/lib/netdev-tc-offloads.c +++ b/lib/netdev-tc-offloads.c @@ -432,8 +432,8 @@ parse_tc_flower_to_match(struct tc_flower *flower, if (eth_type_vlan(key->eth_type)) { match_set_dl_vlan(match, htons(key->vlan_id)); - match_set_dl_vlan_pcp(match, key->vlan_prio); - match_set_dl_type(match, key->encap_eth_type); + match_set_dl_vlan_pcp(match, key->vlan_prio, 0); + match_set_dl_type(match, key->encap_eth_type, 0); flow_fix_vlan_tpid(&match->flow); } else { match_set_dl_type(match, key->eth_type); diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index dcf2183..c38d7b0 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -549,7 +549,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name, * for frames that lack any 802.1Q header later. */ if (tag || !strcmp(binding->type, "localnet") || !strcmp(binding->type, "l2gateway")) { - match_set_dl_vlan(&match, htons(tag)); + match_set_dl_vlan(&match, htons(tag), 0); if (nested_container) { /* When a packet comes from a container sitting behind a * parent_port, we should let it loopback to other containers From patchwork Mon Jul 16 10:00:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jianbo Liu X-Patchwork-Id: 944272 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=mellanox.com 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 41Tf781CwVz9rxs for ; Mon, 16 Jul 2018 20:00:52 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 7BFE3C93; Mon, 16 Jul 2018 10:00:22 +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 711FCAF8 for ; Mon, 16 Jul 2018 10:00:20 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 06DBF76E for ; Mon, 16 Jul 2018 10:00:18 +0000 (UTC) Received: from Internal Mail-Server by MTLPINE1 (envelope-from jianbol@mellanox.com) with ESMTPS (AES256-SHA encrypted); 16 Jul 2018 13:03:18 +0300 Received: from r-vrt-24-60.mtr.labs.mlnx. (r-vrt-24-60.mtr.labs.mlnx [10.213.24.60]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id w6GA0D4j027489; Mon, 16 Jul 2018 13:00:14 +0300 From: Jianbo Liu To: dev@openvswitch.org, simon.horman@netronome.com Date: Mon, 16 Jul 2018 10:00:03 +0000 Message-Id: <20180716100003.19174-5-jianbol@mellanox.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20180716100003.19174-1-jianbol@mellanox.com> References: <20180716100003.19174-1-jianbol@mellanox.com> X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 4/4] Add support to offload QinQ double VLAN headers match 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 Currently the inner VLAN header is ignored when using the TC data-path. As TC flower supports QinQ, now we can offload the rules to match on both outer and inner VLAN headers. Signed-off-by: Jianbo Liu Reviewed-by: Roi Dayan --- acinclude.m4 | 6 ++--- include/linux/pkt_cls.h | 6 ++++- lib/dpif-netlink.c | 2 +- lib/netdev-tc-offloads.c | 57 ++++++++++++++++++++++++++++++++++++-------- lib/tc.c | 62 +++++++++++++++++++++++++++++++++++++++++------- lib/tc.h | 7 +++--- 6 files changed, 113 insertions(+), 27 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 991a627..d6e0d33 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -178,10 +178,10 @@ dnl Configure Linux tc compat. AC_DEFUN([OVS_CHECK_LINUX_TC], [ AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([#include ], [ - int x = TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST; + int x = TCA_FLOWER_KEY_CVLAN_PRIO; ])], - [AC_DEFINE([HAVE_TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST], [1], - [Define to 1 if TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST is avaiable.])]) + [AC_DEFINE([HAVE_TCA_FLOWER_KEY_CVLAN_PRIO], [1], + [Define to 1 if TCA_FLOWER_KEY_CVLAN_PRIO is avaiable.])]) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([#include ], [ diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 60976f3..442323d 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -1,7 +1,7 @@ #ifndef __LINUX_PKT_CLS_WRAPPER_H #define __LINUX_PKT_CLS_WRAPPER_H 1 -#if defined(__KERNEL__) || defined(HAVE_TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST) +#if defined(__KERNEL__) || defined(HAVE_TCA_FLOWER_KEY_CVLAN_PRIO) #include_next #else @@ -196,6 +196,10 @@ enum { TCA_FLOWER_KEY_IP_TTL, /* u8 */ TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */ + TCA_FLOWER_KEY_CVLAN_ID, /* be16 */ + TCA_FLOWER_KEY_CVLAN_PRIO, /* u8 */ + TCA_FLOWER_KEY_CVLAN_ETH_TYPE, /* be16 */ + __TCA_FLOWER_MAX, }; diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index aa9bbd9..62c7120 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -1709,7 +1709,7 @@ dpif_netlink_netdev_match_to_dpif_flow(struct match *match, .flow = &match->flow, .mask = &match->wc.masks, .support = { - .max_vlan_headers = 1, + .max_vlan_headers = 2, }, }; size_t offset; diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c index 3405458..272e86e 100644 --- a/lib/netdev-tc-offloads.c +++ b/lib/netdev-tc-offloads.c @@ -431,9 +431,20 @@ parse_tc_flower_to_match(struct tc_flower *flower, match_set_dl_dst_masked(match, key->dst_mac, mask->dst_mac); if (eth_type_vlan(key->eth_type)) { - match_set_dl_vlan(match, htons(key->vlan_id)); - match_set_dl_vlan_pcp(match, key->vlan_prio, 0); - match_set_dl_type(match, key->encap_eth_type, 0); + match->flow.vlans[0].tpid = key->eth_type; + match->wc.masks.vlans[0].tpid = OVS_BE16_MAX; + match_set_dl_vlan(match, htons(key->vlan_id[0]), 0); + match_set_dl_vlan_pcp(match, key->vlan_prio[0], 0); + + if (eth_type_vlan(key->encap_eth_type[0])) { + match_set_dl_vlan(match, htons(key->vlan_id[1]), 1); + match_set_dl_vlan_pcp(match, key->vlan_prio[1], 1); + match_set_dl_type(match, key->encap_eth_type[1]); + match->flow.vlans[1].tpid = key->encap_eth_type[0]; + match->wc.masks.vlans[1].tpid = OVS_BE16_MAX; + } else { + match_set_dl_type(match, key->encap_eth_type[0]); + } flow_fix_vlan_tpid(&match->flow); } else { match_set_dl_type(match, key->eth_type); @@ -954,14 +965,14 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, && (!pcp_mask || pcp_mask == htons(VLAN_PCP_MASK)) && (vid_mask || pcp_mask)) { if (vid_mask) { - flower.key.vlan_id = vlan_tci_to_vid(key->vlans[0].tci); - VLOG_DBG_RL(&rl, "vlan_id: %d\n", flower.key.vlan_id); + flower.key.vlan_id[0] = vlan_tci_to_vid(key->vlans[0].tci); + VLOG_DBG_RL(&rl, "vlan_id[0]: %d\n", flower.key.vlan_id[0]); } if (pcp_mask) { - flower.key.vlan_prio = vlan_tci_to_pcp(key->vlans[0].tci); - VLOG_DBG_RL(&rl, "vlan_prio: %d\n", flower.key.vlan_prio); + flower.key.vlan_prio[0] = vlan_tci_to_pcp(key->vlans[0].tci); + VLOG_DBG_RL(&rl, "vlan_prio[0]: %d\n", flower.key.vlan_prio[0]); } - flower.key.encap_eth_type = flower.key.eth_type; + flower.key.encap_eth_type[0] = flower.key.eth_type; flower.key.eth_type = key->vlans[0].tpid; } else if (mask->vlans[0].tci == htons(0xffff) && ntohs(key->vlans[0].tci) == 0) { @@ -970,8 +981,34 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, /* partial mask */ return EOPNOTSUPP; } - } else if (mask->vlans[1].tci) { - return EOPNOTSUPP; + } + + if (mask->vlans[1].tci) { + ovs_be16 vid_mask = mask->vlans[1].tci & htons(VLAN_VID_MASK); + ovs_be16 pcp_mask = mask->vlans[1].tci & htons(VLAN_PCP_MASK); + ovs_be16 cfi = mask->vlans[1].tci & htons(VLAN_CFI); + + if (cfi && key->vlans[1].tci & htons(VLAN_CFI) + && (!vid_mask || vid_mask == htons(VLAN_VID_MASK)) + && (!pcp_mask || pcp_mask == htons(VLAN_PCP_MASK)) + && (vid_mask || pcp_mask)) { + if (vid_mask) { + flower.key.vlan_id[1] = vlan_tci_to_vid(key->vlans[1].tci); + VLOG_DBG_RL(&rl, "vlan_id[1]: %d", flower.key.vlan_id[1]); + } + if (pcp_mask) { + flower.key.vlan_prio[1] = vlan_tci_to_pcp(key->vlans[1].tci); + VLOG_DBG_RL(&rl, "vlan_prio[1]: %d", flower.key.vlan_prio[1]); + } + flower.key.encap_eth_type[1] = flower.key.encap_eth_type[0]; + flower.key.encap_eth_type[0] = key->vlans[1].tpid; + } else if (mask->vlans[1].tci == htons(0xffff) && + ntohs(key->vlans[1].tci) == 0) { + /* exact && no vlan */ + } else { + /* partial mask */ + return EOPNOTSUPP; + } } memset(mask->vlans, 0, sizeof mask->vlans); diff --git a/lib/tc.c b/lib/tc.c index 5030399..2157135 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -306,6 +306,9 @@ static const struct nl_policy tca_flower_policy[] = { .optional = true, }, [TCA_FLOWER_KEY_TCP_FLAGS_MASK] = { .type = NL_A_U16, .optional = true, }, + [TCA_FLOWER_KEY_CVLAN_ID] = { .type = NL_A_U16, .optional = true, }, + [TCA_FLOWER_KEY_CVLAN_PRIO] = { .type = NL_A_U8, .optional = true, }, + [TCA_FLOWER_KEY_CVLAN_ETH_TYPE] = { .type = NL_A_U16, .optional = true, }, }; static void @@ -332,21 +335,44 @@ nl_parse_flower_eth(struct nlattr **attrs, struct tc_flower *flower) static void nl_parse_flower_vlan(struct nlattr **attrs, struct tc_flower *flower) { + ovs_be16 encap_ethtype; + if (!eth_type_vlan(flower->key.eth_type)) { return; } - flower->key.encap_eth_type = + flower->key.encap_eth_type[0] = nl_attr_get_be16(attrs[TCA_FLOWER_KEY_ETH_TYPE]); if (attrs[TCA_FLOWER_KEY_VLAN_ID]) { - flower->key.vlan_id = + flower->key.vlan_id[0] = nl_attr_get_u16(attrs[TCA_FLOWER_KEY_VLAN_ID]); } if (attrs[TCA_FLOWER_KEY_VLAN_PRIO]) { - flower->key.vlan_prio = + flower->key.vlan_prio[0] = nl_attr_get_u8(attrs[TCA_FLOWER_KEY_VLAN_PRIO]); } + + if (!attrs[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) { + return; + } + + encap_ethtype = nl_attr_get_be16(attrs[TCA_FLOWER_KEY_VLAN_ETH_TYPE]); + if (!eth_type_vlan(encap_ethtype)) { + return; + } + + flower->key.encap_eth_type[1] = flower->key.encap_eth_type[0]; + flower->key.encap_eth_type[0] = encap_ethtype; + + if (attrs[TCA_FLOWER_KEY_CVLAN_ID]) { + flower->key.vlan_id[1] = + nl_attr_get_u16(attrs[TCA_FLOWER_KEY_CVLAN_ID]); + } + if (attrs[TCA_FLOWER_KEY_CVLAN_PRIO]) { + flower->key.vlan_prio[1] = + nl_attr_get_u8(attrs[TCA_FLOWER_KEY_CVLAN_PRIO]); + } } static void @@ -1577,6 +1603,7 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) uint16_t host_eth_type = ntohs(flower->key.eth_type); bool is_vlan = eth_type_vlan(flower->key.eth_type); + bool is_qinq = is_vlan && eth_type_vlan(flower->key.encap_eth_type[0]); int err; /* need to parse acts first as some acts require changing the matching @@ -1587,7 +1614,11 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) } if (is_vlan) { - host_eth_type = ntohs(flower->key.encap_eth_type); + if (is_qinq) { + host_eth_type = ntohs(flower->key.encap_eth_type[1]); + } else { + host_eth_type = ntohs(flower->key.encap_eth_type[0]); + } } FLOWER_PUT_MASKED_VALUE(dst_mac, TCA_FLOWER_KEY_ETH_DST); @@ -1631,15 +1662,28 @@ nl_msg_put_flower_options(struct ofpbuf *request, struct tc_flower *flower) nl_msg_put_be16(request, TCA_FLOWER_KEY_ETH_TYPE, flower->key.eth_type); if (is_vlan) { - if (flower->key.vlan_id || flower->key.vlan_prio) { + if (flower->key.vlan_id[0] || flower->key.vlan_prio[0]) { nl_msg_put_u16(request, TCA_FLOWER_KEY_VLAN_ID, - flower->key.vlan_id); + flower->key.vlan_id[0]); nl_msg_put_u8(request, TCA_FLOWER_KEY_VLAN_PRIO, - flower->key.vlan_prio); + flower->key.vlan_prio[0]); } - if (flower->key.encap_eth_type) { + if (flower->key.encap_eth_type[0]) { nl_msg_put_be16(request, TCA_FLOWER_KEY_VLAN_ETH_TYPE, - flower->key.encap_eth_type); + flower->key.encap_eth_type[0]); + } + + if (is_qinq) { + if (flower->key.vlan_id[1] || flower->key.vlan_prio[1]) { + nl_msg_put_u16(request, TCA_FLOWER_KEY_CVLAN_ID, + flower->key.vlan_id[1]); + nl_msg_put_u8(request, TCA_FLOWER_KEY_CVLAN_PRIO, + flower->key.vlan_prio[1]); + } + if (flower->key.encap_eth_type[1]) { + nl_msg_put_be16(request, TCA_FLOWER_KEY_CVLAN_ETH_TYPE, + flower->key.encap_eth_type[1]); + } } } diff --git a/lib/tc.h b/lib/tc.h index d954819..447d85f 100644 --- a/lib/tc.h +++ b/lib/tc.h @@ -26,6 +26,7 @@ #include "netlink-socket.h" #include "odp-netlink.h" #include "openvswitch/ofpbuf.h" +#include "openvswitch/flow.h" /* For backwards compatability with older kernels */ #ifndef TC_H_CLSACT @@ -87,10 +88,10 @@ struct tc_flower_key { ovs_be16 sctp_src; ovs_be16 sctp_dst; - uint16_t vlan_id; - uint8_t vlan_prio; + uint16_t vlan_id[FLOW_MAX_VLAN_HEADERS]; + uint8_t vlan_prio[FLOW_MAX_VLAN_HEADERS]; - ovs_be16 encap_eth_type; + ovs_be16 encap_eth_type[FLOW_MAX_VLAN_HEADERS]; uint8_t flags; uint8_t ip_ttl;