linux/include/linux/ptp_classify.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * PTP 1588 support
   4 *
   5 * This file implements a BPF that recognizes PTP event messages.
   6 *
   7 * Copyright (C) 2010 OMICRON electronics GmbH
   8 */
   9
  10#ifndef _PTP_CLASSIFY_H_
  11#define _PTP_CLASSIFY_H_
  12
  13#include <linux/ip.h>
  14#include <linux/skbuff.h>
  15
  16#define PTP_CLASS_NONE  0x00 /* not a PTP event message */
  17#define PTP_CLASS_V1    0x01 /* protocol version 1 */
  18#define PTP_CLASS_V2    0x02 /* protocol version 2 */
  19#define PTP_CLASS_VMASK 0x0f /* max protocol version is 15 */
  20#define PTP_CLASS_IPV4  0x10 /* event in an IPV4 UDP packet */
  21#define PTP_CLASS_IPV6  0x20 /* event in an IPV6 UDP packet */
  22#define PTP_CLASS_L2    0x40 /* event in a L2 packet */
  23#define PTP_CLASS_PMASK 0x70 /* mask for the packet type field */
  24#define PTP_CLASS_VLAN  0x80 /* event in a VLAN tagged packet */
  25
  26#define PTP_CLASS_V1_IPV4 (PTP_CLASS_V1 | PTP_CLASS_IPV4)
  27#define PTP_CLASS_V1_IPV6 (PTP_CLASS_V1 | PTP_CLASS_IPV6) /* probably DNE */
  28#define PTP_CLASS_V2_IPV4 (PTP_CLASS_V2 | PTP_CLASS_IPV4)
  29#define PTP_CLASS_V2_IPV6 (PTP_CLASS_V2 | PTP_CLASS_IPV6)
  30#define PTP_CLASS_V2_L2   (PTP_CLASS_V2 | PTP_CLASS_L2)
  31#define PTP_CLASS_V2_VLAN (PTP_CLASS_V2 | PTP_CLASS_VLAN)
  32#define PTP_CLASS_L4      (PTP_CLASS_IPV4 | PTP_CLASS_IPV6)
  33
  34#define PTP_MSGTYPE_SYNC        0x0
  35#define PTP_MSGTYPE_DELAY_REQ   0x1
  36#define PTP_MSGTYPE_PDELAY_REQ  0x2
  37#define PTP_MSGTYPE_PDELAY_RESP 0x3
  38
  39#define PTP_EV_PORT 319
  40#define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type */
  41
  42#define OFF_PTP_SOURCE_UUID     22 /* PTPv1 only */
  43#define OFF_PTP_SEQUENCE_ID     30
  44
  45/* Below defines should actually be removed at some point in time. */
  46#define IP6_HLEN        40
  47#define UDP_HLEN        8
  48#define OFF_IHL         14
  49#define IPV4_HLEN(data) (((struct iphdr *)(data + OFF_IHL))->ihl << 2)
  50
  51struct clock_identity {
  52        u8 id[8];
  53} __packed;
  54
  55struct port_identity {
  56        struct clock_identity   clock_identity;
  57        __be16                  port_number;
  58} __packed;
  59
  60struct ptp_header {
  61        u8                      tsmt;  /* transportSpecific | messageType */
  62        u8                      ver;   /* reserved          | versionPTP  */
  63        __be16                  message_length;
  64        u8                      domain_number;
  65        u8                      reserved1;
  66        u8                      flag_field[2];
  67        __be64                  correction;
  68        __be32                  reserved2;
  69        struct port_identity    source_port_identity;
  70        __be16                  sequence_id;
  71        u8                      control;
  72        u8                      log_message_interval;
  73} __packed;
  74
  75#if defined(CONFIG_NET_PTP_CLASSIFY)
  76/**
  77 * ptp_classify_raw - classify a PTP packet
  78 * @skb: buffer
  79 *
  80 * Runs a minimal BPF dissector to classify a network packet to
  81 * determine the PTP class. In case the skb does not contain any
  82 * PTP protocol data, PTP_CLASS_NONE will be returned, otherwise
  83 * PTP_CLASS_V1_IPV{4,6}, PTP_CLASS_V2_IPV{4,6} or
  84 * PTP_CLASS_V2_{L2,VLAN}, depending on the packet content.
  85 */
  86unsigned int ptp_classify_raw(const struct sk_buff *skb);
  87
  88/**
  89 * ptp_parse_header - Get pointer to the PTP v2 header
  90 * @skb: packet buffer
  91 * @type: type of the packet (see ptp_classify_raw())
  92 *
  93 * This function takes care of the VLAN, UDP, IPv4 and IPv6 headers. The length
  94 * is checked.
  95 *
  96 * Note, internally skb_mac_header() is used. Make sure that the @skb is
  97 * initialized accordingly.
  98 *
  99 * Return: Pointer to the ptp v2 header or NULL if not found
 100 */
 101struct ptp_header *ptp_parse_header(struct sk_buff *skb, unsigned int type);
 102
 103/**
 104 * ptp_get_msgtype - Extract ptp message type from given header
 105 * @hdr: ptp header
 106 * @type: type of the packet (see ptp_classify_raw())
 107 *
 108 * This function returns the message type for a given ptp header. It takes care
 109 * of the different ptp header versions (v1 or v2).
 110 *
 111 * Return: The message type
 112 */
 113static inline u8 ptp_get_msgtype(const struct ptp_header *hdr,
 114                                 unsigned int type)
 115{
 116        u8 msgtype;
 117
 118        if (unlikely(type & PTP_CLASS_V1)) {
 119                /* msg type is located at the control field for ptp v1 */
 120                msgtype = hdr->control;
 121        } else {
 122                msgtype = hdr->tsmt & 0x0f;
 123        }
 124
 125        return msgtype;
 126}
 127
 128void __init ptp_classifier_init(void);
 129#else
 130static inline void ptp_classifier_init(void)
 131{
 132}
 133static inline unsigned int ptp_classify_raw(struct sk_buff *skb)
 134{
 135        return PTP_CLASS_NONE;
 136}
 137static inline struct ptp_header *ptp_parse_header(struct sk_buff *skb,
 138                                                  unsigned int type)
 139{
 140        return NULL;
 141}
 142static inline u8 ptp_get_msgtype(const struct ptp_header *hdr,
 143                                 unsigned int type)
 144{
 145        /* The return is meaningless. The stub function would not be
 146         * executed since no available header from ptp_parse_header.
 147         */
 148        return PTP_MSGTYPE_SYNC;
 149}
 150#endif
 151#endif /* _PTP_CLASSIFY_H_ */
 152