forked from Mirror/frr
Merge pull request #17340 from nabahr/mapping-agent
PIMD: Implement AutoRP mapping-agent
This commit is contained in:
commit
a3e04a86d2
1565
pimd/pim_autorp.c
1565
pimd/pim_autorp.c
File diff suppressed because it is too large
Load diff
|
@ -14,16 +14,21 @@
|
|||
#define AUTORP_VERSION 1
|
||||
#define AUTORP_ANNOUNCEMENT_TYPE 1
|
||||
#define AUTORP_DISCOVERY_TYPE 2
|
||||
#define PIM_VUNKNOWN 0
|
||||
#define PIM_V1 1
|
||||
#define PIM_V2 2
|
||||
#define PIM_V1_2 3
|
||||
#define AUTORP_PIM_VUNKNOWN 0
|
||||
#define AUTORP_PIM_V1 1
|
||||
#define AUTORP_PIM_V2 2
|
||||
#define AUTORP_PIM_V1_2 3
|
||||
|
||||
#define DEFAULT_ANNOUNCE_INTERVAL 60
|
||||
#define DEFAULT_ANNOUNCE_SCOPE 31
|
||||
#define DEFAULT_ANNOUNCE_HOLDTIME -1
|
||||
#define DEFAULT_AUTORP_ANNOUNCE_INTERVAL 60
|
||||
#define DEFAULT_AUTORP_ANNOUNCE_SCOPE 31
|
||||
#define DEFAULT_AUTORP_ANNOUNCE_HOLDTIME -1
|
||||
|
||||
#define DEFAULT_AUTORP_DISCOVERY_INTERVAL 60
|
||||
#define DEFAULT_AUTORP_DISCOVERY_SCOPE 31
|
||||
#define DEFAULT_AUTORP_DISCOVERY_HOLDTIME 180
|
||||
|
||||
PREDECL_SORTLIST_UNIQ(pim_autorp_rp);
|
||||
PREDECL_SORTLIST_UNIQ(pim_autorp_grppfix);
|
||||
|
||||
struct autorp_pkt_grp {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
|
@ -79,7 +84,15 @@ struct pim_autorp_rp {
|
|||
struct event *hold_timer;
|
||||
struct prefix grp;
|
||||
char grplist[32];
|
||||
struct pim_autorp_rp_item list;
|
||||
struct pim_autorp_grppfix_head grp_pfix_list;
|
||||
struct pim_autorp_rp_item item;
|
||||
};
|
||||
|
||||
struct pim_autorp_grppfix {
|
||||
struct prefix grp;
|
||||
struct in_addr rp;
|
||||
bool negative;
|
||||
struct pim_autorp_grppfix_item item;
|
||||
};
|
||||
|
||||
struct pim_autorp {
|
||||
|
@ -96,13 +109,18 @@ struct pim_autorp {
|
|||
struct event *announce_timer;
|
||||
|
||||
/* Event for sending discovery packets*/
|
||||
/* struct event *discovery_timer; */
|
||||
struct event *send_discovery_timer;
|
||||
|
||||
/* Flag enabling reading discovery packets */
|
||||
bool do_discovery;
|
||||
|
||||
/* Flag enabling mapping agent (reading announcements and sending discovery)*/
|
||||
/* bool do_mapping; */
|
||||
bool send_rp_discovery;
|
||||
|
||||
/* Flag indicating if we are sending discovery messages (true) or if a higher IP mapping
|
||||
* agent preemptied our sending (false)
|
||||
*/
|
||||
bool mapping_agent_active;
|
||||
|
||||
/* List of RP's in received discovery packets */
|
||||
struct pim_autorp_rp_head discovery_rp_list;
|
||||
|
@ -111,7 +129,12 @@ struct pim_autorp {
|
|||
struct pim_autorp_rp_head candidate_rp_list;
|
||||
|
||||
/* List of announced RP's to send in discovery packets */
|
||||
/* struct pim_autorp_rp_head mapping_rp_list; */
|
||||
struct pim_autorp_rp_head mapping_rp_list;
|
||||
|
||||
/* List of the last advertised RP's, via mapping agent discovery
|
||||
* This is only filled if a discovery message was sent
|
||||
*/
|
||||
struct pim_autorp_rp_head advertised_rp_list;
|
||||
|
||||
/* Packet parameters for sending announcement packets */
|
||||
uint8_t announce_scope;
|
||||
|
@ -119,32 +142,32 @@ struct pim_autorp {
|
|||
int32_t announce_holdtime;
|
||||
|
||||
/* Pre-built announcement packet, only changes when configured RP's or packet parameters change */
|
||||
uint8_t *annouce_pkt;
|
||||
uint16_t annouce_pkt_sz;
|
||||
uint8_t *announce_pkt;
|
||||
uint16_t announce_pkt_sz;
|
||||
|
||||
/* TODO: Packet parameters for sending discovery packets
|
||||
* int discovery_scope;
|
||||
* int discovery_interval;
|
||||
* int discovery_holdtime;
|
||||
*/
|
||||
/* Packet parameters for sending discovery packets */
|
||||
uint8_t discovery_scope;
|
||||
uint16_t discovery_interval;
|
||||
uint16_t discovery_holdtime;
|
||||
struct cand_addrsel mapping_agent_addrsel;
|
||||
};
|
||||
|
||||
#define AUTORP_GRPLEN 6
|
||||
#define AUTORP_RPLEN 6
|
||||
#define AUTORP_HDRLEN 8
|
||||
|
||||
void pim_autorp_prefix_list_update(struct pim_instance *pim, struct prefix_list *plist);
|
||||
bool pim_autorp_rm_candidate_rp(struct pim_instance *pim, pim_addr rpaddr);
|
||||
void pim_autorp_add_candidate_rp_group(struct pim_instance *pim,
|
||||
pim_addr rpaddr, struct prefix group);
|
||||
void pim_autorp_add_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr,
|
||||
struct prefix group);
|
||||
bool pim_autorp_rm_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr,
|
||||
struct prefix group);
|
||||
void pim_autorp_add_candidate_rp_plist(struct pim_instance *pim,
|
||||
pim_addr rpaddr, const char *plist);
|
||||
bool pim_autorp_rm_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr,
|
||||
const char *plist);
|
||||
void pim_autorp_add_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist);
|
||||
bool pim_autorp_rm_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist);
|
||||
void pim_autorp_announce_scope(struct pim_instance *pim, uint8_t scope);
|
||||
void pim_autorp_announce_interval(struct pim_instance *pim, uint16_t interval);
|
||||
void pim_autorp_announce_holdtime(struct pim_instance *pim, int32_t holdtime);
|
||||
void pim_autorp_send_discovery_apply(struct pim_autorp *autorp);
|
||||
void pim_autorp_add_ifp(struct interface *ifp);
|
||||
void pim_autorp_rm_ifp(struct interface *ifp);
|
||||
void pim_autorp_start_discovery(struct pim_instance *pim);
|
||||
|
@ -152,7 +175,7 @@ void pim_autorp_stop_discovery(struct pim_instance *pim);
|
|||
void pim_autorp_init(struct pim_instance *pim);
|
||||
void pim_autorp_finish(struct pim_instance *pim);
|
||||
int pim_autorp_config_write(struct pim_instance *pim, struct vty *vty);
|
||||
void pim_autorp_show_autorp(struct vty *vty, struct pim_instance *pim,
|
||||
void pim_autorp_show_autorp(struct vty *vty, struct pim_instance *pim, const char *component,
|
||||
json_object *json);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1769,14 +1769,14 @@ static inline pim_addr if_highest_addr(pim_addr cur, struct interface *ifp)
|
|||
return cur;
|
||||
}
|
||||
|
||||
static void cand_addrsel_clear(struct cand_addrsel *asel)
|
||||
void cand_addrsel_clear(struct cand_addrsel *asel)
|
||||
{
|
||||
asel->run = false;
|
||||
asel->run_addr = PIMADDR_ANY;
|
||||
}
|
||||
|
||||
/* returns whether address or active changed */
|
||||
static bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf)
|
||||
bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf)
|
||||
{
|
||||
bool is_any = false, prev_run = asel->run;
|
||||
struct interface *ifp = NULL;
|
||||
|
|
|
@ -64,7 +64,7 @@ enum cand_addr {
|
|||
CAND_ADDR_EXPLICIT,
|
||||
};
|
||||
|
||||
/* used separately for Cand-RP and Cand-BSR */
|
||||
/* used separately for Cand-RP, Cand-BSR, and AutoRP mapping agent */
|
||||
struct cand_addrsel {
|
||||
bool cfg_enable;
|
||||
enum cand_addr cfg_mode : 8;
|
||||
|
@ -369,6 +369,9 @@ void pim_cand_rp_trigger(struct bsm_scope *scope);
|
|||
void pim_cand_rp_grp_add(struct bsm_scope *scope, const prefix_pim *p);
|
||||
void pim_cand_rp_grp_del(struct bsm_scope *scope, const prefix_pim *p);
|
||||
|
||||
void cand_addrsel_clear(struct cand_addrsel *asel);
|
||||
bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf);
|
||||
|
||||
void pim_cand_addrs_changed(void);
|
||||
|
||||
int pim_crp_process(struct interface *ifp, pim_sgaddr *src_dst, uint8_t *buf,
|
||||
|
|
120
pimd/pim_cmd.c
120
pimd/pim_cmd.c
|
@ -2822,65 +2822,49 @@ DEFPY (show_ip_pim_rp_vrf_all,
|
|||
|
||||
DEFPY (show_ip_pim_autorp,
|
||||
show_ip_pim_autorp_cmd,
|
||||
"show ip pim [vrf NAME] autorp [json$json]",
|
||||
"show ip pim [vrf <NAME|all>] autorp [discovery|candidate|mapping-agent]$component [json$json]",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
VRF_CMD_HELP_STR
|
||||
"All VRF's\n"
|
||||
"PIM AutoRP information\n"
|
||||
"RP Discovery details\n"
|
||||
"Candidate RP details\n"
|
||||
"Mapping Agent details\n"
|
||||
JSON_STR)
|
||||
{
|
||||
json_object *json_parent = NULL;
|
||||
struct vrf *v;
|
||||
json_object *json_parent = NULL;
|
||||
|
||||
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
|
||||
if (!v || !v->info) {
|
||||
if (!json)
|
||||
vty_out(vty, "%% Unable to find pim instance\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (json)
|
||||
json_parent = json_object_new_object();
|
||||
|
||||
pim_autorp_show_autorp(vty, v->info, json_parent);
|
||||
if (vrf && strmatch(vrf, "all")) {
|
||||
json_object *json_vrf = NULL;
|
||||
|
||||
if (json)
|
||||
vty_json(vty, json_parent);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY (show_ip_pim_autorp_vrf_all,
|
||||
show_ip_pim_autorp_vrf_all_cmd,
|
||||
"show ip pim vrf all autorp [json$json]",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
VRF_CMD_HELP_STR
|
||||
"PIM AutoRP information\n"
|
||||
JSON_STR)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
json_object *json_parent = NULL;
|
||||
json_object *json_vrf = NULL;
|
||||
|
||||
if (json)
|
||||
json_parent = json_object_new_object();
|
||||
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
||||
if (vrf->info) {
|
||||
if (!json)
|
||||
vty_out(vty, "VRF: %s\n", vrf->name);
|
||||
else
|
||||
json_vrf = json_object_new_object();
|
||||
|
||||
pim_autorp_show_autorp(vty, vrf->info, json_vrf);
|
||||
RB_FOREACH (v, vrf_name_head, &vrfs_by_name) {
|
||||
if (!v || !v->info)
|
||||
continue;
|
||||
|
||||
if (json)
|
||||
json_object_object_add(json_parent, vrf->name,
|
||||
json_vrf);
|
||||
json_vrf = json_object_new_object();
|
||||
else
|
||||
vty_out(vty, "VRF: %s\n", v->name);
|
||||
|
||||
pim_autorp_show_autorp(vty, v->info, component, json_vrf);
|
||||
|
||||
if (json)
|
||||
json_object_object_add(json_parent, v->name, json_vrf);
|
||||
}
|
||||
} else {
|
||||
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
|
||||
if (!v || !v->info) {
|
||||
if (!json)
|
||||
vty_out(vty, "%% Unable to find pim instance\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
pim_autorp_show_autorp(vty, v->info, component, json_parent);
|
||||
}
|
||||
|
||||
if (json)
|
||||
|
@ -4609,13 +4593,17 @@ DEFPY (pim_autorp_announce_rp,
|
|||
"Prefix list\n"
|
||||
"List name\n")
|
||||
{
|
||||
return pim_process_autorp_candidate_rp_cmd(vty, no, rpaddr_str, (grp_str ? grp : NULL),
|
||||
plist);
|
||||
if (grp_str && (!pim_addr_is_multicast(grp->prefix) || grp->prefixlen < 4)) {
|
||||
vty_out(vty, "%% group prefix %pFX is not a valid multicast range\n", grp);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
return pim_process_autorp_candidate_rp_cmd(vty, no, rpaddr_str, grp_str, plist);
|
||||
}
|
||||
|
||||
DEFPY (pim_autorp_announce_scope_int,
|
||||
pim_autorp_announce_scope_int_cmd,
|
||||
"[no] autorp announce ![{scope (1-255) | interval (1-65535) | holdtime (0-65535)}]",
|
||||
"[no] autorp announce {scope (1-255) | interval (1-65535) | holdtime (0-65535)}",
|
||||
NO_STR
|
||||
"AutoRP\n"
|
||||
"AutoRP Candidate RP announcement\n"
|
||||
|
@ -4626,11 +4614,44 @@ DEFPY (pim_autorp_announce_scope_int,
|
|||
"Announcement holdtime\n"
|
||||
"Time in seconds\n")
|
||||
{
|
||||
return pim_process_autorp_announce_scope_int_cmd(vty, no, scope_str,
|
||||
interval_str,
|
||||
return pim_process_autorp_announce_scope_int_cmd(vty, no, scope_str, interval_str,
|
||||
holdtime_str);
|
||||
}
|
||||
|
||||
DEFPY (pim_autorp_send_rp_discovery,
|
||||
pim_autorp_send_rp_discovery_cmd,
|
||||
"[no] autorp send-rp-discovery [source <address A.B.C.D | interface IFNAME | loopback$loopback | any$any>]",
|
||||
NO_STR
|
||||
"AutoRP\n"
|
||||
"Enable AutoRP mapping agent\n"
|
||||
"Specify AutoRP discovery source\n"
|
||||
"Local address\n"
|
||||
IP_ADDR_STR
|
||||
"Local Interface (uses highest address)\n"
|
||||
IFNAME_STR
|
||||
"Highest loopback address (default)\n"
|
||||
"Highest address of any interface\n")
|
||||
{
|
||||
return pim_process_autorp_send_rp_discovery_cmd(vty, no, any, loopback, ifname, address_str);
|
||||
}
|
||||
|
||||
DEFPY (pim_autorp_send_rp_discovery_scope_int,
|
||||
pim_autorp_send_rp_discovery_scope_int_cmd,
|
||||
"[no] autorp send-rp-discovery {scope (0-255) | interval (1-65535) | holdtime (0-65535)}",
|
||||
NO_STR
|
||||
"AutoRP\n"
|
||||
"Enable AutoRP mapping agent\n"
|
||||
"Packet scope (TTL)\n"
|
||||
"TTL value\n"
|
||||
"Discovery TX interval\n"
|
||||
"Time in seconds\n"
|
||||
"Announcement holdtime\n"
|
||||
"Time in seconds\n")
|
||||
{
|
||||
return pim_process_autorp_send_rp_discovery_scope_int_cmd(vty, no, scope_str, interval_str,
|
||||
holdtime_str);
|
||||
}
|
||||
|
||||
DEFPY (pim_bsr_candidate_bsr,
|
||||
pim_bsr_candidate_bsr_cmd,
|
||||
"[no] bsr candidate-bsr [{priority (0-255)|source <address A.B.C.D|interface IFNAME|loopback$loopback|any$any>}]",
|
||||
|
@ -8886,6 +8907,8 @@ void pim_cmd_init(void)
|
|||
install_element(PIM_NODE, &pim_autorp_discovery_cmd);
|
||||
install_element(PIM_NODE, &pim_autorp_announce_rp_cmd);
|
||||
install_element(PIM_NODE, &pim_autorp_announce_scope_int_cmd);
|
||||
install_element(PIM_NODE, &pim_autorp_send_rp_discovery_cmd);
|
||||
install_element(PIM_NODE, &pim_autorp_send_rp_discovery_scope_int_cmd);
|
||||
install_element(PIM_NODE, &no_pim_ssm_prefix_list_cmd);
|
||||
install_element(PIM_NODE, &no_pim_ssm_prefix_list_name_cmd);
|
||||
install_element(PIM_NODE, &pim_ssm_prefix_list_cmd);
|
||||
|
@ -9043,7 +9066,6 @@ void pim_cmd_init(void)
|
|||
install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_pim_autorp_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_pim_autorp_vrf_all_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_multicast_cmd);
|
||||
install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
|
||||
|
|
|
@ -630,139 +630,88 @@ int pim_process_no_autorp_cmd(struct vty *vty)
|
|||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no,
|
||||
const char *rpaddr_str,
|
||||
const struct prefix_ipv4 *grp,
|
||||
const char *plist)
|
||||
int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str,
|
||||
const char *grp, const char *plist)
|
||||
{
|
||||
char xpath[XPATH_MAXLEN];
|
||||
char grpstr[64];
|
||||
|
||||
if (no) {
|
||||
if ((grp && !is_default_prefix((const struct prefix *)grp)) || plist) {
|
||||
if (grp || plist) {
|
||||
/* If any single values are set, only destroy those */
|
||||
if (grp && !is_default_prefix((const struct prefix *)grp)) {
|
||||
snprintfrr(xpath, sizeof(xpath),
|
||||
"%s/candidate-rp-list[rp-address='%s']/group",
|
||||
FRR_PIM_AUTORP_XPATH, rpaddr_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
|
||||
NULL);
|
||||
}
|
||||
if (plist) {
|
||||
snprintfrr(xpath, sizeof(xpath),
|
||||
"%s/candidate-rp-list[rp-address='%s']/prefix-list",
|
||||
FRR_PIM_AUTORP_XPATH, rpaddr_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
if (grp)
|
||||
nb_cli_enqueue_change(vty, "./group", NB_OP_DESTROY, NULL);
|
||||
if (plist)
|
||||
nb_cli_enqueue_change(vty, "./prefix-list", NB_OP_DESTROY, NULL);
|
||||
} else
|
||||
/* No values set, remove the entire RP */
|
||||
snprintfrr(xpath, sizeof(xpath),
|
||||
"%s/candidate-rp-list[rp-address='%s']",
|
||||
FRR_PIM_AUTORP_XPATH, rpaddr_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
}
|
||||
nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
|
||||
} else {
|
||||
if ((grp && !is_default_prefix((const struct prefix *)grp)) || plist) {
|
||||
snprintfrr(xpath, sizeof(xpath),
|
||||
"%s/candidate-rp-list[rp-address='%s']",
|
||||
FRR_PIM_AUTORP_XPATH, rpaddr_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
if (grp && !is_default_prefix((const struct prefix *)grp)) {
|
||||
snprintfrr(xpath, sizeof(xpath),
|
||||
"%s/candidate-rp-list[rp-address='%s']/group",
|
||||
FRR_PIM_AUTORP_XPATH, rpaddr_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
prefix2str(grp, grpstr,
|
||||
sizeof(grpstr)));
|
||||
}
|
||||
if (plist) {
|
||||
snprintfrr(xpath, sizeof(xpath),
|
||||
"%s/candidate-rp-list[rp-address='%s']/prefix-list",
|
||||
FRR_PIM_AUTORP_XPATH, rpaddr_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
plist);
|
||||
}
|
||||
} else {
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
|
||||
if (grp)
|
||||
nb_cli_enqueue_change(vty, "./group", NB_OP_MODIFY, grp);
|
||||
if (plist)
|
||||
nb_cli_enqueue_change(vty, "./prefix-list", NB_OP_MODIFY, plist);
|
||||
}
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
return nb_cli_apply_changes(vty, "%s/candidate-rp-list[rp-address='%s']",
|
||||
FRR_PIM_AUTORP_XPATH, rpaddr_str);
|
||||
}
|
||||
|
||||
int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no,
|
||||
const char *scope,
|
||||
const char *interval,
|
||||
const char *holdtime)
|
||||
int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no, const char *scope,
|
||||
const char *interval, const char *holdtime)
|
||||
{
|
||||
char xpath[XPATH_MAXLEN];
|
||||
/* At least one value is required, so set/delete anything defined */
|
||||
enum nb_operation op = (no ? NB_OP_DESTROY : NB_OP_MODIFY);
|
||||
|
||||
if (scope)
|
||||
nb_cli_enqueue_change(vty, "./announce-scope", op, scope);
|
||||
if (interval)
|
||||
nb_cli_enqueue_change(vty, "./announce-interval", op, interval);
|
||||
if (holdtime)
|
||||
nb_cli_enqueue_change(vty, "./announce-holdtime", op, holdtime);
|
||||
|
||||
return nb_cli_apply_changes(vty, "%s", FRR_PIM_AUTORP_XPATH);
|
||||
}
|
||||
|
||||
int pim_process_autorp_send_rp_discovery_cmd(struct vty *vty, bool no, bool any, bool loopback,
|
||||
const char *ifname, const char *addr)
|
||||
{
|
||||
/* Just take any "no" version of this command as disable the mapping agent */
|
||||
nb_cli_enqueue_change(vty, "./send-rp-discovery", NB_OP_MODIFY, (no ? "false" : "true"));
|
||||
if (no) {
|
||||
if (scope || interval || holdtime) {
|
||||
/* If any single values are set, only destroy those */
|
||||
if (scope) {
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH,
|
||||
"announce-scope");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
|
||||
NULL);
|
||||
}
|
||||
if (interval) {
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH,
|
||||
"announce-interval");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
|
||||
NULL);
|
||||
}
|
||||
if (holdtime) {
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH,
|
||||
"announce-holdtime");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
/* No values set, remove all */
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH, "announce-scope");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH, "announce-interval");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH, "announce-holdtime");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
}
|
||||
nb_cli_enqueue_change(vty, "./if-any", NB_OP_DESTROY, NULL);
|
||||
nb_cli_enqueue_change(vty, "./interface", NB_OP_DESTROY, NULL);
|
||||
nb_cli_enqueue_change(vty, "./address", NB_OP_DESTROY, NULL);
|
||||
nb_cli_enqueue_change(vty, "./if-loopback", NB_OP_DESTROY, NULL);
|
||||
} else {
|
||||
if (scope || interval || holdtime) {
|
||||
if (scope) {
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH,
|
||||
"announce-scope");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
scope);
|
||||
}
|
||||
if (interval) {
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH,
|
||||
"announce-interval");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
interval);
|
||||
}
|
||||
if (holdtime) {
|
||||
snprintfrr(xpath, sizeof(xpath), "%s/%s",
|
||||
FRR_PIM_AUTORP_XPATH,
|
||||
"announce-holdtime");
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
holdtime);
|
||||
}
|
||||
} else {
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
/* Enabling mapping agent. Loopback is default, so any non-no for of the command will
|
||||
* enable the mapping agent.
|
||||
*/
|
||||
if (any)
|
||||
nb_cli_enqueue_change(vty, "./if-any", NB_OP_CREATE, NULL);
|
||||
else if (ifname)
|
||||
nb_cli_enqueue_change(vty, "./interface", NB_OP_MODIFY, ifname);
|
||||
else if (addr)
|
||||
nb_cli_enqueue_change(vty, "./address", NB_OP_MODIFY, addr);
|
||||
else
|
||||
nb_cli_enqueue_change(vty, "./if-loopback", NB_OP_CREATE, NULL);
|
||||
}
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
return nb_cli_apply_changes(vty, "%s/%s", FRR_PIM_AUTORP_XPATH, "mapping-agent");
|
||||
}
|
||||
|
||||
int pim_process_autorp_send_rp_discovery_scope_int_cmd(struct vty *vty, bool no, const char *scope,
|
||||
const char *interval, const char *holdtime)
|
||||
{
|
||||
/* At least one value is required, so only set/delete the values specified */
|
||||
enum nb_operation op = (no ? NB_OP_DESTROY : NB_OP_MODIFY);
|
||||
|
||||
if (scope)
|
||||
nb_cli_enqueue_change(vty, "./discovery-scope", op, scope);
|
||||
if (interval)
|
||||
nb_cli_enqueue_change(vty, "./discovery-interval", op, interval);
|
||||
if (holdtime)
|
||||
nb_cli_enqueue_change(vty, "./discovery-holdtime", op, holdtime);
|
||||
|
||||
return nb_cli_apply_changes(vty, "%s/%s", FRR_PIM_AUTORP_XPATH, "mapping-agent");
|
||||
}
|
||||
|
||||
bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match)
|
||||
|
|
|
@ -37,14 +37,14 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
|
|||
const char *prefix_list);
|
||||
int pim_process_autorp_cmd(struct vty *vty);
|
||||
int pim_process_no_autorp_cmd(struct vty *vty);
|
||||
int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no,
|
||||
const char *rpaddr_str,
|
||||
const struct prefix_ipv4 *grp,
|
||||
const char *plist);
|
||||
int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no,
|
||||
const char *scope,
|
||||
const char *interval,
|
||||
const char *holdtime);
|
||||
int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str,
|
||||
const char *grp, const char *plist);
|
||||
int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no, const char *scope,
|
||||
const char *interval, const char *holdtime);
|
||||
int pim_process_autorp_send_rp_discovery_cmd(struct vty *vty, bool no, bool any, bool loopback,
|
||||
const char *ifname, const char *addr);
|
||||
int pim_process_autorp_send_rp_discovery_scope_int_cmd(struct vty *vty, bool no, const char *scope,
|
||||
const char *interval, const char *holdtime);
|
||||
int pim_process_ip_pim_cmd(struct vty *vty);
|
||||
int pim_process_no_ip_pim_cmd(struct vty *vty);
|
||||
int pim_process_ip_pim_passive_cmd(struct vty *vty, bool enable);
|
||||
|
|
|
@ -459,6 +459,58 @@ const struct frr_yang_module_info frr_pim_rp_info = {
|
|||
.destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/send-rp-discovery",
|
||||
.cbs = {
|
||||
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_send_rp_discovery_modify,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-scope",
|
||||
.cbs = {
|
||||
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_scope_modify,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-interval",
|
||||
.cbs = {
|
||||
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_interval_modify,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-holdtime",
|
||||
.cbs = {
|
||||
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_holdtime_modify,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/address",
|
||||
.cbs = {
|
||||
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify,
|
||||
.destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/interface",
|
||||
.cbs = {
|
||||
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify,
|
||||
.destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/if-loopback",
|
||||
.cbs = {
|
||||
.create = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create,
|
||||
.destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/if-any",
|
||||
.cbs = {
|
||||
.create = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create,
|
||||
.destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = NULL,
|
||||
},
|
||||
|
|
|
@ -193,6 +193,20 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
struct nb_cb_modify_args *args);
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_send_rp_discovery_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_scope_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_interval_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_holdtime_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create(
|
||||
struct nb_cb_create_args *args);
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
|
||||
/* frr-cand-bsr */
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_candidate_bsr_create(
|
||||
|
|
|
@ -41,12 +41,24 @@ int funcname(struct argtype *args) \
|
|||
} \
|
||||
MACRO_REQUIRE_SEMICOLON()
|
||||
|
||||
#define pim6_autorp_err(funcname, argtype) \
|
||||
int funcname(struct argtype *args) \
|
||||
{ \
|
||||
snprintf(args->errmsg, args->errmsg_len, \
|
||||
"Trying to configure AutoRP in pim6d. " \
|
||||
"AutoRP does not exist for IPv6."); \
|
||||
return NB_ERR_VALIDATION; \
|
||||
} \
|
||||
MACRO_REQUIRE_SEMICOLON()
|
||||
|
||||
#define yang_dnode_get_pimaddr yang_dnode_get_ipv6
|
||||
|
||||
#else /* PIM_IPV != 6 */
|
||||
#define pim6_msdp_err(funcname, argtype) \
|
||||
MACRO_REQUIRE_SEMICOLON()
|
||||
|
||||
#define pim6_autorp_err(funcname, argtype) MACRO_REQUIRE_SEMICOLON()
|
||||
|
||||
#define yang_dnode_get_pimaddr yang_dnode_get_ipv4
|
||||
#endif /* PIM_IPV != 6 */
|
||||
|
||||
|
@ -490,6 +502,26 @@ static void change_query_max_response_time(struct interface *ifp,
|
|||
#endif /* PIM_IPV == 4 */
|
||||
}
|
||||
|
||||
static void yang_addrsel(struct cand_addrsel *addrsel, const struct lyd_node *node)
|
||||
{
|
||||
memset(addrsel->cfg_ifname, 0, sizeof(addrsel->cfg_ifname));
|
||||
addrsel->cfg_addr = PIMADDR_ANY;
|
||||
|
||||
if (yang_dnode_exists(node, "if-any")) {
|
||||
addrsel->cfg_mode = CAND_ADDR_ANY;
|
||||
} else if (yang_dnode_exists(node, "address")) {
|
||||
addrsel->cfg_mode = CAND_ADDR_EXPLICIT;
|
||||
yang_dnode_get_pimaddr(&addrsel->cfg_addr, node, "address");
|
||||
} else if (yang_dnode_exists(node, "interface")) {
|
||||
addrsel->cfg_mode = CAND_ADDR_IFACE;
|
||||
strlcpy(addrsel->cfg_ifname, yang_dnode_get_string(node, "interface"),
|
||||
sizeof(addrsel->cfg_ifname));
|
||||
} else if (yang_dnode_exists(node, "if-loopback")) {
|
||||
addrsel->cfg_mode = CAND_ADDR_LO;
|
||||
}
|
||||
addrsel->cfg_enable = true;
|
||||
}
|
||||
|
||||
int routing_control_plane_protocols_name_validate(
|
||||
struct nb_cb_create_args *args)
|
||||
{
|
||||
|
@ -2854,13 +2886,77 @@ int pim_embedded_rp_maximum_rps_modify(struct nb_cb_modify_args *args)
|
|||
}
|
||||
}
|
||||
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_destroy,
|
||||
nb_cb_destroy_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_destroy,
|
||||
nb_cb_destroy_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_destroy,
|
||||
nb_cb_destroy_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_destroy,
|
||||
nb_cb_destroy_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_create,
|
||||
nb_cb_create_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_destroy,
|
||||
nb_cb_destroy_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_destroy,
|
||||
nb_cb_destroy_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy,
|
||||
nb_cb_destroy_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_send_rp_discovery_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_scope_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_interval_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_holdtime_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create,
|
||||
nb_cb_create_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify,
|
||||
nb_cb_modify_args);
|
||||
pim6_autorp_err(
|
||||
routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy,
|
||||
nb_cb_destroy_args);
|
||||
|
||||
#if PIM_IPV == 4
|
||||
/*
|
||||
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/discovery-enabled
|
||||
*/
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
bool enabled;
|
||||
|
@ -2880,14 +2976,12 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
pim_autorp_stop_discovery(pim);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
bool enabled;
|
||||
|
@ -2906,7 +3000,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
pim_autorp_start_discovery(pim);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
@ -2917,7 +3010,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
uint8_t scope;
|
||||
|
@ -2932,15 +3024,14 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
pim = vrf->info;
|
||||
scope = yang_dnode_get_uint8(args->dnode, NULL);
|
||||
pim_autorp_announce_scope(pim, scope);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
|
@ -2953,8 +3044,8 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
pim_autorp_announce_scope(pim, 0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
@ -2965,7 +3056,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
uint16_t interval;
|
||||
|
@ -2980,15 +3070,14 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
pim = vrf->info;
|
||||
interval = yang_dnode_get_uint16(args->dnode, NULL);
|
||||
pim_autorp_announce_interval(pim, interval);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
|
@ -3001,8 +3090,8 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
pim_autorp_announce_interval(pim, 0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
@ -3013,7 +3102,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
uint16_t holdtime;
|
||||
|
@ -3028,15 +3116,14 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
pim = vrf->info;
|
||||
holdtime = yang_dnode_get_uint16(args->dnode, NULL);
|
||||
pim_autorp_announce_holdtime(pim, holdtime);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
|
@ -3050,8 +3137,8 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
pim = vrf->info;
|
||||
/* 0 is a valid value, so -1 indicates deleting (go back to default) */
|
||||
pim_autorp_announce_holdtime(pim, -1);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
@ -3062,7 +3149,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_create(
|
||||
struct nb_cb_create_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
|
@ -3070,14 +3156,12 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
case NB_EV_APPLY:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
pim_addr rp_addr;
|
||||
|
@ -3095,7 +3179,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
@ -3106,7 +3189,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
struct prefix group;
|
||||
|
@ -3124,15 +3206,14 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
yang_dnode_get_prefix(&group, args->dnode, NULL);
|
||||
apply_mask(&group);
|
||||
pim_autorp_add_candidate_rp_group(pim, rp_addr, group);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
struct prefix group;
|
||||
|
@ -3151,8 +3232,8 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
apply_mask(&group);
|
||||
if (!pim_autorp_rm_candidate_rp_group(pim, rp_addr, group))
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
@ -3163,7 +3244,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
pim_addr rp_addr;
|
||||
|
@ -3180,15 +3260,14 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
plist = yang_dnode_get_string(args->dnode, NULL);
|
||||
yang_dnode_get_pimaddr(&rp_addr, args->dnode, "../rp-address");
|
||||
pim_autorp_add_candidate_rp_plist(pim, rp_addr, plist);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
#if PIM_IPV == 4
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
pim_addr rp_addr;
|
||||
|
@ -3208,32 +3287,212 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
|
|||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
static void yang_addrsel(struct cand_addrsel *addrsel,
|
||||
const struct lyd_node *node)
|
||||
/*
|
||||
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/send-rp-discovery
|
||||
*/
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_send_rp_discovery_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
memset(addrsel->cfg_ifname, 0, sizeof(addrsel->cfg_ifname));
|
||||
addrsel->cfg_addr = PIMADDR_ANY;
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
if (yang_dnode_exists(node, "if-any")) {
|
||||
addrsel->cfg_mode = CAND_ADDR_ANY;
|
||||
} else if (yang_dnode_exists(node, "address")) {
|
||||
addrsel->cfg_mode = CAND_ADDR_EXPLICIT;
|
||||
yang_dnode_get_pimaddr(&addrsel->cfg_addr, node, "address");
|
||||
} else if (yang_dnode_exists(node, "interface")) {
|
||||
addrsel->cfg_mode = CAND_ADDR_IFACE;
|
||||
strlcpy(addrsel->cfg_ifname,
|
||||
yang_dnode_get_string(node, "interface"),
|
||||
sizeof(addrsel->cfg_ifname));
|
||||
} else if (yang_dnode_exists(node, "if-loopback")) {
|
||||
addrsel->cfg_mode = CAND_ADDR_LO;
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
if (pim && pim->autorp) {
|
||||
pim->autorp->send_rp_discovery = yang_dnode_get_bool(args->dnode, NULL);
|
||||
pim_autorp_send_discovery_apply(pim->autorp);
|
||||
} else
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-scope
|
||||
*/
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_scope_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
if (pim && pim->autorp)
|
||||
pim->autorp->discovery_scope = yang_dnode_get_uint8(args->dnode, NULL);
|
||||
else
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-interval
|
||||
*/
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_interval_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
if (pim && pim->autorp)
|
||||
pim->autorp->discovery_interval = yang_dnode_get_uint16(args->dnode, NULL);
|
||||
else
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/discovery-holdtime
|
||||
*/
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_discovery_holdtime_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
if (pim && pim->autorp)
|
||||
pim->autorp->discovery_holdtime = yang_dnode_get_uint16(args->dnode, NULL);
|
||||
else
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
static int pim_autorp_mapping_agent_addrsel(struct pim_autorp *autorp,
|
||||
const struct lyd_node *mapping_agent_node,
|
||||
struct vrf *vrf)
|
||||
{
|
||||
yang_addrsel(&autorp->mapping_agent_addrsel, mapping_agent_node);
|
||||
if (cand_addrsel_update(&autorp->mapping_agent_addrsel, vrf))
|
||||
pim_autorp_send_discovery_apply(autorp);
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath:
|
||||
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/address
|
||||
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/interface
|
||||
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/if-loopback
|
||||
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/mapping-agent/if-any
|
||||
*/
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_create(
|
||||
struct nb_cb_create_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
const struct lyd_node *mapping_agent_node;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
mapping_agent_node = yang_dnode_get_parent(args->dnode, "mapping-agent");
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
if (pim && pim->autorp)
|
||||
return pim_autorp_mapping_agent_addrsel(pim->autorp, mapping_agent_node,
|
||||
vrf);
|
||||
else
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
const struct lyd_node *mapping_agent_node;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
mapping_agent_node = yang_dnode_get_parent(args->dnode, "mapping-agent");
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
if (pim && pim->autorp)
|
||||
return pim_autorp_mapping_agent_addrsel(pim->autorp, mapping_agent_node,
|
||||
vrf);
|
||||
else
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_mapping_agent_addrsel_destroy(
|
||||
struct nb_cb_destroy_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
case NB_EV_APPLY:
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
if (pim && pim->autorp)
|
||||
pim->autorp->mapping_agent_addrsel.cfg_enable = false;
|
||||
else
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
#endif /* PIM_IPV == 4 (for AutoRP)*/
|
||||
|
||||
static int candidate_bsr_addrsel(struct bsm_scope *scope,
|
||||
const struct lyd_node *cand_bsr_node)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "pim_zlookup.h"
|
||||
#include "pim_zebra.h"
|
||||
#include "pim_mlag.h"
|
||||
#include "pim_autorp.h"
|
||||
|
||||
#if MAXVIFS > 256
|
||||
CPP_NOTICE("Work needs to be done to make this work properly via the pim mroute socket\n");
|
||||
|
@ -70,6 +71,9 @@ void pim_prefix_list_update(struct prefix_list *plist)
|
|||
pim_rp_prefix_list_update(pim, plist);
|
||||
pim_ssm_prefix_list_update(pim, plist);
|
||||
pim_upstream_spt_prefix_list_update(pim, plist);
|
||||
#if PIM_IPV == 4
|
||||
pim_autorp_prefix_list_update(pim, plist);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1720,26 +1720,26 @@ def verify_pim_rp_info(
|
|||
)
|
||||
return errormsg
|
||||
|
||||
if not iamRP:
|
||||
if rp_json["iAmRP"] == False:
|
||||
logger.info(
|
||||
"[DUT %s]: Verifying group "
|
||||
"and iAmNotRP [PASSED]!!"
|
||||
" Found Expected: (%s, %s:%s)",
|
||||
dut,
|
||||
grp_addr,
|
||||
"iAmRP",
|
||||
rp_json["iAmRP"],
|
||||
)
|
||||
else:
|
||||
errormsg = (
|
||||
"[DUT %s]: Verifying group"
|
||||
"%s and iAmRP [FAILED]!! "
|
||||
"Expected: (iAmRP: %s),"
|
||||
" Found: (iAmRP: %s)"
|
||||
% (dut, grp_addr, "false", rp_json["iAmRP"])
|
||||
)
|
||||
return errormsg
|
||||
if not iamRP:
|
||||
if rp_json["iAmRP"] == False:
|
||||
logger.info(
|
||||
"[DUT %s]: Verifying group "
|
||||
"and iAmNotRP [PASSED]!!"
|
||||
" Found Expected: (%s, %s:%s)",
|
||||
dut,
|
||||
grp_addr,
|
||||
"iAmRP",
|
||||
rp_json["iAmRP"],
|
||||
)
|
||||
else:
|
||||
errormsg = (
|
||||
"[DUT %s]: Verifying group"
|
||||
"%s and iAmRP [FAILED]!! "
|
||||
"Expected: (iAmRP: %s),"
|
||||
" Found: (iAmRP: %s)"
|
||||
% (dut, grp_addr, "false", rp_json["iAmRP"])
|
||||
)
|
||||
return errormsg
|
||||
|
||||
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
|
||||
return True
|
||||
|
|
|
@ -2,15 +2,25 @@
|
|||
hostname r1
|
||||
password zebra
|
||||
log file /tmp/r1-frr.log
|
||||
!
|
||||
debug pim autorp
|
||||
!
|
||||
interface r1-eth0
|
||||
ip address 10.10.76.1/24
|
||||
ip address 10.0.0.1/24
|
||||
ip igmp
|
||||
ip pim
|
||||
!
|
||||
interface r1-eth1
|
||||
ip address 10.0.1.1/24
|
||||
ip igmp
|
||||
ip pim
|
||||
!
|
||||
ip forwarding
|
||||
!
|
||||
ip route 10.0.2.0/24 10.0.0.2 50
|
||||
ip route 10.0.3.0/24 10.0.0.2 50
|
||||
!
|
||||
router pim
|
||||
autorp discovery
|
||||
rp 10.0.3.4 224.0.1.0/24
|
||||
!
|
|
@ -2,15 +2,25 @@
|
|||
hostname r2
|
||||
password zebra
|
||||
log file /tmp/r2-frr.log
|
||||
!
|
||||
debug pim autorp
|
||||
!
|
||||
interface r2-eth0
|
||||
ip address 10.10.76.2/24
|
||||
ip address 10.0.0.2/24
|
||||
ip igmp
|
||||
ip pim
|
||||
!
|
||||
interface r2-eth1
|
||||
ip address 10.0.2.2/24
|
||||
ip igmp
|
||||
ip pim
|
||||
!
|
||||
ip forwarding
|
||||
!
|
||||
ip route 10.0.1.0/24 10.0.0.1 50
|
||||
ip route 10.0.3.0/24 10.0.2.4 50
|
||||
!
|
||||
router pim
|
||||
autorp discovery
|
||||
rp 10.0.3.4 224.0.1.0/24
|
||||
!
|
26
tests/topotests/pim_autorp/r3/frr.conf
Normal file
26
tests/topotests/pim_autorp/r3/frr.conf
Normal file
|
@ -0,0 +1,26 @@
|
|||
!
|
||||
hostname r3
|
||||
password zebra
|
||||
log file /tmp/r3-frr.log
|
||||
!
|
||||
debug pim autorp
|
||||
!
|
||||
interface r3-eth0
|
||||
ip address 10.0.1.3/24
|
||||
ip igmp
|
||||
ip pim
|
||||
!
|
||||
interface r3-eth1
|
||||
ip address 10.0.3.3/24
|
||||
ip igmp
|
||||
ip pim
|
||||
!
|
||||
ip forwarding
|
||||
!
|
||||
ip route 10.0.0.0/24 10.0.1.1 50
|
||||
ip route 10.0.2.0/24 10.0.3.4 50
|
||||
!
|
||||
router pim
|
||||
autorp discovery
|
||||
rp 10.0.3.4 224.0.1.0/24
|
||||
!
|
26
tests/topotests/pim_autorp/r4/frr.conf
Normal file
26
tests/topotests/pim_autorp/r4/frr.conf
Normal file
|
@ -0,0 +1,26 @@
|
|||
!
|
||||
hostname r4
|
||||
password zebra
|
||||
log file /tmp/r4-frr.log
|
||||
!
|
||||
debug pim autorp
|
||||
!
|
||||
interface r4-eth0
|
||||
ip address 10.0.2.4/24
|
||||
ip igmp
|
||||
ip pim
|
||||
!
|
||||
interface r4-eth1
|
||||
ip address 10.0.3.4/24
|
||||
ip igmp
|
||||
ip pim
|
||||
!
|
||||
ip forwarding
|
||||
!
|
||||
ip route 10.0.0.0/24 10.0.2.2 50
|
||||
ip route 10.0.1.0/24 10.0.2.2 50
|
||||
!
|
||||
router pim
|
||||
autorp discovery
|
||||
rp 10.0.3.4 224.0.1.0/24
|
||||
!
|
|
@ -11,18 +11,14 @@
|
|||
import os
|
||||
import sys
|
||||
import pytest
|
||||
import json
|
||||
from functools import partial
|
||||
|
||||
# pylint: disable=C0413
|
||||
# Import topogen and topotest helpers
|
||||
from lib import topotest
|
||||
from lib.topogen import Topogen, get_topogen
|
||||
from lib.topogen import Topogen, topotest, get_topogen
|
||||
from lib.topolog import logger
|
||||
from lib.pim import (
|
||||
scapy_send_autorp_raw_packet,
|
||||
verify_pim_rp_info,
|
||||
verify_pim_rp_info_is_empty,
|
||||
)
|
||||
from lib.pim import verify_pim_rp_info
|
||||
from lib.common_config import step, write_test_header
|
||||
|
||||
from time import sleep
|
||||
|
@ -32,13 +28,26 @@ test_pim_autorp.py: Test general PIM AutoRP functionality
|
|||
"""
|
||||
|
||||
TOPOLOGY = """
|
||||
Basic AutoRP functionality
|
||||
Test PIM AutoRP functionality:
|
||||
AutoRP candidate RP announcements
|
||||
Mapping agent announcement receive and send discovery
|
||||
AutoRP discovery to active RP info
|
||||
|
||||
+---+---+ +---+---+
|
||||
| | 10.10.76.0/24 | |
|
||||
+ R1 + <------------------> + R2 |
|
||||
| | .1 .2 | |
|
||||
+---+---+ +---+---+
|
||||
+---+---+ +---+---+
|
||||
| | 10.0.0.0/24 | |
|
||||
+ R1 +----------------------+ R2 |
|
||||
| | .1 .2 | |
|
||||
+---+---+ r1-eth0 r2-eth0 +---+---+
|
||||
.1 | r1-eth1 r2-eth1 | .2
|
||||
| |
|
||||
10.0.1.0/24 | | 10.0.2.0/24
|
||||
| |
|
||||
.3 | r3-eth0 r4-eth0 | .4
|
||||
+---+---+ r3-eth1 r4-eth1 +---+---+
|
||||
| | .3 .4 | |
|
||||
+ R3 +----------------------+ R4 |
|
||||
| | 10.0.3.0/24 | |
|
||||
+---+---+ +---+---+
|
||||
"""
|
||||
|
||||
# Save the Current Working Directory to find configuration files.
|
||||
|
@ -55,11 +64,14 @@ def build_topo(tgen):
|
|||
# Create routers
|
||||
tgen.add_router("r1")
|
||||
tgen.add_router("r2")
|
||||
tgen.add_router("r3")
|
||||
tgen.add_router("r4")
|
||||
|
||||
# Create link between router 1 and 2
|
||||
switch = tgen.add_switch("s1-2")
|
||||
switch.add_link(tgen.gears["r1"])
|
||||
switch.add_link(tgen.gears["r2"])
|
||||
# Create topology links
|
||||
tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "r1-eth0", "r2-eth0")
|
||||
tgen.add_link(tgen.gears["r1"], tgen.gears["r3"], "r1-eth1", "r3-eth0")
|
||||
tgen.add_link(tgen.gears["r2"], tgen.gears["r4"], "r2-eth1", "r4-eth0")
|
||||
tgen.add_link(tgen.gears["r3"], tgen.gears["r4"], "r3-eth1", "r4-eth1")
|
||||
|
||||
|
||||
def setup_module(mod):
|
||||
|
@ -68,15 +80,6 @@ def setup_module(mod):
|
|||
tgen = Topogen(build_topo, mod.__name__)
|
||||
tgen.start_topology()
|
||||
|
||||
# Router 1 will be the router configured with "fake" autorp configuration, so give it a default route
|
||||
# to router 2 so that routing to the RP address is not an issue
|
||||
# r1_defrt_setup_cmds = [
|
||||
# "ip route add default via 10.10.76.1 dev r1-eth0",
|
||||
# ]
|
||||
# for cmd in r1_defrt_setup_cmds:
|
||||
# tgen.net["r1"].cmd(cmd)
|
||||
|
||||
logger.info("Testing PIM AutoRP support")
|
||||
router_list = tgen.routers()
|
||||
for rname, router in router_list.items():
|
||||
logger.info("Loading router %s" % rname)
|
||||
|
@ -95,8 +98,8 @@ def teardown_module(mod):
|
|||
tgen.stop_topology()
|
||||
|
||||
|
||||
def test_pim_autorp_discovery_single_rp(request):
|
||||
"Test PIM AutoRP Discovery with single RP"
|
||||
def test_pim_autorp_init(request):
|
||||
"Test PIM AutoRP startup with only the static RP"
|
||||
tgen = get_topogen()
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
@ -104,37 +107,253 @@ def test_pim_autorp_discovery_single_rp(request):
|
|||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
step("Start with no RP configuration")
|
||||
result = verify_pim_rp_info_is_empty(tgen, "r1")
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
|
||||
step("Send AutoRP packet from r1 to r2")
|
||||
# 1 RP(s), hold time 5 secs, 10.10.76.1, group(s) 224.0.0.0/4
|
||||
data = "01005e00012800127f55cfb1080045c00030700c000008110abe0a0a4c01e000012801f001f0001c798b12010005000000000a0a4c0103010004e0000000"
|
||||
scapy_send_autorp_raw_packet(tgen, "r1", "r1-eth0", data)
|
||||
|
||||
step("Verify rp-info from AutoRP packet")
|
||||
result = verify_pim_rp_info(
|
||||
tgen,
|
||||
None,
|
||||
"r2",
|
||||
"224.0.0.0/4",
|
||||
"r2-eth0",
|
||||
"10.10.76.1",
|
||||
"AutoRP",
|
||||
False,
|
||||
"ipv4",
|
||||
True,
|
||||
step("Verify start-up with no extra RP configuration")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"10.0.3.4":[
|
||||
{
|
||||
"rpAddress":"10.0.3.4",
|
||||
"group":"224.0.1.0/24",
|
||||
"source":"Static"
|
||||
}
|
||||
]
|
||||
}"""
|
||||
)
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim rp-info json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct rp-info".format(rtr)
|
||||
|
||||
step("Verify AutoRP configuration times out")
|
||||
result = verify_pim_rp_info_is_empty(tgen, "r2")
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
step("Verify start-up with AutoRP only discovery enabled")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"discovery":{
|
||||
"enabled": true
|
||||
},
|
||||
"announce": {
|
||||
"enabled":false
|
||||
},
|
||||
"mapping-agent": {
|
||||
"enabled":false
|
||||
}
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim autorp json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct autorp configuration".format(
|
||||
rtr
|
||||
)
|
||||
|
||||
|
||||
def test_pim_autorp_discovery_multiple_rp(request):
|
||||
"Test PIM AutoRP Discovery with multiple RP's"
|
||||
def test_pim_autorp_no_mapping_agent_rp(request):
|
||||
"Test PIM AutoRP candidate with no mapping agent"
|
||||
tgen = get_topogen()
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
# Start a candidate RP on r2
|
||||
tgen.routers()["r2"].vtysh_cmd(
|
||||
"""
|
||||
conf
|
||||
router pim
|
||||
autorp announce 10.0.0.2 224.0.0.0/4
|
||||
autorp announce scope 31 interval 1 holdtime 5
|
||||
"""
|
||||
)
|
||||
|
||||
# Without a mapping agent, we should still have no RP
|
||||
step("Verify no RP without mapping agent")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"10.0.3.4":[
|
||||
{
|
||||
"rpAddress":"10.0.3.4",
|
||||
"group":"224.0.1.0/24",
|
||||
"source":"Static"
|
||||
}
|
||||
]
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim rp-info json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct rp-info".format(rtr)
|
||||
|
||||
step("Verify candidate RP in AutoRP on R2")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"discovery":{
|
||||
"enabled": true
|
||||
},
|
||||
"announce": {
|
||||
"enabled":true,
|
||||
"scope":31,
|
||||
"interval":1,
|
||||
"holdtime":5,
|
||||
"rpList":[
|
||||
{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"groupRange":"224.0.0.0/4",
|
||||
"prefixList":"-"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mapping-agent": {
|
||||
"enabled":false
|
||||
}
|
||||
}"""
|
||||
)
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp, tgen.gears["r2"], "show ip pim autorp json", expected
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct autorp configuration".format("r2")
|
||||
|
||||
|
||||
def test_pim_autorp_discovery_rp(request):
|
||||
"Test PIM AutoRP candidate advertised by mapping agent"
|
||||
tgen = get_topogen()
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
# Start the mapping agent on R1
|
||||
tgen.routers()["r1"].vtysh_cmd(
|
||||
"""
|
||||
conf
|
||||
router pim
|
||||
autorp send-rp-discovery source interface r1-eth0
|
||||
autorp send-rp-discovery scope 31 interval 1 holdtime 5
|
||||
"""
|
||||
)
|
||||
|
||||
step("Verify rp-info of the only candidate RP")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"10.0.3.4":[
|
||||
{
|
||||
"rpAddress":"10.0.3.4",
|
||||
"group":"224.0.1.0/24",
|
||||
"source":"Static"
|
||||
}
|
||||
],
|
||||
"10.0.0.2":[
|
||||
{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"group":"224.0.0.0/4",
|
||||
"source":"AutoRP"
|
||||
}
|
||||
]
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim rp-info json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct rp-info".format(rtr)
|
||||
|
||||
step("Verify mapping-agent in AutoRP on R1")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"announce": {
|
||||
"enabled":false
|
||||
},
|
||||
"mapping-agent": {
|
||||
"enabled":true,
|
||||
"active":true,
|
||||
"scope":31,
|
||||
"interval":1,
|
||||
"holdtime":5,
|
||||
"source":"interface",
|
||||
"interface":"r1-eth0",
|
||||
"address":"10.0.0.1",
|
||||
"rpList":{
|
||||
"10.0.0.2":{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"groupRanges":[
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"224.0.0.0/4"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
)
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp, tgen.gears["r1"], "show ip pim autorp json", expected
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct autorp configuration".format("r1")
|
||||
|
||||
step("Verify AutoRP discovery RP's")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"discovery":{
|
||||
"enabled": true,
|
||||
"rpList":{
|
||||
"10.0.0.2":{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"holdtime":5,
|
||||
"groupRanges":[
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"224.0.0.0/4"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim autorp json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct autorp configuration".format(
|
||||
rtr
|
||||
)
|
||||
|
||||
|
||||
def test_pim_autorp_discovery_multiple_rp_same(request):
|
||||
"Test PIM AutoRP Discovery with multiple RP's for same group prefix"
|
||||
tgen = get_topogen()
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
@ -142,42 +361,309 @@ def test_pim_autorp_discovery_multiple_rp(request):
|
|||
if tgen.routers_have_failure():
|
||||
pytest.skip("skipped because of router(s) failure")
|
||||
|
||||
step("Start with no RP configuration")
|
||||
result = verify_pim_rp_info_is_empty(tgen, "r2")
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
|
||||
step("Send AutoRP packet from r1 to r2")
|
||||
# 2 RP(s), hold time 5 secs, 10.10.76.1, group(s) 224.0.0.0/8, 10.10.76.3, group(s) 225.0.0.0/8
|
||||
data = "01005e00012800127f55cfb1080045c0003c700c000008110ab20a0a4c01e000012801f001f000283f5712020005000000000a0a4c0103010008e00000000a0a4c0303010008e1000000"
|
||||
scapy_send_autorp_raw_packet(tgen, "r1", "r1-eth0", data)
|
||||
|
||||
step("Verify rp-info from AutoRP packet")
|
||||
result = verify_pim_rp_info(
|
||||
tgen,
|
||||
None,
|
||||
"r2",
|
||||
"224.0.0.0/8",
|
||||
"r2-eth0",
|
||||
"10.10.76.1",
|
||||
"AutoRP",
|
||||
False,
|
||||
"ipv4",
|
||||
True,
|
||||
# Start a candidate RP on r3
|
||||
tgen.routers()["r3"].vtysh_cmd(
|
||||
"""
|
||||
conf
|
||||
router pim
|
||||
autorp announce 10.0.1.3 224.0.0.0/4
|
||||
autorp announce scope 31 interval 1 holdtime 5
|
||||
"""
|
||||
)
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
result = verify_pim_rp_info(
|
||||
tgen,
|
||||
None,
|
||||
"r2",
|
||||
"225.0.0.0/8",
|
||||
"r2-eth0",
|
||||
"10.10.76.3",
|
||||
"AutoRP",
|
||||
False,
|
||||
"ipv4",
|
||||
True,
|
||||
|
||||
# The new candidate RP has the same group range but a higher IP, they should all
|
||||
# switch to this RP
|
||||
step("Verify rp-info of the candidate RP with the higher IP")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"10.0.3.4":[
|
||||
{
|
||||
"rpAddress":"10.0.3.4",
|
||||
"group":"224.0.1.0/24",
|
||||
"source":"Static"
|
||||
}
|
||||
],
|
||||
"10.0.1.3":[
|
||||
{
|
||||
"rpAddress":"10.0.1.3",
|
||||
"group":"224.0.0.0/4",
|
||||
"source":"AutoRP"
|
||||
}
|
||||
]
|
||||
}"""
|
||||
)
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim rp-info json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct rp-info".format(rtr)
|
||||
|
||||
step("Verify AutoRP discovery RP's")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"discovery":{
|
||||
"enabled": true,
|
||||
"rpList":{
|
||||
"10.0.0.2":{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"holdtime":5,
|
||||
"groupRanges":[
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"224.0.0.0/4"
|
||||
}
|
||||
]
|
||||
},
|
||||
"10.0.1.3":{
|
||||
"rpAddress":"10.0.1.3",
|
||||
"holdtime":5,
|
||||
"groupRanges":[
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"224.0.0.0/4"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim autorp json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct autorp configuration".format(
|
||||
rtr
|
||||
)
|
||||
|
||||
|
||||
def test_pim_autorp_discovery_multiple_rp_different(request):
|
||||
"Test PIM AutoRP Discovery with multiple RP's for different group prefixes"
|
||||
tgen = get_topogen()
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip("skipped because of router(s) failure")
|
||||
|
||||
# Switch R3 candidate to prefix list with different groups
|
||||
step("Change R3 candidate to a prefix list")
|
||||
tgen.routers()["r3"].vtysh_cmd(
|
||||
"""
|
||||
conf
|
||||
ip prefix-list MYLIST permit 225.0.0.0/8
|
||||
ip prefix-list MYLIST permit 226.0.0.0/8
|
||||
router pim
|
||||
autorp announce 10.0.1.3 group-list MYLIST
|
||||
"""
|
||||
)
|
||||
|
||||
# Now that R3 doesn't conflict, we should see both RP's
|
||||
step("Verify rp-info of both candidate RP's")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"10.0.3.4":[
|
||||
{
|
||||
"rpAddress":"10.0.3.4",
|
||||
"group":"224.0.1.0/24",
|
||||
"source":"Static"
|
||||
}
|
||||
],
|
||||
"10.0.0.2":[
|
||||
{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"group":"224.0.0.0/4",
|
||||
"source":"AutoRP"
|
||||
}
|
||||
],
|
||||
"10.0.1.3":[
|
||||
{
|
||||
"rpAddress":"10.0.1.3",
|
||||
"prefixList":"__AUTORP_10.0.1.3__",
|
||||
"source":"AutoRP"
|
||||
}
|
||||
]
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim rp-info json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct rp-info".format(rtr)
|
||||
|
||||
step("Verify AutoRP discovery RP's")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"discovery":{
|
||||
"enabled": true,
|
||||
"rpList":{
|
||||
"10.0.0.2":{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"holdtime":5,
|
||||
"groupRanges":[
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"224.0.0.0/4"
|
||||
}
|
||||
]
|
||||
},
|
||||
"10.0.1.3":{
|
||||
"rpAddress":"10.0.1.3",
|
||||
"holdtime":5,
|
||||
"groupRanges":[
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"225.0.0.0/8"
|
||||
},
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"226.0.0.0/8"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim autorp json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct autorp configuration".format(
|
||||
rtr
|
||||
)
|
||||
|
||||
|
||||
def test_pim_autorp_discovery_neg_prefixes(request):
|
||||
"Test PIM AutoRP Discovery with negative prefixes"
|
||||
tgen = get_topogen()
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip("skipped because of router(s) failure")
|
||||
|
||||
# Add negative prefixes to the R3 candidate prefix list
|
||||
step("Change R3 candidate prefix list to include overlapping negative prefixes")
|
||||
tgen.routers()["r3"].vtysh_cmd(
|
||||
"""
|
||||
conf
|
||||
ip prefix-list MYLIST deny 225.1.0.0/16
|
||||
ip prefix-list MYLIST deny 226.1.0.0/16
|
||||
"""
|
||||
)
|
||||
|
||||
step("Verify rp-info stays the same")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"10.0.3.4":[
|
||||
{
|
||||
"rpAddress":"10.0.3.4",
|
||||
"group":"224.0.1.0/24",
|
||||
"source":"Static"
|
||||
}
|
||||
],
|
||||
"10.0.0.2":[
|
||||
{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"group":"224.0.0.0/4",
|
||||
"source":"AutoRP"
|
||||
}
|
||||
],
|
||||
"10.0.1.3":[
|
||||
{
|
||||
"rpAddress":"10.0.1.3",
|
||||
"prefixList":"__AUTORP_10.0.1.3__",
|
||||
"source":"AutoRP"
|
||||
}
|
||||
]
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim rp-info json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct rp-info".format(rtr)
|
||||
|
||||
step("Verify AutoRP discovery RP's")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"discovery":{
|
||||
"enabled": true,
|
||||
"rpList":{
|
||||
"10.0.0.2":{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"holdtime":5,
|
||||
"groupRanges":[
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"224.0.0.0/4"
|
||||
}
|
||||
]
|
||||
},
|
||||
"10.0.1.3":{
|
||||
"rpAddress":"10.0.1.3",
|
||||
"holdtime":5,
|
||||
"groupRanges":[
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"225.0.0.0/8"
|
||||
},
|
||||
{
|
||||
"negative":false,
|
||||
"prefix":"226.0.0.0/8"
|
||||
},
|
||||
{
|
||||
"negative":true,
|
||||
"prefix":"225.1.0.0/16"
|
||||
},
|
||||
{
|
||||
"negative":true,
|
||||
"prefix":"226.1.0.0/16"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
)
|
||||
for rtr in ["r1", "r2", "r3", "r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim autorp json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct autorp configuration".format(
|
||||
rtr
|
||||
)
|
||||
|
||||
|
||||
def test_pim_autorp_discovery_static(request):
|
||||
|
@ -189,142 +675,60 @@ def test_pim_autorp_discovery_static(request):
|
|||
if tgen.routers_have_failure():
|
||||
pytest.skip("skipped because of router(s) failure")
|
||||
|
||||
step("Start with no RP configuration")
|
||||
result = verify_pim_rp_info_is_empty(tgen, "r2")
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
|
||||
step("Add static RP configuration to r2")
|
||||
rnode = tgen.routers()["r2"]
|
||||
rnode.cmd("vtysh -c 'conf t' -c 'router pim' -c 'rp 10.10.76.3 224.0.0.0/4'")
|
||||
|
||||
step("Verify static rp-info from r2")
|
||||
result = verify_pim_rp_info(
|
||||
tgen,
|
||||
None,
|
||||
"r2",
|
||||
"224.0.0.0/4",
|
||||
"r2-eth0",
|
||||
"10.10.76.3",
|
||||
"Static",
|
||||
False,
|
||||
"ipv4",
|
||||
True,
|
||||
)
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
|
||||
step("Send AutoRP packet from r1 to r2")
|
||||
# 1 RP(s), hold time 5 secs, 10.10.76.1, group(s) 224.0.0.0/4
|
||||
data = "01005e00012800127f55cfb1080045c00030700c000008110abe0a0a4c01e000012801f001f0001c798b12010005000000000a0a4c0103010004e0000000"
|
||||
scapy_send_autorp_raw_packet(tgen, "r1", "r1-eth0", data)
|
||||
|
||||
step("Verify rp-info from AutoRP packet")
|
||||
result = verify_pim_rp_info(
|
||||
tgen,
|
||||
None,
|
||||
"r2",
|
||||
"224.0.0.0/4",
|
||||
"r2-eth0",
|
||||
"10.10.76.1",
|
||||
"AutoRP",
|
||||
False,
|
||||
"ipv4",
|
||||
True,
|
||||
)
|
||||
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
|
||||
|
||||
|
||||
def test_pim_autorp_announce_cli(request):
|
||||
"Test PIM AutoRP Announcement CLI commands"
|
||||
tgen = get_topogen()
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip("skipped because of router(s) failure")
|
||||
|
||||
step("Add AutoRP announcement configuration to r1")
|
||||
r1 = tgen.routers()["r1"]
|
||||
r1.vtysh_cmd(
|
||||
# Add in a static RP with a specific range and make sure both are used
|
||||
step("Add static RP configuration to r4")
|
||||
tgen.routers()["r4"].vtysh_cmd(
|
||||
"""
|
||||
conf
|
||||
conf t
|
||||
router pim
|
||||
autorp announce holdtime 90
|
||||
autorp announce interval 120
|
||||
autorp announce scope 5
|
||||
autorp announce 10.2.3.4 225.0.0.0/24
|
||||
"""
|
||||
)
|
||||
|
||||
expected = {
|
||||
"discoveryEnabled": True,
|
||||
"announce": {
|
||||
"scope": 5,
|
||||
"interval": 120,
|
||||
"holdtime": 90,
|
||||
"rpList": [
|
||||
{"rpAddress": "10.2.3.4", "group": "225.0.0.0/24", "prefixList": ""}
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp, r1, "show ip pim autorp json", expected
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = '"{}" JSON output mismatches'.format(r1.name)
|
||||
assert result is None, assertmsg
|
||||
|
||||
r1.vtysh_cmd(
|
||||
rp 10.0.2.2 239.0.0.0/24
|
||||
"""
|
||||
conf
|
||||
router pim
|
||||
autorp announce 10.2.3.4 group-list ListA
|
||||
"""
|
||||
)
|
||||
expected = {
|
||||
"discoveryEnabled": True,
|
||||
"announce": {
|
||||
"scope": 5,
|
||||
"interval": 120,
|
||||
"holdtime": 90,
|
||||
"rpList": [{"rpAddress": "10.2.3.4", "group": "", "prefixList": "ListA"}],
|
||||
},
|
||||
}
|
||||
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp, r1, "show ip pim autorp json", expected
|
||||
step("Verify static rp-info from r4")
|
||||
expected = json.loads(
|
||||
"""
|
||||
{
|
||||
"10.0.3.4":[
|
||||
{
|
||||
"rpAddress":"10.0.3.4",
|
||||
"group":"224.0.1.0/24",
|
||||
"source":"Static"
|
||||
}
|
||||
],
|
||||
"10.0.0.2":[
|
||||
{
|
||||
"rpAddress":"10.0.0.2",
|
||||
"group":"224.0.0.0/4",
|
||||
"source":"AutoRP"
|
||||
}
|
||||
],
|
||||
"10.0.1.3":[
|
||||
{
|
||||
"rpAddress":"10.0.1.3",
|
||||
"prefixList":"__AUTORP_10.0.1.3__",
|
||||
"source":"AutoRP"
|
||||
}
|
||||
],
|
||||
"10.0.2.2":[
|
||||
{
|
||||
"rpAddress":"10.0.2.2",
|
||||
"group":"239.0.0.0/24",
|
||||
"source":"Static"
|
||||
}
|
||||
]
|
||||
}"""
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = '"{}" JSON output mismatches'.format(r1.name)
|
||||
assert result is None, assertmsg
|
||||
|
||||
|
||||
def test_pim_autorp_announce_group(request):
|
||||
"Test PIM AutoRP Announcement with a single group"
|
||||
tgen = get_topogen()
|
||||
tc_name = request.node.name
|
||||
write_test_header(tc_name)
|
||||
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip("skipped because of router(s) failure")
|
||||
|
||||
step("Add candidate RP configuration to r1")
|
||||
rnode = tgen.routers()["r1"]
|
||||
rnode.cmd(
|
||||
"vtysh -c 'conf t' -c 'router pim' -c 'send-rp-announce 10.10.76.1 224.0.0.0/4'"
|
||||
)
|
||||
step("Verify Announcement sent data")
|
||||
# TODO: Verify AutoRP mapping agent receives candidate RP announcement
|
||||
# Mapping agent is not yet implemented
|
||||
# sleep(10)
|
||||
step("Change AutoRP Announcement packet parameters")
|
||||
rnode.cmd(
|
||||
"vtysh -c 'conf t' -c 'router pim' -c 'send-rp-announce scope 8 interval 10 holdtime 60'"
|
||||
)
|
||||
step("Verify Announcement sent data")
|
||||
# TODO: Verify AutoRP mapping agent receives updated candidate RP announcement
|
||||
# Mapping agent is not yet implemented
|
||||
# sleep(10)
|
||||
for rtr in ["r4"]:
|
||||
test_func = partial(
|
||||
topotest.router_json_cmp,
|
||||
tgen.gears[rtr],
|
||||
"show ip pim rp-info json",
|
||||
expected,
|
||||
)
|
||||
_, result = topotest.run_and_expect(test_func, None)
|
||||
assert result is None, "{} does not have correct rp-info".format(rtr)
|
||||
|
||||
|
||||
def test_memory_leak():
|
||||
|
|
|
@ -21,6 +21,10 @@ module frr-pim-rp {
|
|||
prefix frr-route-types;
|
||||
}
|
||||
|
||||
import frr-interface {
|
||||
prefix "frr-interface";
|
||||
}
|
||||
|
||||
organization
|
||||
"FRRouting";
|
||||
|
||||
|
@ -178,7 +182,7 @@ module frr-pim-rp {
|
|||
leaf announce-interval {
|
||||
type uint16;
|
||||
description
|
||||
"The time between sending C-RP announcement packets.";
|
||||
"The time between sending C-RP announcement packets (seconds).";
|
||||
}
|
||||
|
||||
leaf announce-holdtime {
|
||||
|
@ -216,6 +220,57 @@ module frr-pim-rp {
|
|||
}
|
||||
}
|
||||
} // candidate-rp-list
|
||||
|
||||
container mapping-agent {
|
||||
leaf send-rp-discovery {
|
||||
type boolean;
|
||||
default false;
|
||||
description
|
||||
"Make this router an AutoRP mapping agent";
|
||||
}
|
||||
|
||||
leaf discovery-scope {
|
||||
type uint8;
|
||||
default 31;
|
||||
description
|
||||
"The TTL of the discovery packet";
|
||||
}
|
||||
|
||||
leaf discovery-interval {
|
||||
type uint16 {
|
||||
range "1 .. 65535";
|
||||
}
|
||||
default 60;
|
||||
description
|
||||
"The time between sending discovery advertisements (seconds)";
|
||||
}
|
||||
|
||||
leaf discovery-holdtime {
|
||||
type uint16 {
|
||||
range "0 .. 65535";
|
||||
}
|
||||
default 180;
|
||||
description
|
||||
"The hold time in seconds advertised in the discovery packet.";
|
||||
}
|
||||
|
||||
choice source-address-or-interface {
|
||||
description "Source address to use for mapping agent operation";
|
||||
default if-loopback;
|
||||
leaf address {
|
||||
type inet:ip-address;
|
||||
}
|
||||
leaf interface {
|
||||
type frr-interface:interface-ref;
|
||||
}
|
||||
leaf if-loopback {
|
||||
type empty;
|
||||
}
|
||||
leaf if-any {
|
||||
type empty;
|
||||
}
|
||||
}
|
||||
} // mapping-agent
|
||||
} // auto-rp
|
||||
} // auto-rp-container
|
||||
|
||||
|
|
Loading…
Reference in a new issue