From 981d6c7a1fe0023856094c809205e8b8c4b5b1a0 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 8 Sep 2015 08:10:19 -0700 Subject: [PATCH] Implement "ip pim rp X.Y.Z.A" and "ip pim sm" commands Allow the user to specify the static Rendevous point as well as specifying that an interface is Sparse Mode. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 137 ++++++++++++++++++++++++++++++++++++++++------- pimd/pim_iface.h | 6 +++ pimd/pim_vty.c | 10 +++- pimd/pimd.c | 1 + pimd/pimd.h | 1 + 5 files changed, 134 insertions(+), 21 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index c3f0feb4e2..854cf917cb 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2477,6 +2477,39 @@ DEFUN (show_ip_ssmpingd, return CMD_SUCCESS; } +DEFUN (ip_pim_rp, + ip_pim_rp_cmd, + "ip pim rp A.B.C.D", + IP_STR + "pim multicast routing" + "Rendevous Point" + "ip address of RP") +{ + int result; + + result = inet_pton(AF_INET, argv[0], &qpim_rp); + if (result <= 0) { + vty_out(vty, "%% Bad RP address specified: %s", argv[0]); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN (no_ip_pim_rp, + no_ip_pim_rp_cmd, + "no ip pim rp {A.B.C.D}", + NO_STR + IP_STR + "pim multicast routing" + "Rendevous Point" + "ip address of RP") +{ + qpim_rp.s_addr = 0; + + return CMD_SUCCESS; +} + DEFUN (ip_multicast_routing, ip_multicast_routing_cmd, PIM_CMD_IP_MULTICAST_ROUTING, @@ -3185,51 +3218,73 @@ DEFUN (interface_no_ip_pim_drprio, return CMD_SUCCESS; } -DEFUN (interface_ip_pim_ssm, - interface_ip_pim_ssm_cmd, - "ip pim ssm", - IP_STR - PIM_STR - IFACE_PIM_STR) +static int +pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype) { - struct interface *ifp; - struct pim_interface *pim_ifp; - - ifp = vty->index; - pim_ifp = ifp->info; + struct pim_interface *pim_ifp = ifp->info; if (!pim_ifp) { pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */); if (!pim_ifp) { - vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE); - return CMD_WARNING; + return 0; } } else { PIM_IF_DO_PIM(pim_ifp->options); } + pim_ifp->itype = itype; pim_if_addr_add_all(ifp); pim_if_membership_refresh(ifp); + return 1; +} + + +DEFUN (interface_ip_pim_ssm, + interface_ip_pim_ssm_cmd, + "ip pim ssm", + IP_STR + PIM_STR + IFACE_PIM_STR) +{ + struct interface *ifp; + + ifp = vty->index; + + if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SSM)) { + vty_out(vty, "Could not enable PIM SSM on interface%s", VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; } -DEFUN (interface_no_ip_pim_ssm, - interface_no_ip_pim_ssm_cmd, - "no ip pim ssm", - NO_STR +DEFUN (interface_ip_pim_sm, + interface_ip_pim_sm_cmd, + "ip pim sm", IP_STR PIM_STR IFACE_PIM_STR) { struct interface *ifp; - struct pim_interface *pim_ifp; ifp = vty->index; - pim_ifp = ifp->info; + if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SM)) { + vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +static int +pim_cmd_interface_delete (struct interface *ifp) +{ + struct pim_interface *pim_ifp = ifp->info; + if (!pim_ifp) - return CMD_SUCCESS; + return 1; PIM_IF_DONT_PIM(pim_ifp->options); @@ -3251,6 +3306,44 @@ DEFUN (interface_no_ip_pim_ssm, pim_if_delete(ifp); } + return 1; +} + +DEFUN (interface_no_ip_pim_ssm, + interface_no_ip_pim_ssm_cmd, + "no ip pim ssm", + NO_STR + IP_STR + PIM_STR + IFACE_PIM_STR) +{ + struct interface *ifp; + + ifp = vty->index; + if (!pim_cmd_interface_delete(ifp)) { + vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + +DEFUN (interface_no_ip_pim_sm, + interface_no_ip_pim_sm_cmd, + "no ip pim sm", + NO_STR + IP_STR + PIM_STR + IFACE_PIM_STR) +{ + struct interface *ifp; + + ifp = vty->index; + if (!pim_cmd_interface_delete(ifp)) { + vty_out(vty, "Unable to delete interface information%s", VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; } @@ -4789,6 +4882,8 @@ void pim_cmd_init() install_element (CONFIG_NODE, &ip_multicast_routing_cmd); install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd); + install_element (CONFIG_NODE, &ip_pim_rp_cmd); + install_element (CONFIG_NODE, &no_ip_pim_rp_cmd); install_element (CONFIG_NODE, &ip_ssmpingd_cmd); install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd); #if 0 @@ -4811,6 +4906,8 @@ void pim_cmd_init() install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd); install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd); install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd); + install_element (INTERFACE_NODE, &interface_ip_pim_sm_cmd); + install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd); install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd); install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd); install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd); diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index 4b06b9ff2e..ad6a3264db 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -53,7 +53,13 @@ #define PIM_IF_DONT_IGMP_LISTEN_ALLROUTERS(options) ((options) &= ~PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS) #define PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPRESSION(options) ((options) &= ~PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPRESSION) +enum pim_interface_type { + PIM_INTERFACE_SSM, + PIM_INTERFACE_SM +}; + struct pim_interface { + enum pim_interface_type itype; uint32_t options; /* bit vector */ int mroute_vif_index; struct in_addr primary_address; /* remember addr to detect change */ diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 52e61521d8..1c0c02f777 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -93,11 +93,16 @@ int pim_debug_config_write(struct vty *vty) int pim_global_config_write(struct vty *vty) { int writes = 0; + char buffer[32]; if (PIM_MROUTE_IS_ENABLED) { vty_out(vty, "%s%s", PIM_CMD_IP_MULTICAST_ROUTING, VTY_NEWLINE); ++writes; } + if (qpim_rp.s_addr) { + vty_out(vty, "ip pim rp %s%s", inet_ntop(AF_INET, &qpim_rp, buffer, 32), VTY_NEWLINE); + ++writes; + } if (qpim_ssmpingd_list) { struct listnode *node; @@ -132,7 +137,10 @@ int pim_interface_config_write(struct vty *vty) /* IF ip pim ssm */ if (PIM_IF_TEST_PIM(pim_ifp->options)) { - vty_out(vty, " ip pim ssm%s", VTY_NEWLINE); + if (pim_ifp->itype == PIM_INTERFACE_SSM) + vty_out(vty, " ip pim ssm%s", VTY_NEWLINE); + else + vty_out(vty, " ip pim sm%s", VTY_NEWLINE); ++writes; } diff --git a/pimd/pimd.c b/pimd/pimd.c index fa186eb716..8de469e7fd 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -69,6 +69,7 @@ int64_t qpim_mroute_add_last = 0; int64_t qpim_mroute_del_events = 0; int64_t qpim_mroute_del_last = 0; struct list *qpim_static_route_list = 0; +struct in_addr qpim_rp; static void pim_free() { diff --git a/pimd/pimd.h b/pimd/pimd.h index 8b58a15526..b763b2760d 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -101,6 +101,7 @@ int64_t qpim_mroute_add_last; int64_t qpim_mroute_del_events; int64_t qpim_mroute_del_last; struct list *qpim_static_route_list; /* list of routes added statically */ +extern struct in_addr qpim_rp; #define PIM_JP_HOLDTIME (qpim_t_periodic * 7 / 2) -- 2.39.5