Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIMD: Implement AutoRP mapping-agent #17340

Merged
merged 4 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,559 changes: 1,165 additions & 394 deletions pimd/pim_autorp.c

Large diffs are not rendered by default.

75 changes: 49 additions & 26 deletions pimd/pim_autorp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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;
Expand All @@ -111,48 +129,53 @@ 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;
uint16_t announce_interval;
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;

/* TODO: Packet parameters for sending discovery packets
* int discovery_scope;
* int discovery_interval;
* int discovery_holdtime;
*/
uint8_t *announce_pkt;
uint16_t announce_pkt_sz;

/* 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);
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
4 changes: 2 additions & 2 deletions pimd/pim_bsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion pimd/pim_bsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
114 changes: 68 additions & 46 deletions pimd/pim_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
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;
}
struct vrf *v;

if (json)
json_parent = json_object_new_object();

pim_autorp_show_autorp(vty, v->info, json_parent);

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 (vrf && strmatch(vrf, "all")) {
json_object *json_vrf = NULL;

if (json)
json_parent = json_object_new_object();
RB_FOREACH (v, vrf_name_head, &vrfs_by_name) {
if (!v || !v->info)
continue;

RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
if (vrf->info) {
if (!json)
vty_out(vty, "VRF: %s\n", vrf->name);
else
if (json)
json_vrf = json_object_new_object();
else
vty_out(vty, "VRF: %s\n", v->name);

pim_autorp_show_autorp(vty, vrf->info, json_vrf);
pim_autorp_show_autorp(vty, v->info, component, json_vrf);

if (json)
json_object_object_add(json_parent, vrf->name,
json_vrf);
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)
Expand Down Expand Up @@ -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)}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional? Now the no command must receive arguments to be executed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configuring AutoRP announcements (i.e. candidate RP's) was broken up in two commands:

[no] autorp announce RPADDR ![GROUP_PREFIX | group-list PREFIX_LIST] 
[no] autorp announce {scope (1-255) | interval (1-65535) | holdtime (0-65535)}

I found it confusing to allow the command no autorp announce which, as it was previously, would only reset the scope, interval, and holdtime back to defaults instead of disabling announcements altogether.
I could update that command to disable announcements completely, but I've also got work in progress that fixes the AutoRP candidate RP configuration to be consistent with how the BSR candidate RP is configured which would make this OBE.

AutoRP candidate RP announcements can still be disabled by individually disabling the configured candidate RPs.

NO_STR
"AutoRP\n"
"AutoRP Candidate RP announcement\n"
Expand All @@ -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>}]",
Expand Down Expand Up @@ -8855,6 +8876,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);
Expand Down Expand Up @@ -9010,7 +9033,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);
Expand Down
Loading
Loading