From patchwork Fri Jul 17 15:15:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Murali Karicheri X-Patchwork-Id: 235724 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1796619ilg; Fri, 17 Jul 2020 08:15:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyo82WOr+X0p56BqsATqZwptLiNsKIqegPwdWUJLVe8uLfwrLaLON+8GNIioKLWmw7OVOaU X-Received: by 2002:a50:ab53:: with SMTP id t19mr9883646edc.179.1594998959759; Fri, 17 Jul 2020 08:15:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594998959; cv=none; d=google.com; s=arc-20160816; b=oxfn7S2y//HQTA9kO7vu9FYF6QbWivVM8YTpkXi79MfMVsmKcxb2q91qYDB9I1d6Mx n+y/0JfZEPHdNb4FNiZTPyzVGVmNPjlmMiJBCHYFjHuPlBvDr46HsyBtANBmksP4nhcI t9Nfw/5x+ZfXU/ewsvdTtyQgWKlSsDDasnrIizJsXl+VCtZQeE2+qLdi5OiF/937qwDv ZJpyaDSxxn2H4GniObkcLM4n569Yc7xl3R2R8IX8gbsfSO2zSstgdbpEh8XEuReMFznL zdkzD9s06gr9jBgH+ZsWaQYsKj5uQ8yF3wGN8mOCuxHXguMdcs/eDSEYeD7dhQh6mCXP BlHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=Dw2iOAtcnfbB1pu6oe0nlRs/fFg27k3l9sbaxhJYh+4=; b=ZC6WObncSbLq4/mB6bWb1UdorhJ50ffd31kPP1mSr098k9jH2bf3A9+8QzoCpbodnO M1oT0KNMJJI1MbdJWBKKnrZDMQeSMx2LinrBwczRM16zN0CRjhloWyJvtP56Rr/GrG5H x4OrkIcVCpI2gd3/NoL/fbI6ApNtc0LYHMu+KYbiIO/vOMHmKe0fEzg8mA8T1bazIWd2 C5cEqHZ9Sl+elGPC6UXBDwRvM5QHBHX9x3rxCbQuUTRJQQIrPXooyWv7xFdFU9l0Z5DS 8oKZ7u9eCgFHdrti4igz9kr60fvhzatESQPaptuXSoRjn9JGDt5EpF6wHpmOyXk9IpcM OtVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=p7c0+5ma; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m16si5436775eji.77.2020.07.17.08.15.59; Fri, 17 Jul 2020 08:15:59 -0700 (PDT) Received-SPF: pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=p7c0+5ma; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728072AbgGQPP5 (ORCPT + 9 others); Fri, 17 Jul 2020 11:15:57 -0400 Received: from lelv0143.ext.ti.com ([198.47.23.248]:43448 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726351AbgGQPPS (ORCPT ); Fri, 17 Jul 2020 11:15:18 -0400 Received: from fllv0035.itg.ti.com ([10.64.41.0]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFCdw085653; Fri, 17 Jul 2020 10:15:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1594998912; bh=Dw2iOAtcnfbB1pu6oe0nlRs/fFg27k3l9sbaxhJYh+4=; h=From:To:Subject:Date:In-Reply-To:References; b=p7c0+5mabSUNqLz0Qt5rsFNO12KBWu2evlg778UvRMUWWIefAdkuGJwJa5ZQVKlko kJ9Ws5uAOI03xhsWi0qPuiwz6e+wXWD4VMJWEUgAoqr6bdSYpj/Pt2u6UFRC4iCxHF etuvvY8psGICSlnaYpHHyJPel5dhKs26O9+VKMLg= Received: from DLEE112.ent.ti.com (dlee112.ent.ti.com [157.170.170.23]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFCWp097231; Fri, 17 Jul 2020 10:15:12 -0500 Received: from DLEE113.ent.ti.com (157.170.170.24) by DLEE112.ent.ti.com (157.170.170.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 17 Jul 2020 10:15:12 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 17 Jul 2020 10:15:12 -0500 Received: from uda0868495.fios-router.home (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFBmd010522; Fri, 17 Jul 2020 10:15:12 -0500 From: Murali Karicheri To: , , , , , , , Subject: [net-next PATCH v3 1/7] hsr: enhance netlink socket interface to support PRP Date: Fri, 17 Jul 2020 11:15:05 -0400 Message-ID: <20200717151511.329-2-m-karicheri2@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200717151511.329-1-m-karicheri2@ti.com> References: <20200717151511.329-1-m-karicheri2@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Parallel Redundancy Protocol (PRP) is another redundancy protocol introduced by IEC 63439 standard. It is similar to HSR in many aspects:- - Use a pair of Ethernet interfaces to created the PRP device - Use a 6 byte redundancy protocol part (RCT, Redundancy Check Trailer) similar to HSR Tag. - Has Link Redundancy Entity (LRE) that works with RCT to implement redundancy. Key difference is that the protocol unit is a trailer instead of a prefix as in HSR. That makes it inter-operable with tradition network components such as bridges/switches which treat it as pad bytes, whereas HSR nodes requires some kind of translators (Called redbox) to talk to regular network devices. This features allows regular linux box to be converted to a DAN-P box. DAN-P stands for Dual Attached Node - PRP similar to DAN-H (Dual Attached Node - HSR). Add a comment at the header/source code to explicitly state that the driver files also handles PRP protocol as well. Signed-off-by: Murali Karicheri --- include/uapi/linux/hsr_netlink.h | 2 +- include/uapi/linux/if_link.h | 12 +++++++++- net/hsr/Kconfig | 37 ++++++++++++++++++++----------- net/hsr/hsr_debugfs.c | 2 +- net/hsr/hsr_device.c | 7 ++++-- net/hsr/hsr_device.h | 2 ++ net/hsr/hsr_forward.c | 2 ++ net/hsr/hsr_forward.h | 2 ++ net/hsr/hsr_framereg.c | 1 + net/hsr/hsr_framereg.h | 2 ++ net/hsr/hsr_main.c | 2 ++ net/hsr/hsr_main.h | 11 ++++++++- net/hsr/hsr_netlink.c | 38 ++++++++++++++++++++++++++------ net/hsr/hsr_netlink.h | 2 ++ net/hsr/hsr_slave.c | 2 ++ net/hsr/hsr_slave.h | 2 ++ 16 files changed, 100 insertions(+), 26 deletions(-) -- 2.17.1 diff --git a/include/uapi/linux/hsr_netlink.h b/include/uapi/linux/hsr_netlink.h index c218ef9c35dd..d540ea9bbef4 100644 --- a/include/uapi/linux/hsr_netlink.h +++ b/include/uapi/linux/hsr_netlink.h @@ -17,7 +17,7 @@ /* Generic Netlink HSR family definition */ -/* attributes */ +/* attributes for HSR or PRP node */ enum { HSR_A_UNSPEC, HSR_A_NODE_ADDR, diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 26842ffd0501..2ead061e3fc2 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -908,7 +908,14 @@ enum { #define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1) -/* HSR section */ +/* HSR/PRP section, both uses same interface */ + +/* Different redundancy protocols for hsr device */ +enum { + HSR_PROTOCOL_HSR, + HSR_PROTOCOL_PRP, + HSR_PROTOCOL_MAX, +}; enum { IFLA_HSR_UNSPEC, @@ -918,6 +925,9 @@ enum { IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */ IFLA_HSR_SEQ_NR, IFLA_HSR_VERSION, /* HSR version */ + IFLA_HSR_PROTOCOL, /* Indicate different protocol than + * HSR. For example PRP. + */ __IFLA_HSR_MAX, }; diff --git a/net/hsr/Kconfig b/net/hsr/Kconfig index 8095b034e76e..e2e396870230 100644 --- a/net/hsr/Kconfig +++ b/net/hsr/Kconfig @@ -4,24 +4,35 @@ # config HSR - tristate "High-availability Seamless Redundancy (HSR)" - help + tristate "High-availability Seamless Redundancy (HSR & PRP)" + ---help--- + This enables IEC 62439 defined High-availability Seamless + Redundancy (HSR) and Parallel Redundancy Protocol (PRP). + If you say Y here, then your Linux box will be able to act as a - DANH ("Doubly attached node implementing HSR"). For this to work, - your Linux box needs (at least) two physical Ethernet interfaces, - and it must be connected as a node in a ring network together with - other HSR capable nodes. + DANH ("Doubly attached node implementing HSR") or DANP ("Doubly + attached node implementing PRP"). For this to work, your Linux box + needs (at least) two physical Ethernet interfaces. + + For DANH, it must be connected as a node in a ring network together + with other HSR capable nodes. All Ethernet frames sent over the hsr + device will be sent in both directions on the ring (over both slave + ports), giving a redundant, instant fail-over network. Each HSR node + in the ring acts like a bridge for HSR frames, but filters frames + that have been forwarded earlier. - All Ethernet frames sent over the hsr device will be sent in both - directions on the ring (over both slave ports), giving a redundant, - instant fail-over network. Each HSR node in the ring acts like a - bridge for HSR frames, but filters frames that have been forwarded - earlier. + For DANP, it must be connected as a node connecting to two + separate networks over the two slave interfaces. Like HSR, Ethernet + frames sent over the prp device will be sent to both networks giving + a redundant, instant fail-over network. Unlike HSR, PRP networks + can have Singly Attached Nodes (SAN) such as PC, printer, bridges + etc and will be able to communicate with DANP nodes. This code is a "best effort" to comply with the HSR standard as described in IEC 62439-3:2010 (HSRv0) and IEC 62439-3:2012 (HSRv1), - but no compliancy tests have been made. Use iproute2 to select - the version you desire. + and PRP standard described in IEC 62439-4:2012 (PRP), but no + compliancy tests have been made. Use iproute2 to select the protocol + you would like to use. You need to perform any and all necessary tests yourself before relying on this code in a safety critical system! diff --git a/net/hsr/hsr_debugfs.c b/net/hsr/hsr_debugfs.c index 9787ef11ca71..c1932c0a15be 100644 --- a/net/hsr/hsr_debugfs.c +++ b/net/hsr/hsr_debugfs.c @@ -1,5 +1,5 @@ /* - * hsr_debugfs code + * debugfs code for HSR & PRP * Copyright (C) 2019 Texas Instruments Incorporated * * Author(s): diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 8a927b647829..40ac45123a62 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -3,9 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se - * * This file contains device methods for creating, using and destroying - * virtual HSR devices. + * virtual HSR or PRP devices. */ #include @@ -427,6 +426,10 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], ether_addr_copy(hsr_dev->dev_addr, slave[0]->dev_addr); + /* currently PRP is not supported */ + if (protocol_version == PRP_V1) + return -EPROTONOSUPPORT; + /* Make sure we recognize frames from ourselves in hsr_rcv() */ res = hsr_create_self_node(hsr, hsr_dev->dev_addr, slave[1]->dev_addr); diff --git a/net/hsr/hsr_device.h b/net/hsr/hsr_device.h index b8f9262ed101..868373822ee4 100644 --- a/net/hsr/hsr_device.h +++ b/net/hsr/hsr_device.h @@ -3,6 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * include file for HSR and PRP. */ #ifndef __HSR_DEVICE_H diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index e42fd356f073..fc1e7ee9c2d4 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -3,6 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * Frame router for HSR and PRP. */ #include "hsr_forward.h" diff --git a/net/hsr/hsr_forward.h b/net/hsr/hsr_forward.h index 51a69295566c..b2a6fa319d94 100644 --- a/net/hsr/hsr_forward.h +++ b/net/hsr/hsr_forward.h @@ -3,6 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * include file for HSR and PRP. */ #ifndef __HSR_FORWARD_H diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 530de24b1fb5..13b2190e6556 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c @@ -8,6 +8,7 @@ * interface. A frame is identified by its source MAC address and its HSR * sequence number. This code keeps track of senders and their sequence numbers * to allow filtering of duplicate frames, and to detect HSR ring errors. + * Same code handles filtering of duplicates for PRP as well. */ #include diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h index 0f0fa12b4329..c06447780d05 100644 --- a/net/hsr/hsr_framereg.h +++ b/net/hsr/hsr_framereg.h @@ -3,6 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * include file for HSR and PRP. */ #ifndef __HSR_FRAMEREG_H diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c index 144da15f0a81..2fd1976e5b1c 100644 --- a/net/hsr/hsr_main.c +++ b/net/hsr/hsr_main.c @@ -3,6 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * Event handling for HSR and PRP devices. */ #include diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h index f74193465bf5..8cf10d67d5f9 100644 --- a/net/hsr/hsr_main.h +++ b/net/hsr/hsr_main.h @@ -3,6 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * include file for HSR and PRP. */ #ifndef __HSR_PRIVATE_H @@ -131,6 +133,13 @@ struct hsr_port { enum hsr_port_type type; }; +/* used by driver internally to differentiate various protocols */ +enum hsr_version { + HSR_V0 = 0, + HSR_V1, + PRP_V1, +}; + struct hsr_priv { struct rcu_head rcu_head; struct list_head ports; @@ -141,7 +150,7 @@ struct hsr_priv { int announce_count; u16 sequence_nr; u16 sup_sequence_nr; /* For HSRv1 separate seq_nr for supervision */ - u8 prot_version; /* Indicate if HSRv0 or HSRv1. */ + enum hsr_version prot_version; /* Indicate if HSRv0, HSRv1 or PRPv1 */ spinlock_t seqnr_lock; /* locking for sequence_nr */ spinlock_t list_lock; /* locking for node list */ unsigned char sup_multicast_addr[ETH_ALEN]; diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c index 6e14b7d22639..be929786d7d3 100644 --- a/net/hsr/hsr_netlink.c +++ b/net/hsr/hsr_netlink.c @@ -4,7 +4,7 @@ * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se * - * Routines for handling Netlink messages for HSR. + * Routines for handling Netlink messages for HSR and PRP. */ #include "hsr_netlink.h" @@ -22,6 +22,7 @@ static const struct nla_policy hsr_policy[IFLA_HSR_MAX + 1] = { [IFLA_HSR_VERSION] = { .type = NLA_U8 }, [IFLA_HSR_SUPERVISION_ADDR] = { .len = ETH_ALEN }, [IFLA_HSR_SEQ_NR] = { .type = NLA_U16 }, + [IFLA_HSR_PROTOCOL] = { .type = NLA_U8 }, }; /* Here, it seems a netdevice has already been allocated for us, and the @@ -32,7 +33,9 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev, struct netlink_ext_ack *extack) { struct net_device *link[2]; - unsigned char multicast_spec, hsr_version; + unsigned char multicast_spec; + enum hsr_version proto_version; + u8 proto = HSR_PROTOCOL_HSR; if (!data) { NL_SET_ERR_MSG_MOD(extack, "No slave devices specified"); @@ -69,18 +72,34 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev, else multicast_spec = nla_get_u8(data[IFLA_HSR_MULTICAST_SPEC]); + if (data[IFLA_HSR_PROTOCOL]) + proto = nla_get_u8(data[IFLA_HSR_PROTOCOL]); + + if (proto >= HSR_PROTOCOL_MAX) { + NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol\n"); + return -EINVAL; + } + if (!data[IFLA_HSR_VERSION]) { - hsr_version = 0; + proto_version = HSR_V0; } else { - hsr_version = nla_get_u8(data[IFLA_HSR_VERSION]); - if (hsr_version > 1) { + if (proto == HSR_PROTOCOL_PRP) { + NL_SET_ERR_MSG_MOD(extack, "PRP version unsupported\n"); + return -EINVAL; + } + + proto_version = nla_get_u8(data[IFLA_HSR_VERSION]); + if (proto_version > HSR_V1) { NL_SET_ERR_MSG_MOD(extack, - "Only versions 0..1 are supported"); + "Only HSR version 0/1 supported\n"); return -EINVAL; } } - return hsr_dev_finalize(dev, link, multicast_spec, hsr_version, extack); + if (proto == HSR_PROTOCOL_PRP) + proto_version = PRP_V1; + + return hsr_dev_finalize(dev, link, multicast_spec, proto_version, extack); } static void hsr_dellink(struct net_device *dev, struct list_head *head) @@ -102,6 +121,7 @@ static void hsr_dellink(struct net_device *dev, struct list_head *head) static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev) { struct hsr_priv *hsr = netdev_priv(dev); + u8 proto = HSR_PROTOCOL_HSR; struct hsr_port *port; port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A); @@ -120,6 +140,10 @@ static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev) hsr->sup_multicast_addr) || nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr->sequence_nr)) goto nla_put_failure; + if (hsr->prot_version == PRP_V1) + proto = HSR_PROTOCOL_PRP; + if (nla_put_u8(skb, IFLA_HSR_PROTOCOL, proto)) + goto nla_put_failure; return 0; diff --git a/net/hsr/hsr_netlink.h b/net/hsr/hsr_netlink.h index 1121bb192a18..501552d9753b 100644 --- a/net/hsr/hsr_netlink.h +++ b/net/hsr/hsr_netlink.h @@ -3,6 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * include file for HSR and PRP. */ #ifndef __HSR_NETLINK_H diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c index 25b6ffba26cd..b5c0834de338 100644 --- a/net/hsr/hsr_slave.c +++ b/net/hsr/hsr_slave.c @@ -3,6 +3,8 @@ * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * Frame handler other utility functions for HSR and PRP. */ #include "hsr_slave.h" diff --git a/net/hsr/hsr_slave.h b/net/hsr/hsr_slave.h index 8953ea279ce9..9708a4f0ec09 100644 --- a/net/hsr/hsr_slave.h +++ b/net/hsr/hsr_slave.h @@ -2,6 +2,8 @@ /* Copyright 2011-2014 Autronica Fire and Security AS * * 2011-2014 Arvid Brodin, arvid.brodin@alten.se + * + * include file for HSR and PRP. */ #ifndef __HSR_SLAVE_H From patchwork Fri Jul 17 15:15:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Murali Karicheri X-Patchwork-Id: 235723 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1796556ilg; Fri, 17 Jul 2020 08:15:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxQuWFnDdQcHSs8sT2NXeAPXfRamF2J0uf0FilbKEtK410qF7NTlcoYlnSTyyHCStEBhvSc X-Received: by 2002:a17:906:3b01:: with SMTP id g1mr9490405ejf.353.1594998954647; Fri, 17 Jul 2020 08:15:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594998954; cv=none; d=google.com; s=arc-20160816; b=bjIatuWzJWrwriyrKGMz6TkvKdScKY8EY8+dPAz68xrXzGbNxdrmycX3YzBgzO7m1F T1DI3wmHYm91idOyHkNZpKFhpAmJQiUL5PamBm9NmlNSwmScLJAOcPuPUXjDMlLp4RgL pHuMigCSA0uflnxqLDnrfcTy619z2B0fay0qBR0b2/XP93nEOkpouPEWHcymKpVV+4k1 wZQgmzaIADi0WFF6yUZEV/HOp8qLFOUjFPGhfWSSjHzs1xSmoarBtpZUtqW9bgGRxit5 LeidbhQOc5Tvsw0O9a2SvrRrfECCHjFoFkzG3aQ1XWNk2EReYrLEW1GqFpBHzhdRKdV0 eX/w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=22xCI2rLwzkGNrjRKKsT/ANJsxuoRQPnQp7a0zUc31c=; b=t8TVTkr+hCtTgm/8/AbN/9WPz+/nc4HuhRzdq7Isw2xtM5y5KpYndgBaiMyDlkbMR9 1n9o3/a1EvhGOUYRlFuKik/tChtOlPDCVWGCEiks8DTEntHcxH/5JcwalOUe2ZpPAoNq DBrzMInJWvFEyE6NTO7HV3PEpcplUmPJlyv9VXanCsKomMtvQqLZ9ksdJZ1/uL3cldrf seBqrGTPa4P8M/d0WSdWBuptnIgug7x4T//7cG6ux+ov7DIjaqeK914aC0sdh8vDjK4z HzBuOi42XQ6c8jqv8/YoQd0tHDmrDR5KQvb7eozSm5tb2/XVjGEFgzJ/WlSYFH1YBUoj 8LKA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=ZsaJoTfP; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id by7si5185311edb.303.2020.07.17.08.15.54; Fri, 17 Jul 2020 08:15:54 -0700 (PDT) Received-SPF: pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=ZsaJoTfP; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726818AbgGQPPS (ORCPT + 9 others); Fri, 17 Jul 2020 11:15:18 -0400 Received: from lelv0142.ext.ti.com ([198.47.23.249]:35788 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726071AbgGQPPS (ORCPT ); Fri, 17 Jul 2020 11:15:18 -0400 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFDLc013298; Fri, 17 Jul 2020 10:15:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1594998913; bh=22xCI2rLwzkGNrjRKKsT/ANJsxuoRQPnQp7a0zUc31c=; h=From:To:Subject:Date:In-Reply-To:References; b=ZsaJoTfPWBDhvjqESgPXwTuN0Rk20+scACbMVnTwsHJHx9/792Cyj5IsYqpvIr9BP 2B7hFFZFJfx2dnvwml3ccAjiw3vxE673ioxcGS97GTYY5AKROZ+vBQ10y+Xcg0DXH8 letPTy5cL5oauUqhUMngRIOUpDWDo4XWYbdadXzk= Received: from DLEE114.ent.ti.com (dlee114.ent.ti.com [157.170.170.25]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 06HFFDVx111735 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 17 Jul 2020 10:15:13 -0500 Received: from DLEE103.ent.ti.com (157.170.170.33) by DLEE114.ent.ti.com (157.170.170.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 17 Jul 2020 10:15:13 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE103.ent.ti.com (157.170.170.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 17 Jul 2020 10:15:12 -0500 Received: from uda0868495.fios-router.home (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFBme010522; Fri, 17 Jul 2020 10:15:12 -0500 From: Murali Karicheri To: , , , , , , , Subject: [net-next PATCH v3 2/7] net: hsr: introduce common code for skb initialization Date: Fri, 17 Jul 2020 11:15:06 -0400 Message-ID: <20200717151511.329-3-m-karicheri2@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200717151511.329-1-m-karicheri2@ti.com> References: <20200717151511.329-1-m-karicheri2@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org As a preparatory patch to introduce PRP protocol support in the driver, refactor the skb init code to a separate function. Signed-off-by: Murali Karicheri --- net/hsr/hsr_device.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) -- 2.17.1 diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 40ac45123a62..600b9da4a44e 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -230,15 +230,11 @@ static const struct header_ops hsr_header_ops = { .parse = eth_header_parse, }; -static void send_hsr_supervision_frame(struct hsr_port *master, - u8 type, u8 hsr_ver) +static struct sk_buff *hsr_init_skb(struct hsr_port *master, u8 hsr_ver) { + struct hsr_priv *hsr = master->hsr; struct sk_buff *skb; int hlen, tlen; - struct hsr_tag *hsr_tag; - struct hsr_sup_tag *hsr_stag; - struct hsr_sup_payload *hsr_sp; - unsigned long irqflags; hlen = LL_RESERVED_SPACE(master->dev); tlen = master->dev->needed_tailroom; @@ -247,22 +243,44 @@ static void send_hsr_supervision_frame(struct hsr_port *master, sizeof(struct hsr_sup_payload) + hlen + tlen); if (!skb) - return; + return skb; skb_reserve(skb, hlen); - skb->dev = master->dev; skb->protocol = htons(hsr_ver ? ETH_P_HSR : ETH_P_PRP); skb->priority = TC_PRIO_CONTROL; if (dev_hard_header(skb, skb->dev, (hsr_ver ? ETH_P_HSR : ETH_P_PRP), - master->hsr->sup_multicast_addr, + hsr->sup_multicast_addr, skb->dev->dev_addr, skb->len) <= 0) goto out; + skb_reset_mac_header(skb); skb_reset_network_header(skb); skb_reset_transport_header(skb); + return skb; +out: + kfree_skb(skb); + + return NULL; +} + +static void send_hsr_supervision_frame(struct hsr_port *master, + u8 type, u8 hsr_ver) +{ + struct sk_buff *skb; + struct hsr_tag *hsr_tag; + struct hsr_sup_tag *hsr_stag; + struct hsr_sup_payload *hsr_sp; + unsigned long irqflags; + + skb = hsr_init_skb(master, hsr_ver); + if (!skb) { + WARN_ONCE(1, "HSR: Could not send supervision frame\n"); + return; + } + if (hsr_ver > 0) { hsr_tag = skb_put(skb, sizeof(struct hsr_tag)); hsr_tag->encap_proto = htons(ETH_P_PRP); @@ -299,11 +317,8 @@ static void send_hsr_supervision_frame(struct hsr_port *master, return; hsr_forward_skb(skb, master); - return; -out: - WARN_ONCE(1, "HSR: Could not send supervision frame\n"); - kfree_skb(skb); + return; } /* Announce (supervision frame) timer function From patchwork Fri Jul 17 15:15:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Murali Karicheri X-Patchwork-Id: 235719 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1796217ilg; Fri, 17 Jul 2020 08:15:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxZ0WpA8+p01JdU7VspyXHu3N0lPXaSMDhjR6M6WzLtZ7zsHC2deYX4XasSkI0Ez+0gvxOD X-Received: by 2002:a50:afa2:: with SMTP id h31mr9706692edd.303.1594998932518; Fri, 17 Jul 2020 08:15:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594998932; cv=none; d=google.com; s=arc-20160816; b=KHUIGW+H/JAIoY9b32daHc7jTPK5efvHu+E+sACyG+a9C2buKdnKyIMozr7ucFHJG4 GlYK4JlDM16PCqrHYHJm73YjUYNLDHDhJFbMid8ZpDScIIAZo3bm+PAlTspPTIyz3y2w bg9pEejJg7VY7js0UZhvADMqK8giTeXAcMmlnraHn6GPCNP/Aa9BmbtSUA2dtiY9yWMp EjfJ2MjalnrDe1YECsifrGJxiMA0ycvKt+ED/JqPQzXjhM34Q45cm41paGjQNoQoiRCn QpHU+1Bw+dgxc7YFIc18Pvrr5KBL+k46WrP/V/QPDHloMPHpa5L41iEey2SiFBXwDYpJ Mszw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=XoyH1qcQRGYflLne2efG5ubW4jRaYKybjOR27SaPtws=; b=vKbjYl+jJJ3XEkBoFsLWDskXDwtWybChbe/+Kx08Bg4x5mHoUVntbZtYWTov1rIhsC uTuxn0E6LYRHxD2Ntnv6DjPuJ1LY6/FsVWhA2Mvw0k3Hb53+zWRqZnvDkpwtIyaM3PQH 1HL1qhMD5JF8iJgErrJMn4VjHdxcOvnCkXWylnYpzt+OXSsYybVF306UlS0X8eWW9J8t 10vvl64xZ6+jlUUABToUypDcg3+hzXJp5+FUE6Uk1aLFcgiWg+u2aCoVesTIJ5h/bzwT YZFDBgLPaIehPKWOGXUIDg9D41c9khCHxUc/+tzIkjTAMjwae+hjlCD/v72epNwa/Ezl gn7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=Fz3+CGpb; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w10si5129102ejv.343.2020.07.17.08.15.32; Fri, 17 Jul 2020 08:15:32 -0700 (PDT) Received-SPF: pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=Fz3+CGpb; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727854AbgGQPPY (ORCPT + 9 others); Fri, 17 Jul 2020 11:15:24 -0400 Received: from fllv0016.ext.ti.com ([198.47.19.142]:54312 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727101AbgGQPPV (ORCPT ); Fri, 17 Jul 2020 11:15:21 -0400 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFDmC081673; Fri, 17 Jul 2020 10:15:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1594998913; bh=XoyH1qcQRGYflLne2efG5ubW4jRaYKybjOR27SaPtws=; h=From:To:Subject:Date:In-Reply-To:References; b=Fz3+CGpb0d7ABJxEVnSlpMbNLXxVr7FB+SYc1tRF6cUvPvIzSnxHFSEncjlSUvFC9 Jhv9JgxJZ4M/wUpioWD2TMGj4q/eJ7aaBtTHesEX1yZAV1ei/hQMbiQHSMuwdNKT/J j5Te1wgWD4XH2ilKHDFxAKYHJREwjhdMZlzcCOYU= Received: from DLEE113.ent.ti.com (dlee113.ent.ti.com [157.170.170.24]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 06HFFDpG111754 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 17 Jul 2020 10:15:13 -0500 Received: from DLEE112.ent.ti.com (157.170.170.23) by DLEE113.ent.ti.com (157.170.170.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 17 Jul 2020 10:15:13 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE112.ent.ti.com (157.170.170.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 17 Jul 2020 10:15:13 -0500 Received: from uda0868495.fios-router.home (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFBmf010522; Fri, 17 Jul 2020 10:15:13 -0500 From: Murali Karicheri To: , , , , , , , Subject: [net-next PATCH v3 3/7] net: hsr: introduce protocol specific function pointers Date: Fri, 17 Jul 2020 11:15:07 -0400 Message-ID: <20200717151511.329-4-m-karicheri2@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200717151511.329-1-m-karicheri2@ti.com> References: <20200717151511.329-1-m-karicheri2@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org As a preparatory patch to introduce support for PRP protocol, add a protocol ops ptr in the private hsr structure to hold function pointers as some of the functions at protocol level packet handling is different for HSR vs PRP. It is expected that PRP will add its of set of functions for protocol handling. Modify existing hsr_announce() function to call proto_ops->send_sv_frame() to send supervision frame for HSR. This is expected to be different for PRP. So introduce a ops function ptr, send_sv_frame() for the same and initialize it to send_hsr_supervsion_frame(). Modify hsr_announce() to call proto_ops->send_sv_frame(). Signed-off-by: Murali Karicheri --- net/hsr/hsr_device.c | 74 ++++++++++++++++++++++++-------------------- net/hsr/hsr_main.h | 6 ++++ 2 files changed, 47 insertions(+), 33 deletions(-) -- 2.17.1 diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 600b9da4a44e..006e715eccb6 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -230,7 +230,7 @@ static const struct header_ops hsr_header_ops = { .parse = eth_header_parse, }; -static struct sk_buff *hsr_init_skb(struct hsr_port *master, u8 hsr_ver) +static struct sk_buff *hsr_init_skb(struct hsr_port *master, u16 proto) { struct hsr_priv *hsr = master->hsr; struct sk_buff *skb; @@ -247,10 +247,10 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master, u8 hsr_ver) skb_reserve(skb, hlen); skb->dev = master->dev; - skb->protocol = htons(hsr_ver ? ETH_P_HSR : ETH_P_PRP); + skb->protocol = htons(proto); skb->priority = TC_PRIO_CONTROL; - if (dev_hard_header(skb, skb->dev, (hsr_ver ? ETH_P_HSR : ETH_P_PRP), + if (dev_hard_header(skb, skb->dev, proto, hsr->sup_multicast_addr, skb->dev->dev_addr, skb->len) <= 0) goto out; @@ -267,47 +267,62 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master, u8 hsr_ver) } static void send_hsr_supervision_frame(struct hsr_port *master, - u8 type, u8 hsr_ver) + unsigned long *interval) { - struct sk_buff *skb; - struct hsr_tag *hsr_tag; - struct hsr_sup_tag *hsr_stag; + struct hsr_priv *hsr = master->hsr; + __u8 type = HSR_TLV_LIFE_CHECK; + struct hsr_tag *hsr_tag = NULL; struct hsr_sup_payload *hsr_sp; + struct hsr_sup_tag *hsr_stag; unsigned long irqflags; + struct sk_buff *skb; + u16 proto; + + *interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); + if (hsr->announce_count < 3 && hsr->prot_version == 0) { + type = HSR_TLV_ANNOUNCE; + *interval = msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL); + hsr->announce_count++; + } + + if (!hsr->prot_version) + proto = ETH_P_PRP; + else + proto = ETH_P_HSR; - skb = hsr_init_skb(master, hsr_ver); + skb = hsr_init_skb(master, proto); if (!skb) { WARN_ONCE(1, "HSR: Could not send supervision frame\n"); return; } - if (hsr_ver > 0) { + if (hsr->prot_version > 0) { hsr_tag = skb_put(skb, sizeof(struct hsr_tag)); hsr_tag->encap_proto = htons(ETH_P_PRP); set_hsr_tag_LSDU_size(hsr_tag, HSR_V1_SUP_LSDUSIZE); } hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag)); - set_hsr_stag_path(hsr_stag, (hsr_ver ? 0x0 : 0xf)); - set_hsr_stag_HSR_ver(hsr_stag, hsr_ver); + set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf)); + set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version); /* From HSRv1 on we have separate supervision sequence numbers. */ spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags); - if (hsr_ver > 0) { - hsr_stag->sequence_nr = htons(master->hsr->sup_sequence_nr); - hsr_tag->sequence_nr = htons(master->hsr->sequence_nr); - master->hsr->sup_sequence_nr++; - master->hsr->sequence_nr++; + if (hsr->prot_version > 0) { + hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr); + hsr->sup_sequence_nr++; + hsr_tag->sequence_nr = htons(hsr->sequence_nr); + hsr->sequence_nr++; } else { - hsr_stag->sequence_nr = htons(master->hsr->sequence_nr); - master->hsr->sequence_nr++; + hsr_stag->sequence_nr = htons(hsr->sequence_nr); + hsr->sequence_nr++; } spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags); hsr_stag->HSR_TLV_type = type; /* TODO: Why 12 in HSRv0? */ - hsr_stag->HSR_TLV_length = - hsr_ver ? sizeof(struct hsr_sup_payload) : 12; + hsr_stag->HSR_TLV_length = hsr->prot_version ? + sizeof(struct hsr_sup_payload) : 12; /* Payload: MacAddressA */ hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload)); @@ -333,19 +348,7 @@ static void hsr_announce(struct timer_list *t) rcu_read_lock(); master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); - - if (hsr->announce_count < 3 && hsr->prot_version == 0) { - send_hsr_supervision_frame(master, HSR_TLV_ANNOUNCE, - hsr->prot_version); - hsr->announce_count++; - - interval = msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL); - } else { - send_hsr_supervision_frame(master, HSR_TLV_LIFE_CHECK, - hsr->prot_version); - - interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); - } + hsr->proto_ops->send_sv_frame(master, &interval); if (is_admin_up(master->dev)) mod_timer(&hsr->announce_timer, jiffies + interval); @@ -382,6 +385,10 @@ static struct device_type hsr_type = { .name = "hsr", }; +static struct hsr_proto_ops hsr_ops = { + .send_sv_frame = send_hsr_supervision_frame, +}; + void hsr_dev_setup(struct net_device *dev) { eth_hw_addr_random(dev); @@ -445,6 +452,7 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], if (protocol_version == PRP_V1) return -EPROTONOSUPPORT; + hsr->proto_ops = &hsr_ops; /* Make sure we recognize frames from ourselves in hsr_rcv() */ res = hsr_create_self_node(hsr, hsr_dev->dev_addr, slave[1]->dev_addr); diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h index 8cf10d67d5f9..671270115a50 100644 --- a/net/hsr/hsr_main.h +++ b/net/hsr/hsr_main.h @@ -140,6 +140,11 @@ enum hsr_version { PRP_V1, }; +struct hsr_proto_ops { + /* format and send supervision frame */ + void (*send_sv_frame)(struct hsr_port *port, unsigned long *interval); +}; + struct hsr_priv { struct rcu_head rcu_head; struct list_head ports; @@ -153,6 +158,7 @@ struct hsr_priv { enum hsr_version prot_version; /* Indicate if HSRv0, HSRv1 or PRPv1 */ spinlock_t seqnr_lock; /* locking for sequence_nr */ spinlock_t list_lock; /* locking for node list */ + struct hsr_proto_ops *proto_ops; unsigned char sup_multicast_addr[ETH_ALEN]; #ifdef CONFIG_DEBUG_FS struct dentry *node_tbl_root; From patchwork Fri Jul 17 15:15:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Murali Karicheri X-Patchwork-Id: 235720 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1796296ilg; Fri, 17 Jul 2020 08:15:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw/BYfRdifERx+oX3Gzl/neQgfGxnC810PSAOHBijd197zJ5r/+N1IpYuuLTMZnabVf5Ha3 X-Received: by 2002:aa7:d04a:: with SMTP id n10mr9949316edo.132.1594998936951; Fri, 17 Jul 2020 08:15:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594998936; cv=none; d=google.com; s=arc-20160816; b=dPvrER4xFlYcvmeKokZcdjrzzdm9UDzR0Cm1uTAn1EZlefaIF4voxKqGW84eOlOuYZ dt/y/frZHL0Cg6KlbR58mGbITHoUJFmaPTADSMmw9BCe8n03fRMwowRjXMNk28USwJyp Xi6wSqinNiPTeXQIr3Y0tnqUSc3Jh7TxB1wKZQqhd6WOKIONbX4WRwxY4e+8okvUA8r6 t4t0lh49dtvEGakkmOIcGj5bJQ6mMWKn62ZWHlqvjGZcL2vpu8zyMdib2bU9cbijS8WW x0UvXlQR6GEzxYSKSRT5Mxx6V853IO6CtnoaAU05GnfKwbehVS7a5vjbzwcCkCRvyhMW pxSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=f4qg+VStq02+ZWJdwnETxUsJyjBw4+53xWSU1QQPRqk=; b=yn9+ndAFst39+xE1yOWbaiuWsSsjO3nRmzKj4bOmUKffa+IEZNlEXv2eMMzIWuh2jw Pzcj7jyNMH+zBN+BkNjBbrdpZCSRfMIsPrIG1X0PHuBQ52u7iKGeslnbKm0n8DE65Llw Ux0OgItcKAs2A5iBad4xKQpivByrZtvegsaMKKCaa0AVq03NfHzxu02D2phGMHYSZZBu 2Oz27V72oRjhfQRspwKcRyUi7RUxcFiCugUEnDy8kjMlqzSxpF8ED5uxauixQYYcgEnM 5b4gpKac6OM/NQhyXnklVdVqFLbY/1y8d8zrsOcJt/DigbBsfLYapf+nCGT3MvhHJjHN Z4PQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=P6SuEXMW; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w10si5129102ejv.343.2020.07.17.08.15.36; Fri, 17 Jul 2020 08:15:36 -0700 (PDT) Received-SPF: pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=P6SuEXMW; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727953AbgGQPPf (ORCPT + 9 others); Fri, 17 Jul 2020 11:15:35 -0400 Received: from fllv0015.ext.ti.com ([198.47.19.141]:47494 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726233AbgGQPPT (ORCPT ); Fri, 17 Jul 2020 11:15:19 -0400 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFEj7015399; Fri, 17 Jul 2020 10:15:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1594998914; bh=f4qg+VStq02+ZWJdwnETxUsJyjBw4+53xWSU1QQPRqk=; h=From:To:Subject:Date:In-Reply-To:References; b=P6SuEXMWpWo7gEXXUBYRUjZgPL0AND/fVYut7204Khf2sPnrXhewQisTwcxdFiFT6 TU7UZZoHaC0ZbULR3X4R2GZkjqpQNr6yCx3W4MPLIKLAm6YwPcVwPf9wmFk7N0jv4z p1A+4olvTxdU59CPRZjRdIootSUAmYdKK/WZAORw= Received: from DLEE111.ent.ti.com (dlee111.ent.ti.com [157.170.170.22]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 06HFFEO7102131 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 17 Jul 2020 10:15:14 -0500 Received: from DLEE102.ent.ti.com (157.170.170.32) by DLEE111.ent.ti.com (157.170.170.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 17 Jul 2020 10:15:14 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE102.ent.ti.com (157.170.170.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 17 Jul 2020 10:15:13 -0500 Received: from uda0868495.fios-router.home (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFBmg010522; Fri, 17 Jul 2020 10:15:13 -0500 From: Murali Karicheri To: , , , , , , , Subject: [net-next PATCH v3 4/7] net: prp: add supervision frame generation utility function Date: Fri, 17 Jul 2020 11:15:08 -0400 Message-ID: <20200717151511.329-5-m-karicheri2@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200717151511.329-1-m-karicheri2@ti.com> References: <20200717151511.329-1-m-karicheri2@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add support for generation of PRP supervision frames. For PRP, supervision frame format is similar to HSR version 0, but have a PRP Redundancy Control Trailer (RCT) added and uses a different message type, PRP_TLV_LIFE_CHECK_DD. Also update is_supervision_frame() to include the new message type used for PRP supervision frame. Signed-off-by: Murali Karicheri --- net/hsr/hsr_device.c | 64 ++++++++++++++++++++++++++++++++++++++++++- net/hsr/hsr_forward.c | 4 ++- net/hsr/hsr_main.h | 22 +++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) -- 2.17.1 diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 006e715eccb6..74eaf28743a4 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -238,6 +238,10 @@ static struct sk_buff *hsr_init_skb(struct hsr_port *master, u16 proto) hlen = LL_RESERVED_SPACE(master->dev); tlen = master->dev->needed_tailroom; + /* skb size is same for PRP/HSR frames, only difference + * being, for PRP it is a trailer and for HSR it is a + * header + */ skb = dev_alloc_skb(sizeof(struct hsr_tag) + sizeof(struct hsr_sup_tag) + sizeof(struct hsr_sup_payload) + hlen + tlen); @@ -336,6 +340,55 @@ static void send_hsr_supervision_frame(struct hsr_port *master, return; } +static void send_prp_supervision_frame(struct hsr_port *master, + unsigned long *interval) +{ + struct hsr_priv *hsr = master->hsr; + struct hsr_sup_payload *hsr_sp; + struct hsr_sup_tag *hsr_stag; + unsigned long irqflags; + struct sk_buff *skb; + struct prp_rct *rct; + u8 *tail; + + skb = hsr_init_skb(master, ETH_P_PRP); + if (!skb) { + WARN_ONCE(1, "PRP: Could not send supervision frame\n"); + return; + } + + *interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); + hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag)); + set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf)); + set_hsr_stag_HSR_ver(hsr_stag, (hsr->prot_version ? 1 : 0)); + + /* From HSRv1 on we have separate supervision sequence numbers. */ + spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags); + hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr); + hsr->sup_sequence_nr++; + hsr_stag->HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD; + hsr_stag->HSR_TLV_length = sizeof(struct hsr_sup_payload); + + /* Payload: MacAddressA */ + hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload)); + ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr); + + if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) { + spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags); + return; + } + + tail = skb_tail_pointer(skb) - HSR_HLEN; + rct = (struct prp_rct *)tail; + rct->PRP_suffix = htons(ETH_P_PRP); + set_prp_LSDU_size(rct, HSR_V1_SUP_LSDUSIZE); + rct->sequence_nr = htons(hsr->sequence_nr); + hsr->sequence_nr++; + spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags); + + hsr_forward_skb(skb, master); +} + /* Announce (supervision frame) timer function */ static void hsr_announce(struct timer_list *t) @@ -389,6 +442,10 @@ static struct hsr_proto_ops hsr_ops = { .send_sv_frame = send_hsr_supervision_frame, }; +struct hsr_proto_ops prp_ops = { + .send_sv_frame = send_prp_supervision_frame, +}; + void hsr_dev_setup(struct net_device *dev) { eth_hw_addr_random(dev); @@ -452,7 +509,12 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], if (protocol_version == PRP_V1) return -EPROTONOSUPPORT; - hsr->proto_ops = &hsr_ops; + /* initialize protocol specific functions */ + if (protocol_version == PRP_V1) + hsr->proto_ops = &prp_ops; + else + hsr->proto_ops = &hsr_ops; + /* Make sure we recognize frames from ourselves in hsr_rcv() */ res = hsr_create_self_node(hsr, hsr_dev->dev_addr, slave[1]->dev_addr); diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index fc1e7ee9c2d4..3a536a7d98e8 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -76,7 +76,9 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb) } if (hsr_sup_tag->HSR_TLV_type != HSR_TLV_ANNOUNCE && - hsr_sup_tag->HSR_TLV_type != HSR_TLV_LIFE_CHECK) + hsr_sup_tag->HSR_TLV_type != HSR_TLV_LIFE_CHECK && + hsr_sup_tag->HSR_TLV_type != PRP_TLV_LIFE_CHECK_DD && + hsr_sup_tag->HSR_TLV_type != PRP_TLV_LIFE_CHECK_DA) return false; if (hsr_sup_tag->HSR_TLV_length != 12 && hsr_sup_tag->HSR_TLV_length != sizeof(struct hsr_sup_payload)) diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h index 671270115a50..58e1ad21b66f 100644 --- a/net/hsr/hsr_main.h +++ b/net/hsr/hsr_main.h @@ -35,6 +35,10 @@ #define HSR_TLV_ANNOUNCE 22 #define HSR_TLV_LIFE_CHECK 23 +/* PRP V1 life check for Duplicate discard */ +#define PRP_TLV_LIFE_CHECK_DD 20 +/* PRP V1 life check for Duplicate Accept */ +#define PRP_TLV_LIFE_CHECK_DA 21 /* HSR Tag. * As defined in IEC-62439-3:2010, the HSR tag is really { ethertype = 0x88FB, @@ -126,6 +130,24 @@ enum hsr_port_type { HSR_PT_PORTS, /* This must be the last item in the enum */ }; +/* PRP Redunancy Control Trailor (RCT). + * As defined in IEC-62439-4:2012, the PRP RCT is really { sequence Nr, + * Lan indentifier (LanId), LSDU_size and PRP_suffix = 0x88FB }. + * + * Field names as defined in the IEC:2012 standard for PRP. + */ +struct prp_rct { + __be16 sequence_nr; + __be16 lan_id_and_LSDU_size; + __be16 PRP_suffix; +} __packed; + +static inline void set_prp_LSDU_size(struct prp_rct *rct, u16 LSDU_size) +{ + rct->lan_id_and_LSDU_size = htons((ntohs(rct->lan_id_and_LSDU_size) & + 0xF000) | (LSDU_size & 0x0FFF)); +} + struct hsr_port { struct list_head port_list; struct net_device *dev; From patchwork Fri Jul 17 15:15:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Murali Karicheri X-Patchwork-Id: 235717 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1796069ilg; Fri, 17 Jul 2020 08:15:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy3y0K3CEoCPnPMmiKJCD2Cp6cx0YQT2MQe9qHClf0LnAWEI7orUqdOWnDzfdwN7s4vaoqF X-Received: by 2002:a17:906:3b9b:: with SMTP id u27mr9574206ejf.500.1594998923738; Fri, 17 Jul 2020 08:15:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594998923; cv=none; d=google.com; s=arc-20160816; b=IZSJAPEQZhJgH5jGvotmfPUsx5nlJH0B1PwtFevWrNbesJRY0AxqFvOtbRGCGURJTi QKE/zW5G7aptDFUbwcaTJEMneprV9mMVPBHa9nOekUWyh5iDAGNUZ0n07rsYYgigOd92 Fx4uZzE4UIBKsoBuDEeOciAqeXE27fogZzioKmCLvq4Xod2ae2CCqXosxH8Z5R9IiF4o zcxKZwQ/gGHaKxFEe9UZdKEhcJkQfWEYUvqLmo9NP+zf4e2fhjTovYMfaR1np84dv2Pw RvYa4exSEIbLX918bEfMncABLjtaQ4bTVvM2zvT7uZP+pjMPzR69uPhjP+m+FyWh+IAJ UMMw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=fYtEzLC0C86iSflK+GCQ1fpBsFZgGHV3q5nHZ9uLEik=; b=Bg0YvbFqEDDoqydwwL8/N1lZ67RgrDq/ITXmUiM7wMp90eoOYW7Uc+Gk2SuBmMAEHV JHt9BwSzF8aifjUjcfNX3hw8ax89UZimxnn1GAuVEmt3QO6Qi1aMH48bhbXDcCnqRZ3w ncIGPTLy8pzEQ6oAyPSJIzHzYbAM8SeH6IAkhKNIqCt6lYow3x66DkrmPGLv2aW+luxs w8p6pprCOqkdT1c5NdEzSI9BodLHnTRYTZXM+s6pefUIkUzxiF2APXKnsDzzHaQzmQTY gnfdyKKEdFQ2SCwrue0wHVQZpwg8cjp4h1CuQZjM6cOW3bTOsJHMrmu4lHDnh67SKKCc RpYw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=mv7IZQfa; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e6si5292170ejx.444.2020.07.17.08.15.23; Fri, 17 Jul 2020 08:15:23 -0700 (PDT) Received-SPF: pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=mv7IZQfa; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727096AbgGQPPU (ORCPT + 9 others); Fri, 17 Jul 2020 11:15:20 -0400 Received: from fllv0015.ext.ti.com ([198.47.19.141]:47496 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726293AbgGQPPS (ORCPT ); Fri, 17 Jul 2020 11:15:18 -0400 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFFlb015404; Fri, 17 Jul 2020 10:15:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1594998915; bh=fYtEzLC0C86iSflK+GCQ1fpBsFZgGHV3q5nHZ9uLEik=; h=From:To:Subject:Date:In-Reply-To:References; b=mv7IZQfarLlaCWv/7aEUvVpRI7vz4sjQ30mH0up6mghRHlp1uhPdvtxBmlw3d1pPg /OikWsrdtZe/2LMffRpy5XTeHO3t/Dk5s3Ay3YjSsyfzsNuJRg8gbYdO8UhpPoxv58 cnkqdKQQJOt/BeDGemSYLVTlHZjKstpaFlp2HJdQ= Received: from DLEE114.ent.ti.com (dlee114.ent.ti.com [157.170.170.25]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 06HFFEU5111808 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 17 Jul 2020 10:15:15 -0500 Received: from DLEE103.ent.ti.com (157.170.170.33) by DLEE114.ent.ti.com (157.170.170.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 17 Jul 2020 10:15:14 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE103.ent.ti.com (157.170.170.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 17 Jul 2020 10:15:14 -0500 Received: from uda0868495.fios-router.home (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFBmh010522; Fri, 17 Jul 2020 10:15:14 -0500 From: Murali Karicheri To: , , , , , , , Subject: [net-next PATCH v3 5/7] net: hsr: define and use proto_ops ptrs to handle hsr specific frames Date: Fri, 17 Jul 2020 11:15:09 -0400 Message-ID: <20200717151511.329-6-m-karicheri2@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200717151511.329-1-m-karicheri2@ti.com> References: <20200717151511.329-1-m-karicheri2@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org As a preparatory patch to introduce PRP, refactor the code specific to handling HSR frames into separate functions and call them through proto_ops function pointers. Signed-off-by: Murali Karicheri --- net/hsr/hsr_device.c | 5 +++- net/hsr/hsr_forward.c | 63 +++++++++++++++++++++++++------------------ net/hsr/hsr_forward.h | 7 ++++- net/hsr/hsr_main.h | 8 ++++++ 4 files changed, 55 insertions(+), 28 deletions(-) -- 2.17.1 diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 74eaf28743a4..022393bed40a 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -440,9 +440,12 @@ static struct device_type hsr_type = { static struct hsr_proto_ops hsr_ops = { .send_sv_frame = send_hsr_supervision_frame, + .create_tagged_frame = hsr_create_tagged_frame, + .get_untagged_frame = hsr_get_untagged_frame, + .fill_frame_info = hsr_fill_frame_info, }; -struct hsr_proto_ops prp_ops = { +static struct hsr_proto_ops prp_ops = { .send_sv_frame = send_prp_supervision_frame, }; diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index 3a536a7d98e8..7fc6cc7b29bb 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -116,8 +116,8 @@ static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in, return skb; } -static struct sk_buff *frame_get_stripped_skb(struct hsr_frame_info *frame, - struct hsr_port *port) +struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame, + struct hsr_port *port) { if (!frame->skb_std) frame->skb_std = create_stripped_skb(frame->skb_hsr, frame); @@ -187,8 +187,8 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, /* If the original frame was an HSR tagged frame, just clone it to be sent * unchanged. Otherwise, create a private frame especially tagged for 'port'. */ -static struct sk_buff *frame_get_tagged_skb(struct hsr_frame_info *frame, - struct hsr_port *port) +struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, + struct hsr_port *port) { if (frame->skb_hsr) return skb_clone(frame->skb_hsr, GFP_ATOMIC); @@ -252,6 +252,7 @@ static void hsr_forward_do(struct hsr_frame_info *frame) struct sk_buff *skb; hsr_for_each_port(frame->port_rcv->hsr, port) { + struct hsr_priv *hsr = port->hsr; /* Don't send frame back the way it came */ if (port == frame->port_rcv) continue; @@ -277,9 +278,10 @@ static void hsr_forward_do(struct hsr_frame_info *frame) } if (port->type != HSR_PT_MASTER) - skb = frame_get_tagged_skb(frame, port); + skb = hsr->proto_ops->create_tagged_frame(frame, port); else - skb = frame_get_stripped_skb(frame, port); + skb = hsr->proto_ops->get_untagged_frame(frame, port); + if (!skb) { /* FIXME: Record the dropped frame? */ continue; @@ -312,12 +314,34 @@ static void check_local_dest(struct hsr_priv *hsr, struct sk_buff *skb, } } -static int hsr_fill_frame_info(struct hsr_frame_info *frame, - struct sk_buff *skb, struct hsr_port *port) +void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, + struct hsr_frame_info *frame) { - struct ethhdr *ethhdr; + struct hsr_priv *hsr = frame->port_rcv->hsr; unsigned long irqflags; + if (proto == htons(ETH_P_PRP) || proto == htons(ETH_P_HSR)) { + frame->skb_std = NULL; + frame->skb_hsr = skb; + frame->sequence_nr = hsr_get_skb_sequence_nr(skb); + } else { + frame->skb_std = skb; + frame->skb_hsr = NULL; + /* Sequence nr for the master node */ + spin_lock_irqsave(&hsr->seqnr_lock, irqflags); + frame->sequence_nr = hsr->sequence_nr; + hsr->sequence_nr++; + spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags); + } +} + +static int fill_frame_info(struct hsr_frame_info *frame, + struct sk_buff *skb, struct hsr_port *port) +{ + struct hsr_priv *hsr = port->hsr; + struct ethhdr *ethhdr; + __be16 proto; + frame->is_supervision = is_supervision_frame(port->hsr, skb); frame->node_src = hsr_get_node(port, skb, frame->is_supervision); if (!frame->node_src) @@ -330,23 +354,10 @@ static int hsr_fill_frame_info(struct hsr_frame_info *frame, /* FIXME: */ netdev_warn_once(skb->dev, "VLAN not yet supported"); } - if (ethhdr->h_proto == htons(ETH_P_PRP) || - ethhdr->h_proto == htons(ETH_P_HSR)) { - frame->skb_std = NULL; - frame->skb_hsr = skb; - frame->sequence_nr = hsr_get_skb_sequence_nr(skb); - } else { - frame->skb_std = skb; - frame->skb_hsr = NULL; - /* Sequence nr for the master node */ - spin_lock_irqsave(&port->hsr->seqnr_lock, irqflags); - frame->sequence_nr = port->hsr->sequence_nr; - port->hsr->sequence_nr++; - spin_unlock_irqrestore(&port->hsr->seqnr_lock, irqflags); - } - + proto = ethhdr->h_proto; frame->port_rcv = port; - check_local_dest(port->hsr, skb, frame); + hsr->proto_ops->fill_frame_info(proto, skb, frame); + check_local_dest(hsr, skb, frame); return 0; } @@ -362,7 +373,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) goto out_drop; } - if (hsr_fill_frame_info(&frame, skb, port) < 0) + if (fill_frame_info(&frame, skb, port) < 0) goto out_drop; hsr_register_frame_in(frame.node_src, port, frame.sequence_nr); hsr_forward_do(&frame); diff --git a/net/hsr/hsr_forward.h b/net/hsr/hsr_forward.h index b2a6fa319d94..893207792d56 100644 --- a/net/hsr/hsr_forward.h +++ b/net/hsr/hsr_forward.h @@ -14,5 +14,10 @@ #include "hsr_main.h" void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port); - +struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, + struct hsr_port *port); +struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame, + struct hsr_port *port); +void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, + struct hsr_frame_info *frame); #endif /* __HSR_FORWARD_H */ diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h index 58e1ad21b66f..14f442c57a84 100644 --- a/net/hsr/hsr_main.h +++ b/net/hsr/hsr_main.h @@ -162,9 +162,17 @@ enum hsr_version { PRP_V1, }; +struct hsr_frame_info; + struct hsr_proto_ops { /* format and send supervision frame */ void (*send_sv_frame)(struct hsr_port *port, unsigned long *interval); + struct sk_buff * (*get_untagged_frame)(struct hsr_frame_info *frame, + struct hsr_port *port); + struct sk_buff * (*create_tagged_frame)(struct hsr_frame_info *frame, + struct hsr_port *port); + void (*fill_frame_info)(__be16 proto, struct sk_buff *skb, + struct hsr_frame_info *frame); }; struct hsr_priv { From patchwork Fri Jul 17 15:15:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Murali Karicheri X-Patchwork-Id: 235718 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1796133ilg; Fri, 17 Jul 2020 08:15:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxmKINAuXb6xbYRa9/VQ3FrMYnpxp2p8qWaQSHc/QH//uomdrw1zot70K9uFlDaaiz4Npsb X-Received: by 2002:a17:906:95d9:: with SMTP id n25mr9214329ejy.437.1594998927320; Fri, 17 Jul 2020 08:15:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594998927; cv=none; d=google.com; s=arc-20160816; b=arxx0jQS9Hmzg4aTGqaoGRTWpv4nDsYX1zNKpYA7oysX3P5hzUVMnoXzQO5VWl03JN nUsnaD2Yji+2gJGMmtk7q87NND3Ki5POtuhGJGzcHrBmzRkZPnYkwDaCmSKcu6xZ5Sfg kkzZYQAMxI30C/XTnQ8Al4EJSHaqxXq5BoRD2XWWNzA+Fvw8fxrazTYuaEEjBD48S/4J MknedTztaGBfRKCFWUHl5X3lMYfa6J5DSZDSZqWAw2EUzqjHUWtt1ASsSJ/EL5gz3wXu 2aax1USl1f0S0gzTvv25BdqygutQVi6yyDhmxnrTLz0xy6s/5BFxdGCEzPa1lT9P4KiJ Sppg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=BHb5JnmA/toKJUOVFBZMgoE2Q8jn8vKVNWhBuZY5/mM=; b=xSiqrUNxAspOTRNpOgM7WG/Ni7Ws53B4rrprqUkjBh7IFGPwPpend2k9vu3ufWYqw9 /ljGcv2Ez148e8xmWoQ9XQOY8mwjBze4U6UkfvbHgXZ4tarIUCN00d2hsCWLUIlMN3gk Hctk8zj58USJKTyS6UAKtsyyv4AKh3+Ve4drkYEpTz+rKQRJklb1YqoWUnOUMbqbHr9p O45zGWh3qjzM9IebgbqoqWgBNJqBlfemQYxfRNBDSpRza01dVIozhgve1KffBg41qp2k 0GVb4KQuzLKo8aVsQMFIbsFMoZM7jNOEZUjRrPNiDz08nunEUOBv1xbdsrR34sN5jLxn xkUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=ZFWxpNgV; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e6si5292170ejx.444.2020.07.17.08.15.26; Fri, 17 Jul 2020 08:15:27 -0700 (PDT) Received-SPF: pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=ZFWxpNgV; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727906AbgGQPPZ (ORCPT + 9 others); Fri, 17 Jul 2020 11:15:25 -0400 Received: from fllv0015.ext.ti.com ([198.47.19.141]:47500 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726071AbgGQPPV (ORCPT ); Fri, 17 Jul 2020 11:15:21 -0400 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFF1Q015408; Fri, 17 Jul 2020 10:15:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1594998915; bh=BHb5JnmA/toKJUOVFBZMgoE2Q8jn8vKVNWhBuZY5/mM=; h=From:To:Subject:Date:In-Reply-To:References; b=ZFWxpNgVqF9DHhy6i8QMQ/VBO84dyjVaYL0MA0LiYf7mfYizfgLyq6EotcCoJNUo7 F377/VRqAh8XxT9PPL68we9bqTYMPqFc5fvEfQHjsOtFcm1Vs7Y4OOmRPbRP6wwb4W +GtQHAwPp85FAvdy7HvyDc1mylmsZrpTd6N0M4TA= Received: from DFLE112.ent.ti.com (dfle112.ent.ti.com [10.64.6.33]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 06HFFFOM111834 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 17 Jul 2020 10:15:15 -0500 Received: from DFLE104.ent.ti.com (10.64.6.25) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 17 Jul 2020 10:15:15 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 17 Jul 2020 10:15:14 -0500 Received: from uda0868495.fios-router.home (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFBmi010522; Fri, 17 Jul 2020 10:15:14 -0500 From: Murali Karicheri To: , , , , , , , Subject: [net-next PATCH v3 6/7] net: prp: add packet handling support Date: Fri, 17 Jul 2020 11:15:10 -0400 Message-ID: <20200717151511.329-7-m-karicheri2@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200717151511.329-1-m-karicheri2@ti.com> References: <20200717151511.329-1-m-karicheri2@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org DAN-P (Dual Attached Nodes PRP) nodes are expected to receive traditional IP packets as well as PRP (Parallel Redundancy Protocol) tagged (trailer) packets. PRP trailer is 6 bytes of PRP protocol unit called RCT, Redundancy Control Trailer (RCT) similar to HSR tag. PRP network can have traditional devices such as bridges/switches or PC attached to it and should be able to communicate. Regular Ethernet devices treat the RCT as pads. This patch adds logic to format L2 frames from network stack to add a trailer (RCT) and send it as duplicates over the slave interfaces when the protocol is PRP as per IEC 62439-3. At the ingress, it strips the trailer, do duplicate detection and rejection and forward a stripped frame up the network stack. PRP device should accept frames from Singly Attached Nodes (SAN) and thus the driver mark the link where the frame came from in the node table. Signed-off-by: Murali Karicheri --- net/hsr/hsr_device.c | 20 ++- net/hsr/hsr_forward.c | 268 ++++++++++++++++++++++++++++++++--------- net/hsr/hsr_forward.h | 7 ++ net/hsr/hsr_framereg.c | 94 ++++++++++++--- net/hsr/hsr_framereg.h | 29 ++++- net/hsr/hsr_main.h | 73 ++++++++++- net/hsr/hsr_slave.c | 24 +++- net/hsr/hsr_slave.h | 2 + 8 files changed, 429 insertions(+), 88 deletions(-) -- 2.17.1 diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 022393bed40a..ab953a1a0d6c 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -443,10 +443,17 @@ static struct hsr_proto_ops hsr_ops = { .create_tagged_frame = hsr_create_tagged_frame, .get_untagged_frame = hsr_get_untagged_frame, .fill_frame_info = hsr_fill_frame_info, + .invalid_dan_ingress_frame = hsr_invalid_dan_ingress_frame, }; static struct hsr_proto_ops prp_ops = { .send_sv_frame = send_prp_supervision_frame, + .create_tagged_frame = prp_create_tagged_frame, + .get_untagged_frame = prp_get_untagged_frame, + .drop_frame = prp_drop_frame, + .fill_frame_info = prp_fill_frame_info, + .handle_san_frame = prp_handle_san_frame, + .update_san_info = prp_update_san_info, }; void hsr_dev_setup(struct net_device *dev) @@ -508,15 +515,16 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], ether_addr_copy(hsr_dev->dev_addr, slave[0]->dev_addr); - /* currently PRP is not supported */ - if (protocol_version == PRP_V1) - return -EPROTONOSUPPORT; - /* initialize protocol specific functions */ - if (protocol_version == PRP_V1) + if (protocol_version == PRP_V1) { + /* For PRP, lan_id has most significant 3 bits holding + * the net_id of PRP_LAN_ID + */ + hsr->net_id = PRP_LAN_ID << 1; hsr->proto_ops = &prp_ops; - else + } else { hsr->proto_ops = &hsr_ops; + } /* Make sure we recognize frames from ourselves in hsr_rcv() */ res = hsr_create_self_node(hsr, hsr_dev->dev_addr, diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index 7fc6cc7b29bb..666d1562db03 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -17,18 +17,6 @@ struct hsr_node; -struct hsr_frame_info { - struct sk_buff *skb_std; - struct sk_buff *skb_hsr; - struct hsr_port *port_rcv; - struct hsr_node *node_src; - u16 sequence_nr; - bool is_supervision; - bool is_vlan; - bool is_local_dest; - bool is_local_exclusive; -}; - /* The uses I can see for these HSR supervision frames are: * 1) Use the frames that are sent after node initialization ("HSR_TLV.Type = * 22") to reset any sequence_nr counters belonging to that node. Useful if @@ -87,8 +75,8 @@ static bool is_supervision_frame(struct hsr_priv *hsr, struct sk_buff *skb) return true; } -static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in, - struct hsr_frame_info *frame) +static struct sk_buff *create_stripped_skb_hsr(struct sk_buff *skb_in, + struct hsr_frame_info *frame) { struct sk_buff *skb; int copylen; @@ -119,33 +107,113 @@ static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in, struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame, struct hsr_port *port) { - if (!frame->skb_std) - frame->skb_std = create_stripped_skb(frame->skb_hsr, frame); + if (!frame->skb_std) { + if (frame->skb_hsr) { + frame->skb_std = + create_stripped_skb_hsr(frame->skb_hsr, frame); + } else { + /* Unexpected */ + WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n", + __FILE__, __LINE__, port->dev->name); + return NULL; + } + } + + return skb_clone(frame->skb_std, GFP_ATOMIC); +} + +struct sk_buff *prp_get_untagged_frame(struct hsr_frame_info *frame, + struct hsr_port *port) +{ + if (!frame->skb_std) { + if (frame->skb_prp) { + /* trim the skb by len - HSR_HLEN to exclude RCT */ + skb_trim(frame->skb_prp, + frame->skb_prp->len - HSR_HLEN); + frame->skb_std = + __pskb_copy(frame->skb_prp, + skb_headroom(frame->skb_prp), + GFP_ATOMIC); + } else { + /* Unexpected */ + WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n", + __FILE__, __LINE__, port->dev->name); + return NULL; + } + } + return skb_clone(frame->skb_std, GFP_ATOMIC); } +static void prp_set_lan_id(struct prp_rct *trailer, + struct hsr_port *port) +{ + int lane_id; + + if (port->type == HSR_PT_SLAVE_A) + lane_id = 0; + else + lane_id = 1; + + /* Add net_id in the upper 3 bits of lane_id */ + lane_id |= port->hsr->net_id; + set_prp_lan_id(trailer, lane_id); +} + +/* Tailroom for PRP rct should have been created before calling this */ +static void prp_fill_rct(struct sk_buff *skb, struct hsr_frame_info *frame, + struct hsr_port *port) +{ + struct prp_rct *trailer; + int lsdu_size; + + if (!skb) + return; + + if (frame->is_vlan) + skb_put_padto(skb, VLAN_ETH_ZLEN); + else + skb_put_padto(skb, ETH_ZLEN); + + trailer = (struct prp_rct *)skb_put(skb, HSR_HLEN); + lsdu_size = skb->len - 14; + if (frame->is_vlan) + lsdu_size -= 4; + prp_set_lan_id(trailer, port); + set_prp_LSDU_size(trailer, lsdu_size); + trailer->sequence_nr = htons(frame->sequence_nr); + trailer->PRP_suffix = htons(ETH_P_PRP); +} + +static void hsr_set_path_id(struct hsr_ethhdr *hsr_ethhdr, + struct hsr_port *port) +{ + int path_id; + + if (port->type == HSR_PT_SLAVE_A) + path_id = 0; + else + path_id = 1; + + set_hsr_tag_path(&hsr_ethhdr->hsr_tag, path_id); +} + static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame, struct hsr_port *port, u8 proto_version) { struct hsr_ethhdr *hsr_ethhdr; - int lane_id; int lsdu_size; /* pad to minimum packet size which is 60 + 6 (HSR tag) */ skb_put_padto(skb, ETH_ZLEN + HSR_HLEN); - if (port->type == HSR_PT_SLAVE_A) - lane_id = 0; - else - lane_id = 1; - lsdu_size = skb->len - 14; if (frame->is_vlan) lsdu_size -= 4; hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb); - set_hsr_tag_path(&hsr_ethhdr->hsr_tag, lane_id); + hsr_set_path_id(hsr_ethhdr, port); set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size); hsr_ethhdr->hsr_tag.sequence_nr = htons(frame->sequence_nr); hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto; @@ -153,16 +221,28 @@ static void hsr_fill_tag(struct sk_buff *skb, struct hsr_frame_info *frame, ETH_P_HSR : ETH_P_PRP); } -static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, - struct hsr_frame_info *frame, - struct hsr_port *port) +/* If the original frame was an HSR tagged frame, just clone it to be sent + * unchanged. Otherwise, create a private frame especially tagged for 'port'. + */ +struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, + struct hsr_port *port) { - int movelen; unsigned char *dst, *src; struct sk_buff *skb; + int movelen; + + if (frame->skb_hsr) { + struct hsr_ethhdr *hsr_ethhdr = + (struct hsr_ethhdr *)skb_mac_header(frame->skb_hsr); + + /* set the lane id properly */ + hsr_set_path_id(hsr_ethhdr, port); + return skb_clone(frame->skb_hsr, GFP_ATOMIC); + } /* Create the new skb with enough headroom to fit the HSR tag */ - skb = __pskb_copy(skb_o, skb_headroom(skb_o) + HSR_HLEN, GFP_ATOMIC); + skb = __pskb_copy(frame->skb_std, + skb_headroom(frame->skb_std) + HSR_HLEN, GFP_ATOMIC); if (!skb) return NULL; skb_reset_mac_header(skb); @@ -184,21 +264,29 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o, return skb; } -/* If the original frame was an HSR tagged frame, just clone it to be sent - * unchanged. Otherwise, create a private frame especially tagged for 'port'. - */ -struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, +struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame, struct hsr_port *port) { - if (frame->skb_hsr) - return skb_clone(frame->skb_hsr, GFP_ATOMIC); + struct sk_buff *skb; - if (port->type != HSR_PT_SLAVE_A && port->type != HSR_PT_SLAVE_B) { - WARN_ONCE(1, "HSR: Bug: trying to create a tagged frame for a non-ring port"); - return NULL; + if (frame->skb_prp) { + struct prp_rct *trailer = skb_get_PRP_rct(frame->skb_prp); + + if (trailer) { + prp_set_lan_id(trailer, port); + } else { + WARN_ONCE(!trailer, "errored PRP skb"); + return NULL; + } + return skb_clone(frame->skb_prp, GFP_ATOMIC); } - return create_tagged_skb(frame->skb_std, frame, port); + skb = skb_copy_expand(frame->skb_std, 0, + skb_tailroom(frame->skb_std) + HSR_HLEN, + GFP_ATOMIC); + prp_fill_rct(skb, frame, port); + + return skb; } static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev, @@ -235,9 +323,18 @@ static int hsr_xmit(struct sk_buff *skb, struct hsr_port *port, return dev_queue_xmit(skb); } +bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port) +{ + return ((frame->port_rcv->type == HSR_PT_SLAVE_A && + port->type == HSR_PT_SLAVE_B) || + (frame->port_rcv->type == HSR_PT_SLAVE_B && + port->type == HSR_PT_SLAVE_A)); +} + /* Forward the frame through all devices except: * - Back through the receiving device * - If it's a HSR frame: through a device where it has passed before + * - if it's a PRP frame: through another PRP slave device (no bridge) * - To the local HSR master only if the frame is directly addressed to it, or * a non-supervision multicast or broadcast frame. * @@ -265,25 +362,33 @@ static void hsr_forward_do(struct hsr_frame_info *frame) if (port->type != HSR_PT_MASTER && frame->is_local_exclusive) continue; - /* Don't send frame over port where it has been sent before */ - if (hsr_register_frame_out(port, frame->node_src, + /* Don't send frame over port where it has been sent before. + * Also fro SAN, this shouldn't be done. + */ + if (!frame->is_from_san && + hsr_register_frame_out(port, frame->node_src, frame->sequence_nr)) continue; if (frame->is_supervision && port->type == HSR_PT_MASTER) { - hsr_handle_sup_frame(frame->skb_hsr, - frame->node_src, - frame->port_rcv); + hsr_handle_sup_frame(frame); continue; } + /* Check if frame is to be dropped. Eg. for PRP no forward + * between ports. + */ + if (hsr->proto_ops->drop_frame && + hsr->proto_ops->drop_frame(frame, port)) + continue; + if (port->type != HSR_PT_MASTER) skb = hsr->proto_ops->create_tagged_frame(frame, port); else skb = hsr->proto_ops->get_untagged_frame(frame, port); if (!skb) { - /* FIXME: Record the dropped frame? */ + frame->port_rcv->dev->stats.rx_dropped++; continue; } @@ -314,19 +419,20 @@ static void check_local_dest(struct hsr_priv *hsr, struct sk_buff *skb, } } -void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, - struct hsr_frame_info *frame) +static void handle_std_frame(struct sk_buff *skb, + struct hsr_frame_info *frame) { - struct hsr_priv *hsr = frame->port_rcv->hsr; + struct hsr_port *port = frame->port_rcv; + struct hsr_priv *hsr = port->hsr; unsigned long irqflags; - if (proto == htons(ETH_P_PRP) || proto == htons(ETH_P_HSR)) { - frame->skb_std = NULL; - frame->skb_hsr = skb; - frame->sequence_nr = hsr_get_skb_sequence_nr(skb); + frame->skb_hsr = NULL; + frame->skb_prp = NULL; + frame->skb_std = skb; + + if (port->type != HSR_PT_MASTER) { + frame->is_from_san = true; } else { - frame->skb_std = skb; - frame->skb_hsr = NULL; /* Sequence nr for the master node */ spin_lock_irqsave(&hsr->seqnr_lock, irqflags); frame->sequence_nr = hsr->sequence_nr; @@ -335,29 +441,74 @@ void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, } } +void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, + struct hsr_frame_info *frame) +{ + if (proto == htons(ETH_P_PRP) || + proto == htons(ETH_P_HSR)) { + /* HSR tagged frame :- Data or Supervision */ + frame->skb_std = NULL; + frame->skb_prp = NULL; + frame->skb_hsr = skb; + frame->sequence_nr = hsr_get_skb_sequence_nr(skb); + return; + } + + /* Standard frame or PRP from master port */ + handle_std_frame(skb, frame); +} + +void prp_fill_frame_info(__be16 proto, struct sk_buff *skb, + struct hsr_frame_info *frame) +{ + /* Supervision frame */ + struct prp_rct *rct = skb_get_PRP_rct(skb); + + if (rct && + prp_check_lsdu_size(skb, rct, frame->is_supervision)) { + frame->skb_hsr = NULL; + frame->skb_std = NULL; + frame->skb_prp = skb; + frame->sequence_nr = prp_get_skb_sequence_nr(rct); + return; + } + handle_std_frame(skb, frame); +} + static int fill_frame_info(struct hsr_frame_info *frame, struct sk_buff *skb, struct hsr_port *port) { struct hsr_priv *hsr = port->hsr; + struct hsr_vlan_ethhdr *vlan_hdr; struct ethhdr *ethhdr; __be16 proto; + memset(frame, 0, sizeof(*frame)); frame->is_supervision = is_supervision_frame(port->hsr, skb); - frame->node_src = hsr_get_node(port, skb, frame->is_supervision); + frame->node_src = hsr_get_node(port, &hsr->node_db, skb, + frame->is_supervision, + port->type); if (!frame->node_src) return -1; /* Unknown node and !is_supervision, or no mem */ ethhdr = (struct ethhdr *)skb_mac_header(skb); frame->is_vlan = false; - if (ethhdr->h_proto == htons(ETH_P_8021Q)) { + proto = ethhdr->h_proto; + + if (proto == htons(ETH_P_8021Q)) frame->is_vlan = true; + + if (frame->is_vlan) { + vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr; + proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; /* FIXME: */ netdev_warn_once(skb->dev, "VLAN not yet supported"); } - proto = ethhdr->h_proto; + + frame->is_from_san = false; frame->port_rcv = port; hsr->proto_ops->fill_frame_info(proto, skb, frame); - check_local_dest(hsr, skb, frame); + check_local_dest(port->hsr, skb, frame); return 0; } @@ -375,6 +526,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) if (fill_frame_info(&frame, skb, port) < 0) goto out_drop; + hsr_register_frame_in(frame.node_src, port, frame.sequence_nr); hsr_forward_do(&frame); /* Gets called for ingress frames as well as egress from master port. @@ -387,6 +539,8 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) if (frame.skb_hsr) kfree_skb(frame.skb_hsr); + if (frame.skb_prp) + kfree_skb(frame.skb_prp); if (frame.skb_std) kfree_skb(frame.skb_std); return; diff --git a/net/hsr/hsr_forward.h b/net/hsr/hsr_forward.h index 893207792d56..618140d484ad 100644 --- a/net/hsr/hsr_forward.h +++ b/net/hsr/hsr_forward.h @@ -14,10 +14,17 @@ #include "hsr_main.h" void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port); +struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame, + struct hsr_port *port); struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame, struct hsr_port *port); struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame, struct hsr_port *port); +struct sk_buff *prp_get_untagged_frame(struct hsr_frame_info *frame, + struct hsr_port *port); +bool prp_drop_frame(struct hsr_frame_info *frame, struct hsr_port *port); +void prp_fill_frame_info(__be16 proto, struct sk_buff *skb, + struct hsr_frame_info *frame); void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb, struct hsr_frame_info *frame); #endif /* __HSR_FORWARD_H */ diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 13b2190e6556..5c97de459905 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c @@ -127,6 +127,19 @@ void hsr_del_nodes(struct list_head *node_db) kfree(node); } +void prp_handle_san_frame(bool san, enum hsr_port_type port, + struct hsr_node *node) +{ + /* Mark if the SAN node is over LAN_A or LAN_B */ + if (port == HSR_PT_SLAVE_A) { + node->san_a = true; + return; + } + + if (port == HSR_PT_SLAVE_B) + node->san_b = true; +} + /* Allocate an hsr_node and add it to node_db. 'addr' is the node's address_A; * seq_out is used to initialize filtering of outgoing duplicate frames * originating from the newly added node. @@ -134,7 +147,8 @@ void hsr_del_nodes(struct list_head *node_db) static struct hsr_node *hsr_add_node(struct hsr_priv *hsr, struct list_head *node_db, unsigned char addr[], - u16 seq_out) + u16 seq_out, bool san, + enum hsr_port_type rx_port) { struct hsr_node *new_node, *node; unsigned long now; @@ -155,6 +169,9 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr, for (i = 0; i < HSR_PT_PORTS; i++) new_node->seq_out[i] = seq_out; + if (san && hsr->proto_ops->handle_san_frame) + hsr->proto_ops->handle_san_frame(san, rx_port, new_node); + spin_lock_bh(&hsr->list_lock); list_for_each_entry_rcu(node, node_db, mac_list, lockdep_is_held(&hsr->list_lock)) { @@ -172,15 +189,26 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr, return node; } +void prp_update_san_info(struct hsr_node *node, bool is_sup) +{ + if (!is_sup) + return; + + node->san_a = false; + node->san_b = false; +} + /* Get the hsr_node from which 'skb' was sent. */ -struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, - bool is_sup) +struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db, + struct sk_buff *skb, bool is_sup, + enum hsr_port_type rx_port) { - struct list_head *node_db = &port->hsr->node_db; struct hsr_priv *hsr = port->hsr; struct hsr_node *node; struct ethhdr *ethhdr; + struct prp_rct *rct; + bool san = false; u16 seq_out; if (!skb_mac_header_was_set(skb)) @@ -189,14 +217,21 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, ethhdr = (struct ethhdr *)skb_mac_header(skb); list_for_each_entry_rcu(node, node_db, mac_list) { - if (ether_addr_equal(node->macaddress_A, ethhdr->h_source)) + if (ether_addr_equal(node->macaddress_A, ethhdr->h_source)) { + if (hsr->proto_ops->update_san_info) + hsr->proto_ops->update_san_info(node, is_sup); return node; - if (ether_addr_equal(node->macaddress_B, ethhdr->h_source)) + } + if (ether_addr_equal(node->macaddress_B, ethhdr->h_source)) { + if (hsr->proto_ops->update_san_info) + hsr->proto_ops->update_san_info(node, is_sup); return node; + } } - /* Everyone may create a node entry, connected node to a HSR device. */ - + /* Everyone may create a node entry, connected node to a HSR/PRP + * device. + */ if (ethhdr->h_proto == htons(ETH_P_PRP) || ethhdr->h_proto == htons(ETH_P_HSR)) { /* Use the existing sequence_nr from the tag as starting point @@ -204,31 +239,47 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, */ seq_out = hsr_get_skb_sequence_nr(skb) - 1; } else { - /* this is called also for frames from master port and - * so warn only for non master ports - */ - if (port->type != HSR_PT_MASTER) - WARN_ONCE(1, "%s: Non-HSR frame\n", __func__); - seq_out = HSR_SEQNR_START; + rct = skb_get_PRP_rct(skb); + if (rct && prp_check_lsdu_size(skb, rct, is_sup)) { + seq_out = prp_get_skb_sequence_nr(rct); + } else { + if (rx_port != HSR_PT_MASTER) + san = true; + seq_out = HSR_SEQNR_START; + } } - return hsr_add_node(hsr, node_db, ethhdr->h_source, seq_out); + return hsr_add_node(hsr, node_db, ethhdr->h_source, seq_out, + san, rx_port); } /* Use the Supervision frame's info about an eventual macaddress_B for merging * nodes that has previously had their macaddress_B registered as a separate * node. */ -void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, - struct hsr_port *port_rcv) +void hsr_handle_sup_frame(struct hsr_frame_info *frame) { + struct hsr_node *node_curr = frame->node_src; + struct hsr_port *port_rcv = frame->port_rcv; struct hsr_priv *hsr = port_rcv->hsr; struct hsr_sup_payload *hsr_sp; struct hsr_node *node_real; + struct sk_buff *skb = NULL; struct list_head *node_db; struct ethhdr *ethhdr; int i; + /* Here either frame->skb_hsr or frame->skb_prp should be + * valid as supervision frame always will have protocol + * header info. + */ + if (frame->skb_hsr) + skb = frame->skb_hsr; + else if (frame->skb_prp) + skb = frame->skb_prp; + if (!skb) + return; + ethhdr = (struct ethhdr *)skb_mac_header(skb); /* Leave the ethernet header. */ @@ -249,7 +300,8 @@ void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, if (!node_real) /* No frame received from AddrA of this node yet */ node_real = hsr_add_node(hsr, node_db, hsr_sp->macaddress_A, - HSR_SEQNR_START - 1); + HSR_SEQNR_START - 1, true, + port_rcv->type); if (!node_real) goto done; /* No mem */ if (node_real == node_curr) @@ -275,7 +327,11 @@ void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, kfree_rcu(node_curr, rcu_head); done: - skb_push(skb, sizeof(struct hsrv1_ethhdr_sp)); + /* PRP uses v0 header */ + if (ethhdr->h_proto == htons(ETH_P_HSR)) + skb_push(skb, sizeof(struct hsrv1_ethhdr_sp)); + else + skb_push(skb, sizeof(struct hsrv0_ethhdr_sp)); } /* 'skb' is a frame meant for this host, that is to be passed to upper layers. diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h index c06447780d05..86b43f539f2c 100644 --- a/net/hsr/hsr_framereg.h +++ b/net/hsr/hsr_framereg.h @@ -14,12 +14,26 @@ struct hsr_node; +struct hsr_frame_info { + struct sk_buff *skb_std; + struct sk_buff *skb_hsr; + struct sk_buff *skb_prp; + struct hsr_port *port_rcv; + struct hsr_node *node_src; + u16 sequence_nr; + bool is_supervision; + bool is_vlan; + bool is_local_dest; + bool is_local_exclusive; + bool is_from_san; +}; + void hsr_del_self_node(struct hsr_priv *hsr); void hsr_del_nodes(struct list_head *node_db); -struct hsr_node *hsr_get_node(struct hsr_port *port, struct sk_buff *skb, - bool is_sup); -void hsr_handle_sup_frame(struct sk_buff *skb, struct hsr_node *node_curr, - struct hsr_port *port); +struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db, + struct sk_buff *skb, bool is_sup, + enum hsr_port_type rx_port); +void hsr_handle_sup_frame(struct hsr_frame_info *frame); bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr); void hsr_addr_subst_source(struct hsr_node *node, struct sk_buff *skb); @@ -49,6 +63,10 @@ int hsr_get_node_data(struct hsr_priv *hsr, int *if2_age, u16 *if2_seq); +void prp_handle_san_frame(bool san, enum hsr_port_type port, + struct hsr_node *node); +void prp_update_san_info(struct hsr_node *node, bool is_sup); + struct hsr_node { struct list_head mac_list; unsigned char macaddress_A[ETH_ALEN]; @@ -57,6 +75,9 @@ struct hsr_node { enum hsr_port_type addr_B_port; unsigned long time_in[HSR_PT_PORTS]; bool time_in_stale[HSR_PT_PORTS]; + /* if the node is a SAN */ + bool san_a; + bool san_b; u16 seq_out[HSR_PT_PORTS]; struct rcu_head rcu_head; }; diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h index 14f442c57a84..7dc92ce5a134 100644 --- a/net/hsr/hsr_main.h +++ b/net/hsr/hsr_main.h @@ -12,6 +12,7 @@ #include #include +#include /* Time constants as specified in the HSR specification (IEC-62439-3 2010) * Table 8. @@ -86,7 +87,12 @@ struct hsr_ethhdr { struct hsr_tag hsr_tag; } __packed; -/* HSR Supervision Frame data types. +struct hsr_vlan_ethhdr { + struct vlan_ethhdr vlanhdr; + struct hsr_tag hsr_tag; +} __packed; + +/* HSR/PRP Supervision Frame data types. * Field names as defined in the IEC:2010 standard for HSR. */ struct hsr_sup_tag { @@ -142,6 +148,16 @@ struct prp_rct { __be16 PRP_suffix; } __packed; +static inline u16 get_prp_LSDU_size(struct prp_rct *rct) +{ + return ntohs(rct->lan_id_and_LSDU_size) & 0x0FFF; +} + +static inline void set_prp_lan_id(struct prp_rct *rct, u16 lan_id) +{ + rct->lan_id_and_LSDU_size = htons((ntohs(rct->lan_id_and_LSDU_size) & + 0x0FFF) | (lan_id << 12)); +} static inline void set_prp_LSDU_size(struct prp_rct *rct, u16 LSDU_size) { rct->lan_id_and_LSDU_size = htons((ntohs(rct->lan_id_and_LSDU_size) & @@ -163,16 +179,22 @@ enum hsr_version { }; struct hsr_frame_info; +struct hsr_node; struct hsr_proto_ops { /* format and send supervision frame */ void (*send_sv_frame)(struct hsr_port *port, unsigned long *interval); + void (*handle_san_frame)(bool san, enum hsr_port_type port, + struct hsr_node *node); + bool (*drop_frame)(struct hsr_frame_info *frame, struct hsr_port *port); struct sk_buff * (*get_untagged_frame)(struct hsr_frame_info *frame, struct hsr_port *port); struct sk_buff * (*create_tagged_frame)(struct hsr_frame_info *frame, struct hsr_port *port); void (*fill_frame_info)(__be16 proto, struct sk_buff *skb, struct hsr_frame_info *frame); + bool (*invalid_dan_ingress_frame)(__be16 protocol); + void (*update_san_info)(struct hsr_node *node, bool is_sup); }; struct hsr_priv { @@ -189,6 +211,12 @@ struct hsr_priv { spinlock_t seqnr_lock; /* locking for sequence_nr */ spinlock_t list_lock; /* locking for node list */ struct hsr_proto_ops *proto_ops; +#define PRP_LAN_ID 0x5 /* 0x1010 for A and 0x1011 for B. Bit 0 is set + * based on SLAVE_A or SLAVE_B + */ + u8 net_id; /* for PRP, it occupies most significant 3 bits + * of lan_id + */ unsigned char sup_multicast_addr[ETH_ALEN]; #ifdef CONFIG_DEBUG_FS struct dentry *node_tbl_root; @@ -209,6 +237,49 @@ static inline u16 hsr_get_skb_sequence_nr(struct sk_buff *skb) return ntohs(hsr_ethhdr->hsr_tag.sequence_nr); } +static inline struct prp_rct *skb_get_PRP_rct(struct sk_buff *skb) +{ + unsigned char *tail = skb_tail_pointer(skb) - HSR_HLEN; + + struct prp_rct *rct = (struct prp_rct *)tail; + + if (rct->PRP_suffix == htons(ETH_P_PRP)) + return rct; + + return NULL; +} + +/* Assume caller has confirmed this skb is PRP suffixed */ +static inline u16 prp_get_skb_sequence_nr(struct prp_rct *rct) +{ + return ntohs(rct->sequence_nr); +} + +static inline u16 get_prp_lan_id(struct prp_rct *rct) +{ + return ntohs(rct->lan_id_and_LSDU_size) >> 12; +} + +/* assume there is a valid rct */ +static inline bool prp_check_lsdu_size(struct sk_buff *skb, + struct prp_rct *rct, + bool is_sup) +{ + struct ethhdr *ethhdr; + int expected_lsdu_size; + + if (is_sup) { + expected_lsdu_size = HSR_V1_SUP_LSDUSIZE; + } else { + ethhdr = (struct ethhdr *)skb_mac_header(skb); + expected_lsdu_size = skb->len - 14; + if (ethhdr->h_proto == htons(ETH_P_8021Q)) + expected_lsdu_size -= 4; + } + + return (expected_lsdu_size == get_prp_LSDU_size(rct)); +} + #if IS_ENABLED(CONFIG_DEBUG_FS) void hsr_debugfs_rename(struct net_device *dev); void hsr_debugfs_init(struct hsr_priv *priv, struct net_device *hsr_dev); diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c index b5c0834de338..36d5fcf09c61 100644 --- a/net/hsr/hsr_slave.c +++ b/net/hsr/hsr_slave.c @@ -16,12 +16,22 @@ #include "hsr_forward.h" #include "hsr_framereg.h" +bool hsr_invalid_dan_ingress_frame(__be16 protocol) +{ + return (protocol != htons(ETH_P_PRP) && protocol != htons(ETH_P_HSR)); +} + static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb) { struct sk_buff *skb = *pskb; struct hsr_port *port; + struct hsr_priv *hsr; __be16 protocol; + /* Packets from dev_loopback_xmit() do not have L2 header, bail out */ + if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) + return RX_HANDLER_PASS; + if (!skb_mac_header_was_set(skb)) { WARN_ONCE(1, "%s: skb invalid", __func__); return RX_HANDLER_PASS; @@ -30,6 +40,7 @@ static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb) port = hsr_port_get_rcu(skb->dev); if (!port) goto finish_pass; + hsr = port->hsr; if (hsr_addr_is_self(port->hsr, eth_hdr(skb)->h_source)) { /* Directly kill frames sent by ourselves */ @@ -37,12 +48,23 @@ static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb) goto finish_consume; } + /* For HSR, only tagged frames are expected, but for PRP + * there could be non tagged frames as well from Single + * attached nodes (SANs). + */ protocol = eth_hdr(skb)->h_proto; - if (protocol != htons(ETH_P_PRP) && protocol != htons(ETH_P_HSR)) + if (hsr->proto_ops->invalid_dan_ingress_frame && + hsr->proto_ops->invalid_dan_ingress_frame(protocol)) goto finish_pass; skb_push(skb, ETH_HLEN); + if (skb_mac_header(skb) != skb->data) { + WARN_ONCE(1, "%s:%d: Malformed frame at source port %s)\n", + __func__, __LINE__, port->dev->name); + goto finish_consume; + } + hsr_forward_skb(skb, port); finish_consume: diff --git a/net/hsr/hsr_slave.h b/net/hsr/hsr_slave.h index 9708a4f0ec09..edc4612bb009 100644 --- a/net/hsr/hsr_slave.h +++ b/net/hsr/hsr_slave.h @@ -32,4 +32,6 @@ static inline struct hsr_port *hsr_port_get_rcu(const struct net_device *dev) rcu_dereference(dev->rx_handler_data) : NULL; } +bool hsr_invalid_dan_ingress_frame(__be16 protocol); + #endif /* __HSR_SLAVE_H */ From patchwork Fri Jul 17 15:15:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Murali Karicheri X-Patchwork-Id: 235722 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1796532ilg; Fri, 17 Jul 2020 08:15:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzoDy11lHush2ykF+PjnmisFhqjhhdHtuKxQ+9M+X1pPna3e7ajyBdQBEHwzxMe3Pzcs86T X-Received: by 2002:a17:906:a156:: with SMTP id bu22mr8792333ejb.322.1594998953001; Fri, 17 Jul 2020 08:15:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594998952; cv=none; d=google.com; s=arc-20160816; b=azU0tfFoyfHJ0eWRqFVPzankIJrxQKISH8D+yTUHw0ohuN5dqMiHKg+ETqQgj0n4+u 70jCiIQyjCWet0fofr3UIU/FH/tYRI8mfWvBFtQMJNiNwdt78+RcKpyBcQC7mtnjbmnw eqNbm0y7R6g32h0KeAu45tN6EthVByJHSinaFo+2nNhxKrYGQRSedxDCNLaFFHvZgoHl vMZ3qj+Tw5e/Rg2WCdXzGaEACMnZzRE2jFAccRq1LBvg0+PsH9ZooRezdNXKnw8lB7le my6x5U+oXF7agrvLRUazaP7wdHyngODCv16xFZqkBJHZUzbnMnEBLrSqwyRWqxvMSxeq JGew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=DIxOOQwIi12wLQSGUItZsPXBRsZgdqTGMtvo+XZ3cO0=; b=WxDEtRm3a/wa33jldX0CGrGTdA+ypUuGGB7IfYVd2+D541AOmVsA5lgoxGZ7K5ztOK ZVHQykrfCfnetL1x1UURHOWz0mTlIoHqtGfjdEl0MaO19ucp+Qur3tMmhKOI791JkUcB PjWMVNsBr6B/crkoh74Pn1mIe6421ffXmzn9dxX1sW9O/M4jWwvOJqRFyy63fJmIBKxc djiR4VO7F73Pf7StjakBVpcVU6dDgIFZoGPjnk6T3CJ/g8nXEA2AW7EbRwQYAzdD4pQH UsfgNzImx1nUWsPcGTvhAW5z7dOlYlAl959VisPBkM2UUvIomuciEBPVtGpDStsUcQFh Rrqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=w2fO94op; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id by7si5185311edb.303.2020.07.17.08.15.52; Fri, 17 Jul 2020 08:15:52 -0700 (PDT) Received-SPF: pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=w2fO94op; spf=pass (google.com: domain of netdev-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728001AbgGQPPn (ORCPT + 9 others); Fri, 17 Jul 2020 11:15:43 -0400 Received: from lelv0143.ext.ti.com ([198.47.23.248]:43452 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726882AbgGQPPT (ORCPT ); Fri, 17 Jul 2020 11:15:19 -0400 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFG9X085664; Fri, 17 Jul 2020 10:15:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1594998916; bh=DIxOOQwIi12wLQSGUItZsPXBRsZgdqTGMtvo+XZ3cO0=; h=From:To:Subject:Date:In-Reply-To:References; b=w2fO94opv0/Uwfz0x4+DtoAI4aD3rmGw9JNtkUNj8emS9MEzzs1VscwQOrqcloP9W f8Szq6TX1KYK8mnf/ANcHlGVpt5jtf9To8QQLVjEITvVd6k6WrOTIW6h2u36eZi2XK BlbqvXUga1l5lrXVFPLBovjcw7kWpMW0qCDki7d8= Received: from DLEE115.ent.ti.com (dlee115.ent.ti.com [157.170.170.26]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 06HFFFwu069299 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 17 Jul 2020 10:15:15 -0500 Received: from DLEE110.ent.ti.com (157.170.170.21) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 17 Jul 2020 10:15:15 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 17 Jul 2020 10:15:15 -0500 Received: from uda0868495.fios-router.home (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 06HFFBmj010522; Fri, 17 Jul 2020 10:15:15 -0500 From: Murali Karicheri To: , , , , , , , Subject: [net-next PATCH v3 7/7] net: prp: enhance debugfs to display PRP info Date: Fri, 17 Jul 2020 11:15:11 -0400 Message-ID: <20200717151511.329-8-m-karicheri2@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200717151511.329-1-m-karicheri2@ti.com> References: <20200717151511.329-1-m-karicheri2@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Print PRP specific information from node table as part of debugfs node table display. Also display the node as DAN-H or DAN-P depending on the info from node table. Signed-off-by: Murali Karicheri --- net/hsr/hsr_debugfs.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) -- 2.17.1 diff --git a/net/hsr/hsr_debugfs.c b/net/hsr/hsr_debugfs.c index c1932c0a15be..3b6f675bd55a 100644 --- a/net/hsr/hsr_debugfs.c +++ b/net/hsr/hsr_debugfs.c @@ -24,7 +24,7 @@ static struct dentry *hsr_debugfs_root_dir; static void print_mac_address(struct seq_file *sfp, unsigned char *mac) { - seq_printf(sfp, "%02x:%02x:%02x:%02x:%02x:%02x:", + seq_printf(sfp, "%02x:%02x:%02x:%02x:%02x:%02x ", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } @@ -35,20 +35,32 @@ hsr_node_table_show(struct seq_file *sfp, void *data) struct hsr_priv *priv = (struct hsr_priv *)sfp->private; struct hsr_node *node; - seq_puts(sfp, "Node Table entries\n"); - seq_puts(sfp, "MAC-Address-A, MAC-Address-B, time_in[A], "); - seq_puts(sfp, "time_in[B], Address-B port\n"); + seq_printf(sfp, "Node Table entries for (%s) device\n", + (priv->prot_version == PRP_V1 ? "PRP" : "HSR")); + seq_puts(sfp, "MAC-Address-A, MAC-Address-B, time_in[A], "); + seq_puts(sfp, "time_in[B], Address-B port, "); + if (priv->prot_version == PRP_V1) + seq_puts(sfp, "SAN-A, SAN-B, DAN-P\n"); + else + seq_puts(sfp, "DAN-H\n"); + rcu_read_lock(); list_for_each_entry_rcu(node, &priv->node_db, mac_list) { /* skip self node */ if (hsr_addr_is_self(priv, node->macaddress_A)) continue; print_mac_address(sfp, &node->macaddress_A[0]); - seq_puts(sfp, " "); print_mac_address(sfp, &node->macaddress_B[0]); - seq_printf(sfp, "0x%lx, ", node->time_in[HSR_PT_SLAVE_A]); - seq_printf(sfp, "0x%lx ", node->time_in[HSR_PT_SLAVE_B]); - seq_printf(sfp, "0x%x\n", node->addr_B_port); + seq_printf(sfp, "%10lx, ", node->time_in[HSR_PT_SLAVE_A]); + seq_printf(sfp, "%10lx, ", node->time_in[HSR_PT_SLAVE_B]); + seq_printf(sfp, "%14x, ", node->addr_B_port); + + if (priv->prot_version == PRP_V1) + seq_printf(sfp, "%5x, %5x, %5x\n", + node->san_a, node->san_b, + (node->san_a == 0 && node->san_b == 0)); + else + seq_printf(sfp, "%5x\n", 1); } rcu_read_unlock(); return 0; @@ -57,7 +69,8 @@ hsr_node_table_show(struct seq_file *sfp, void *data) /* hsr_node_table_open - Open the node_table file * * Description: - * This routine opens a debugfs file node_table of specific hsr device + * This routine opens a debugfs file node_table of specific hsr + * or prp device */ static int hsr_node_table_open(struct inode *inode, struct file *filp)