mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 21:47:15 +02:00
nhrp: add cisco-authentication
password support
Implemented: - handling 8 char long password, aka Cisco style. - minimal error inidication routine - test case, password change affects conection Signed-off-by: Volodymyr Huti <v.huti@vyos.io>
This commit is contained in:
parent
d5b0c76edd
commit
51f0700286
|
@ -84,6 +84,12 @@ Configuring NHRP
|
||||||
registration requests are sent. By default registrations are sent every one
|
registration requests are sent. By default registrations are sent every one
|
||||||
third of the holdtime.
|
third of the holdtime.
|
||||||
|
|
||||||
|
.. clicmd:: ip nhrp authentication PASSWORD
|
||||||
|
|
||||||
|
Enables Cisco style authentication on NHRP packets. This embeds the
|
||||||
|
plaintext password to the outgoing NHRP packets.
|
||||||
|
Maximum length of the is 8 characters.
|
||||||
|
|
||||||
.. clicmd:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local
|
.. clicmd:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local
|
||||||
|
|
||||||
Map an IP address of a station to the station's NBMA address.
|
Map an IP address of a station to the station's NBMA address.
|
||||||
|
|
|
@ -216,7 +216,7 @@ static void nhrp_reg_send_req(struct event *t)
|
||||||
cie->holding_time = htons(if_ad->holdtime);
|
cie->holding_time = htons(if_ad->holdtime);
|
||||||
cie->mtu = htons(if_ad->mtu);
|
cie->mtu = htons(if_ad->mtu);
|
||||||
|
|
||||||
nhrp_ext_request(zb, hdr, ifp);
|
nhrp_ext_request(zb, hdr);
|
||||||
|
|
||||||
/* Cisco NAT detection extension */
|
/* Cisco NAT detection extension */
|
||||||
if (sockunion_family(&r->proto_addr) != AF_UNSPEC) {
|
if (sockunion_family(&r->proto_addr) != AF_UNSPEC) {
|
||||||
|
@ -240,7 +240,7 @@ static void nhrp_reg_send_req(struct event *t)
|
||||||
cie->mtu = htons(if_ad->mtu);
|
cie->mtu = htons(if_ad->mtu);
|
||||||
nhrp_ext_complete(zb, ext);
|
nhrp_ext_complete(zb, ext);
|
||||||
|
|
||||||
nhrp_packet_complete(zb, hdr);
|
nhrp_packet_complete(zb, hdr, ifp);
|
||||||
nhrp_peer_send(r->peer, zb);
|
nhrp_peer_send(r->peer, zb);
|
||||||
zbuf_free(zb);
|
zbuf_free(zb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,14 +115,32 @@ uint16_t nhrp_packet_calculate_checksum(const uint8_t *pdu, uint16_t len)
|
||||||
return (~csum) & 0xffff;
|
return (~csum) & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nhrp_packet_complete(struct zbuf *zb, struct nhrp_packet_header *hdr)
|
void nhrp_packet_complete(struct zbuf *zb, struct nhrp_packet_header *hdr,
|
||||||
|
struct interface *ifp)
|
||||||
{
|
{
|
||||||
|
nhrp_packet_complete_auth(zb, hdr, ifp, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nhrp_packet_complete_auth(struct zbuf *zb, struct nhrp_packet_header *hdr,
|
||||||
|
struct interface *ifp, bool auth)
|
||||||
|
{
|
||||||
|
struct nhrp_interface *nifp = ifp->info;
|
||||||
|
struct zbuf *auth_token = nifp->auth_token;
|
||||||
|
struct nhrp_extension_header *dst;
|
||||||
unsigned short size;
|
unsigned short size;
|
||||||
|
|
||||||
|
if (auth && auth_token) {
|
||||||
|
dst = nhrp_ext_push(zb, hdr,
|
||||||
|
NHRP_EXTENSION_AUTHENTICATION |
|
||||||
|
NHRP_EXTENSION_FLAG_COMPULSORY);
|
||||||
|
zbuf_copy_peek(zb, auth_token, zbuf_size(auth_token));
|
||||||
|
nhrp_ext_complete(zb, dst);
|
||||||
|
}
|
||||||
|
|
||||||
if (hdr->extension_offset)
|
if (hdr->extension_offset)
|
||||||
nhrp_ext_push(zb, hdr,
|
nhrp_ext_push(zb, hdr,
|
||||||
NHRP_EXTENSION_END
|
NHRP_EXTENSION_END |
|
||||||
| NHRP_EXTENSION_FLAG_COMPULSORY);
|
NHRP_EXTENSION_FLAG_COMPULSORY);
|
||||||
|
|
||||||
size = zb->tail - (uint8_t *)hdr;
|
size = zb->tail - (uint8_t *)hdr;
|
||||||
hdr->packet_size = htons(size);
|
hdr->packet_size = htons(size);
|
||||||
|
@ -225,8 +243,7 @@ struct nhrp_extension_header *nhrp_ext_pull(struct zbuf *zb,
|
||||||
return ext;
|
return ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nhrp_ext_request(struct zbuf *zb, struct nhrp_packet_header *hdr,
|
void nhrp_ext_request(struct zbuf *zb, struct nhrp_packet_header *hdr)
|
||||||
struct interface *ifp)
|
|
||||||
{
|
{
|
||||||
/* Place holders for standard extensions */
|
/* Place holders for standard extensions */
|
||||||
nhrp_ext_push(zb, hdr,
|
nhrp_ext_push(zb, hdr,
|
||||||
|
|
|
@ -603,7 +603,7 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nhrp_packet_complete(zb, hdr);
|
nhrp_packet_complete(zb, hdr, ifp);
|
||||||
nhrp_peer_send(peer, zb);
|
nhrp_peer_send(peer, zb);
|
||||||
err:
|
err:
|
||||||
nhrp_peer_unref(peer);
|
nhrp_peer_unref(peer);
|
||||||
|
@ -730,7 +730,8 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nhrp_packet_complete(zb, hdr);
|
// auth ext was validated and copied from the request
|
||||||
|
nhrp_packet_complete_auth(zb, hdr, ifp, false);
|
||||||
nhrp_peer_send(p->peer, zb);
|
nhrp_peer_send(p->peer, zb);
|
||||||
err:
|
err:
|
||||||
zbuf_free(zb);
|
zbuf_free(zb);
|
||||||
|
@ -812,7 +813,7 @@ void nhrp_peer_send_indication(struct interface *ifp, uint16_t protocol_type,
|
||||||
|
|
||||||
/* Payload is the packet causing indication */
|
/* Payload is the packet causing indication */
|
||||||
zbuf_copy(zb, pkt, zbuf_used(pkt));
|
zbuf_copy(zb, pkt, zbuf_used(pkt));
|
||||||
nhrp_packet_complete(zb, hdr);
|
nhrp_packet_complete(zb, hdr, ifp);
|
||||||
nhrp_peer_send(p, zb);
|
nhrp_peer_send(p, zb);
|
||||||
nhrp_peer_unref(p);
|
nhrp_peer_unref(p);
|
||||||
zbuf_free(zb);
|
zbuf_free(zb);
|
||||||
|
@ -1063,7 +1064,8 @@ static void nhrp_peer_forward(struct nhrp_peer *p,
|
||||||
nhrp_ext_complete(zb, dst);
|
nhrp_ext_complete(zb, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
nhrp_packet_complete(zb, hdr);
|
// XXX: auth already handled ???
|
||||||
|
nhrp_packet_complete_auth(zb, hdr, pp->ifp, false);
|
||||||
nhrp_peer_send(p, zb);
|
nhrp_peer_send(p, zb);
|
||||||
zbuf_free(zb);
|
zbuf_free(zb);
|
||||||
zbuf_free(zb_copy);
|
zbuf_free(zb_copy);
|
||||||
|
@ -1089,8 +1091,7 @@ static void nhrp_packet_debug(struct zbuf *zb, const char *dir)
|
||||||
|
|
||||||
reply = packet_types[hdr->type].type == PACKET_REPLY;
|
reply = packet_types[hdr->type].type == PACKET_REPLY;
|
||||||
debugf(NHRP_DEBUG_COMMON, "%s %s(%d) %pSU -> %pSU", dir,
|
debugf(NHRP_DEBUG_COMMON, "%s %s(%d) %pSU -> %pSU", dir,
|
||||||
(packet_types[hdr->type].name ? packet_types[hdr->type].name
|
(packet_types[hdr->type].name ? : "Unknown"),
|
||||||
: "Unknown"),
|
|
||||||
hdr->type, reply ? &dst_proto : &src_proto,
|
hdr->type, reply ? &dst_proto : &src_proto,
|
||||||
reply ? &src_proto : &dst_proto);
|
reply ? &src_proto : &dst_proto);
|
||||||
}
|
}
|
||||||
|
@ -1106,11 +1107,70 @@ static int proto2afi(uint16_t proto)
|
||||||
return AF_UNSPEC;
|
return AF_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nhrp_route_info {
|
static int nhrp_packet_send_error(struct nhrp_packet_parser *pp,
|
||||||
int local;
|
uint16_t indication_code, uint16_t offset)
|
||||||
struct interface *ifp;
|
{
|
||||||
struct nhrp_vc *vc;
|
union sockunion src_proto, dst_proto;
|
||||||
};
|
struct nhrp_packet_header *hdr;
|
||||||
|
struct zbuf *zb;
|
||||||
|
|
||||||
|
src_proto = pp->src_proto;
|
||||||
|
dst_proto = pp->dst_proto;
|
||||||
|
if (packet_types[pp->hdr->type].type != PACKET_REPLY) {
|
||||||
|
src_proto = pp->dst_proto;
|
||||||
|
dst_proto = pp->src_proto;
|
||||||
|
}
|
||||||
|
/* Create reply */
|
||||||
|
zb = zbuf_alloc(1500); // XXX: hardcode -> calculation routine
|
||||||
|
hdr = nhrp_packet_push(zb, NHRP_PACKET_ERROR_INDICATION, &pp->src_nbma,
|
||||||
|
&src_proto, &dst_proto);
|
||||||
|
|
||||||
|
hdr->u.error.code = indication_code;
|
||||||
|
hdr->u.error.offset = htons(offset);
|
||||||
|
hdr->flags = pp->hdr->flags;
|
||||||
|
hdr->hop_count = 0; // XXX: cisco returns 255
|
||||||
|
|
||||||
|
/* Payload is the packet causing error */
|
||||||
|
/* Don`t add extension according to RFC */
|
||||||
|
/* wireshark gives bad checksum, without exts */
|
||||||
|
// pp->hdr->checksum = nhrp_packet_calculate_checksum(zbuf_used(&pp->payload))
|
||||||
|
zbuf_put(zb, pp->hdr, sizeof(*pp->hdr));
|
||||||
|
zbuf_copy(zb, &pp->payload, zbuf_used(&pp->payload));
|
||||||
|
nhrp_packet_complete_auth(zb, hdr, pp->ifp, false);
|
||||||
|
|
||||||
|
/* nhrp_packet_debug(zb, "SEND_ERROR"); */
|
||||||
|
nhrp_peer_send(pp->peer, zb);
|
||||||
|
zbuf_free(zb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool nhrp_connection_authorized(struct nhrp_packet_parser *pp)
|
||||||
|
{
|
||||||
|
struct nhrp_cisco_authentication_extension *auth_ext;
|
||||||
|
struct nhrp_interface *nifp = pp->ifp->info;
|
||||||
|
struct zbuf *auth = nifp->auth_token;
|
||||||
|
struct nhrp_extension_header *ext;
|
||||||
|
struct zbuf *extensions, pl;
|
||||||
|
int cmp = 0;
|
||||||
|
|
||||||
|
|
||||||
|
extensions = zbuf_alloc(zbuf_used(&pp->extensions));
|
||||||
|
zbuf_copy_peek(extensions, &pp->extensions, zbuf_used(&pp->extensions));
|
||||||
|
while ((ext = nhrp_ext_pull(extensions, &pl)) != NULL) {
|
||||||
|
switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) {
|
||||||
|
case NHRP_EXTENSION_AUTHENTICATION:
|
||||||
|
cmp = memcmp(auth->buf, pl.buf, zbuf_size(auth));
|
||||||
|
auth_ext = (struct nhrp_cisco_authentication_extension *)
|
||||||
|
auth->buf;
|
||||||
|
debugf(NHRP_DEBUG_COMMON,
|
||||||
|
"Processing Authentication Extension for (%s:%s|%d)",
|
||||||
|
auth_ext->secret, (const char *)pl.buf, cmp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zbuf_free(extensions);
|
||||||
|
return cmp == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb)
|
void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb)
|
||||||
{
|
{
|
||||||
|
@ -1191,10 +1251,20 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb)
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RFC2332 5.3.4 - Authentication is always done pairwise on an NHRP
|
||||||
|
* hop-by-hop basis; i.e. regenerated at each hop. */
|
||||||
nhrp_packet_debug(zb, "Recv");
|
nhrp_packet_debug(zb, "Recv");
|
||||||
|
if (nifp->auth_token &&
|
||||||
/* FIXME: Check authentication here. This extension needs to be
|
(hdr->type != NHRP_PACKET_ERROR_INDICATION ||
|
||||||
* pre-handled. */
|
hdr->u.error.code != NHRP_ERROR_AUTHENTICATION_FAILURE)) {
|
||||||
|
if (!nhrp_connection_authorized(&pp)) {
|
||||||
|
nhrp_packet_send_error(&pp,
|
||||||
|
NHRP_ERROR_AUTHENTICATION_FAILURE,
|
||||||
|
0);
|
||||||
|
info = "authentication failure";
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Figure out if this is local */
|
/* Figure out if this is local */
|
||||||
target_addr = (packet_types[hdr->type].type == PACKET_REPLY)
|
target_addr = (packet_types[hdr->type].type == PACKET_REPLY)
|
||||||
|
|
|
@ -425,7 +425,7 @@ static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s)
|
||||||
"Shortcut res_req: set cie ht to %u and mtu to %u. shortcut ht is %u",
|
"Shortcut res_req: set cie ht to %u and mtu to %u. shortcut ht is %u",
|
||||||
ntohs(cie->holding_time), ntohs(cie->mtu), s->holding_time);
|
ntohs(cie->holding_time), ntohs(cie->mtu), s->holding_time);
|
||||||
|
|
||||||
nhrp_ext_request(zb, hdr, ifp);
|
nhrp_ext_request(zb, hdr);
|
||||||
|
|
||||||
/* Cisco NAT detection extension */
|
/* Cisco NAT detection extension */
|
||||||
hdr->flags |= htons(NHRP_FLAG_RESOLUTION_NAT);
|
hdr->flags |= htons(NHRP_FLAG_RESOLUTION_NAT);
|
||||||
|
@ -438,7 +438,7 @@ static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s)
|
||||||
nhrp_ext_complete(zb, ext);
|
nhrp_ext_complete(zb, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
nhrp_packet_complete(zb, hdr);
|
nhrp_packet_complete(zb, hdr, ifp);
|
||||||
|
|
||||||
nhrp_peer_send(peer, zb);
|
nhrp_peer_send(peer, zb);
|
||||||
nhrp_peer_unref(peer);
|
nhrp_peer_unref(peer);
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
#include "nhrpd.h"
|
#include "nhrpd.h"
|
||||||
#include "netlink.h"
|
#include "netlink.h"
|
||||||
|
#include "nhrp_protocol.h"
|
||||||
|
|
||||||
|
#include "nhrpd/nhrp_vty_clippy.c"
|
||||||
|
|
||||||
static int nhrp_config_write(struct vty *vty);
|
static int nhrp_config_write(struct vty *vty);
|
||||||
static struct cmd_node zebra_node = {
|
static struct cmd_node zebra_node = {
|
||||||
|
@ -459,6 +462,56 @@ DEFUN(if_no_nhrp_holdtime, if_no_nhrp_holdtime_cmd,
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define NHRP_CISCO_PASS_LEN 8
|
||||||
|
DEFPY(if_nhrp_authentication, if_nhrp_authentication_cmd,
|
||||||
|
AFI_CMD "nhrp authentication PASSWORD$password",
|
||||||
|
AFI_STR
|
||||||
|
NHRP_STR
|
||||||
|
"Specify plaint text password used for authenticantion\n"
|
||||||
|
"Password, plain text, limited to 8 characters\n")
|
||||||
|
{
|
||||||
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||||
|
struct nhrp_cisco_authentication_extension *auth;
|
||||||
|
struct nhrp_interface *nifp = ifp->info;
|
||||||
|
int pass_len = strlen(password);
|
||||||
|
|
||||||
|
if (pass_len > NHRP_CISCO_PASS_LEN) {
|
||||||
|
vty_out(vty, "Password size limit exceeded (%d>%d)\n",
|
||||||
|
pass_len, NHRP_CISCO_PASS_LEN);
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nifp->auth_token)
|
||||||
|
zbuf_free(nifp->auth_token);
|
||||||
|
|
||||||
|
nifp->auth_token = zbuf_alloc(pass_len + sizeof(uint32_t));
|
||||||
|
auth = (struct nhrp_cisco_authentication_extension *)
|
||||||
|
nifp->auth_token->buf;
|
||||||
|
auth->type = htonl(NHRP_AUTHENTICATION_PLAINTEXT);
|
||||||
|
memcpy(auth->secret, password, pass_len);
|
||||||
|
|
||||||
|
// XXX RFC: reset active (non-authorized) connections?
|
||||||
|
/* vty_out(vty, "NHRP passwd (%s:%s)", nifp->ifp->name, auth->secret); */
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEFPY(if_no_nhrp_authentication, if_no_nhrp_authentication_cmd,
|
||||||
|
"no " AFI_CMD "nhrp authentication PASSWORD$password",
|
||||||
|
NO_STR
|
||||||
|
AFI_STR
|
||||||
|
NHRP_STR
|
||||||
|
"Reset password used for authentication\n"
|
||||||
|
"Password, plain text\n")
|
||||||
|
{
|
||||||
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||||
|
struct nhrp_interface *nifp = ifp->info;
|
||||||
|
if (nifp->auth_token)
|
||||||
|
zbuf_free(nifp->auth_token);
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DEFUN(if_nhrp_mtu, if_nhrp_mtu_cmd,
|
DEFUN(if_nhrp_mtu, if_nhrp_mtu_cmd,
|
||||||
"ip nhrp mtu <(576-1500)|opennhrp>",
|
"ip nhrp mtu <(576-1500)|opennhrp>",
|
||||||
IP_STR
|
IP_STR
|
||||||
|
@ -1053,6 +1106,7 @@ DEFUN(show_dmvpn, show_dmvpn_cmd,
|
||||||
static void clear_nhrp_cache(struct nhrp_cache *c, void *data)
|
static void clear_nhrp_cache(struct nhrp_cache *c, void *data)
|
||||||
{
|
{
|
||||||
struct info_ctx *ctx = data;
|
struct info_ctx *ctx = data;
|
||||||
|
|
||||||
if (c->cur.type <= NHRP_CACHE_DYNAMIC) {
|
if (c->cur.type <= NHRP_CACHE_DYNAMIC) {
|
||||||
nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL,
|
nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -1129,6 +1183,7 @@ static void interface_config_write_nhrp_map(struct nhrp_cache_config *c,
|
||||||
static int interface_config_write(struct vty *vty)
|
static int interface_config_write(struct vty *vty)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
||||||
|
struct nhrp_cisco_authentication_extension *auth;
|
||||||
struct write_map_ctx mapctx;
|
struct write_map_ctx mapctx;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct nhrp_interface *nifp;
|
struct nhrp_interface *nifp;
|
||||||
|
@ -1155,6 +1210,12 @@ static int interface_config_write(struct vty *vty)
|
||||||
if (nifp->source)
|
if (nifp->source)
|
||||||
vty_out(vty, " tunnel source %s\n", nifp->source);
|
vty_out(vty, " tunnel source %s\n", nifp->source);
|
||||||
|
|
||||||
|
if (nifp->auth_token) {
|
||||||
|
auth = (struct nhrp_cisco_authentication_extension *)
|
||||||
|
nifp->auth_token->buf;
|
||||||
|
vty_out(vty, " ip nhrp authentication %s\n", auth->secret);
|
||||||
|
}
|
||||||
|
|
||||||
for (afi = 0; afi < AFI_MAX; afi++) {
|
for (afi = 0; afi < AFI_MAX; afi++) {
|
||||||
struct nhrp_afi_data *ad = &nifp->afi[afi];
|
struct nhrp_afi_data *ad = &nifp->afi[afi];
|
||||||
|
|
||||||
|
@ -1256,6 +1317,8 @@ void nhrp_config_init(void)
|
||||||
install_element(INTERFACE_NODE, &if_no_nhrp_network_id_cmd);
|
install_element(INTERFACE_NODE, &if_no_nhrp_network_id_cmd);
|
||||||
install_element(INTERFACE_NODE, &if_nhrp_holdtime_cmd);
|
install_element(INTERFACE_NODE, &if_nhrp_holdtime_cmd);
|
||||||
install_element(INTERFACE_NODE, &if_no_nhrp_holdtime_cmd);
|
install_element(INTERFACE_NODE, &if_no_nhrp_holdtime_cmd);
|
||||||
|
install_element(INTERFACE_NODE, &if_nhrp_authentication_cmd);
|
||||||
|
install_element(INTERFACE_NODE, &if_no_nhrp_authentication_cmd);
|
||||||
install_element(INTERFACE_NODE, &if_nhrp_mtu_cmd);
|
install_element(INTERFACE_NODE, &if_nhrp_mtu_cmd);
|
||||||
install_element(INTERFACE_NODE, &if_no_nhrp_mtu_cmd);
|
install_element(INTERFACE_NODE, &if_no_nhrp_mtu_cmd);
|
||||||
install_element(INTERFACE_NODE, &if_nhrp_flags_cmd);
|
install_element(INTERFACE_NODE, &if_nhrp_flags_cmd);
|
||||||
|
|
|
@ -311,6 +311,7 @@ DECLARE_DLIST(nhrp_reglist, struct nhrp_registration, reglist_entry);
|
||||||
struct nhrp_interface {
|
struct nhrp_interface {
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
|
struct zbuf *auth_token;
|
||||||
unsigned enabled : 1;
|
unsigned enabled : 1;
|
||||||
|
|
||||||
char *ipsec_profile, *ipsec_fallback_profile, *source;
|
char *ipsec_profile, *ipsec_fallback_profile, *source;
|
||||||
|
@ -480,9 +481,13 @@ struct nhrp_packet_header *nhrp_packet_push(struct zbuf *zb, uint8_t type,
|
||||||
const union sockunion *src_nbma,
|
const union sockunion *src_nbma,
|
||||||
const union sockunion *src_proto,
|
const union sockunion *src_proto,
|
||||||
const union sockunion *dst_proto);
|
const union sockunion *dst_proto);
|
||||||
void nhrp_packet_complete(struct zbuf *zb, struct nhrp_packet_header *hdr);
|
|
||||||
uint16_t nhrp_packet_calculate_checksum(const uint8_t *pdu, uint16_t len);
|
uint16_t nhrp_packet_calculate_checksum(const uint8_t *pdu, uint16_t len);
|
||||||
|
|
||||||
|
void nhrp_packet_complete(struct zbuf *zb, struct nhrp_packet_header *hdr,
|
||||||
|
struct interface *ifp);
|
||||||
|
void nhrp_packet_complete_auth(struct zbuf *zb, struct nhrp_packet_header *hdr,
|
||||||
|
struct interface *ifp, bool auth);
|
||||||
|
|
||||||
struct nhrp_packet_header *nhrp_packet_pull(struct zbuf *zb,
|
struct nhrp_packet_header *nhrp_packet_pull(struct zbuf *zb,
|
||||||
union sockunion *src_nbma,
|
union sockunion *src_nbma,
|
||||||
union sockunion *src_proto,
|
union sockunion *src_proto,
|
||||||
|
@ -501,8 +506,7 @@ nhrp_ext_push(struct zbuf *zb, struct nhrp_packet_header *hdr, uint16_t type);
|
||||||
void nhrp_ext_complete(struct zbuf *zb, struct nhrp_extension_header *ext);
|
void nhrp_ext_complete(struct zbuf *zb, struct nhrp_extension_header *ext);
|
||||||
struct nhrp_extension_header *nhrp_ext_pull(struct zbuf *zb,
|
struct nhrp_extension_header *nhrp_ext_pull(struct zbuf *zb,
|
||||||
struct zbuf *payload);
|
struct zbuf *payload);
|
||||||
void nhrp_ext_request(struct zbuf *zb, struct nhrp_packet_header *hdr,
|
void nhrp_ext_request(struct zbuf *zb, struct nhrp_packet_header *hdr);
|
||||||
struct interface *);
|
|
||||||
int nhrp_ext_reply(struct zbuf *zb, struct nhrp_packet_header *hdr,
|
int nhrp_ext_reply(struct zbuf *zb, struct nhrp_packet_header *hdr,
|
||||||
struct interface *ifp, struct nhrp_extension_header *ext,
|
struct interface *ifp, struct nhrp_extension_header *ext,
|
||||||
struct zbuf *extpayload);
|
struct zbuf *extpayload);
|
||||||
|
|
|
@ -42,3 +42,7 @@ noinst_HEADERS += \
|
||||||
nhrpd/zbuf.h \
|
nhrpd/zbuf.h \
|
||||||
nhrpd/znl.h \
|
nhrpd/znl.h \
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
clippy_scan += \
|
||||||
|
nhrpd/nhrp_vty.c \
|
||||||
|
# end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
log stdout debugging
|
log stdout debugging
|
||||||
! debug nhrp all
|
! debug nhrp all
|
||||||
interface r1-gre0
|
interface r1-gre0
|
||||||
|
ip nhrp authentication secret
|
||||||
ip nhrp holdtime 500
|
ip nhrp holdtime 500
|
||||||
ip nhrp shortcut
|
ip nhrp shortcut
|
||||||
ip nhrp network-id 42
|
ip nhrp network-id 42
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
log stdout debugging
|
log stdout debugging
|
||||||
nhrp nflog-group 1
|
nhrp nflog-group 1
|
||||||
interface r2-gre0
|
interface r2-gre0
|
||||||
|
ip nhrp authentication secret
|
||||||
ip nhrp holdtime 500
|
ip nhrp holdtime 500
|
||||||
ip nhrp redirect
|
ip nhrp redirect
|
||||||
ip nhrp network-id 42
|
ip nhrp network-id 42
|
||||||
|
|
|
@ -214,19 +214,64 @@ def test_protocols_convergence():
|
||||||
def test_nhrp_connection():
|
def test_nhrp_connection():
|
||||||
"Assert that the NHRP peers can find themselves."
|
"Assert that the NHRP peers can find themselves."
|
||||||
tgen = get_topogen()
|
tgen = get_topogen()
|
||||||
|
pingrouter = tgen.gears["r1"]
|
||||||
|
hubrouter = tgen.gears["r2"]
|
||||||
if tgen.routers_have_failure():
|
if tgen.routers_have_failure():
|
||||||
pytest.skip(tgen.errors)
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
pingrouter = tgen.gears["r1"]
|
def ping_helper():
|
||||||
logger.info("Check Ping IPv4 from R1 to R2 = 10.255.255.2)")
|
output = pingrouter.run("ping 10.255.255.2 -f -c 100")
|
||||||
output = pingrouter.run("ping 10.255.255.2 -f -c 1000")
|
|
||||||
logger.info(output)
|
logger.info(output)
|
||||||
if "1000 packets transmitted, 1000 received" not in output:
|
return output
|
||||||
|
|
||||||
|
# force session to reinitialize
|
||||||
|
def relink_session():
|
||||||
|
for r in ["r1", "r2"]:
|
||||||
|
tgen.gears[r].vtysh_cmd("clear ip nhrp cache")
|
||||||
|
tgen.net[r].cmd("ip l del {}-gre0".format(r));
|
||||||
|
_populate_iface();
|
||||||
|
|
||||||
|
### Passwords are the same
|
||||||
|
logger.info("Check Ping IPv4 from R1 to R2 = 10.255.255.2")
|
||||||
|
output = ping_helper()
|
||||||
|
if "100 packets transmitted, 100 received" not in output:
|
||||||
assertmsg = "expected ping IPv4 from R1 to R2 should be ok"
|
assertmsg = "expected ping IPv4 from R1 to R2 should be ok"
|
||||||
assert 0, assertmsg
|
assert 0, assertmsg
|
||||||
else:
|
else:
|
||||||
logger.info("Check Ping IPv4 from R1 to R2 OK")
|
logger.info("Check Ping IPv4 from R1 to R2 OK")
|
||||||
|
|
||||||
|
### Passwords are different
|
||||||
|
logger.info("Modify password and send ping again, should drop")
|
||||||
|
hubrouter.vtysh_cmd("""
|
||||||
|
configure
|
||||||
|
interface r2-gre0
|
||||||
|
ip nhrp authentication secret12
|
||||||
|
""")
|
||||||
|
relink_session()
|
||||||
|
topotest.sleep(10, "Waiting for session to initialize")
|
||||||
|
output = ping_helper()
|
||||||
|
if "Network is unreachable" not in output:
|
||||||
|
assertmsg = "expected ping IPv4 from R1 to R2 - should be down"
|
||||||
|
assert 0, assertmsg
|
||||||
|
else:
|
||||||
|
logger.info("Check Ping IPv4 from R1 to R2 missing - OK")
|
||||||
|
|
||||||
|
### Passwords are the same - again
|
||||||
|
logger.info("Recover password and verify conectivity is back")
|
||||||
|
hubrouter.vtysh_cmd("""
|
||||||
|
configure
|
||||||
|
interface r2-gre0
|
||||||
|
ip nhrp authentication secret
|
||||||
|
""")
|
||||||
|
relink_session()
|
||||||
|
topotest.sleep(10, "Waiting for session to initialize")
|
||||||
|
output = pingrouter.run("ping 10.255.255.2 -f -c 100")
|
||||||
|
logger.info(output)
|
||||||
|
if "100 packets transmitted, 100 received" not in output:
|
||||||
|
assertmsg = "expected ping IPv4 from R1 to R2 should be ok"
|
||||||
|
assert 0, assertmsg
|
||||||
|
else:
|
||||||
|
logger.info("Check Ping IPv4 from R1 to R2 OK")
|
||||||
|
|
||||||
def test_route_install():
|
def test_route_install():
|
||||||
"Test use of NHRP routes by other protocols (sharpd here)."
|
"Test use of NHRP routes by other protocols (sharpd here)."
|
||||||
|
|
Loading…
Reference in a new issue