Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * PTP 1588 support
0004  *
0005  * This file implements a BPF that recognizes PTP event messages.
0006  *
0007  * Copyright (C) 2010 OMICRON electronics GmbH
0008  */
0009 
0010 #ifndef _PTP_CLASSIFY_H_
0011 #define _PTP_CLASSIFY_H_
0012 
0013 #include <linux/ip.h>
0014 #include <linux/skbuff.h>
0015 
0016 #define PTP_CLASS_NONE  0x00 /* not a PTP event message */
0017 #define PTP_CLASS_V1    0x01 /* protocol version 1 */
0018 #define PTP_CLASS_V2    0x02 /* protocol version 2 */
0019 #define PTP_CLASS_VMASK 0x0f /* max protocol version is 15 */
0020 #define PTP_CLASS_IPV4  0x10 /* event in an IPV4 UDP packet */
0021 #define PTP_CLASS_IPV6  0x20 /* event in an IPV6 UDP packet */
0022 #define PTP_CLASS_L2    0x40 /* event in a L2 packet */
0023 #define PTP_CLASS_PMASK 0x70 /* mask for the packet type field */
0024 #define PTP_CLASS_VLAN  0x80 /* event in a VLAN tagged packet */
0025 
0026 #define PTP_CLASS_V1_IPV4 (PTP_CLASS_V1 | PTP_CLASS_IPV4)
0027 #define PTP_CLASS_V1_IPV6 (PTP_CLASS_V1 | PTP_CLASS_IPV6) /* probably DNE */
0028 #define PTP_CLASS_V2_IPV4 (PTP_CLASS_V2 | PTP_CLASS_IPV4)
0029 #define PTP_CLASS_V2_IPV6 (PTP_CLASS_V2 | PTP_CLASS_IPV6)
0030 #define PTP_CLASS_V2_L2   (PTP_CLASS_V2 | PTP_CLASS_L2)
0031 #define PTP_CLASS_V2_VLAN (PTP_CLASS_V2 | PTP_CLASS_VLAN)
0032 #define PTP_CLASS_L4      (PTP_CLASS_IPV4 | PTP_CLASS_IPV6)
0033 
0034 #define PTP_MSGTYPE_SYNC        0x0
0035 #define PTP_MSGTYPE_DELAY_REQ   0x1
0036 #define PTP_MSGTYPE_PDELAY_REQ  0x2
0037 #define PTP_MSGTYPE_PDELAY_RESP 0x3
0038 
0039 #define PTP_EV_PORT 319
0040 #define PTP_GEN_PORT 320
0041 #define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type */
0042 
0043 #define OFF_PTP_SOURCE_UUID 22 /* PTPv1 only */
0044 #define OFF_PTP_SEQUENCE_ID 30
0045 
0046 /* PTP header flag fields */
0047 #define PTP_FLAG_TWOSTEP    BIT(1)
0048 
0049 /* Below defines should actually be removed at some point in time. */
0050 #define IP6_HLEN    40
0051 #define UDP_HLEN    8
0052 #define OFF_IHL     14
0053 #define IPV4_HLEN(data) (((struct iphdr *)(data + OFF_IHL))->ihl << 2)
0054 
0055 struct clock_identity {
0056     u8 id[8];
0057 } __packed;
0058 
0059 struct port_identity {
0060     struct clock_identity   clock_identity;
0061     __be16          port_number;
0062 } __packed;
0063 
0064 struct ptp_header {
0065     u8          tsmt;  /* transportSpecific | messageType */
0066     u8          ver;   /* reserved          | versionPTP  */
0067     __be16          message_length;
0068     u8          domain_number;
0069     u8          reserved1;
0070     u8          flag_field[2];
0071     __be64          correction;
0072     __be32          reserved2;
0073     struct port_identity    source_port_identity;
0074     __be16          sequence_id;
0075     u8          control;
0076     u8          log_message_interval;
0077 } __packed;
0078 
0079 #if defined(CONFIG_NET_PTP_CLASSIFY)
0080 /**
0081  * ptp_classify_raw - classify a PTP packet
0082  * @skb: buffer
0083  *
0084  * Runs a minimal BPF dissector to classify a network packet to
0085  * determine the PTP class. In case the skb does not contain any
0086  * PTP protocol data, PTP_CLASS_NONE will be returned, otherwise
0087  * PTP_CLASS_V1_IPV{4,6}, PTP_CLASS_V2_IPV{4,6} or
0088  * PTP_CLASS_V2_{L2,VLAN}, depending on the packet content.
0089  */
0090 unsigned int ptp_classify_raw(const struct sk_buff *skb);
0091 
0092 /**
0093  * ptp_parse_header - Get pointer to the PTP v2 header
0094  * @skb: packet buffer
0095  * @type: type of the packet (see ptp_classify_raw())
0096  *
0097  * This function takes care of the VLAN, UDP, IPv4 and IPv6 headers. The length
0098  * is checked.
0099  *
0100  * Note, internally skb_mac_header() is used. Make sure that the @skb is
0101  * initialized accordingly.
0102  *
0103  * Return: Pointer to the ptp v2 header or NULL if not found
0104  */
0105 struct ptp_header *ptp_parse_header(struct sk_buff *skb, unsigned int type);
0106 
0107 /**
0108  * ptp_get_msgtype - Extract ptp message type from given header
0109  * @hdr: ptp header
0110  * @type: type of the packet (see ptp_classify_raw())
0111  *
0112  * This function returns the message type for a given ptp header. It takes care
0113  * of the different ptp header versions (v1 or v2).
0114  *
0115  * Return: The message type
0116  */
0117 static inline u8 ptp_get_msgtype(const struct ptp_header *hdr,
0118                  unsigned int type)
0119 {
0120     u8 msgtype;
0121 
0122     if (unlikely(type & PTP_CLASS_V1)) {
0123         /* msg type is located at the control field for ptp v1 */
0124         msgtype = hdr->control;
0125     } else {
0126         msgtype = hdr->tsmt & 0x0f;
0127     }
0128 
0129     return msgtype;
0130 }
0131 
0132 /**
0133  * ptp_msg_is_sync - Evaluates whether the given skb is a PTP Sync message
0134  * @skb: packet buffer
0135  * @type: type of the packet (see ptp_classify_raw())
0136  *
0137  * This function evaluates whether the given skb is a PTP Sync message.
0138  *
0139  * Return: true if sync message, false otherwise
0140  */
0141 bool ptp_msg_is_sync(struct sk_buff *skb, unsigned int type);
0142 
0143 void __init ptp_classifier_init(void);
0144 #else
0145 static inline void ptp_classifier_init(void)
0146 {
0147 }
0148 static inline unsigned int ptp_classify_raw(struct sk_buff *skb)
0149 {
0150     return PTP_CLASS_NONE;
0151 }
0152 static inline struct ptp_header *ptp_parse_header(struct sk_buff *skb,
0153                           unsigned int type)
0154 {
0155     return NULL;
0156 }
0157 static inline u8 ptp_get_msgtype(const struct ptp_header *hdr,
0158                  unsigned int type)
0159 {
0160     /* The return is meaningless. The stub function would not be
0161      * executed since no available header from ptp_parse_header.
0162      */
0163     return PTP_MSGTYPE_SYNC;
0164 }
0165 static inline bool ptp_msg_is_sync(struct sk_buff *skb, unsigned int type)
0166 {
0167     return false;
0168 }
0169 #endif
0170 #endif /* _PTP_CLASSIFY_H_ */