3 * Copyright (C) 2018 Cumulus Networks, Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "srcdest_table.h"
27 #include "static_memory.h"
28 #include "static_vrf.h"
29 #include "static_routes.h"
30 #include "static_zebra.h"
31 #include "static_vty.h"
33 DEFINE_MTYPE_STATIC(STATIC
, STATIC_RTABLE_INFO
, "Static Route Table Info");
35 static void zebra_stable_node_cleanup(struct route_table
*table
,
36 struct route_node
*node
)
38 struct static_nexthop
*nh
;
39 struct static_path
*pn
;
40 struct static_route_info
*si
;
41 struct route_table
*src_table
;
42 struct route_node
*src_node
;
43 struct static_path
*src_pn
;
44 struct static_route_info
*src_si
;
49 frr_each_safe(static_path_list
, &si
->path_list
, pn
) {
50 frr_each_safe(static_nexthop_list
, &pn
->nexthop_list
,
52 static_nexthop_list_del(&pn
->nexthop_list
, nh
);
53 XFREE(MTYPE_STATIC_NEXTHOP
, nh
);
55 static_path_list_del(&si
->path_list
, pn
);
56 XFREE(MTYPE_STATIC_PATH
, pn
);
59 /* clean up for dst table */
60 src_table
= srcdest_srcnode_table(node
);
62 /* This means the route_node is part of the top
63 * hierarchy and refers to a destination prefix.
65 for (src_node
= route_top(src_table
); src_node
;
66 src_node
= route_next(src_node
)) {
67 src_si
= src_node
->info
;
69 frr_each_safe(static_path_list
,
70 &src_si
->path_list
, src_pn
) {
71 frr_each_safe(static_nexthop_list
,
72 &src_pn
->nexthop_list
,
74 static_nexthop_list_del(
75 &src_pn
->nexthop_list
,
77 XFREE(MTYPE_STATIC_NEXTHOP
, nh
);
79 static_path_list_del(&src_si
->path_list
,
81 XFREE(MTYPE_STATIC_PATH
, src_pn
);
84 XFREE(MTYPE_STATIC_ROUTE
, src_node
->info
);
88 XFREE(MTYPE_STATIC_ROUTE
, node
->info
);
92 static struct static_vrf
*static_vrf_alloc(void)
94 struct route_table
*table
;
95 struct static_vrf
*svrf
;
96 struct stable_info
*info
;
100 svrf
= XCALLOC(MTYPE_STATIC_RTABLE_INFO
, sizeof(struct static_vrf
));
102 for (afi
= AFI_IP
; afi
<= AFI_IP6
; afi
++) {
103 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MULTICAST
; safi
++) {
105 table
= srcdest_table_init();
107 table
= route_table_init();
109 info
= XCALLOC(MTYPE_STATIC_RTABLE_INFO
,
110 sizeof(struct stable_info
));
114 route_table_set_info(table
, info
);
116 table
->cleanup
= zebra_stable_node_cleanup
;
117 svrf
->stable
[afi
][safi
] = table
;
123 static int static_vrf_new(struct vrf
*vrf
)
125 struct static_vrf
*svrf
;
127 svrf
= static_vrf_alloc();
134 static int static_vrf_enable(struct vrf
*vrf
)
136 static_zebra_vrf_register(vrf
);
138 static_fixup_vrf_ids(vrf
->info
);
143 static int static_vrf_disable(struct vrf
*vrf
)
145 static_zebra_vrf_unregister(vrf
);
149 static int static_vrf_delete(struct vrf
*vrf
)
151 struct route_table
*table
;
152 struct static_vrf
*svrf
;
158 for (afi
= AFI_IP
; afi
<= AFI_IP6
; afi
++) {
159 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MULTICAST
; safi
++) {
160 table
= svrf
->stable
[afi
][safi
];
161 info
= route_table_get_info(table
);
162 route_table_finish(table
);
163 XFREE(MTYPE_STATIC_RTABLE_INFO
, info
);
164 svrf
->stable
[afi
][safi
] = NULL
;
167 XFREE(MTYPE_STATIC_RTABLE_INFO
, svrf
);
171 /* Lookup the static routing table in a VRF. */
172 struct route_table
*static_vrf_static_table(afi_t afi
, safi_t safi
,
173 struct static_vrf
*svrf
)
178 if (afi
>= AFI_MAX
|| safi
>= SAFI_MAX
)
181 return svrf
->stable
[afi
][safi
];
184 struct static_vrf
*static_vrf_lookup_by_id(vrf_id_t vrf_id
)
188 vrf
= vrf_lookup_by_id(vrf_id
);
190 return ((struct static_vrf
*)vrf
->info
);
195 struct static_vrf
*static_vrf_lookup_by_name(const char *name
)
200 name
= VRF_DEFAULT_NAME
;
202 vrf
= vrf_lookup_by_name(name
);
204 return ((struct static_vrf
*)vrf
->info
);
209 static int static_vrf_config_write(struct vty
*vty
)
213 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
214 if (vrf
->vrf_id
!= VRF_DEFAULT
)
215 vty_frame(vty
, "vrf %s\n", vrf
->name
);
217 static_config(vty
, vrf
->info
, AFI_IP
,
218 SAFI_UNICAST
, "ip route");
219 static_config(vty
, vrf
->info
, AFI_IP
,
220 SAFI_MULTICAST
, "ip mroute");
221 static_config(vty
, vrf
->info
, AFI_IP6
,
222 SAFI_UNICAST
, "ipv6 route");
224 if (vrf
->vrf_id
!= VRF_DEFAULT
)
225 vty_endframe(vty
, " exit-vrf\n!\n");
231 int static_vrf_has_config(struct static_vrf
*svrf
)
233 struct route_table
*table
;
238 * NOTE: This is a don't care for the default VRF, but we go through
239 * the motions to keep things consistent.
241 FOREACH_AFI_SAFI (afi
, safi
) {
242 table
= svrf
->stable
[afi
][safi
];
245 if (route_table_count(table
))
252 void static_vrf_init(void)
254 vrf_init(static_vrf_new
, static_vrf_enable
,
255 static_vrf_disable
, static_vrf_delete
, NULL
);
257 vrf_cmd_init(static_vrf_config_write
, &static_privs
);
260 void static_vrf_terminate(void)
265 struct static_vrf
*static_vty_get_unknown_vrf(const char *vrf_name
)
267 struct static_vrf
*svrf
;
270 svrf
= static_vrf_lookup_by_name(vrf_name
);
275 vrf
= vrf_get(VRF_UNKNOWN
, vrf_name
);
281 /* Mark as having FRR configuration */
282 vrf_set_user_cfged(vrf
);