Skip to content

Commit

Permalink
Merge pull request #17340 from nabahr/mapping-agent
Browse files Browse the repository at this point in the history
PIMD: Implement AutoRP mapping-agent
  • Loading branch information
rzalamena authored Nov 21, 2024
2 parents 0af5c2a + 13c0722 commit a3e04a8
Show file tree
Hide file tree
Showing 18 changed files with 2,488 additions and 860 deletions.
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)}",
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 @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit a3e04a8

Please sign in to comment.