1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* PIM support for VxLAN BUM flooding
4 * Copyright (C) 2019 Cumulus Networks, Inc.
10 #include "pim_instance.h"
12 /* global timer used for miscellaneous staggered processing */
13 #define PIM_VXLAN_WORK_TIME 1
14 /* number of SG entries processed at one shot */
15 #define PIM_VXLAN_WORK_MAX 500
16 /* frequency of periodic NULL registers */
17 #define PIM_VXLAN_NULL_REG_INTERVAL 60 /* seconds */
19 #define vxlan_mlag (vxlan_info.mlag)
21 enum pim_vxlan_sg_flags
{
22 PIM_VXLAN_SGF_NONE
= 0,
23 PIM_VXLAN_SGF_DEL_IN_PROG
= (1 << 0),
24 PIM_VXLAN_SGF_OIF_INSTALLED
= (1 << 1)
28 struct pim_instance
*pim
;
32 char sg_str
[PIM_SG_LEN
];
34 enum pim_vxlan_sg_flags flags
;
35 struct pim_upstream
*up
;
36 struct listnode
*work_node
; /* to pim_vxlan.work_list */
38 /* termination info (only applicable to termination XG mroutes)
39 * term_if - termination device ipmr-lo is added to the OIL
40 * as local/IGMP membership to allow termination of vxlan traffic
42 struct interface
*term_oif
;
45 * iif - lo/vrf or peerlink (on MLAG setups)
46 * peerlink_oif - added to the OIL to send encapsulated BUM traffic to
47 * the MLAG peer switch
49 struct interface
*iif
;
50 /* on a MLAG setup the peerlink is added as a static OIF */
51 struct interface
*orig_oif
;
54 enum pim_vxlan_mlag_flags
{
55 PIM_VXLAN_MLAGF_NONE
= 0,
56 PIM_VXLAN_MLAGF_ENABLED
= (1 << 0),
57 PIM_VXLAN_MLAGF_DO_REG
= (1 << 1)
60 struct pim_vxlan_mlag
{
61 enum pim_vxlan_mlag_flags flags
;
62 /* XXX - remove this variable from here */
65 /* routed interface setup on top of MLAG peerlink */
66 struct interface
*peerlink_rif
;
67 struct in_addr reg_addr
;
70 enum pim_vxlan_flags
{
72 PIM_VXLANF_WORK_INITED
= (1 << 0)
76 enum pim_vxlan_flags flags
;
78 struct thread
*work_timer
;
79 struct list
*work_list
;
80 struct listnode
*next_work
;
83 struct pim_vxlan_mlag mlag
;
87 * 1. one (S, G) entry where S=local-VTEP-IP and G==BUM-mcast-grp for
88 * each BUM MDT. This is the origination entry.
89 * 2. and one (*, G) entry each MDT. This is the termination place holder.
91 * Note: This doesn't mean that only (*, G) mroutes are used for tunnel
92 * termination. (S, G) mroutes with ipmr-lo in the OIL can also be
93 * used for tunnel termiation if SPT switchover happens; however such
94 * SG entries are created by traffic and will NOT be a part of the vxlan SG
97 static inline bool pim_vxlan_is_orig_mroute(struct pim_vxlan_sg
*vxlan_sg
)
99 return !pim_addr_is_any(vxlan_sg
->sg
.src
);
102 static inline bool pim_vxlan_is_local_sip(struct pim_upstream
*up
)
104 return !pim_addr_is_any(up
->sg
.src
) &&
105 up
->rpf
.source_nexthop
.interface
&&
106 if_is_loopback(up
->rpf
.source_nexthop
.interface
);
109 static inline bool pim_vxlan_is_term_dev_cfg(struct pim_instance
*pim
,
110 struct interface
*ifp
)
112 return pim
->vxlan
.term_if_cfg
== ifp
;
115 extern struct pim_vxlan
*pim_vxlan_p
;
116 extern struct pim_vxlan_sg
*pim_vxlan_sg_find(struct pim_instance
*pim
,
118 extern struct pim_vxlan_sg
*pim_vxlan_sg_add(struct pim_instance
*pim
,
120 extern void pim_vxlan_sg_del(struct pim_instance
*pim
, pim_sgaddr
*sg
);
121 extern void pim_vxlan_update_sg_reg_state(struct pim_instance
*pim
,
122 struct pim_upstream
*up
, bool reg_join
);
123 extern struct pim_interface
*pim_vxlan_get_term_ifp(struct pim_instance
*pim
);
124 extern void pim_vxlan_add_vif(struct interface
*ifp
);
125 extern void pim_vxlan_del_vif(struct interface
*ifp
);
126 extern void pim_vxlan_add_term_dev(struct pim_instance
*pim
,
127 struct interface
*ifp
);
128 extern void pim_vxlan_del_term_dev(struct pim_instance
*pim
);
129 extern bool pim_vxlan_get_register_src(struct pim_instance
*pim
,
130 struct pim_upstream
*up
, struct in_addr
*src_p
);
131 extern void pim_vxlan_mlag_update(bool enable
, bool peer_state
, uint32_t role
,
132 struct interface
*peerlink_rif
,
133 struct in_addr
*reg_addr
);
134 extern bool pim_vxlan_do_mlag_reg(void);
135 extern void pim_vxlan_inherit_mlag_flags(struct pim_instance
*pim
,
136 struct pim_upstream
*up
, bool inherit
);
138 /* Shutdown of PIM stop the thread */
139 extern void pim_vxlan_terminate(void);
140 #endif /* PIM_VXLAN_H */