]>
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
27 #include "zebra/debug.h"
28 #include "zebra/zserv.h"
29 #include "zebra/rib.h"
30 #include "zebra/zebra_vrf.h"
31 #include "zebra/router-id.h"
33 extern struct zebra_t zebrad
;
35 /* VRF information update. */
37 zebra_vrf_add_update (struct zebra_vrf
*zvrf
)
39 struct listnode
*node
, *nnode
;
42 if (IS_ZEBRA_DEBUG_EVENT
)
43 zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf
->name
);
45 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
46 zsend_vrf_add (client
, zvrf
);
50 zebra_vrf_delete_update (struct zebra_vrf
*zvrf
)
52 struct listnode
*node
, *nnode
;
55 if (IS_ZEBRA_DEBUG_EVENT
)
56 zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf
->name
);
58 for (ALL_LIST_ELEMENTS (zebrad
.client_list
, node
, nnode
, client
))
59 zsend_vrf_delete (client
, zvrf
);
63 zebra_vrf_update_all (struct zserv
*client
)
68 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
70 if ((vrf
= vrf_iter2vrf (iter
)) && vrf
->vrf_id
)
71 zsend_vrf_add (client
, vrf_info_lookup (vrf
->vrf_id
));
75 /* Callback upon creating a new VRF. */
77 zebra_vrf_new (vrf_id_t vrf_id
, const char *name
, void **info
)
79 struct zebra_vrf
*zvrf
= *info
;
81 zlog_info ("ZVRF %s with id %u", name
, vrf_id
);
85 zvrf
= zebra_vrf_alloc (vrf_id
, name
);
86 zvrf
->zns
= zebra_ns_lookup (NS_DEFAULT
); /* Point to the global (single) NS */
88 router_id_init (zvrf
);
91 if (zvrf
->vrf_id
== VRF_UNKNOWN
)
92 zvrf
->vrf_id
= vrf_id
;
97 /* Callback upon enabling a VRF. */
99 zebra_vrf_enable (vrf_id_t vrf_id
, const char *name
, void **info
)
101 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*) (*info
);
105 zebra_vrf_add_update (zvrf
);
110 /* Callback upon disabling a VRF. */
112 zebra_vrf_disable (vrf_id_t vrf_id
, const char *name
, void **info
)
114 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*)(*info
);
116 if (IS_ZEBRA_DEBUG_KERNEL
)
117 zlog_debug ("VRF %s id %u is now disabled.",
118 zvrf
->name
, zvrf
->vrf_id
);
124 zebra_vrf_delete (vrf_id_t vrf_id
, const char *name
, void **info
)
126 struct zebra_vrf
*zvrf
= (struct zebra_vrf
*) (*info
);
130 zebra_vrf_delete_update (zvrf
);
132 rib_close_table (zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
133 rib_close_table (zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
135 list_delete_all_node (zvrf
->rid_all_sorted_list
);
136 list_delete_all_node (zvrf
->rid_lo_sorted_list
);
138 XFREE (MTYPE_ZEBRA_VRF
, zvrf
);
143 /* Lookup the routing table in a VRF based on both VRF-Id and table-id.
144 * NOTE: Table-id is relevant only in the Default VRF.
147 zebra_vrf_table_with_table_id (afi_t afi
, safi_t safi
,
148 vrf_id_t vrf_id
, u_int32_t table_id
)
150 struct route_table
*table
= NULL
;
152 if (afi
>= AFI_MAX
|| safi
>= SAFI_MAX
)
155 if (vrf_id
== VRF_DEFAULT
)
157 if (table_id
== RT_TABLE_MAIN
||
158 table_id
== zebrad
.rtm_table_default
)
159 table
= zebra_vrf_table (afi
, safi
, vrf_id
);
161 table
= zebra_vrf_other_route_table (afi
, table_id
, vrf_id
);
164 table
= zebra_vrf_table (afi
, safi
, vrf_id
);
170 * Create a routing table for the specific AFI/SAFI in the given VRF.
173 zebra_vrf_table_create (struct zebra_vrf
*zvrf
, afi_t afi
, safi_t safi
)
175 rib_table_info_t
*info
;
176 struct route_table
*table
;
178 assert (!zvrf
->table
[afi
][safi
]);
180 table
= route_table_init ();
181 zvrf
->table
[afi
][safi
] = table
;
183 info
= XCALLOC (MTYPE_RIB_TABLE_INFO
, sizeof (*info
));
190 /* Allocate new zebra VRF. */
192 zebra_vrf_alloc (vrf_id_t vrf_id
, const char *name
)
194 struct zebra_vrf
*zvrf
;
196 zvrf
= XCALLOC (MTYPE_ZEBRA_VRF
, sizeof (struct zebra_vrf
));
198 /* Allocate routing table and static table. */
199 zebra_vrf_table_create (zvrf
, AFI_IP
, SAFI_UNICAST
);
200 zebra_vrf_table_create (zvrf
, AFI_IP6
, SAFI_UNICAST
);
201 zvrf
->stable
[AFI_IP
][SAFI_UNICAST
] = route_table_init ();
202 zvrf
->stable
[AFI_IP6
][SAFI_UNICAST
] = route_table_init ();
203 zebra_vrf_table_create (zvrf
, AFI_IP
, SAFI_MULTICAST
);
204 zebra_vrf_table_create (zvrf
, AFI_IP6
, SAFI_MULTICAST
);
205 zvrf
->stable
[AFI_IP
][SAFI_MULTICAST
] = route_table_init ();
206 zvrf
->stable
[AFI_IP6
][SAFI_MULTICAST
] = route_table_init ();
208 zvrf
->rnh_table
[AFI_IP
] = route_table_init();
209 zvrf
->rnh_table
[AFI_IP6
] = route_table_init();
211 zvrf
->import_check_table
[AFI_IP
] = route_table_init();
212 zvrf
->import_check_table
[AFI_IP6
] = route_table_init();
215 zvrf
->vrf_id
= vrf_id
;
219 strncpy (zvrf
->name
, name
, strlen(name
));
220 zvrf
->name
[strlen(name
)] = '\0';
226 /* Lookup VRF by identifier. */
228 zebra_vrf_lookup (vrf_id_t vrf_id
)
230 return vrf_info_lookup (vrf_id
);
233 /* Lookup the routing table in an enabled VRF. */
235 zebra_vrf_table (afi_t afi
, safi_t safi
, vrf_id_t vrf_id
)
237 struct zebra_vrf
*zvrf
= vrf_info_lookup (vrf_id
);
242 if (afi
>= AFI_MAX
|| safi
>= SAFI_MAX
)
245 return zvrf
->table
[afi
][safi
];
248 /* Lookup the static routing table in a VRF. */
250 zebra_vrf_static_table (afi_t afi
, safi_t safi
, struct zebra_vrf
*zvrf
)
255 if (afi
>= AFI_MAX
|| safi
>= SAFI_MAX
)
258 return zvrf
->stable
[afi
][safi
];
262 zebra_vrf_other_route_table (afi_t afi
, u_int32_t table_id
, vrf_id_t vrf_id
)
264 struct zebra_vrf
*zvrf
;
265 rib_table_info_t
*info
;
266 struct route_table
*table
;
268 zvrf
= vrf_info_lookup (vrf_id
);
275 if (table_id
>= ZEBRA_KERNEL_TABLE_MAX
)
278 if ((vrf_id
== VRF_DEFAULT
) && (table_id
!= RT_TABLE_MAIN
) && (table_id
!= zebrad
.rtm_table_default
))
280 if (zvrf
->other_table
[afi
][table_id
] == NULL
)
282 table
= route_table_init();
283 info
= XCALLOC (MTYPE_RIB_TABLE_INFO
, sizeof (*info
));
286 info
->safi
= SAFI_UNICAST
;
288 zvrf
->other_table
[afi
][table_id
] = table
;
291 return (zvrf
->other_table
[afi
][table_id
]);
294 return zvrf
->table
[afi
][SAFI_UNICAST
];
297 /* Zebra VRF initialization. */
299 zebra_vrf_init (void)
301 vrf_add_hook (VRF_NEW_HOOK
, zebra_vrf_new
);
302 vrf_add_hook (VRF_ENABLE_HOOK
, zebra_vrf_enable
);
303 vrf_add_hook (VRF_DISABLE_HOOK
, zebra_vrf_disable
);
304 vrf_add_hook (VRF_DELETE_HOOK
, zebra_vrf_delete
);