| /* SPDX-License-Identifier: GPL-2.0 */ | |
| #ifndef _PFCP_H_ | |
| #define _PFCP_H_ | |
| #include <uapi/linux/if_ether.h> | |
| #include <net/dst_metadata.h> | |
| #include <linux/netdevice.h> | |
| #include <uapi/linux/ipv6.h> | |
| #include <net/udp_tunnel.h> | |
| #include <uapi/linux/udp.h> | |
| #include <uapi/linux/ip.h> | |
| #include <linux/string.h> | |
| #include <linux/types.h> | |
| #include <linux/bits.h> | |
| #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_priority:4; | |
| #else | |
| #error "Please fix <asm/byteorder>" | |
| #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 |