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