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