]> git.proxmox.com Git - mirror_frr.git/blame - zebra/irdp_interface.c
zebra: kill zebra_memory.h, use MTYPE_STATIC
[mirror_frr.git] / zebra / irdp_interface.c
CommitLineData
ca776988 1/*
2 *
43e52561
QY
3 * Copyright (C) 1997, 2000
4 * Portions:
5 * Swedish University of Agricultural Sciences
6 * Robert Olsson
7 * Kunihiro Ishiguro
8 *
9 * Thanks to Jens Laas at Swedish University of Agricultural Sciences
10 * for reviewing and tests.
ca776988 11 *
12 * This file is part of GNU Zebra.
13 *
14 * GNU Zebra is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2, or (at your option) any
17 * later version.
18 *
19 * GNU Zebra is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
896014f4
DL
24 * You should have received a copy of the GNU General Public License along
25 * with this program; see the file COPYING; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
ca776988 27 */
28
ca776988 29#include <zebra.h>
30
ca776988 31#include "if.h"
32#include "vty.h"
33#include "sockunion.h"
34#include "prefix.h"
35#include "command.h"
36#include "memory.h"
37#include "stream.h"
38#include "ioctl.h"
39#include "connected.h"
40#include "log.h"
41#include "zclient.h"
42#include "thread.h"
9df414fe 43#include "lib_errors.h"
ca776988 44#include "zebra/interface.h"
45#include "zebra/rtadv.h"
46#include "zebra/rib.h"
3801e764 47#include "zebra/zebra_router.h"
ca776988 48#include "zebra/redistribute.h"
49#include "zebra/irdp.h"
9df414fe 50#include "zebra/zebra_errors.h"
ca776988 51#include <netinet/ip_icmp.h>
52#include "if.h"
53#include "sockunion.h"
54#include "log.h"
5920b3eb 55#include "network.h"
ca776988 56
ca776988 57extern int irdp_sock;
ca776988 58
bf8d3d6a 59DEFINE_MTYPE_STATIC(ZEBRA, IRDP_IF, "IRDP interface data");
ead4ee99 60
996c9314
LB
61#define IRDP_CONFIGED \
62 do { \
63 if (!irdp) { \
64 vty_out(vty, \
65 "Please Configure IRDP before using this command\n"); \
66 return CMD_WARNING_CONFIG_FAILED; \
67 } \
68 } while (0)
e92044cd 69
ead4ee99
DL
70static struct irdp_interface *irdp_if_get(struct interface *ifp)
71{
72 struct zebra_if *zi = ifp->info;
e92044cd
DS
73
74 if (!zi)
75 return NULL;
76
ead4ee99
DL
77 if (!zi->irdp)
78 zi->irdp = XCALLOC(MTYPE_IRDP_IF, sizeof(*zi->irdp));
e92044cd
DS
79
80 if (!zi->irdp->started)
81 return NULL;
82
ead4ee99
DL
83 return zi->irdp;
84}
85
86static int irdp_if_delete(struct interface *ifp)
87{
88 struct zebra_if *zi = ifp->info;
89 if (!zi)
90 return 0;
91 XFREE(MTYPE_IRDP_IF, zi->irdp);
92 return 0;
93}
94
7533cad7 95static const char *inet_2a(uint32_t a, char *b, size_t b_len)
ab0f6155 96{
7533cad7
QY
97 snprintf(b, b_len, "%u.%u.%u.%u", (a)&0xFF, (a >> 8) & 0xFF,
98 (a >> 16) & 0xFF, (a >> 24) & 0xFF);
d62a17ae 99 return b;
ab0f6155 100}
ca776988 101
ca776988 102
d62a17ae 103static struct prefix *irdp_get_prefix(struct interface *ifp)
ca776988 104{
d62a17ae 105 struct listnode *node;
106 struct connected *ifc;
e52702f2 107
d62a17ae 108 if (ifp->connected)
109 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc))
110 return ifc->address;
0c0f9112 111
d62a17ae 112 return NULL;
ca776988 113}
114
115/* Join to the add/leave multicast group. */
d7c0a89a 116static int if_group(struct interface *ifp, int sock, uint32_t group,
d62a17ae 117 int add_leave)
ca776988 118{
d62a17ae 119 struct ip_mreq m;
120 struct prefix *p;
121 int ret;
122 char b1[INET_ADDRSTRLEN];
123
124 memset(&m, 0, sizeof(m));
125 m.imr_multiaddr.s_addr = htonl(group);
126 p = irdp_get_prefix(ifp);
127
128 if (!p) {
e914ccbe 129 flog_warn(EC_ZEBRA_NO_IFACE_ADDR,
9df414fe 130 "IRDP: can't get address for %s", ifp->name);
d62a17ae 131 return 1;
132 }
133
134 m.imr_interface = p->u.prefix4;
135
136 ret = setsockopt(sock, IPPROTO_IP, add_leave, (char *)&m,
137 sizeof(struct ip_mreq));
138 if (ret < 0)
450971aa 139 flog_err_sys(EC_LIB_SOCKET, "IRDP: %s can't setsockopt %s: %s",
9df414fe
QY
140 add_leave == IP_ADD_MEMBERSHIP ? "join group"
141 : "leave group",
7533cad7
QY
142 inet_2a(group, b1, sizeof(b1)),
143 safe_strerror(errno));
d62a17ae 144
145 return ret;
ca776988 146}
147
d62a17ae 148static int if_add_group(struct interface *ifp)
ca776988 149{
d62a17ae 150 struct zebra_if *zi = ifp->info;
ead4ee99 151 struct irdp_interface *irdp = zi->irdp;
d62a17ae 152 int ret;
153 char b1[INET_ADDRSTRLEN];
154
ead4ee99
DL
155 if (!irdp)
156 return -1;
157
d62a17ae 158 ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP, IP_ADD_MEMBERSHIP);
159 if (ret < 0) {
160 return ret;
161 }
162
163 if (irdp->flags & IF_DEBUG_MISC)
164 zlog_debug("IRDP: Adding group %s for %s",
7533cad7
QY
165 inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1, sizeof(b1)),
166 ifp->name);
d62a17ae 167 return 0;
ca776988 168}
2da40f49 169
d62a17ae 170static int if_drop_group(struct interface *ifp)
ca776988 171{
d62a17ae 172 struct zebra_if *zi = ifp->info;
ead4ee99 173 struct irdp_interface *irdp = zi->irdp;
d62a17ae 174 int ret;
175 char b1[INET_ADDRSTRLEN];
176
ead4ee99
DL
177 if (!irdp)
178 return -1;
179
d62a17ae 180 ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP,
181 IP_DROP_MEMBERSHIP);
182 if (ret < 0)
183 return ret;
184
185 if (irdp->flags & IF_DEBUG_MISC)
186 zlog_debug("IRDP: Leaving group %s for %s",
7533cad7
QY
187 inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1, sizeof(b1)),
188 ifp->name);
d62a17ae 189 return 0;
ca776988 190}
191
ead4ee99 192static void if_set_defaults(struct irdp_interface *irdp)
ca776988 193{
d62a17ae 194 irdp->MaxAdvertInterval = IRDP_MAXADVERTINTERVAL;
195 irdp->MinAdvertInterval = IRDP_MINADVERTINTERVAL;
196 irdp->Preference = IRDP_PREFERENCE;
197 irdp->Lifetime = IRDP_LIFETIME;
ca776988 198}
199
200
d62a17ae 201static struct Adv *Adv_new(void)
ca776988 202{
d62a17ae 203 return XCALLOC(MTYPE_TMP, sizeof(struct Adv));
ca776988 204}
205
d62a17ae 206static void Adv_free(struct Adv *adv)
ca776988 207{
d62a17ae 208 XFREE(MTYPE_TMP, adv);
ca776988 209}
210
d62a17ae 211static void irdp_if_start(struct interface *ifp, int multicast,
212 int set_defaults)
ca776988 213{
d62a17ae 214 struct zebra_if *zi = ifp->info;
ead4ee99 215 struct irdp_interface *irdp = zi->irdp;
d62a17ae 216 struct listnode *node;
217 struct connected *ifc;
d7c0a89a 218 uint32_t timer, seed;
ca776988 219
ead4ee99
DL
220 assert(irdp);
221
e92044cd 222 irdp->started = true;
d62a17ae 223 if (irdp->flags & IF_ACTIVE) {
9df414fe 224 zlog_debug("IRDP: Interface is already active %s", ifp->name);
d62a17ae 225 return;
226 }
227 if ((irdp_sock < 0) && ((irdp_sock = irdp_sock_init()) < 0)) {
e914ccbe 228 flog_warn(EC_ZEBRA_IRDP_CANNOT_ACTIVATE_IFACE,
3efd0893 229 "IRDP: Cannot activate interface %s (cannot create IRDP socket)",
9df414fe 230 ifp->name);
d62a17ae 231 return;
232 }
233 irdp->flags |= IF_ACTIVE;
ca776988 234
d62a17ae 235 if (!multicast)
236 irdp->flags |= IF_BROADCAST;
ca776988 237
d62a17ae 238 if_add_update(ifp);
ca776988 239
d62a17ae 240 if (!(ifp->flags & IFF_UP)) {
e914ccbe 241 flog_warn(EC_ZEBRA_IRDP_IFACE_DOWN,
9df414fe 242 "IRDP: Interface is down %s", ifp->name);
d62a17ae 243 }
ca776988 244
d62a17ae 245 /* Shall we cancel if_start if if_add_group fails? */
ca776988 246
d62a17ae 247 if (multicast) {
248 if_add_group(ifp);
e52702f2 249
d62a17ae 250 if (!(ifp->flags & (IFF_MULTICAST | IFF_ALLMULTI))) {
e914ccbe 251 flog_warn(EC_ZEBRA_IRDP_IFACE_MCAST_DISABLED,
9df414fe 252 "IRDP: Interface not multicast enabled %s",
d62a17ae 253 ifp->name);
254 }
255 }
ca776988 256
d62a17ae 257 if (set_defaults)
ead4ee99 258 if_set_defaults(irdp);
ca776988 259
d62a17ae 260 irdp->irdp_sent = 0;
ca776988 261
d62a17ae 262 /* The spec suggests this for randomness */
ca776988 263
d62a17ae 264 seed = 0;
265 if (ifp->connected)
266 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
267 seed = ifc->address->u.prefix4.s_addr;
268 break;
269 }
e52702f2 270
d62a17ae 271 srandom(seed);
5920b3eb 272 timer = (frr_weak_random() % IRDP_DEFAULT_INTERVAL) + 1;
ca776988 273
d62a17ae 274 irdp->AdvPrefList = list_new();
275 irdp->AdvPrefList->del = (void (*)(void *))Adv_free; /* Destructor */
ca776988 276
277
d62a17ae 278 /* And this for startup. Speed limit from 1991 :-). But it's OK*/
ca776988 279
d62a17ae 280 if (irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS
281 && timer > MAX_INITIAL_ADVERT_INTERVAL)
282 timer = MAX_INITIAL_ADVERT_INTERVAL;
ca776988 283
e52702f2 284
d62a17ae 285 if (irdp->flags & IF_DEBUG_MISC)
286 zlog_debug("IRDP: Init timer for %s set to %u", ifp->name,
287 timer);
ca776988 288
d62a17ae 289 irdp->t_advertise = NULL;
3801e764 290 thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer,
d62a17ae 291 &irdp->t_advertise);
ca776988 292}
293
d62a17ae 294static void irdp_if_stop(struct interface *ifp)
ca776988 295{
d62a17ae 296 struct zebra_if *zi = ifp->info;
ead4ee99 297 struct irdp_interface *irdp = zi->irdp;
e52702f2 298
d62a17ae 299 if (irdp == NULL) {
9df414fe 300 zlog_debug("Interface %s structure is NULL", ifp->name);
d62a17ae 301 return;
302 }
ca776988 303
d62a17ae 304 if (!(irdp->flags & IF_ACTIVE)) {
9df414fe 305 zlog_debug("Interface is not active %s", ifp->name);
d62a17ae 306 return;
307 }
ca776988 308
d62a17ae 309 if (!(irdp->flags & IF_BROADCAST))
310 if_drop_group(ifp);
ca776988 311
d62a17ae 312 irdp_advert_off(ifp);
ca776988 313
6a154c88 314 list_delete(&irdp->AdvPrefList);
ca776988 315
d62a17ae 316 irdp->flags = 0;
ca776988 317}
318
319
d62a17ae 320static void irdp_if_shutdown(struct interface *ifp)
ca776988 321{
d62a17ae 322 struct zebra_if *zi = ifp->info;
ead4ee99 323 struct irdp_interface *irdp = zi->irdp;
ca776988 324
ead4ee99
DL
325 if (!irdp)
326 return;
e92044cd 327
d62a17ae 328 if (irdp->flags & IF_SHUTDOWN) {
9df414fe 329 zlog_debug("IRDP: Interface is already shutdown %s", ifp->name);
d62a17ae 330 return;
331 }
ca776988 332
d62a17ae 333 irdp->flags |= IF_SHUTDOWN;
334 irdp->flags &= ~IF_ACTIVE;
ca776988 335
d62a17ae 336 if (!(irdp->flags & IF_BROADCAST))
337 if_drop_group(ifp);
e52702f2 338
d62a17ae 339 /* Tell the hosts we are out of service */
340 irdp_advert_off(ifp);
ca776988 341}
342
d62a17ae 343static void irdp_if_no_shutdown(struct interface *ifp)
ca776988 344{
ead4ee99 345 struct irdp_interface *irdp = irdp_if_get(ifp);
ca776988 346
e92044cd
DS
347 if (!irdp)
348 return;
349
d62a17ae 350 if (!(irdp->flags & IF_SHUTDOWN)) {
9df414fe 351 zlog_debug("IRDP: Interface is not shutdown %s", ifp->name);
d62a17ae 352 return;
353 }
ca776988 354
d62a17ae 355 irdp->flags &= ~IF_SHUTDOWN;
ca776988 356
2951a7a4 357 irdp_if_start(ifp, irdp->flags & IF_BROADCAST ? false : true, false);
ca776988 358}
359
360
361/* Write configuration to user */
362
2eb27eec 363int irdp_config_write(struct vty *vty, struct interface *ifp)
ca776988 364{
d62a17ae 365 struct zebra_if *zi = ifp->info;
ead4ee99 366 struct irdp_interface *irdp = zi->irdp;
d62a17ae 367 struct Adv *adv;
368 struct listnode *node;
369 char b1[INET_ADDRSTRLEN];
ca776988 370
ead4ee99
DL
371 if (!irdp)
372 return 0;
373
d62a17ae 374 if (irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) {
ca776988 375
d62a17ae 376 if (irdp->flags & IF_SHUTDOWN)
377 vty_out(vty, " ip irdp shutdown \n");
ca776988 378
d62a17ae 379 if (irdp->flags & IF_BROADCAST)
380 vty_out(vty, " ip irdp broadcast\n");
381 else
382 vty_out(vty, " ip irdp multicast\n");
ca776988 383
d62a17ae 384 vty_out(vty, " ip irdp preference %ld\n", irdp->Preference);
ca776988 385
d62a17ae 386 for (ALL_LIST_ELEMENTS_RO(irdp->AdvPrefList, node, adv))
387 vty_out(vty, " ip irdp address %s preference %d\n",
7533cad7
QY
388 inet_2a(adv->ip.s_addr, b1, sizeof(b1)),
389 adv->pref);
ca776988 390
d62a17ae 391 vty_out(vty, " ip irdp holdtime %d\n", irdp->Lifetime);
ca776988 392
d62a17ae 393 vty_out(vty, " ip irdp minadvertinterval %ld\n",
394 irdp->MinAdvertInterval);
ca776988 395
d62a17ae 396 vty_out(vty, " ip irdp maxadvertinterval %ld\n",
397 irdp->MaxAdvertInterval);
398 }
2eb27eec 399 return 0;
ca776988 400}
401
402
403DEFUN (ip_irdp_multicast,
404 ip_irdp_multicast_cmd,
405 "ip irdp multicast",
406 IP_STR
3a2d747c
QY
407 "ICMP Router discovery on this interface\n"
408 "Use multicast mode\n")
ca776988 409{
d62a17ae 410 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 411 irdp_if_get(ifp);
ca776988 412
2951a7a4 413 irdp_if_start(ifp, true, true);
d62a17ae 414 return CMD_SUCCESS;
ca776988 415}
416
417DEFUN (ip_irdp_broadcast,
418 ip_irdp_broadcast_cmd,
419 "ip irdp broadcast",
420 IP_STR
3a2d747c
QY
421 "ICMP Router discovery on this interface\n"
422 "Use broadcast mode\n")
ca776988 423{
d62a17ae 424 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 425 irdp_if_get(ifp);
ca776988 426
2951a7a4 427 irdp_if_start(ifp, false, true);
d62a17ae 428 return CMD_SUCCESS;
ca776988 429}
430
996933fd 431DEFUN (no_ip_irdp,
432 no_ip_irdp_cmd,
ca776988 433 "no ip irdp",
8d0f15fd 434 NO_STR
ca776988 435 IP_STR
436 "Disable ICMP Router discovery on this interface\n")
437{
d62a17ae 438 VTY_DECLVAR_CONTEXT(interface, ifp);
ca776988 439
d62a17ae 440 irdp_if_stop(ifp);
441 return CMD_SUCCESS;
ca776988 442}
443
444DEFUN (ip_irdp_shutdown,
445 ip_irdp_shutdown_cmd,
446 "ip irdp shutdown",
447 IP_STR
d7fa34c1 448 "ICMP Router discovery on this interface\n"
ca776988 449 "ICMP Router discovery shutdown on this interface\n")
450{
d62a17ae 451 VTY_DECLVAR_CONTEXT(interface, ifp);
ca776988 452
d62a17ae 453 irdp_if_shutdown(ifp);
454 return CMD_SUCCESS;
ca776988 455}
456
996933fd 457DEFUN (no_ip_irdp_shutdown,
458 no_ip_irdp_shutdown_cmd,
ca776988 459 "no ip irdp shutdown",
8d0f15fd 460 NO_STR
ca776988 461 IP_STR
d7fa34c1 462 "ICMP Router discovery on this interface\n"
ca776988 463 "ICMP Router discovery no shutdown on this interface\n")
464{
d62a17ae 465 VTY_DECLVAR_CONTEXT(interface, ifp);
ca776988 466
d62a17ae 467 irdp_if_no_shutdown(ifp);
468 return CMD_SUCCESS;
ca776988 469}
470
471DEFUN (ip_irdp_holdtime,
472 ip_irdp_holdtime_cmd,
6147e2c6 473 "ip irdp holdtime (0-9000)",
ca776988 474 IP_STR
475 "ICMP Router discovery on this interface\n"
476 "Set holdtime value\n"
477 "Holdtime value in seconds. Default is 1800 seconds\n")
478{
d62a17ae 479 int idx_number = 3;
480 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 481 struct irdp_interface *irdp = irdp_if_get(ifp);
ca776988 482
e92044cd
DS
483 IRDP_CONFIGED;
484
d62a17ae 485 irdp->Lifetime = atoi(argv[idx_number]->arg);
486 return CMD_SUCCESS;
ca776988 487}
488
489DEFUN (ip_irdp_minadvertinterval,
490 ip_irdp_minadvertinterval_cmd,
6147e2c6 491 "ip irdp minadvertinterval (3-1800)",
ca776988 492 IP_STR
493 "ICMP Router discovery on this interface\n"
494 "Set minimum time between advertisement\n"
495 "Minimum advertisement interval in seconds\n")
496{
d62a17ae 497 int idx_number = 3;
498 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 499 struct irdp_interface *irdp = irdp_if_get(ifp);
d62a17ae 500
e92044cd
DS
501 IRDP_CONFIGED;
502
d62a17ae 503 if ((unsigned)atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) {
504 irdp->MinAdvertInterval = atoi(argv[idx_number]->arg);
505 return CMD_SUCCESS;
506 } else {
507 vty_out(vty,
3efd0893 508 "%% MinAdvertInterval must be less than or equal to MaxAdvertInterval\n");
d62a17ae 509 return CMD_WARNING_CONFIG_FAILED;
510 }
ca776988 511}
512
513DEFUN (ip_irdp_maxadvertinterval,
514 ip_irdp_maxadvertinterval_cmd,
6147e2c6 515 "ip irdp maxadvertinterval (4-1800)",
ca776988 516 IP_STR
517 "ICMP Router discovery on this interface\n"
518 "Set maximum time between advertisement\n"
519 "Maximum advertisement interval in seconds\n")
520{
d62a17ae 521 int idx_number = 3;
522 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 523 struct irdp_interface *irdp = irdp_if_get(ifp);
d62a17ae 524
e92044cd
DS
525 IRDP_CONFIGED;
526
d62a17ae 527 if (irdp->MinAdvertInterval <= (unsigned)atoi(argv[idx_number]->arg)) {
528 irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg);
529 return CMD_SUCCESS;
530 } else {
531 vty_out(vty,
3efd0893 532 "%% MaxAdvertInterval must be greater than or equal to MinAdvertInterval\n");
d62a17ae 533 return CMD_WARNING_CONFIG_FAILED;
534 }
ca776988 535}
536
accb156b 537/* DEFUN needs to be fixed for negative ranages...
538 * "ip irdp preference <-2147483648-2147483647>",
539 * Be positive for now. :-)
540 */
541
ca776988 542DEFUN (ip_irdp_preference,
543 ip_irdp_preference_cmd,
6147e2c6 544 "ip irdp preference (0-2147483647)",
ca776988 545 IP_STR
546 "ICMP Router discovery on this interface\n"
547 "Set default preference level for this interface\n"
548 "Preference level\n")
549{
d62a17ae 550 int idx_number = 3;
551 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 552 struct irdp_interface *irdp = irdp_if_get(ifp);
ca776988 553
e92044cd
DS
554 IRDP_CONFIGED;
555
d62a17ae 556 irdp->Preference = atoi(argv[idx_number]->arg);
557 return CMD_SUCCESS;
ca776988 558}
559
560DEFUN (ip_irdp_address_preference,
561 ip_irdp_address_preference_cmd,
6147e2c6 562 "ip irdp address A.B.C.D preference (0-2147483647)",
ca776988 563 IP_STR
3a2d747c 564 "Alter ICMP Router discovery preference on this interface\n"
ca776988 565 "Set IRDP address for advertise\n"
3a2d747c
QY
566 "IPv4 address\n"
567 "Specify IRDP non-default preference to advertise\n"
ca776988 568 "Preference level\n")
569{
d62a17ae 570 int idx_ipv4 = 3;
571 int idx_number = 5;
572 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 573 struct irdp_interface *irdp = irdp_if_get(ifp);
d62a17ae 574 struct listnode *node;
575 struct in_addr ip;
576 int pref;
577 int ret;
d62a17ae 578 struct Adv *adv;
579
e92044cd
DS
580 IRDP_CONFIGED;
581
d62a17ae 582 ret = inet_aton(argv[idx_ipv4]->arg, &ip);
583 if (!ret)
584 return CMD_WARNING_CONFIG_FAILED;
585
586 pref = atoi(argv[idx_number]->arg);
587
588 for (ALL_LIST_ELEMENTS_RO(irdp->AdvPrefList, node, adv))
589 if (adv->ip.s_addr == ip.s_addr)
590 return CMD_SUCCESS;
591
592 adv = Adv_new();
593 adv->ip = ip;
594 adv->pref = pref;
595 listnode_add(irdp->AdvPrefList, adv);
596
597 return CMD_SUCCESS;
ca776988 598}
599
996933fd 600DEFUN (no_ip_irdp_address_preference,
601 no_ip_irdp_address_preference_cmd,
6147e2c6 602 "no ip irdp address A.B.C.D preference (0-2147483647)",
8d0f15fd 603 NO_STR
ca776988 604 IP_STR
3a2d747c 605 "Alter ICMP Router discovery preference on this interface\n"
ca776988 606 "Select IRDP address\n"
3a2d747c
QY
607 "IPv4 address\n"
608 "Reset ICMP Router discovery preference on this interface\n"
ca776988 609 "Old preference level\n")
610{
d62a17ae 611 int idx_ipv4 = 4;
612 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 613 struct irdp_interface *irdp = irdp_if_get(ifp);
d62a17ae 614 struct listnode *node, *nnode;
615 struct in_addr ip;
616 int ret;
d62a17ae 617 struct Adv *adv;
618
e92044cd
DS
619 IRDP_CONFIGED;
620
d62a17ae 621 ret = inet_aton(argv[idx_ipv4]->arg, &ip);
622 if (!ret)
623 return CMD_WARNING_CONFIG_FAILED;
624
625 for (ALL_LIST_ELEMENTS(irdp->AdvPrefList, node, nnode, adv)) {
626 if (adv->ip.s_addr == ip.s_addr) {
627 listnode_delete(irdp->AdvPrefList, adv);
628 break;
629 }
630 }
631
632 return CMD_SUCCESS;
ca776988 633}
634
635DEFUN (ip_irdp_debug_messages,
636 ip_irdp_debug_messages_cmd,
637 "ip irdp debug messages",
638 IP_STR
3a2d747c
QY
639 "ICMP Router discovery debug Averts. and Solicits (short)\n"
640 "IRDP debugging options\n"
641 "Enable debugging for IRDP messages\n")
ca776988 642{
d62a17ae 643 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 644 struct irdp_interface *irdp = irdp_if_get(ifp);
ca776988 645
e92044cd
DS
646 IRDP_CONFIGED;
647
d62a17ae 648 irdp->flags |= IF_DEBUG_MESSAGES;
ca776988 649
d62a17ae 650 return CMD_SUCCESS;
ca776988 651}
652
653DEFUN (ip_irdp_debug_misc,
654 ip_irdp_debug_misc_cmd,
655 "ip irdp debug misc",
656 IP_STR
3a2d747c
QY
657 "ICMP Router discovery debug Averts. and Solicits (short)\n"
658 "IRDP debugging options\n"
659 "Enable debugging for miscellaneous IRDP events\n")
ca776988 660{
d62a17ae 661 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 662 struct irdp_interface *irdp = irdp_if_get(ifp);
ca776988 663
e92044cd
DS
664 IRDP_CONFIGED;
665
d62a17ae 666 irdp->flags |= IF_DEBUG_MISC;
ca776988 667
d62a17ae 668 return CMD_SUCCESS;
ca776988 669}
670
671DEFUN (ip_irdp_debug_packet,
672 ip_irdp_debug_packet_cmd,
673 "ip irdp debug packet",
674 IP_STR
3a2d747c
QY
675 "ICMP Router discovery debug Averts. and Solicits (short)\n"
676 "IRDP debugging options\n"
677 "Enable debugging for IRDP packets\n")
ca776988 678{
d62a17ae 679 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 680 struct irdp_interface *irdp = irdp_if_get(ifp);
ca776988 681
e92044cd
DS
682 IRDP_CONFIGED;
683
d62a17ae 684 irdp->flags |= IF_DEBUG_PACKET;
ca776988 685
d62a17ae 686 return CMD_SUCCESS;
ca776988 687}
688
689
690DEFUN (ip_irdp_debug_disable,
691 ip_irdp_debug_disable_cmd,
692 "ip irdp debug disable",
693 IP_STR
3a2d747c
QY
694 "ICMP Router discovery debug Averts. and Solicits (short)\n"
695 "IRDP debugging options\n"
696 "Disable debugging for all IRDP events\n")
ca776988 697{
d62a17ae 698 VTY_DECLVAR_CONTEXT(interface, ifp);
ead4ee99 699 struct irdp_interface *irdp = irdp_if_get(ifp);
ca776988 700
e92044cd
DS
701 IRDP_CONFIGED;
702
d62a17ae 703 irdp->flags &= ~IF_DEBUG_PACKET;
704 irdp->flags &= ~IF_DEBUG_MESSAGES;
705 irdp->flags &= ~IF_DEBUG_MISC;
ca776988 706
d62a17ae 707 return CMD_SUCCESS;
ca776988 708}
709
4d762f26 710void irdp_if_init(void)
ca776988 711{
2eb27eec 712 hook_register(zebra_if_config_wr, irdp_config_write);
ead4ee99 713 hook_register(if_del, irdp_if_delete);
2eb27eec 714
d62a17ae 715 install_element(INTERFACE_NODE, &ip_irdp_broadcast_cmd);
716 install_element(INTERFACE_NODE, &ip_irdp_multicast_cmd);
717 install_element(INTERFACE_NODE, &no_ip_irdp_cmd);
718 install_element(INTERFACE_NODE, &ip_irdp_shutdown_cmd);
719 install_element(INTERFACE_NODE, &no_ip_irdp_shutdown_cmd);
720 install_element(INTERFACE_NODE, &ip_irdp_holdtime_cmd);
721 install_element(INTERFACE_NODE, &ip_irdp_maxadvertinterval_cmd);
722 install_element(INTERFACE_NODE, &ip_irdp_minadvertinterval_cmd);
723 install_element(INTERFACE_NODE, &ip_irdp_preference_cmd);
724 install_element(INTERFACE_NODE, &ip_irdp_address_preference_cmd);
725 install_element(INTERFACE_NODE, &no_ip_irdp_address_preference_cmd);
726
727 install_element(INTERFACE_NODE, &ip_irdp_debug_messages_cmd);
728 install_element(INTERFACE_NODE, &ip_irdp_debug_misc_cmd);
729 install_element(INTERFACE_NODE, &ip_irdp_debug_packet_cmd);
730 install_element(INTERFACE_NODE, &ip_irdp_debug_disable_cmd);
ca776988 731}