/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PFCP_H_ #define _PFCP_H_ #include #include #include #include #include #include #include #include #include #include #define PFCP_PORT 8805 /* PFCP protocol header */ struct pfcphdr { u8 flags; u8 message_type; __be16 message_length; }; /* PFCP header flags */ #define PFCP_SEID_FLAG BIT(0) #define PFCP_MP_FLAG BIT(1) #define PFCP_VERSION_MASK GENMASK(4, 0) #define PFCP_HLEN (sizeof(struct udphdr) + sizeof(struct pfcphdr)) /* PFCP node related messages */ struct pfcphdr_node { u8 seq_number[3]; u8 reserved; }; /* PFCP session related messages */ struct pfcphdr_session { __be64 seid; u8 seq_number[3]; #ifdef __LITTLE_ENDIAN_BITFIELD u8 message_priority:4, reserved:4; #elif defined(__BIG_ENDIAN_BITFIELD) u8 reserved:4, message_priprity:4; #else #error "Please fix " #endif }; struct pfcp_metadata { u8 type; __be64 seid; } __packed; enum { PFCP_TYPE_NODE = 0, PFCP_TYPE_SESSION = 1, }; #define PFCP_HEADROOM (sizeof(struct iphdr) + sizeof(struct udphdr) + \ sizeof(struct pfcphdr) + sizeof(struct ethhdr)) #define PFCP6_HEADROOM (sizeof(struct ipv6hdr) + sizeof(struct udphdr) + \ sizeof(struct pfcphdr) + sizeof(struct ethhdr)) static inline struct pfcphdr *pfcp_hdr(struct sk_buff *skb) { return (struct pfcphdr *)(udp_hdr(skb) + 1); } static inline struct pfcphdr_node *pfcp_hdr_node(struct sk_buff *skb) { return (struct pfcphdr_node *)(pfcp_hdr(skb) + 1); } static inline struct pfcphdr_session *pfcp_hdr_session(struct sk_buff *skb) { return (struct pfcphdr_session *)(pfcp_hdr(skb) + 1); } static inline bool netif_is_pfcp(const struct net_device *dev) { return dev->rtnl_link_ops && !strcmp(dev->rtnl_link_ops->kind, "pfcp"); } #endif