xref: /OK3568_Linux_fs/kernel/include/linux/pim.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef __LINUX_PIM_H
3*4882a593Smuzhiyun #define __LINUX_PIM_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/skbuff.h>
6*4882a593Smuzhiyun #include <asm/byteorder.h>
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /* Message types - V1 */
9*4882a593Smuzhiyun #define PIM_V1_VERSION		cpu_to_be32(0x10000000)
10*4882a593Smuzhiyun #define PIM_V1_REGISTER		1
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun /* Message types - V2 */
13*4882a593Smuzhiyun #define PIM_VERSION		2
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /* RFC7761, sec 4.9:
16*4882a593Smuzhiyun  *  Type
17*4882a593Smuzhiyun  *        Types for specific PIM messages.  PIM Types are:
18*4882a593Smuzhiyun  *
19*4882a593Smuzhiyun  *  Message Type                          Destination
20*4882a593Smuzhiyun  *  ---------------------------------------------------------------------
21*4882a593Smuzhiyun  *  0 = Hello                             Multicast to ALL-PIM-ROUTERS
22*4882a593Smuzhiyun  *  1 = Register                          Unicast to RP
23*4882a593Smuzhiyun  *  2 = Register-Stop                     Unicast to source of Register
24*4882a593Smuzhiyun  *                                        packet
25*4882a593Smuzhiyun  *  3 = Join/Prune                        Multicast to ALL-PIM-ROUTERS
26*4882a593Smuzhiyun  *  4 = Bootstrap                         Multicast to ALL-PIM-ROUTERS
27*4882a593Smuzhiyun  *  5 = Assert                            Multicast to ALL-PIM-ROUTERS
28*4882a593Smuzhiyun  *  6 = Graft (used in PIM-DM only)       Unicast to RPF'(S)
29*4882a593Smuzhiyun  *  7 = Graft-Ack (used in PIM-DM only)   Unicast to source of Graft
30*4882a593Smuzhiyun  *                                        packet
31*4882a593Smuzhiyun  *  8 = Candidate-RP-Advertisement        Unicast to Domain's BSR
32*4882a593Smuzhiyun  */
33*4882a593Smuzhiyun enum {
34*4882a593Smuzhiyun 	PIM_TYPE_HELLO,
35*4882a593Smuzhiyun 	PIM_TYPE_REGISTER,
36*4882a593Smuzhiyun 	PIM_TYPE_REGISTER_STOP,
37*4882a593Smuzhiyun 	PIM_TYPE_JOIN_PRUNE,
38*4882a593Smuzhiyun 	PIM_TYPE_BOOTSTRAP,
39*4882a593Smuzhiyun 	PIM_TYPE_ASSERT,
40*4882a593Smuzhiyun 	PIM_TYPE_GRAFT,
41*4882a593Smuzhiyun 	PIM_TYPE_GRAFT_ACK,
42*4882a593Smuzhiyun 	PIM_TYPE_CANDIDATE_RP_ADV
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #define PIM_NULL_REGISTER	cpu_to_be32(0x40000000)
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /* RFC7761, sec 4.9:
48*4882a593Smuzhiyun  * The PIM header common to all PIM messages is:
49*4882a593Smuzhiyun  *   0                   1                   2                   3
50*4882a593Smuzhiyun  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
51*4882a593Smuzhiyun  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52*4882a593Smuzhiyun  *  |PIM Ver| Type  |   Reserved    |           Checksum            |
53*4882a593Smuzhiyun  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54*4882a593Smuzhiyun  */
55*4882a593Smuzhiyun struct pimhdr {
56*4882a593Smuzhiyun 	__u8	type;
57*4882a593Smuzhiyun 	__u8	reserved;
58*4882a593Smuzhiyun 	__be16	csum;
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /* PIMv2 register message header layout (ietf-draft-idmr-pimvsm-v2-00.ps */
62*4882a593Smuzhiyun struct pimreghdr {
63*4882a593Smuzhiyun 	__u8	type;
64*4882a593Smuzhiyun 	__u8	reserved;
65*4882a593Smuzhiyun 	__be16	csum;
66*4882a593Smuzhiyun 	__be32	flags;
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun int pim_rcv_v1(struct sk_buff *skb);
70*4882a593Smuzhiyun 
ipmr_pimsm_enabled(void)71*4882a593Smuzhiyun static inline bool ipmr_pimsm_enabled(void)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	return IS_BUILTIN(CONFIG_IP_PIMSM_V1) || IS_BUILTIN(CONFIG_IP_PIMSM_V2);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
pim_hdr(const struct sk_buff * skb)76*4882a593Smuzhiyun static inline struct pimhdr *pim_hdr(const struct sk_buff *skb)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun 	return (struct pimhdr *)skb_transport_header(skb);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
pim_hdr_version(const struct pimhdr * pimhdr)81*4882a593Smuzhiyun static inline u8 pim_hdr_version(const struct pimhdr *pimhdr)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	return pimhdr->type >> 4;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
pim_hdr_type(const struct pimhdr * pimhdr)86*4882a593Smuzhiyun static inline u8 pim_hdr_type(const struct pimhdr *pimhdr)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	return pimhdr->type & 0xf;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /* check if the address is 224.0.0.13, RFC7761 sec 4.3.1 */
pim_ipv4_all_pim_routers(__be32 addr)92*4882a593Smuzhiyun static inline bool pim_ipv4_all_pim_routers(__be32 addr)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	return addr == htonl(0xE000000D);
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun #endif
97