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