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: MSDP peer MD5 authentication #12459

Merged
merged 5 commits into from
Jul 30, 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
18 changes: 18 additions & 0 deletions doc/user/pim.rst
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,17 @@ Commands available for MSDP:
The filtering will only take effect starting from the command
application.

.. clicmd:: msdp peer A.B.C.D password WORD

Use MD5 authentication to connect with the remote peer.

.. note::

The authentication will only take effect when starting a new
connection.

To apply it immediately call `clear ip msdp peer A.B.C.D`.


.. _show-pim-information:

Expand Down Expand Up @@ -715,6 +726,13 @@ Clear commands reset various variables.
removes the next hop tracking for the bsr and resets the upstreams
for the dynamically learnt RPs.

.. clicmd:: clear ip msdp peer A.B.C.D

Reset MSDP peer connection.

Use this command to set/unset MD5 authentication.


PIM EVPN configuration
======================
To use PIM in the underlay for overlay BUM forwarding associate a multicast
Expand Down
10 changes: 10 additions & 0 deletions lib/sockopt.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ extern int setsockopt_ipv6_tclass(int, int);
(((af) == AF_INET) : SOPT_SIZE_CMSG_IFINDEX_IPV4() \
? SOPT_SIZE_CMSG_PKTINFO_IPV6())

/*
* If not defined then define the value for `TCP_MD5SIG_MAXKEYLEN`. This seems
* to be unavailable for NetBSD 8, FreeBSD 11 and FreeBSD 12.
*
* The value below was copied from `linux/tcp.h` from the Linux kernel headers.
*/
#ifndef TCP_MD5SIG_MAXKEYLEN
#define TCP_MD5SIG_MAXKEYLEN 80
#endif

extern int setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr,
ifindex_t ifindex);
extern int setsockopt_ipv4_multicast(int sock, int optname,
Expand Down
87 changes: 87 additions & 0 deletions pimd/pim_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2823,6 +2823,39 @@ DEFPY (clear_ip_mroute_count,
return clear_ip_mroute_count_command(vty, name);
}

DEFPY(clear_ip_msdp_peer, clear_ip_msdp_peer_cmd,
"clear ip msdp peer A.B.C.D$peer [vrf WORD$vrfname]",
CLEAR_STR
IP_STR
MSDP_STR
"Restart MSDP peer\n"
"MSDP peer address\n"
VRF_CMD_HELP_STR)
{
const struct pim_instance *pim;
const struct listnode *node;
const struct vrf *vrf;
struct pim_msdp_peer *mp;

if (vrfname) {
vrf = vrf_lookup_by_name(vrfname);
if (vrf == NULL)
return CMD_WARNING;
} else
vrf = vrf_lookup_by_id(VRF_DEFAULT);

pim = vrf->info;
for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, mp)) {
if (mp->peer.s_addr != peer.s_addr)
continue;

pim_msdp_peer_restart(mp);
break;
}

return CMD_SUCCESS;
}

DEFPY (show_ip_mroute_count,
show_ip_mroute_count_cmd,
"show ip mroute [vrf NAME] count [json$json]",
Expand Down Expand Up @@ -6285,6 +6318,57 @@ DEFPY_ATTR(ip_pim_msdp_peer,
return ret;
}

DEFPY(msdp_peer_md5, msdp_peer_md5_cmd,
"msdp peer A.B.C.D$peer password WORD$psk",
CFG_MSDP_STR
"Configure MSDP peer\n"
"MSDP Peer address\n"
"Use MD5 authentication\n"
"MD5 pre shared key\n")
{
const struct lyd_node *peer_node;
char xpath[XPATH_MAXLEN + 24];

snprintf(xpath, sizeof(xpath), "%s/msdp-peer[peer-ip='%s']",
VTY_CURR_XPATH, peer_str);
peer_node = yang_dnode_get(vty->candidate_config->dnode, xpath);
if (peer_node == NULL) {
vty_out(vty, "%% MSDP peer %s not yet configured\n", peer_str);
return CMD_SUCCESS;
}

nb_cli_enqueue_change(vty, "./authentication-type", NB_OP_MODIFY, "MD5");
nb_cli_enqueue_change(vty, "./authentication-key", NB_OP_MODIFY, psk);

return nb_cli_apply_changes(vty, "%s", xpath);
}

DEFPY(no_msdp_peer_md5, no_msdp_peer_md5_cmd,
"no msdp peer A.B.C.D$peer password [WORD]",
NO_STR
CFG_MSDP_STR
"Configure MSDP peer\n"
"MSDP Peer address\n"
"Use MD5 authentication\n"
"MD5 pre shared key\n")
{
const struct lyd_node *peer_node;
char xpath[XPATH_MAXLEN + 24];

snprintf(xpath, sizeof(xpath), "%s/msdp-peer[peer-ip='%s']",
VTY_CURR_XPATH, peer_str);
peer_node = yang_dnode_get(vty->candidate_config->dnode, xpath);
if (peer_node == NULL) {
vty_out(vty, "%% MSDP peer %s not yet configured\n", peer_str);
return CMD_SUCCESS;
}

nb_cli_enqueue_change(vty, "./authentication-type", NB_OP_MODIFY,
"None");

return nb_cli_apply_changes(vty, "%s", xpath);
}

DEFPY(pim_msdp_timers, pim_msdp_timers_cmd,
"msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
CFG_MSDP_STR
Expand Down Expand Up @@ -8320,6 +8404,8 @@ void pim_cmd_init(void)

install_element(PIM_NODE, &pim_msdp_peer_cmd);
install_element(PIM_NODE, &no_pim_msdp_peer_cmd);
install_element(PIM_NODE, &msdp_peer_md5_cmd);
install_element(PIM_NODE, &no_msdp_peer_md5_cmd);
install_element(PIM_NODE, &pim_msdp_timers_cmd);
install_element(PIM_NODE, &no_pim_msdp_timers_cmd);
install_element(PIM_NODE, &msdp_peer_sa_filter_cmd);
Expand Down Expand Up @@ -8462,6 +8548,7 @@ void pim_cmd_init(void)
install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);

install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
install_element(ENABLE_NODE, &clear_ip_msdp_peer_cmd);
install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
Expand Down
1 change: 1 addition & 0 deletions pimd/pim_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ DEFINE_MTYPE(PIMD, PIM_RP, "PIM RP info");
DEFINE_MTYPE(PIMD, PIM_FILTER_NAME, "PIM RP filter info");
DEFINE_MTYPE(PIMD, PIM_MSDP_PEER, "PIM MSDP peer");
DEFINE_MTYPE(PIMD, PIM_MSDP_MG_NAME, "PIM MSDP mesh-group name");
DEFINE_MTYPE(PIMD, PIM_MSDP_AUTH_KEY, "PIM MSDP authentication key");
DEFINE_MTYPE(PIMD, PIM_MSDP_SA, "PIM MSDP source-active cache");
DEFINE_MTYPE(PIMD, PIM_MSDP_MG, "PIM MSDP mesh group");
DEFINE_MTYPE(PIMD, PIM_MSDP_MG_MBR, "PIM MSDP mesh group mbr");
Expand Down
1 change: 1 addition & 0 deletions pimd/pim_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ DECLARE_MTYPE(PIM_MSDP_MG_NAME);
DECLARE_MTYPE(PIM_MSDP_SA);
DECLARE_MTYPE(PIM_MSDP_MG);
DECLARE_MTYPE(PIM_MSDP_MG_MBR);
DECLARE_MTYPE(PIM_MSDP_AUTH_KEY);
DECLARE_MTYPE(PIM_SEC_ADDR);
DECLARE_MTYPE(PIM_JP_AGG_GROUP);
DECLARE_MTYPE(PIM_JP_AGG_SOURCE);
Expand Down
37 changes: 32 additions & 5 deletions pimd/pim_msdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,10 @@ static void pim_msdp_peer_listen(struct pim_msdp_peer *mp)
* first listening peer is configured; but don't bother tearing it down
* when
* all the peers go down */
pim_msdp_sock_listen(mp->pim);
if (mp->auth_type == MSDP_AUTH_NONE)
pim_msdp_sock_listen(mp->pim);
else
pim_msdp_sock_auth_listen(mp);
}

/* 11.2.A4 and 11.2.A5: transition active or passive peer to
Expand Down Expand Up @@ -1045,6 +1048,7 @@ struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim,

mp->state = PIM_MSDP_INACTIVE;
mp->fd = -1;
mp->auth_listen_sock = -1;
strlcpy(mp->last_reset, "-", sizeof(mp->last_reset));
/* higher IP address is listener */
if (ntohl(mp->local.s_addr) > ntohl(mp->peer.s_addr)) {
Expand Down Expand Up @@ -1100,6 +1104,12 @@ static void pim_msdp_peer_free(struct pim_msdp_peer *mp)
stream_fifo_free(mp->obuf);
}

/* Free authentication data. */
event_cancel(&mp->auth_listen_ev);
XFREE(MTYPE_PIM_MSDP_AUTH_KEY, mp->auth_key);
if (mp->auth_listen_sock != -1)
close(mp->auth_listen_sock);

XFREE(MTYPE_PIM_MSDP_MG_NAME, mp->mesh_group_name);

mp->pim = NULL;
Expand Down Expand Up @@ -1128,19 +1138,32 @@ void pim_msdp_peer_del(struct pim_msdp_peer **mp)
*mp = NULL;
}

void pim_msdp_peer_change_source(struct pim_msdp_peer *mp,
const struct in_addr *addr)
void pim_msdp_peer_restart(struct pim_msdp_peer *mp)
{
pim_msdp_peer_stop_tcp_conn(mp, true);
/* Stop auth listening socket if any. */
event_cancel(&mp->auth_listen_ev);
if (mp->auth_listen_sock != -1) {
close(mp->auth_listen_sock);
mp->auth_listen_sock = -1;
}

mp->local = *addr;
/* Stop previously running connection. */
pim_msdp_peer_stop_tcp_conn(mp, true);

/* Start connection again. */
if (PIM_MSDP_PEER_IS_LISTENER(mp))
pim_msdp_peer_listen(mp);
else
pim_msdp_peer_connect(mp);
}

void pim_msdp_peer_change_source(struct pim_msdp_peer *mp,
const struct in_addr *addr)
{
mp->local = *addr;
pim_msdp_peer_restart(mp);
}

/* peer hash and peer list helpers */
static unsigned int pim_msdp_peer_hash_key_make(const void *p)
{
Expand Down Expand Up @@ -1318,6 +1341,10 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim)
vty_out(vty, " msdp peer %pI4 source %pI4\n", &mp->peer,
&mp->local);

if (mp->auth_type == MSDP_AUTH_MD5)
vty_out(vty, " msdp peer %pI4 password %s\n", &mp->peer,
mp->auth_key);

if (mp->acl_in)
vty_out(vty, " msdp peer %pI4 sa-filter %s in\n",
&mp->peer, mp->acl_in);
Expand Down
21 changes: 21 additions & 0 deletions pimd/pim_msdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ enum pim_msdp_peer_flags {
PIM_MSDP_PEERF_IN_GROUP = (1 << 2),
};

enum msdp_auth_type {
MSDP_AUTH_NONE = 0,
MSDP_AUTH_MD5 = 1,
};

struct pim_msdp_peer {
struct pim_instance *pim;

Expand All @@ -98,6 +103,13 @@ struct pim_msdp_peer {
char *mesh_group_name;
char key_str[INET_ADDRSTRLEN];

/* Authentication data. */
enum msdp_auth_type auth_type;
char *auth_key;

int auth_listen_sock;
struct event *auth_listen_ev;

/* state */
enum pim_msdp_peer_state state;
enum pim_msdp_peer_flags flags;
Expand Down Expand Up @@ -309,6 +321,15 @@ void pim_msdp_peer_del(struct pim_msdp_peer **mp);
void pim_msdp_peer_change_source(struct pim_msdp_peer *mp,
const struct in_addr *addr);

/**
* Restart peer's connection.
*
* This is used internally in MSDP and should be used by northbound
* when wanting to immediately apply connections settings such as
* authentication.
*/
void pim_msdp_peer_restart(struct pim_msdp_peer *mp);

#else /* PIM_IPV == 6 */
static inline void pim_msdp_init(struct pim_instance *pim,
struct event_loop *master)
Expand Down
Loading
Loading