]>
Commit | Line | Data |
---|---|---|
fe18ee2d DS |
1 | /* zebra NS Routines |
2 | * Copyright (C) 2016 Cumulus Networks, Inc. | |
3 | * Donald Sharp | |
4 | * | |
5 | * This file is part of Quagga. | |
6 | * | |
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 | |
10 | * later version. | |
11 | * | |
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. | |
16 | * | |
896014f4 DL |
17 | * You should have received a copy of the GNU General Public License along |
18 | * with this program; see the file COPYING; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
fe18ee2d DS |
20 | */ |
21 | #include "zebra.h" | |
22 | ||
13460c44 | 23 | #include "lib/ns.h" |
fe18ee2d DS |
24 | #include "lib/vrf.h" |
25 | #include "lib/prefix.h" | |
26 | #include "lib/memory.h" | |
27 | ||
28 | #include "rtadv.h" | |
29 | #include "zebra_ns.h" | |
7c551956 | 30 | #include "zebra_vrf.h" |
4a1ab8e4 | 31 | #include "zebra_memory.h" |
05f7f5db | 32 | #include "rt.h" |
b7cfce93 | 33 | #include "zebra_vxlan.h" |
4a1ab8e4 | 34 | |
d62a17ae | 35 | DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space") |
fe18ee2d | 36 | |
5335613b DS |
37 | static __inline int |
38 | zebra_ns_table_entry_compare(const struct zebra_ns_table *e1, | |
39 | const struct zebra_ns_table *e2); | |
40 | ||
41 | RB_GENERATE(zebra_ns_table_head, zebra_ns_table, zebra_ns_table_entry, | |
42 | zebra_ns_table_entry_compare); | |
43 | ||
337960dd | 44 | static struct zebra_ns *dzns; |
fe18ee2d | 45 | |
5335613b DS |
46 | static __inline int |
47 | zebra_ns_table_entry_compare(const struct zebra_ns_table *e1, | |
48 | const struct zebra_ns_table *e2) | |
49 | { | |
50 | if (e1->tableid == e2->tableid) | |
51 | return (e1->afi - e2->afi); | |
52 | ||
53 | return e1->tableid - e2->tableid; | |
54 | } | |
55 | ||
d62a17ae | 56 | struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id) |
fe18ee2d | 57 | { |
d62a17ae | 58 | return dzns; |
fe18ee2d DS |
59 | } |
60 | ||
84915b0a | 61 | /* Do global enable actions - open sockets, read kernel config etc. */ |
d62a17ae | 62 | int zebra_ns_enable(ns_id_t ns_id, void **info) |
fe18ee2d | 63 | { |
d62a17ae | 64 | struct zebra_ns *zns = (struct zebra_ns *)(*info); |
fe18ee2d | 65 | |
d62a17ae | 66 | #if defined(HAVE_RTADV) |
67 | rtadv_init(zns); | |
fe18ee2d DS |
68 | #endif |
69 | ||
d62a17ae | 70 | kernel_init(zns); |
71 | interface_list(zns); | |
72 | route_read(zns); | |
fe18ee2d | 73 | |
d62a17ae | 74 | return 0; |
fe18ee2d DS |
75 | } |
76 | ||
ae825b8b DS |
77 | struct route_table *zebra_ns_find_table(struct zebra_ns *zns, |
78 | uint32_t tableid, afi_t afi) | |
79 | { | |
55cd0f61 DS |
80 | struct zebra_ns_table finder; |
81 | struct zebra_ns_table *znst; | |
ae825b8b DS |
82 | |
83 | memset(&finder, 0, sizeof(finder)); | |
84 | finder.afi = afi; | |
85 | finder.tableid = tableid; | |
55cd0f61 | 86 | znst = RB_FIND(zebra_ns_table_head, &zns->ns_tables, &finder); |
ae825b8b DS |
87 | |
88 | if (znst) | |
89 | return znst->table; | |
90 | else | |
91 | return NULL; | |
92 | } | |
93 | ||
5335613b DS |
94 | struct route_table *zebra_ns_get_table(struct zebra_ns *zns, |
95 | struct zebra_vrf *zvrf, uint32_t tableid, | |
96 | afi_t afi) | |
97 | { | |
98 | struct zebra_ns_table finder; | |
99 | struct zebra_ns_table *znst; | |
100 | rib_table_info_t *info; | |
101 | ||
102 | memset(&finder, 0, sizeof(finder)); | |
103 | finder.afi = afi; | |
104 | finder.tableid = tableid; | |
105 | znst = RB_FIND(zebra_ns_table_head, &zns->ns_tables, &finder); | |
106 | ||
107 | if (znst) | |
108 | return znst->table; | |
109 | ||
110 | znst = XCALLOC(MTYPE_ZEBRA_NS, sizeof(*znst)); | |
111 | znst->tableid = tableid; | |
112 | znst->afi = afi; | |
113 | znst->table = | |
114 | (afi == AFI_IP6) ? srcdest_table_init() : route_table_init(); | |
115 | ||
116 | info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info)); | |
117 | info->zvrf = zvrf; | |
118 | info->afi = afi; | |
119 | info->safi = SAFI_UNICAST; | |
120 | znst->table->info = info; | |
121 | znst->table->cleanup = zebra_rtable_node_cleanup; | |
122 | ||
123 | RB_INSERT(zebra_ns_table_head, &zns->ns_tables, znst); | |
124 | return znst->table; | |
125 | } | |
126 | ||
783fc3cd | 127 | static void zebra_ns_free_table(struct zebra_ns_table *znst) |
5335613b DS |
128 | { |
129 | void *table_info; | |
130 | rib_close_table(znst->table); | |
131 | ||
132 | table_info = znst->table->info; | |
133 | route_table_finish(znst->table); | |
134 | XFREE(MTYPE_RIB_TABLE_INFO, table_info); | |
135 | XFREE(MTYPE_ZEBRA_NS, znst); | |
5335613b DS |
136 | } |
137 | ||
d62a17ae | 138 | int zebra_ns_disable(ns_id_t ns_id, void **info) |
fe18ee2d | 139 | { |
5335613b | 140 | struct zebra_ns_table *znst; |
d62a17ae | 141 | struct zebra_ns *zns = (struct zebra_ns *)(*info); |
fe18ee2d | 142 | |
55cd0f61 DS |
143 | while (!RB_EMPTY(zebra_ns_table_head, &zns->ns_tables)) { |
144 | znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables); | |
145 | ||
5335613b | 146 | RB_REMOVE(zebra_ns_table_head, &zns->ns_tables, znst); |
783fc3cd | 147 | zebra_ns_free_table(znst); |
5335613b | 148 | } |
d62a17ae | 149 | route_table_finish(zns->if_table); |
b7cfce93 | 150 | zebra_vxlan_ns_disable(zns); |
d62a17ae | 151 | #if defined(HAVE_RTADV) |
152 | rtadv_terminate(zns); | |
fe18ee2d DS |
153 | #endif |
154 | ||
d62a17ae | 155 | kernel_terminate(zns); |
fe18ee2d | 156 | |
d62a17ae | 157 | return 0; |
fe18ee2d DS |
158 | } |
159 | ||
5335613b | 160 | |
d62a17ae | 161 | int zebra_ns_init(void) |
fe18ee2d | 162 | { |
d62a17ae | 163 | dzns = XCALLOC(MTYPE_ZEBRA_NS, sizeof(struct zebra_ns)); |
fe18ee2d | 164 | |
d62a17ae | 165 | ns_init(); |
13460c44 | 166 | |
84915b0a | 167 | /* Do any needed per-NS data structure allocation. */ |
168 | dzns->if_table = route_table_init(); | |
169 | zebra_vxlan_ns_init(dzns); | |
170 | ||
171 | /* Register zebra VRF callbacks, create and activate default VRF. */ | |
d62a17ae | 172 | zebra_vrf_init(); |
fe18ee2d | 173 | |
84915b0a | 174 | /* Default NS is activated */ |
f1abb72c | 175 | zebra_ns_enable(NS_DEFAULT, (void **)&dzns); |
fe18ee2d | 176 | |
d62a17ae | 177 | return 0; |
fe18ee2d | 178 | } |