]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* RIPd and zebra interface. |
2 | * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org> | |
3 | * | |
4 | * This file is part of GNU Zebra. | |
5 | * | |
6 | * GNU Zebra 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 | |
8 | * Free Software Foundation; either version 2, or (at your option) any | |
9 | * later version. | |
10 | * | |
11 | * GNU Zebra is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
896014f4 DL |
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 | |
718e3744 | 19 | */ |
20 | ||
21 | #include <zebra.h> | |
22 | ||
23 | #include "command.h" | |
24 | #include "prefix.h" | |
bce8e868 | 25 | #include "table.h" |
718e3744 | 26 | #include "stream.h" |
bce8e868 | 27 | #include "memory.h" |
718e3744 | 28 | #include "routemap.h" |
29 | #include "zclient.h" | |
30 | #include "log.h" | |
7076bb2f | 31 | #include "vrf.h" |
718e3744 | 32 | #include "ripd/ripd.h" |
33 | #include "ripd/rip_debug.h" | |
dc63bfd4 | 34 | #include "ripd/rip_interface.h" |
718e3744 | 35 | |
36 | /* All information about zebra. */ | |
37 | struct zclient *zclient = NULL; | |
6b0655a2 | 38 | |
bce8e868 | 39 | /* Send ECMP routes to zebra. */ |
d62a17ae | 40 | static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) |
718e3744 | 41 | { |
d62a17ae | 42 | struct list *list = (struct list *)rp->info; |
c9fb3e23 RW |
43 | struct zapi_route api; |
44 | struct zapi_nexthop *api_nh; | |
d62a17ae | 45 | struct listnode *listnode = NULL; |
46 | struct rip_info *rinfo = NULL; | |
47 | int count = 0; | |
48 | ||
c9fb3e23 | 49 | memset(&api, 0, sizeof(api)); |
d00061ea RW |
50 | api.vrf_id = VRF_DEFAULT; |
51 | api.type = ZEBRA_ROUTE_RIP; | |
d00061ea RW |
52 | api.safi = SAFI_UNICAST; |
53 | ||
d00061ea RW |
54 | SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); |
55 | for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { | |
a74e593b RW |
56 | if (count >= MULTIPATH_NUM) |
57 | break; | |
c9fb3e23 RW |
58 | api_nh = &api.nexthops[count]; |
59 | api_nh->gate.ipv4 = rinfo->nexthop; | |
60 | api_nh->type = NEXTHOP_TYPE_IPV4; | |
61 | if (cmd == ZEBRA_ROUTE_ADD) | |
d00061ea RW |
62 | SET_FLAG(rinfo->flags, RIP_RTF_FIB); |
63 | else | |
64 | UNSET_FLAG(rinfo->flags, RIP_RTF_FIB); | |
c9fb3e23 | 65 | count++; |
d00061ea | 66 | } |
d62a17ae | 67 | |
c9fb3e23 | 68 | api.prefix = rp->p; |
d00061ea | 69 | api.nexthop_num = count; |
d62a17ae | 70 | |
d00061ea | 71 | rinfo = listgetdata(listhead(list)); |
d62a17ae | 72 | |
d00061ea RW |
73 | SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); |
74 | api.metric = rinfo->metric; | |
d62a17ae | 75 | |
d00061ea RW |
76 | if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) { |
77 | SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); | |
78 | api.distance = rinfo->distance; | |
79 | } | |
d62a17ae | 80 | |
d00061ea RW |
81 | if (rinfo->tag) { |
82 | SET_FLAG(api.message, ZAPI_MESSAGE_TAG); | |
83 | api.tag = rinfo->tag; | |
84 | } | |
d62a17ae | 85 | |
c9fb3e23 | 86 | zclient_route_send(cmd, zclient, &api); |
d00061ea RW |
87 | |
88 | if (IS_RIP_DEBUG_ZEBRA) { | |
89 | if (rip->ecmp) | |
90 | zlog_debug("%s: %s/%d nexthops %d", | |
c9fb3e23 | 91 | (cmd == ZEBRA_ROUTE_ADD) |
d00061ea RW |
92 | ? "Install into zebra" |
93 | : "Delete from zebra", | |
94 | inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen, | |
95 | count); | |
96 | else | |
97 | zlog_debug("%s: %s/%d", | |
c9fb3e23 | 98 | (cmd == ZEBRA_ROUTE_ADD) |
d00061ea RW |
99 | ? "Install into zebra" |
100 | : "Delete from zebra", | |
101 | inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen); | |
d62a17ae | 102 | } |
d00061ea RW |
103 | |
104 | rip_global_route_changes++; | |
718e3744 | 105 | } |
106 | ||
bce8e868 | 107 | /* Add/update ECMP routes to zebra. */ |
d62a17ae | 108 | void rip_zebra_ipv4_add(struct route_node *rp) |
718e3744 | 109 | { |
c9fb3e23 | 110 | rip_zebra_ipv4_send(rp, ZEBRA_ROUTE_ADD); |
bce8e868 | 111 | } |
718e3744 | 112 | |
bce8e868 | 113 | /* Delete ECMP routes from zebra. */ |
d62a17ae | 114 | void rip_zebra_ipv4_delete(struct route_node *rp) |
bce8e868 | 115 | { |
c9fb3e23 | 116 | rip_zebra_ipv4_send(rp, ZEBRA_ROUTE_DELETE); |
718e3744 | 117 | } |
118 | ||
119 | /* Zebra route add and delete treatment. */ | |
74489921 RW |
120 | static int rip_zebra_read_route(int command, struct zclient *zclient, |
121 | zebra_size_t length, vrf_id_t vrf_id) | |
718e3744 | 122 | { |
74489921 | 123 | struct zapi_route api; |
d62a17ae | 124 | struct in_addr nexthop; |
74489921 | 125 | unsigned long ifindex; |
d62a17ae | 126 | |
127 | if (!rip) | |
128 | return 0; | |
129 | ||
74489921 RW |
130 | if (zapi_route_decode(zclient->ibuf, &api) < 0) |
131 | return -1; | |
132 | ||
133 | nexthop = api.nexthops[0].gate.ipv4; | |
134 | ifindex = api.nexthops[0].ifindex; | |
d62a17ae | 135 | |
136 | /* Then fetch IPv4 prefixes. */ | |
74489921 RW |
137 | if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) |
138 | rip_redistribute_add(api.type, RIP_ROUTE_REDISTRIBUTE, | |
139 | (struct prefix_ipv4 *)&api.prefix, ifindex, | |
140 | &nexthop, api.metric, api.distance, | |
141 | api.tag); | |
142 | else if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) | |
143 | rip_redistribute_delete(api.type, RIP_ROUTE_REDISTRIBUTE, | |
144 | (struct prefix_ipv4 *)&api.prefix, | |
d62a17ae | 145 | ifindex); |
146 | ||
147 | return 0; | |
718e3744 | 148 | } |
149 | ||
d62a17ae | 150 | void rip_zclient_reset(void) |
718e3744 | 151 | { |
d62a17ae | 152 | zclient_reset(zclient); |
718e3744 | 153 | } |
154 | ||
155 | /* RIP route-map set for redistribution */ | |
d62a17ae | 156 | static void rip_routemap_set(int type, const char *name) |
718e3744 | 157 | { |
d62a17ae | 158 | if (rip->route_map[type].name) |
159 | free(rip->route_map[type].name); | |
718e3744 | 160 | |
d62a17ae | 161 | rip->route_map[type].name = strdup(name); |
162 | rip->route_map[type].map = route_map_lookup_by_name(name); | |
718e3744 | 163 | } |
164 | ||
d62a17ae | 165 | static void rip_redistribute_metric_set(int type, unsigned int metric) |
718e3744 | 166 | { |
d62a17ae | 167 | rip->route_map[type].metric_config = 1; |
168 | rip->route_map[type].metric = metric; | |
718e3744 | 169 | } |
170 | ||
d62a17ae | 171 | static int rip_metric_unset(int type, unsigned int metric) |
718e3744 | 172 | { |
173 | #define DONT_CARE_METRIC_RIP 17 | |
d62a17ae | 174 | if (metric != DONT_CARE_METRIC_RIP |
175 | && rip->route_map[type].metric != metric) | |
176 | return 1; | |
177 | rip->route_map[type].metric_config = 0; | |
178 | rip->route_map[type].metric = 0; | |
179 | return 0; | |
718e3744 | 180 | } |
181 | ||
182 | /* RIP route-map unset for redistribution */ | |
d62a17ae | 183 | static int rip_routemap_unset(int type, const char *name) |
718e3744 | 184 | { |
d62a17ae | 185 | if (!rip->route_map[type].name |
186 | || (name != NULL && strcmp(rip->route_map[type].name, name))) | |
187 | return 1; | |
718e3744 | 188 | |
d62a17ae | 189 | free(rip->route_map[type].name); |
190 | rip->route_map[type].name = NULL; | |
191 | rip->route_map[type].map = NULL; | |
718e3744 | 192 | |
d62a17ae | 193 | return 0; |
718e3744 | 194 | } |
6b0655a2 | 195 | |
718e3744 | 196 | /* Redistribution types */ |
197 | static struct { | |
d62a17ae | 198 | int type; |
199 | int str_min_len; | |
200 | const char *str; | |
201 | } redist_type[] = {{ZEBRA_ROUTE_KERNEL, 1, "kernel"}, | |
202 | {ZEBRA_ROUTE_CONNECT, 1, "connected"}, | |
203 | {ZEBRA_ROUTE_STATIC, 1, "static"}, | |
204 | {ZEBRA_ROUTE_OSPF, 1, "ospf"}, | |
205 | {ZEBRA_ROUTE_BGP, 2, "bgp"}, | |
206 | {ZEBRA_ROUTE_VNC, 1, "vnc"}, | |
207 | {0, 0, NULL}}; | |
208 | ||
209 | static int rip_redistribute_unset(int type) | |
718e3744 | 210 | { |
d62a17ae | 211 | if (!vrf_bitmap_check(zclient->redist[AFI_IP][type], VRF_DEFAULT)) |
212 | return CMD_SUCCESS; | |
718e3744 | 213 | |
d62a17ae | 214 | vrf_bitmap_unset(zclient->redist[AFI_IP][type], VRF_DEFAULT); |
718e3744 | 215 | |
d62a17ae | 216 | if (zclient->sock > 0) |
217 | zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, | |
218 | AFI_IP, type, 0, VRF_DEFAULT); | |
718e3744 | 219 | |
d62a17ae | 220 | /* Remove the routes from RIP table. */ |
221 | rip_redistribute_withdraw(type); | |
718e3744 | 222 | |
d62a17ae | 223 | return CMD_SUCCESS; |
718e3744 | 224 | } |
225 | ||
d62a17ae | 226 | int rip_redistribute_check(int type) |
718e3744 | 227 | { |
d62a17ae | 228 | return vrf_bitmap_check(zclient->redist[AFI_IP][type], VRF_DEFAULT); |
718e3744 | 229 | } |
230 | ||
d62a17ae | 231 | void rip_redistribute_clean(void) |
718e3744 | 232 | { |
d62a17ae | 233 | int i; |
234 | ||
235 | for (i = 0; redist_type[i].str; i++) { | |
236 | if (vrf_bitmap_check( | |
237 | zclient->redist[AFI_IP][redist_type[i].type], | |
238 | VRF_DEFAULT)) { | |
239 | if (zclient->sock > 0) | |
240 | zebra_redistribute_send( | |
241 | ZEBRA_REDISTRIBUTE_DELETE, zclient, | |
242 | AFI_IP, redist_type[i].type, 0, | |
243 | VRF_DEFAULT); | |
244 | ||
245 | vrf_bitmap_unset( | |
246 | zclient->redist[AFI_IP][redist_type[i].type], | |
247 | VRF_DEFAULT); | |
248 | ||
249 | /* Remove the routes from RIP table. */ | |
250 | rip_redistribute_withdraw(redist_type[i].type); | |
251 | } | |
718e3744 | 252 | } |
718e3744 | 253 | } |
254 | ||
718e3744 | 255 | DEFUN (rip_redistribute_type, |
256 | rip_redistribute_type_cmd, | |
40d1cbfb | 257 | "redistribute " FRR_REDIST_STR_RIPD, |
9a57dc69 | 258 | REDIST_STR |
ab0181ee | 259 | FRR_REDIST_HELP_STR_RIPD) |
718e3744 | 260 | { |
d62a17ae | 261 | int i; |
262 | ||
263 | for (i = 0; redist_type[i].str; i++) { | |
264 | if (strncmp(redist_type[i].str, argv[1]->arg, | |
265 | redist_type[i].str_min_len) | |
266 | == 0) { | |
267 | zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, | |
268 | AFI_IP, redist_type[i].type, 0, | |
269 | VRF_DEFAULT); | |
270 | return CMD_SUCCESS; | |
271 | } | |
718e3744 | 272 | } |
718e3744 | 273 | |
d62a17ae | 274 | vty_out(vty, "Invalid type %s\n", argv[1]->arg); |
718e3744 | 275 | |
d62a17ae | 276 | return CMD_WARNING_CONFIG_FAILED; |
718e3744 | 277 | } |
278 | ||
279 | DEFUN (no_rip_redistribute_type, | |
280 | no_rip_redistribute_type_cmd, | |
40d1cbfb | 281 | "no redistribute " FRR_REDIST_STR_RIPD, |
718e3744 | 282 | NO_STR |
9a57dc69 | 283 | REDIST_STR |
ab0181ee | 284 | FRR_REDIST_HELP_STR_RIPD) |
718e3744 | 285 | { |
d62a17ae | 286 | int i; |
287 | ||
288 | for (i = 0; redist_type[i].str; i++) { | |
289 | if (strncmp(redist_type[i].str, argv[2]->arg, | |
290 | redist_type[i].str_min_len) | |
291 | == 0) { | |
292 | rip_metric_unset(redist_type[i].type, | |
293 | DONT_CARE_METRIC_RIP); | |
294 | rip_routemap_unset(redist_type[i].type, NULL); | |
295 | rip_redistribute_unset(redist_type[i].type); | |
296 | return CMD_SUCCESS; | |
297 | } | |
298 | } | |
299 | ||
300 | vty_out(vty, "Invalid type %s\n", argv[2]->arg); | |
301 | ||
302 | return CMD_WARNING_CONFIG_FAILED; | |
718e3744 | 303 | } |
304 | ||
305 | DEFUN (rip_redistribute_type_routemap, | |
306 | rip_redistribute_type_routemap_cmd, | |
40d1cbfb | 307 | "redistribute " FRR_REDIST_STR_RIPD " route-map WORD", |
9a57dc69 | 308 | REDIST_STR |
ab0181ee | 309 | FRR_REDIST_HELP_STR_RIPD |
718e3744 | 310 | "Route map reference\n" |
311 | "Pointer to route-map entries\n") | |
312 | { | |
d62a17ae | 313 | int idx_protocol = 1; |
314 | int idx_word = 3; | |
315 | int i; | |
316 | ||
317 | for (i = 0; redist_type[i].str; i++) { | |
318 | if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { | |
319 | rip_routemap_set(redist_type[i].type, | |
320 | argv[idx_word]->arg); | |
321 | zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, | |
322 | AFI_IP, redist_type[i].type, 0, | |
323 | VRF_DEFAULT); | |
324 | return CMD_SUCCESS; | |
325 | } | |
326 | } | |
718e3744 | 327 | |
d62a17ae | 328 | vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); |
718e3744 | 329 | |
d62a17ae | 330 | return CMD_WARNING_CONFIG_FAILED; |
718e3744 | 331 | } |
332 | ||
333 | DEFUN (no_rip_redistribute_type_routemap, | |
334 | no_rip_redistribute_type_routemap_cmd, | |
40d1cbfb | 335 | "no redistribute " FRR_REDIST_STR_RIPD " route-map WORD", |
718e3744 | 336 | NO_STR |
9a57dc69 | 337 | REDIST_STR |
ab0181ee | 338 | FRR_REDIST_HELP_STR_RIPD |
718e3744 | 339 | "Route map reference\n" |
340 | "Pointer to route-map entries\n") | |
341 | { | |
d62a17ae | 342 | int idx_protocol = 2; |
343 | int idx_word = 4; | |
344 | int i; | |
345 | ||
346 | for (i = 0; redist_type[i].str; i++) { | |
347 | if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { | |
348 | if (rip_routemap_unset(redist_type[i].type, | |
349 | argv[idx_word]->arg)) | |
350 | return CMD_WARNING_CONFIG_FAILED; | |
351 | rip_redistribute_unset(redist_type[i].type); | |
352 | return CMD_SUCCESS; | |
353 | } | |
354 | } | |
355 | ||
356 | vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); | |
357 | ||
358 | return CMD_WARNING_CONFIG_FAILED; | |
718e3744 | 359 | } |
360 | ||
361 | DEFUN (rip_redistribute_type_metric, | |
362 | rip_redistribute_type_metric_cmd, | |
40d1cbfb | 363 | "redistribute " FRR_REDIST_STR_RIPD " metric (0-16)", |
9a57dc69 | 364 | REDIST_STR |
ab0181ee | 365 | FRR_REDIST_HELP_STR_RIPD |
718e3744 | 366 | "Metric\n" |
367 | "Metric value\n") | |
368 | { | |
d62a17ae | 369 | int idx_protocol = 1; |
370 | int idx_number = 3; | |
371 | int i; | |
372 | int metric; | |
373 | ||
374 | metric = atoi(argv[idx_number]->arg); | |
375 | ||
376 | for (i = 0; redist_type[i].str; i++) { | |
377 | if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { | |
378 | rip_redistribute_metric_set(redist_type[i].type, | |
379 | metric); | |
380 | zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, | |
381 | AFI_IP, redist_type[i].type, 0, | |
382 | VRF_DEFAULT); | |
383 | return CMD_SUCCESS; | |
384 | } | |
385 | } | |
718e3744 | 386 | |
d62a17ae | 387 | vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); |
718e3744 | 388 | |
d62a17ae | 389 | return CMD_WARNING_CONFIG_FAILED; |
718e3744 | 390 | } |
391 | ||
392 | DEFUN (no_rip_redistribute_type_metric, | |
393 | no_rip_redistribute_type_metric_cmd, | |
40d1cbfb | 394 | "no redistribute " FRR_REDIST_STR_RIPD " metric (0-16)", |
718e3744 | 395 | NO_STR |
9a57dc69 | 396 | REDIST_STR |
ab0181ee | 397 | FRR_REDIST_HELP_STR_RIPD |
718e3744 | 398 | "Metric\n" |
399 | "Metric value\n") | |
400 | { | |
d62a17ae | 401 | int idx_protocol = 2; |
402 | int idx_number = 4; | |
403 | int i; | |
404 | ||
405 | for (i = 0; redist_type[i].str; i++) { | |
406 | if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { | |
407 | if (rip_metric_unset(redist_type[i].type, | |
408 | atoi(argv[idx_number]->arg))) | |
409 | return CMD_WARNING_CONFIG_FAILED; | |
410 | rip_redistribute_unset(redist_type[i].type); | |
411 | return CMD_SUCCESS; | |
412 | } | |
413 | } | |
414 | ||
415 | vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); | |
416 | ||
417 | return CMD_WARNING_CONFIG_FAILED; | |
718e3744 | 418 | } |
419 | ||
16705130 | 420 | DEFUN (rip_redistribute_type_metric_routemap, |
421 | rip_redistribute_type_metric_routemap_cmd, | |
40d1cbfb | 422 | "redistribute " FRR_REDIST_STR_RIPD " metric (0-16) route-map WORD", |
9a57dc69 | 423 | REDIST_STR |
ab0181ee | 424 | FRR_REDIST_HELP_STR_RIPD |
16705130 | 425 | "Metric\n" |
426 | "Metric value\n" | |
427 | "Route map reference\n" | |
428 | "Pointer to route-map entries\n") | |
429 | { | |
d62a17ae | 430 | int idx_protocol = 1; |
431 | int idx_number = 3; | |
432 | int idx_word = 5; | |
433 | int i; | |
434 | int metric; | |
435 | ||
436 | metric = atoi(argv[idx_number]->arg); | |
437 | ||
438 | for (i = 0; redist_type[i].str; i++) { | |
439 | if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { | |
440 | rip_redistribute_metric_set(redist_type[i].type, | |
441 | metric); | |
442 | rip_routemap_set(redist_type[i].type, | |
443 | argv[idx_word]->arg); | |
444 | zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, | |
445 | AFI_IP, redist_type[i].type, 0, | |
446 | VRF_DEFAULT); | |
447 | return CMD_SUCCESS; | |
448 | } | |
449 | } | |
16705130 | 450 | |
d62a17ae | 451 | vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); |
16705130 | 452 | |
d62a17ae | 453 | return CMD_WARNING_CONFIG_FAILED; |
16705130 | 454 | } |
455 | ||
456 | ||
718e3744 | 457 | DEFUN (no_rip_redistribute_type_metric_routemap, |
458 | no_rip_redistribute_type_metric_routemap_cmd, | |
40d1cbfb | 459 | "no redistribute " FRR_REDIST_STR_RIPD " metric (0-16) route-map WORD", |
718e3744 | 460 | NO_STR |
9a57dc69 | 461 | REDIST_STR |
ab0181ee | 462 | FRR_REDIST_HELP_STR_RIPD |
718e3744 | 463 | "Metric\n" |
464 | "Metric value\n" | |
465 | "Route map reference\n" | |
466 | "Pointer to route-map entries\n") | |
467 | { | |
d62a17ae | 468 | int idx_protocol = 2; |
469 | int idx_number = 4; | |
470 | int idx_word = 6; | |
471 | int i; | |
472 | ||
473 | for (i = 0; redist_type[i].str; i++) { | |
474 | if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { | |
475 | if (rip_metric_unset(redist_type[i].type, | |
476 | atoi(argv[idx_number]->arg))) | |
477 | return CMD_WARNING_CONFIG_FAILED; | |
478 | if (rip_routemap_unset(redist_type[i].type, | |
479 | argv[idx_word]->arg)) { | |
480 | rip_redistribute_metric_set( | |
481 | redist_type[i].type, | |
482 | atoi(argv[idx_number]->arg)); | |
483 | return CMD_WARNING_CONFIG_FAILED; | |
484 | } | |
485 | rip_redistribute_unset(redist_type[i].type); | |
486 | return CMD_SUCCESS; | |
487 | } | |
488 | } | |
489 | ||
490 | vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); | |
491 | ||
492 | return CMD_WARNING_CONFIG_FAILED; | |
718e3744 | 493 | } |
6b0655a2 | 494 | |
718e3744 | 495 | /* Default information originate. */ |
496 | ||
497 | DEFUN (rip_default_information_originate, | |
498 | rip_default_information_originate_cmd, | |
499 | "default-information originate", | |
500 | "Control distribution of default route\n" | |
501 | "Distribute a default route\n") | |
502 | { | |
d62a17ae | 503 | struct prefix_ipv4 p; |
504 | ||
505 | if (!rip->default_information) { | |
506 | memset(&p, 0, sizeof(struct prefix_ipv4)); | |
507 | p.family = AF_INET; | |
718e3744 | 508 | |
d62a17ae | 509 | rip->default_information = 1; |
718e3744 | 510 | |
d62a17ae | 511 | rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0, |
512 | NULL, 0, 0, 0); | |
513 | } | |
718e3744 | 514 | |
d62a17ae | 515 | return CMD_SUCCESS; |
718e3744 | 516 | } |
517 | ||
518 | DEFUN (no_rip_default_information_originate, | |
519 | no_rip_default_information_originate_cmd, | |
520 | "no default-information originate", | |
521 | NO_STR | |
522 | "Control distribution of default route\n" | |
523 | "Distribute a default route\n") | |
524 | { | |
d62a17ae | 525 | struct prefix_ipv4 p; |
526 | ||
527 | if (rip->default_information) { | |
528 | memset(&p, 0, sizeof(struct prefix_ipv4)); | |
529 | p.family = AF_INET; | |
718e3744 | 530 | |
d62a17ae | 531 | rip->default_information = 0; |
718e3744 | 532 | |
d62a17ae | 533 | rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, |
534 | 0); | |
535 | } | |
718e3744 | 536 | |
d62a17ae | 537 | return CMD_SUCCESS; |
718e3744 | 538 | } |
6b0655a2 | 539 | |
d62a17ae | 540 | int config_write_rip_redistribute(struct vty *vty, int config_mode) |
718e3744 | 541 | { |
d62a17ae | 542 | int i; |
543 | ||
d00061ea RW |
544 | for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { |
545 | if (i == zclient->redist_default | |
546 | || !vrf_bitmap_check(zclient->redist[AFI_IP][i], | |
547 | VRF_DEFAULT)) | |
548 | continue; | |
549 | ||
550 | if (!config_mode) { | |
551 | vty_out(vty, " %s", zebra_route_string(i)); | |
552 | continue; | |
553 | } | |
554 | ||
555 | if (rip->route_map[i].metric_config) { | |
556 | if (rip->route_map[i].name) | |
557 | vty_out(vty, | |
558 | " redistribute %s metric %d route-map %s\n", | |
559 | zebra_route_string(i), | |
560 | rip->route_map[i].metric, | |
561 | rip->route_map[i].name); | |
562 | else | |
563 | vty_out(vty, " redistribute %s metric %d\n", | |
564 | zebra_route_string(i), | |
565 | rip->route_map[i].metric); | |
566 | } else { | |
567 | if (rip->route_map[i].name) | |
568 | vty_out(vty, " redistribute %s route-map %s\n", | |
569 | zebra_route_string(i), | |
570 | rip->route_map[i].name); | |
571 | else | |
572 | vty_out(vty, " redistribute %s\n", | |
573 | zebra_route_string(i)); | |
d62a17ae | 574 | } |
d00061ea RW |
575 | } |
576 | ||
d62a17ae | 577 | return 0; |
718e3744 | 578 | } |
579 | ||
d62a17ae | 580 | static void rip_zebra_connected(struct zclient *zclient) |
7076bb2f | 581 | { |
d62a17ae | 582 | zclient_send_reg_requests(zclient, VRF_DEFAULT); |
7076bb2f FL |
583 | } |
584 | ||
d62a17ae | 585 | void rip_zclient_init(struct thread_master *master) |
718e3744 | 586 | { |
d62a17ae | 587 | /* Set default value to the zebra client structure. */ |
588 | zclient = zclient_new(master); | |
342213ea | 589 | zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs); |
d62a17ae | 590 | zclient->zebra_connected = rip_zebra_connected; |
591 | zclient->interface_add = rip_interface_add; | |
592 | zclient->interface_delete = rip_interface_delete; | |
593 | zclient->interface_address_add = rip_interface_address_add; | |
594 | zclient->interface_address_delete = rip_interface_address_delete; | |
595 | zclient->interface_up = rip_interface_up; | |
596 | zclient->interface_down = rip_interface_down; | |
74489921 RW |
597 | zclient->redistribute_route_add = rip_zebra_read_route; |
598 | zclient->redistribute_route_del = rip_zebra_read_route; | |
d62a17ae | 599 | |
d62a17ae | 600 | /* Install command elements to rip node. */ |
601 | install_element(RIP_NODE, &rip_redistribute_type_cmd); | |
602 | install_element(RIP_NODE, &rip_redistribute_type_routemap_cmd); | |
603 | install_element(RIP_NODE, &rip_redistribute_type_metric_cmd); | |
604 | install_element(RIP_NODE, &rip_redistribute_type_metric_routemap_cmd); | |
605 | install_element(RIP_NODE, &no_rip_redistribute_type_cmd); | |
606 | install_element(RIP_NODE, &no_rip_redistribute_type_routemap_cmd); | |
607 | install_element(RIP_NODE, &no_rip_redistribute_type_metric_cmd); | |
608 | install_element(RIP_NODE, | |
609 | &no_rip_redistribute_type_metric_routemap_cmd); | |
610 | install_element(RIP_NODE, &rip_default_information_originate_cmd); | |
611 | install_element(RIP_NODE, &no_rip_default_information_originate_cmd); | |
718e3744 | 612 | } |
a2f9eb82 | 613 | |
d62a17ae | 614 | void rip_zclient_stop(void) |
a2f9eb82 | 615 | { |
d62a17ae | 616 | zclient_stop(zclient); |
617 | zclient_free(zclient); | |
a2f9eb82 | 618 | } |