]>
git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vrf.c
2 * Copyright (C) 2016 CumulusNetworks
5 * This file is part of Quagga
7 * Quagga 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
12 * Quagga 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.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29 #include "zebra/debug.h"
30 #include "zebra/zserv.h"
31 #include "zebra/rib.h"
32 #include "zebra/zebra_vrf.h"
33 #include "zebra/router-id.h"
34 #include "zebra/zebra_memory.h"
35 #include "zebra/zebra_static.h"
36 #include "zebra/zebra_mpls.h"
38 extern struct zebra_t zebrad
;
40 /* VRF information update. */
42 zebra_vrf_add_update (struct zebra_vrf
*zvrf
)
44 struct listnode
*node
, *nnode
;
47 if (IS_ZEBRA_DEBUG_EVENT
)
48 zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf
->name
);
50 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
51 zsend_vrf_add (client
, zvrf
);
55 zebra_vrf_delete_update (struct zebra_vrf
*zvrf
)
57 struct listnode
*node
, *nnode
;
60 if (IS_ZEBRA_DEBUG_EVENT
)
61 zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf
->name
);
63 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
64 zsend_vrf_delete (client
, zvrf
);
68 zebra_vrf_update_all (struct zserv
*client
)
72 RB_FOREACH (vrf
, vrf_id_head
, &vrfs_by_id
)
75 zsend_vrf_add (client
, vrf_info_lookup (vrf
->vrf_id
));
79 /* Callback upon creating a new VRF. */
81 zebra_vrf_new (vrf_id_t vrf_id
, const char *name
, void **info
)
83 struct zebra_vrf
*zvrf
= *info
;
85 if (IS_ZEBRA_DEBUG_EVENT
)
86 zlog_info ("ZVRF %s with id %u", name
, vrf_id
);
90 zvrf
= zebra_vrf_list_lookup_by_name (name
);
93 zvrf
= zebra_vrf_alloc (vrf_id
, name
);
94 zvrf
->zns
= zebra_ns_lookup (NS_DEFAULT
); /* Point to the global (single) NS */
96 router_id_init (zvrf
);
100 *info
= (void *)zvrf
;
101 router_id_init (zvrf
);
105 if (zvrf
->vrf_id
== VRF_UNKNOWN
)
106 zvrf
->vrf_id
= vrf_id
;
112 * Moving an interface amongst different vrf's
113 * causes the interface to get a new ifindex
114 * so we need to find static routes with
115 * the old ifindex and replace with new
116 * ifindex to insert back into the table
119 zebra_vrf_static_route_interface_fixup (struct interface
*ifp
)
123 struct zebra_vrf
*zvrf
= zebra_vrf_lookup (ifp
->vrf_id
);
124 struct route_table
*stable
= NULL
;
125 struct route_node
*rn
= NULL
;
126 struct static_route
*si
= NULL
;
131 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
133 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
135 stable
= zvrf
->stable
[afi
][safi
];
137 for (rn
= route_top (stable
); rn
; rn
= route_next (rn
))
142 if ((strcmp (si
->ifname
, ifp
->name
) == 0) &&
143 (si
->ifindex
!= ifp
->ifindex
))
145 si
->ifindex
= ifp
->ifindex
;
146 static_install_route (afi
, safi
, &rn
->p
, si
);
155 /* Callback upon enabling a VRF. */
157 zebra_vrf_enable (vrf_id_t vrf_id
, const char *name
, void **info
)
159 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*) (*info
);
160 struct route_table
*stable
= NULL
;
161 struct route_node
*rn
= NULL
;
162 struct static_route
*si
= NULL
;
163 struct interface
*ifp
= NULL
;
169 zebra_vrf_add_update (zvrf
);
171 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
173 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
175 stable
= zvrf
->stable
[afi
][safi
];
178 for (rn
= route_top (stable
); rn
; rn
= route_next (rn
))
186 ifp
= if_lookup_by_name_vrf (si
->ifname
, si
->vrf_id
);
188 si
->ifindex
= ifp
->ifindex
;
192 static_install_route (afi
, safi
, &rn
->p
, si
);
201 /* Callback upon disabling a VRF. */
203 zebra_vrf_disable (vrf_id_t vrf_id
, const char *name
, void **info
)
205 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)(*info
);
206 struct route_table
*stable
= NULL
;
207 struct route_node
*rn
= NULL
;
211 if (IS_ZEBRA_DEBUG_KERNEL
)
212 zlog_debug ("VRF %s id %u is now disabled.",
213 zvrf
->name
, zvrf
->vrf_id
);
215 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
217 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
219 stable
= zvrf
->stable
[afi
][safi
];
222 for (rn
= route_top (stable
); rn
; rn
= route_next (rn
))
225 static_uninstall_route(afi
, safi
, &rn
->p
, rn
->info
);
234 zebra_vrf_delete (vrf_id_t vrf_id
, const char *name
, void **info
)
236 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*) (*info
);
240 zebra_vrf_delete_update (zvrf
);
242 rib_close_table (zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
243 rib_close_table (zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
245 list_delete_all_node (zvrf
->rid_all_sorted_list
);
246 list_delete_all_node (zvrf
->rid_lo_sorted_list
);
248 zvrf
->vrf_id
= VRF_UNKNOWN
;
254 /* Lookup the routing table in a VRF based on both VRF-Id and table-id.
255 * NOTE: Table-id is relevant only in the Default VRF.
258 zebra_vrf_table_with_table_id (afi_t afi
, safi_t safi
,
259 vrf_id_t vrf_id
, u_int32_t table_id
)
261 struct route_table
*table
= NULL
;
263 if (afi
>= AFI_MAX
|| safi
>= SAFI_MAX
)
266 if (vrf_id
== VRF_DEFAULT
)
268 if (table_id
== RT_TABLE_MAIN
||
269 table_id
== zebrad
.rtm_table_default
)
270 table
= zebra_vrf_table (afi
, safi
, vrf_id
);
272 table
= zebra_vrf_other_route_table (afi
, table_id
, vrf_id
);
275 table
= zebra_vrf_table (afi
, safi
, vrf_id
);
281 * Create a routing table for the specific AFI/SAFI in the given VRF.
284 zebra_vrf_table_create (struct zebra_vrf
*zvrf
, afi_t afi
, safi_t safi
)
286 rib_table_info_t
*info
;
287 struct route_table
*table
;
289 assert (!zvrf
->table
[afi
][safi
]);
291 table
= route_table_init ();
292 zvrf
->table
[afi
][safi
] = table
;
294 info
= XCALLOC (MTYPE_RIB_TABLE_INFO
, sizeof (*info
));
301 /* Allocate new zebra VRF. */
303 zebra_vrf_alloc (vrf_id_t vrf_id
, const char *name
)
305 struct zebra_vrf
*zvrf
;
307 zvrf
= XCALLOC (MTYPE_ZEBRA_VRF
, sizeof (struct zebra_vrf
));
309 /* Allocate routing table and static table. */
310 zebra_vrf_table_create (zvrf
, AFI_IP
, SAFI_UNICAST
);
311 zebra_vrf_table_create (zvrf
, AFI_IP6
, SAFI_UNICAST
);
312 zvrf
->stable
[AFI_IP
][SAFI_UNICAST
] = route_table_init ();
313 zvrf
->stable
[AFI_IP6
][SAFI_UNICAST
] = route_table_init ();
314 zebra_vrf_table_create (zvrf
, AFI_IP
, SAFI_MULTICAST
);
315 zebra_vrf_table_create (zvrf
, AFI_IP6
, SAFI_MULTICAST
);
316 zvrf
->stable
[AFI_IP
][SAFI_MULTICAST
] = route_table_init ();
317 zvrf
->stable
[AFI_IP6
][SAFI_MULTICAST
] = route_table_init ();
319 zvrf
->rnh_table
[AFI_IP
] = route_table_init();
320 zvrf
->rnh_table
[AFI_IP6
] = route_table_init();
322 zvrf
->import_check_table
[AFI_IP
] = route_table_init();
323 zvrf
->import_check_table
[AFI_IP6
] = route_table_init();
326 zvrf
->vrf_id
= vrf_id
;
330 strncpy (zvrf
->name
, name
, strlen(name
));
331 zvrf
->name
[strlen(name
)] = '\0';
334 zebra_mpls_init_tables (zvrf
);
339 /* Lookup VRF by identifier. */
341 zebra_vrf_lookup (vrf_id_t vrf_id
)
343 return vrf_info_lookup (vrf_id
);
346 /* Lookup VRF by name. */
348 zebra_vrf_list_lookup_by_name (const char *name
)
353 name
= VRF_DEFAULT_NAME
;
355 vrf
= vrf_list_lookup_by_name (name
);
357 return ((struct zebra_vrf
*) vrf
->info
);
362 /* Lookup the routing table in an enabled VRF. */
364 zebra_vrf_table (afi_t afi
, safi_t safi
, vrf_id_t vrf_id
)
366 struct zebra_vrf
*zvrf
= vrf_info_lookup (vrf_id
);
371 if (afi
>= AFI_MAX
|| safi
>= SAFI_MAX
)
374 return zvrf
->table
[afi
][safi
];
377 /* Lookup the static routing table in a VRF. */
379 zebra_vrf_static_table (afi_t afi
, safi_t safi
, struct zebra_vrf
*zvrf
)
384 if (afi
>= AFI_MAX
|| safi
>= SAFI_MAX
)
387 return zvrf
->stable
[afi
][safi
];
391 zebra_vrf_other_route_table (afi_t afi
, u_int32_t table_id
, vrf_id_t vrf_id
)
393 struct zebra_vrf
*zvrf
;
394 rib_table_info_t
*info
;
395 struct route_table
*table
;
397 zvrf
= vrf_info_lookup (vrf_id
);
404 if (table_id
>= ZEBRA_KERNEL_TABLE_MAX
)
407 if ((vrf_id
== VRF_DEFAULT
) && (table_id
!= RT_TABLE_MAIN
) && (table_id
!= zebrad
.rtm_table_default
))
409 if (zvrf
->other_table
[afi
][table_id
] == NULL
)
411 table
= route_table_init();
412 info
= XCALLOC (MTYPE_RIB_TABLE_INFO
, sizeof (*info
));
415 info
->safi
= SAFI_UNICAST
;
417 zvrf
->other_table
[afi
][table_id
] = table
;
420 return (zvrf
->other_table
[afi
][table_id
]);
423 return zvrf
->table
[afi
][SAFI_UNICAST
];
426 /* Wrapper hook point for zebra daemon so that ifindex can be set
427 * DEFUN macro not used as extract.pl HAS to ignore this
428 * See also interface_cmd in lib/if.c
430 DEFUN_NOSH (zebra_vrf
,
433 "Select a VRF to configure\n"
436 // VTY_DECLVAR_CONTEXT (vrf, vrfp);
440 if ((ret
= vrf_cmd
.func (self
, vty
, argc
, argv
)) != CMD_SUCCESS
)
447 vrf_config_write (struct vty
*vty
)
449 struct listnode
*node
;
451 struct zebra_vrf
*zvrf
;
453 for (ALL_LIST_ELEMENTS_RO (vrf_list
, node
, vrf
))
456 if (! zvrf
|| strcmp (zvrf
->name
, VRF_DEFAULT_NAME
))
458 vty_out (vty
, "vrf %s%s", zvrf
->name
, VTY_NEWLINE
);
459 vty_out (vty
, "!%s", VTY_NEWLINE
);
465 struct cmd_node vrf_node
=
472 /* Zebra VRF initialization. */
474 zebra_vrf_init (void)
476 vrf_add_hook (VRF_NEW_HOOK
, zebra_vrf_new
);
477 vrf_add_hook (VRF_ENABLE_HOOK
, zebra_vrf_enable
);
478 vrf_add_hook (VRF_DISABLE_HOOK
, zebra_vrf_disable
);
479 vrf_add_hook (VRF_DELETE_HOOK
, zebra_vrf_delete
);
483 install_node (&vrf_node
, vrf_config_write
);
484 install_default (VRF_NODE
);
485 install_element (CONFIG_NODE
, &zebra_vrf_cmd
);
486 install_element (CONFIG_NODE
, &no_vrf_cmd
);