Line data Source code
1 : /* PIM support for VxLAN BUM flooding
2 : *
3 : * Copyright (C) 2019 Cumulus Networks, Inc.
4 : *
5 : * This file is part of FRR.
6 : *
7 : * FRR is free software; you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the
9 : * Free Software Foundation; either version 2, or (at your option) any
10 : * later version.
11 : *
12 : * FRR is distributed in the hope that it will be useful, but
13 : * WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : * General Public License for more details.
16 : * This program is free software; you can redistribute it and/or modify
17 : * it under the terms of the GNU General Public License as published by
18 : * the Free Software Foundation; either version 2 of the License, or
19 : * (at your option) any later version.
20 : */
21 :
22 : #ifndef PIM_VXLAN_H
23 : #define PIM_VXLAN_H
24 :
25 : #include "pim_instance.h"
26 :
27 : /* global timer used for miscellaneous staggered processing */
28 : #define PIM_VXLAN_WORK_TIME 1
29 : /* number of SG entries processed at one shot */
30 : #define PIM_VXLAN_WORK_MAX 500
31 : /* frequency of periodic NULL registers */
32 : #define PIM_VXLAN_NULL_REG_INTERVAL 60 /* seconds */
33 :
34 : #define vxlan_mlag (vxlan_info.mlag)
35 :
36 : enum pim_vxlan_sg_flags {
37 : PIM_VXLAN_SGF_NONE = 0,
38 : PIM_VXLAN_SGF_DEL_IN_PROG = (1 << 0),
39 : PIM_VXLAN_SGF_OIF_INSTALLED = (1 << 1)
40 : };
41 :
42 : struct pim_vxlan_sg {
43 : struct pim_instance *pim;
44 :
45 : /* key */
46 : pim_sgaddr sg;
47 : char sg_str[PIM_SG_LEN];
48 :
49 : enum pim_vxlan_sg_flags flags;
50 : struct pim_upstream *up;
51 : struct listnode *work_node; /* to pim_vxlan.work_list */
52 :
53 : /* termination info (only applicable to termination XG mroutes)
54 : * term_if - termination device ipmr-lo is added to the OIL
55 : * as local/IGMP membership to allow termination of vxlan traffic
56 : */
57 : struct interface *term_oif;
58 :
59 : /* origination info
60 : * iif - lo/vrf or peerlink (on MLAG setups)
61 : * peerlink_oif - added to the OIL to send encapsulated BUM traffic to
62 : * the MLAG peer switch
63 : */
64 : struct interface *iif;
65 : /* on a MLAG setup the peerlink is added as a static OIF */
66 : struct interface *orig_oif;
67 : };
68 :
69 : enum pim_vxlan_mlag_flags {
70 : PIM_VXLAN_MLAGF_NONE = 0,
71 : PIM_VXLAN_MLAGF_ENABLED = (1 << 0),
72 : PIM_VXLAN_MLAGF_DO_REG = (1 << 1)
73 : };
74 :
75 : struct pim_vxlan_mlag {
76 : enum pim_vxlan_mlag_flags flags;
77 : /* XXX - remove this variable from here */
78 : int role;
79 : bool peer_state;
80 : /* routed interface setup on top of MLAG peerlink */
81 : struct interface *peerlink_rif;
82 : struct in_addr reg_addr;
83 : };
84 :
85 : enum pim_vxlan_flags {
86 : PIM_VXLANF_NONE = 0,
87 : PIM_VXLANF_WORK_INITED = (1 << 0)
88 : };
89 :
90 : struct pim_vxlan {
91 : enum pim_vxlan_flags flags;
92 :
93 : struct thread *work_timer;
94 : struct list *work_list;
95 : struct listnode *next_work;
96 : int max_work_cnt;
97 :
98 : struct pim_vxlan_mlag mlag;
99 : };
100 :
101 : /* zebra adds-
102 : * 1. one (S, G) entry where S=local-VTEP-IP and G==BUM-mcast-grp for
103 : * each BUM MDT. This is the origination entry.
104 : * 2. and one (*, G) entry each MDT. This is the termination place holder.
105 : *
106 : * Note: This doesn't mean that only (*, G) mroutes are used for tunnel
107 : * termination. (S, G) mroutes with ipmr-lo in the OIL can also be
108 : * used for tunnel termiation if SPT switchover happens; however such
109 : * SG entries are created by traffic and will NOT be a part of the vxlan SG
110 : * database.
111 : */
112 0 : static inline bool pim_vxlan_is_orig_mroute(struct pim_vxlan_sg *vxlan_sg)
113 : {
114 0 : return !pim_addr_is_any(vxlan_sg->sg.src);
115 : }
116 :
117 0 : static inline bool pim_vxlan_is_local_sip(struct pim_upstream *up)
118 : {
119 0 : return !pim_addr_is_any(up->sg.src) &&
120 0 : up->rpf.source_nexthop.interface &&
121 0 : if_is_loopback(up->rpf.source_nexthop.interface);
122 : }
123 :
124 3 : static inline bool pim_vxlan_is_term_dev_cfg(struct pim_instance *pim,
125 : struct interface *ifp)
126 : {
127 3 : return pim->vxlan.term_if_cfg == ifp;
128 : }
129 :
130 : extern struct pim_vxlan *pim_vxlan_p;
131 : extern struct pim_vxlan_sg *pim_vxlan_sg_find(struct pim_instance *pim,
132 : pim_sgaddr *sg);
133 : extern struct pim_vxlan_sg *pim_vxlan_sg_add(struct pim_instance *pim,
134 : pim_sgaddr *sg);
135 : extern void pim_vxlan_sg_del(struct pim_instance *pim, pim_sgaddr *sg);
136 : extern void pim_vxlan_update_sg_reg_state(struct pim_instance *pim,
137 : struct pim_upstream *up, bool reg_join);
138 : extern struct pim_interface *pim_vxlan_get_term_ifp(struct pim_instance *pim);
139 : extern void pim_vxlan_add_vif(struct interface *ifp);
140 : extern void pim_vxlan_del_vif(struct interface *ifp);
141 : extern void pim_vxlan_add_term_dev(struct pim_instance *pim,
142 : struct interface *ifp);
143 : extern void pim_vxlan_del_term_dev(struct pim_instance *pim);
144 : extern bool pim_vxlan_get_register_src(struct pim_instance *pim,
145 : struct pim_upstream *up, struct in_addr *src_p);
146 : extern void pim_vxlan_mlag_update(bool enable, bool peer_state, uint32_t role,
147 : struct interface *peerlink_rif,
148 : struct in_addr *reg_addr);
149 : extern bool pim_vxlan_do_mlag_reg(void);
150 : extern void pim_vxlan_inherit_mlag_flags(struct pim_instance *pim,
151 : struct pim_upstream *up, bool inherit);
152 :
153 : /* Shutdown of PIM stop the thread */
154 : extern void pim_vxlan_terminate(void);
155 : #endif /* PIM_VXLAN_H */
|