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_EV_PORT 319
  35#define PTP_GEN_BIT 0x08 /* indicates general message, if set in message type */
  36
  37#define OFF_PTP_SOURCE_UUID     22 /* PTPv1 only */
  38#define OFF_PTP_SEQUENCE_ID     30
  39
  40/* Below defines should actually be removed at some point in time. */
  41#define IP6_HLEN        40
  42#define UDP_HLEN        8
  43#define OFF_IHL         14
  44#define IPV4_HLEN(data) (((struct iphdr *)(data + OFF_IHL))->ihl << 2)
  45
  46struct clock_identity {
  47        u8 id[8];
  48} __packed;
  49
  50struct port_identity {
  51        struct clock_identity   clock_identity;
  52        __be16                  port_number;
  53} __packed;
  54
  55struct ptp_header {
  56        u8                      tsmt;  /* transportSpecific | messageType */
  57        u8                      ver;   /* reserved          | versionPTP  */
  58        __be16                  message_length;
  59        u8                      domain_number;
  60        u8                      reserved1;
  61        u8                      flag_field[2];
  62        __be64                  correction;
  63        __be32                  reserved2;
  64        struct port_identity    source_port_identity;
  65        __be16                  sequence_id;
  66        u8                      control;
  67        u8                      log_message_interval;
  68} __packed;
  69
  70#if defined(CONFIG_NET_PTP_CLASSIFY)
  71/**
  72 * ptp_classify_raw - classify a PTP packet
  73 * @skb: buffer
  74 *
  75 * Runs a minimal BPF dissector to classify a network packet to
  76 * determine the PTP class. In case the skb does not contain any
  77 * PTP protocol data, PTP_CLASS_NONE will be returned, otherwise
  78 * PTP_CLASS_V1_IPV{4,6}, PTP_CLASS_V2_IPV{4,6} or
  79 * PTP_CLASS_V2_{L2,VLAN}, depending on the packet content.
  80 */
  81unsigned int ptp_classify_raw(const struct sk_buff *skb);
  82
  83/**
  84 * ptp_parse_header - Get pointer to the PTP v2 header
  85 * @skb: packet buffer
  86 * @type: type of the packet (see ptp_classify_raw())
  87 *
  88 * This function takes care of the VLAN, UDP, IPv4 and IPv6 headers. The length
  89 * is checked.
  90 *
  91 * Note, internally skb_mac_header() is used. Make sure that the @skb is
  92 * initialized accordingly.
  93 *
  94 * Return: Pointer to the ptp v2 header or NULL if not found
  95 */
  96struct ptp_header *ptp_parse_header(struct sk_buff *skb, unsigned int type);
  97
  98/**
  99 * ptp_get_msgtype - Extract ptp message type from given header
 100 * @hdr: ptp header
 101 * @type: type of the packet (see ptp_classify_raw())
 102 *
 103 * This function returns the message type for a given ptp header. It takes care
 104 * of the different ptp header versions (v1 or v2).
 105 *
 106 * Return: The message type
 107 */
 108static inline u8 ptp_get_msgtype(const struct ptp_header *hdr,
 109                                 unsigned int type)
 110{
 111        u8 msgtype;
 112
 113        if (unlikely(type & PTP_CLASS_V1)) {
 114                /* msg type is located at the control field for ptp v1 */
 115                msgtype = hdr->control;
 116        } else {
 117                msgtype = hdr->tsmt & 0x0f;
 118        }
 119
 120        return msgtype;
 121}
 122
 123void __init ptp_classifier_init(void);
 124#else
 125static inline void ptp_classifier_init(void)
 126{
 127}
 128static inline unsigned int ptp_classify_raw(struct sk_buff *skb)
 129{
 130        return PTP_CLASS_NONE;
 131}
 132static inline struct ptp_header *ptp_parse_header(struct sk_buff *skb,
 133                                                  unsigned int type)
 134{
 135        return NULL;
 136}
 137static inline u8 ptp_get_msgtype(const struct ptp_header *hdr,
 138                                 unsigned int type)
 139{
 140        /* The return is meaningless. The stub function would not be
 141         * executed since no available header from ptp_parse_header.
 142         */
 143        return 0;
 144}
 145#endif
 146#endif /* _PTP_CLASSIFY_H_ */
 147