diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index ed7e57a95e..9c32ab1c32 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2427,7 +2427,7 @@ DEFUN (show_ip_ssmpingd, DEFUN (ip_pim_rp, ip_pim_rp_cmd, - "ip pim rp A.B.C.D", + "ip pim rp A.B.C.D [A.B.C.D/M]", IP_STR "pim multicast routing\n" "Rendevous Point\n" @@ -2436,13 +2436,15 @@ DEFUN (ip_pim_rp, int idx_ipv4 = 3; int result; - result = inet_pton(AF_INET, argv[idx_ipv4]->arg, &qpim_rp.rpf_addr.s_addr); - if (result <= 0) { - vty_out(vty, "%% Bad RP address specified: %s", argv[idx_ipv4]->arg); - return CMD_WARNING; - } + result = pim_rp_new (argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg); - if (!pim_rp_setup ()) + if (result == -1) + { + vty_out(vty, "%% Bad RP address specified: %s", argv[idx_ipv4]->arg); + return CMD_ERR_NO_MATCH; + } + + if (result == -2) { vty_out(vty, "%% No Path to RP address specified: %s", argv[idx_ipv4]->arg); return CMD_WARNING; @@ -2453,14 +2455,15 @@ DEFUN (ip_pim_rp, DEFUN (no_ip_pim_rp, no_ip_pim_rp_cmd, - "no ip pim rp [A.B.C.D]", + "no ip pim rp A.B.C.D [A.B.C.D/M]", NO_STR IP_STR "pim multicast routing\n" "Rendevous Point\n" "ip address of RP\n") { - qpim_rp.rpf_addr.s_addr = INADDR_NONE; + int idx_ipv4 = 4; + pim_rp_del (argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg); return CMD_SUCCESS; } diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h index 4ae089f16b..ce300f0ab0 100644 --- a/pimd/pim_mroute.h +++ b/pimd/pim_mroute.h @@ -159,7 +159,7 @@ struct igmpmsg #endif #ifndef IGMPMSG_WRVIFWHOLE -#define IGMPMSG_WRVIFWHOLE 4 +#define IGMPMSG_WRVIFWHOLE 4 /* For PIM processing */ #endif /* diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c index 61fc480bf9..df7f7051d3 100644 --- a/pimd/pim_msg.c +++ b/pimd/pim_msg.c @@ -25,10 +25,12 @@ #include "log.h" #include "pimd.h" +#include "pim_vty.h" #include "pim_pim.h" #include "pim_msg.h" #include "pim_util.h" #include "pim_str.h" +#include "pim_rp.h" void pim_msg_build_header(uint8_t *pim_msg, int pim_msg_size, uint8_t pim_msg_type) @@ -177,8 +179,9 @@ pim_msg_join_prune_encode (uint8_t *buf, int buf_size, int is_join, remain = end - pim_msg_curr; if (source.s_addr == INADDR_ANY) { + struct pim_rpf *rpf = pim_rp_g (group); bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT | PIM_ENCODE_RPT_BIT; - stosend = qpim_rp.rpf_addr; + stosend = rpf->rpf_addr; } else { diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 15a0e65574..f484b5cc82 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -44,28 +44,6 @@ struct thread *send_test_packet_timer = NULL; -/* - * This seems stupidly expensive. A list lookup. Why is this - * not a hash? - */ -static int -pim_check_is_my_ip_address (struct in_addr dest_addr) -{ - /* - * See if we can short-cut some? - * This might not make sense if we ever leave a static RP - * type of configuration. - * Note - Premature optimization might bite our patooeys' here. - */ - if (I_am_RP(dest_addr) && (dest_addr.s_addr == qpim_rp.rpf_addr.s_addr)) - return 1; - - if (if_lookup_exact_address (&dest_addr, AF_INET)) - return 1; - - return 0; -} - static void pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg, struct in_addr originator) @@ -263,7 +241,10 @@ pim_register_recv (struct interface *ifp, struct prefix_sg sg; uint32_t *bits; - if (!pim_check_is_my_ip_address (dest_addr)) { +#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4 + ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN); + + if (!pim_rp_check_is_my_ip_address (ip_hdr->ip_dst, dest_addr)) { if (PIM_DEBUG_PIM_REG) { char dest[100]; @@ -308,8 +289,6 @@ pim_register_recv (struct interface *ifp, * Line above. So we need to add 4 bytes to get to the * start of the actual Encapsulated data. */ -#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4 - ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN); memset (&sg, 0, sizeof (struct prefix_sg)); sg.src = ip_hdr->ip_src; sg.grp = ip_hdr->ip_dst; diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index b98ff2859a..5e2ee2e716 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -25,6 +25,7 @@ #include "if.h" #include "pimd.h" +#include "pim_vty.h" #include "pim_str.h" #include "pim_rp.h" #include "pim_str.h" @@ -33,6 +34,30 @@ static int i_am_rp = 0; +static struct pim_rpf qpim_rp = { .rpf_addr.s_addr = INADDR_NONE }; + +int +pim_rp_new (const char *rp, const char *group_range) +{ + int result; + + result = inet_pton (AF_INET, rp, &qpim_rp.rpf_addr.s_addr); + if (result <= 0) + return -1; + + if (!pim_rp_setup ()) + return -2; + + return 0; +} + +int +pim_rp_del (const char *rp, const char *group_range) +{ + qpim_rp.rpf_addr.s_addr = INADDR_NONE; + + return 0; +} int pim_rp_setup (void) @@ -127,3 +152,38 @@ pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source) return 1; } + +int +pim_rp_config_write (struct vty *vty) +{ + char buffer[32]; + + if (qpim_rp.rpf_addr.s_addr != INADDR_NONE) + { + vty_out(vty, "ip pim rp %s%s", inet_ntop(AF_INET, &qpim_rp.rpf_addr, buffer, 32), VTY_NEWLINE); + return 1; + } + + return 0; +} + +int +pim_rp_check_is_my_ip_address (struct in_addr group, struct in_addr dest_addr) +{ + /* + * See if we can short-cut some? + * This might not make sense if we ever leave a static RP + * type of configuration. + * Note - Premature optimization might bite our patooeys' here. + */ + if (I_am_RP(group)) + { + if (dest_addr.s_addr == qpim_rp.rpf_addr.s_addr) + return 1; + } + + if (if_lookup_exact_address (&dest_addr, AF_INET)) + return 1; + + return 0; +} diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index ccbc5b6ad4..6299971567 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -21,12 +21,21 @@ #ifndef PIM_RP_H #define PIM_RP_H +int pim_rp_new (const char *rp, const char *group); +int pim_rp_del (const char *rp, const char *group); + +int pim_rp_config_write (struct vty *vty); + int pim_rp_setup (void); + void pim_rp_check_rp (struct in_addr old, struct in_addr new); int pim_rp_i_am_rp (struct in_addr group); + +int pim_rp_check_is_my_ip_address (struct in_addr group, struct in_addr dest_addr); + int pim_rp_set_upstream_addr (struct in_addr *up, struct in_addr source); + struct pim_rpf *pim_rp_g (struct in_addr group); -void pim_rp_forward_packet (struct ip *ip_hdr); #define I_am_RP(G) pim_rp_i_am_rp ((G)) #define RP(G) pim_rp_g ((G)) diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 9c3df6bbdc..e27c69411c 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -34,6 +34,7 @@ #include "pim_pim.h" #include "pim_oil.h" #include "pim_static.h" +#include "pim_rp.h" int pim_debug_config_write (struct vty *vty) @@ -124,16 +125,13 @@ 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, "ip multicast-routing%s", VTY_NEWLINE); ++writes; } - if (qpim_rp.rpf_addr.s_addr != INADDR_NONE) { - vty_out(vty, "ip pim rp %s%s", inet_ntop(AF_INET, &qpim_rp.rpf_addr, buffer, 32), VTY_NEWLINE); - ++writes; - } + + writes += pim_rp_config_write (vty); if (qpim_ssmpingd_list) { struct listnode *node; diff --git a/pimd/pimd.c b/pimd/pimd.c index d4a0250a0e..709c367135 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -69,7 +69,6 @@ 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 = NULL; -struct pim_rpf qpim_rp = { .rpf_addr.s_addr = INADDR_NONE }; int32_t qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT; int32_t qpim_register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT; diff --git a/pimd/pimd.h b/pimd/pimd.h index e91959948a..b4b8d4886d 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -104,7 +104,6 @@ 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 */ -struct pim_rpf qpim_rp; #define PIM_JP_HOLDTIME (qpim_t_periodic * 7 / 2)