]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/rfapi/vnc_export_table.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / bgpd / rfapi / vnc_export_table.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 *
4 * Copyright 2009-2016, LabN Consulting, L.L.C.
5 *
6 */
7
8
9 #include "lib/zebra.h"
10 #include "lib/prefix.h"
11 #include "lib/agg_table.h"
12 #include "lib/memory.h"
13 #include "lib/vty.h"
14
15 #include "bgpd/bgpd.h"
16 #include "bgpd/bgp_route.h"
17
18 #include "bgpd/rfapi/vnc_export_table.h"
19 #include "bgpd/rfapi/rfapi_private.h"
20 #include "bgpd/rfapi/rfapi_import.h"
21 #include "bgpd/rfapi/vnc_debug.h"
22
23 struct agg_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type,
24 const struct prefix *p)
25 {
26 struct agg_table *t = NULL;
27 struct agg_node *rn = NULL;
28 afi_t afi;
29
30 if (!bgp || !bgp->rfapi)
31 return NULL;
32
33 afi = family2afi(p->family);
34 assert(afi == AFI_IP || afi == AFI_IP6);
35
36 switch (type) {
37 case EXPORT_TYPE_BGP:
38 if (!bgp->rfapi->rt_export_bgp[afi])
39 bgp->rfapi->rt_export_bgp[afi] = agg_table_init();
40 t = bgp->rfapi->rt_export_bgp[afi];
41 break;
42
43 case EXPORT_TYPE_ZEBRA:
44 if (!bgp->rfapi->rt_export_zebra[afi])
45 bgp->rfapi->rt_export_zebra[afi] = agg_table_init();
46 t = bgp->rfapi->rt_export_zebra[afi];
47 break;
48 }
49
50 if (t)
51 rn = agg_node_get(t, p);
52 return rn;
53 }
54
55 struct agg_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type,
56 const struct prefix *p)
57 {
58 struct agg_table *t = NULL;
59 struct agg_node *rn = NULL;
60 afi_t afi;
61
62 if (!bgp || !bgp->rfapi)
63 return NULL;
64
65 afi = family2afi(p->family);
66 assert(afi == AFI_IP || afi == AFI_IP6);
67
68 switch (type) {
69 case EXPORT_TYPE_BGP:
70 if (!bgp->rfapi->rt_export_bgp[afi])
71 bgp->rfapi->rt_export_bgp[afi] = agg_table_init();
72 t = bgp->rfapi->rt_export_bgp[afi];
73 break;
74
75 case EXPORT_TYPE_ZEBRA:
76 if (!bgp->rfapi->rt_export_zebra[afi])
77 bgp->rfapi->rt_export_zebra[afi] = agg_table_init();
78 t = bgp->rfapi->rt_export_zebra[afi];
79 break;
80 }
81
82 if (t)
83 rn = agg_node_lookup(t, p);
84 return rn;
85 }
86
87 struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype,
88 const struct prefix *p, struct peer *peer,
89 uint8_t type, uint8_t subtype)
90 {
91 struct agg_node *etn;
92 struct vnc_export_info *eti;
93
94 etn = vnc_etn_get(bgp, etype, p);
95 assert(etn);
96
97 for (eti = etn->info; eti; eti = eti->next) {
98 if (peer == eti->peer && type == eti->type
99 && subtype == eti->subtype) {
100
101 break;
102 }
103 }
104
105 if (eti) {
106 agg_unlock_node(etn);
107 } else {
108 eti = XCALLOC(MTYPE_RFAPI_ETI, sizeof(struct vnc_export_info));
109 eti->node = etn;
110 eti->peer = peer;
111 peer_lock(peer);
112 eti->type = type;
113 eti->subtype = subtype;
114 eti->next = etn->info;
115 etn->info = eti;
116 }
117
118 return eti;
119 }
120
121 void vnc_eti_delete(struct vnc_export_info *goner)
122 {
123 struct agg_node *etn;
124 struct vnc_export_info *eti;
125 struct vnc_export_info *eti_prev = NULL;
126
127 etn = goner->node;
128
129 for (eti = etn->info; eti; eti_prev = eti, eti = eti->next) {
130 if (eti == goner)
131 break;
132 }
133
134 if (!eti) {
135 vnc_zlog_debug_verbose("%s: COULDN'T FIND ETI", __func__);
136 return;
137 }
138
139 if (eti_prev) {
140 eti_prev->next = goner->next;
141 } else {
142 etn->info = goner->next;
143 }
144
145 peer_unlock(eti->peer);
146 goner->node = NULL;
147 XFREE(MTYPE_RFAPI_ETI, goner);
148
149 agg_unlock_node(etn);
150 }
151
152 struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp,
153 vnc_export_type_t etype,
154 const struct prefix *p,
155 struct peer *peer, uint8_t type,
156 uint8_t subtype)
157 {
158 struct agg_node *etn;
159 struct vnc_export_info *eti;
160
161 etn = vnc_etn_lookup(bgp, etype, p);
162 if (!etn)
163 return NULL;
164
165 for (eti = etn->info; eti; eti = eti->next) {
166 if (peer == eti->peer && type == eti->type
167 && subtype == eti->subtype) {
168
169 break;
170 }
171 }
172
173 agg_unlock_node(etn);
174
175 if (eti && eti->timer)
176 return eti;
177
178 return NULL;
179 }