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