Skip to content

Commit 792d1dd

Browse files
dleroy1337kerberos
andcommitted
nhrpd: add cisco-authentication password support
Taking over this development from #14788 This commit addresses 4 issues found in the previous PR 1) FRR would accept messages from a spoke without authentication when FRR NHRP had auth configured. 2) The error indication was not being sent in network byte order 3) The debug print in nhrp_connection_authorized was not correctly printing the received password 4) The addresses portion of the mandatory part of the error indication was invalid on the wire (confirmed in wireshark) Signed-off-by: Dave LeRoy <[email protected]> Co-authored-by: Volodymyr Huti <[email protected]>
1 parent 5b9e9aa commit 792d1dd

File tree

7 files changed

+51
-43
lines changed

7 files changed

+51
-43
lines changed

doc/user/nhrpd.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Configuring NHRP
8888

8989
Enables Cisco style authentication on NHRP packets. This embeds the
9090
plaintext password to the outgoing NHRP packets.
91-
Maximum length of the is 8 characters.
91+
Maximum length of the password is 8 characters.
9292

9393
.. clicmd:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local
9494

nhrpd/nhrp_interface.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ static int nhrp_if_delete_hook(struct interface *ifp)
9999
free(nifp->ipsec_fallback_profile);
100100
if (nifp->source)
101101
free(nifp->source);
102+
if (nifp->auth_token)
103+
zbuf_free(nifp->auth_token);
102104

103105
XFREE(MTYPE_NHRP_IF, ifp->info);
104106
return 0;

nhrpd/nhrp_peer.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
730730
}
731731
}
732732

733-
// auth ext was validated and copied from the request
733+
/* auth ext was validated and copied from the request */
734734
nhrp_packet_complete_auth(zb, hdr, ifp, false);
735735
nhrp_peer_send(p->peer, zb);
736736
err:
@@ -1064,7 +1064,6 @@ static void nhrp_peer_forward(struct nhrp_peer *p,
10641064
nhrp_ext_complete(zb, dst);
10651065
}
10661066

1067-
// XXX: auth already handled ???
10681067
nhrp_packet_complete_auth(zb, hdr, pp->ifp, false);
10691068
nhrp_peer_send(p, zb);
10701069
zbuf_free(zb);
@@ -1121,24 +1120,26 @@ static int nhrp_packet_send_error(struct nhrp_packet_parser *pp,
11211120
dst_proto = pp->src_proto;
11221121
}
11231122
/* Create reply */
1124-
zb = zbuf_alloc(1500); // XXX: hardcode -> calculation routine
1123+
zb = zbuf_alloc(1500);
11251124
hdr = nhrp_packet_push(zb, NHRP_PACKET_ERROR_INDICATION, &pp->src_nbma,
11261125
&src_proto, &dst_proto);
11271126

1128-
hdr->u.error.code = indication_code;
1127+
hdr->u.error.code = htons(indication_code);
11291128
hdr->u.error.offset = htons(offset);
11301129
hdr->flags = pp->hdr->flags;
1131-
hdr->hop_count = 0; // XXX: cisco returns 255
1130+
hdr->hop_count = 0; /* XXX: cisco returns 255 */
11321131

11331132
/* Payload is the packet causing error */
11341133
/* Don`t add extension according to RFC */
1135-
/* wireshark gives bad checksum, without exts */
1136-
// pp->hdr->checksum = nhrp_packet_calculate_checksum(zbuf_used(&pp->payload))
11371134
zbuf_put(zb, pp->hdr, sizeof(*pp->hdr));
1138-
zbuf_copy(zb, &pp->payload, zbuf_used(&pp->payload));
1135+
zbuf_put(zb, sockunion_get_addr(&pp->src_nbma),
1136+
hdr->src_nbma_address_len);
1137+
zbuf_put(zb, sockunion_get_addr(&pp->src_proto),
1138+
hdr->src_protocol_address_len);
1139+
zbuf_put(zb, sockunion_get_addr(&pp->dst_proto),
1140+
hdr->dst_protocol_address_len);
11391141
nhrp_packet_complete_auth(zb, hdr, pp->ifp, false);
11401142

1141-
/* nhrp_packet_debug(zb, "SEND_ERROR"); */
11421143
nhrp_peer_send(pp->peer, zb);
11431144
zbuf_free(zb);
11441145
return 0;
@@ -1151,8 +1152,7 @@ static bool nhrp_connection_authorized(struct nhrp_packet_parser *pp)
11511152
struct zbuf *auth = nifp->auth_token;
11521153
struct nhrp_extension_header *ext;
11531154
struct zbuf *extensions, pl;
1154-
int cmp = 0;
1155-
1155+
int cmp = 1;
11561156

11571157
extensions = zbuf_alloc(zbuf_used(&pp->extensions));
11581158
zbuf_copy_peek(extensions, &pp->extensions, zbuf_used(&pp->extensions));
@@ -1164,7 +1164,14 @@ static bool nhrp_connection_authorized(struct nhrp_packet_parser *pp)
11641164
auth->buf;
11651165
debugf(NHRP_DEBUG_COMMON,
11661166
"Processing Authentication Extension for (%s:%s|%d)",
1167-
auth_ext->secret, (const char *)pl.buf, cmp);
1167+
auth_ext->secret,
1168+
((struct nhrp_cisco_authentication_extension *)
1169+
pl.buf)
1170+
->secret,
1171+
cmp);
1172+
break;
1173+
default:
1174+
/* Ignoring all received extensions except Authentication*/
11681175
break;
11691176
}
11701177
}

nhrpd/nhrp_vty.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ DEFPY(if_nhrp_authentication, if_nhrp_authentication_cmd,
467467
AFI_CMD "nhrp authentication PASSWORD$password",
468468
AFI_STR
469469
NHRP_STR
470-
"Specify plaint text password used for authenticantion\n"
470+
"Specify plain text password used for authenticantion\n"
471471
"Password, plain text, limited to 8 characters\n")
472472
{
473473
VTY_DECLVAR_CONTEXT(interface, ifp);
@@ -490,8 +490,6 @@ DEFPY(if_nhrp_authentication, if_nhrp_authentication_cmd,
490490
auth->type = htonl(NHRP_AUTHENTICATION_PLAINTEXT);
491491
memcpy(auth->secret, password, pass_len);
492492

493-
// XXX RFC: reset active (non-authorized) connections?
494-
/* vty_out(vty, "NHRP passwd (%s:%s)", nifp->ifp->name, auth->secret); */
495493
return CMD_SUCCESS;
496494
}
497495

@@ -501,11 +499,12 @@ DEFPY(if_no_nhrp_authentication, if_no_nhrp_authentication_cmd,
501499
NO_STR
502500
AFI_STR
503501
NHRP_STR
504-
"Reset password used for authentication\n"
505-
"Password, plain text\n")
502+
"Specify plain text password used for authenticantion\n"
503+
"Password, plain text, limited to 8 characters\n")
506504
{
507505
VTY_DECLVAR_CONTEXT(interface, ifp);
508506
struct nhrp_interface *nifp = ifp->info;
507+
509508
if (nifp->auth_token)
510509
zbuf_free(nifp->auth_token);
511510
return CMD_SUCCESS;

tests/topotests/nhrp_topo/r1/nhrpd.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ log stdout debugging
22
! debug nhrp all
33
interface r1-gre0
44
ip nhrp authentication secret
5-
ip nhrp holdtime 500
5+
ip nhrp holdtime 10
66
ip nhrp shortcut
77
ip nhrp network-id 42
88
ip nhrp nhs dynamic nbma 10.2.1.2

tests/topotests/nhrp_topo/r2/nhrpd.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ log stdout debugging
33
nhrp nflog-group 1
44
interface r2-gre0
55
ip nhrp authentication secret
6-
ip nhrp holdtime 500
6+
ip nhrp holdtime 10
77
ip nhrp redirect
88
ip nhrp network-id 42
99
ip nhrp registration no-unique

tests/topotests/nhrp_topo/test_nhrp_topo.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from lib import topotest
2929
from lib.topogen import Topogen, TopoRouter, get_topogen
3030
from lib.topolog import logger
31-
from lib.common_config import required_linux_kernel_version
31+
from lib.common_config import required_linux_kernel_version, retry
3232

3333
# Required to instantiate the topology builder class.
3434

@@ -231,14 +231,27 @@ def relink_session():
231231
tgen.net[r].cmd("ip l del {}-gre0".format(r));
232232
_populate_iface();
233233

234+
@retry(retry_timeout=40, initial_wait=5)
235+
def verify_same_password():
236+
output = ping_helper()
237+
if "100 packets transmitted, 100 received" not in output:
238+
assertmsg = "expected ping IPv4 from R1 to R2 should be ok"
239+
assert 0, assertmsg
240+
else:
241+
logger.info("Check Ping IPv4 from R1 to R2 OK")
242+
243+
@retry(retry_timeout=40, initial_wait=5)
244+
def verify_mismatched_password():
245+
output = ping_helper()
246+
if "Network is unreachable" not in output:
247+
assertmsg = "expected ping IPv4 from R1 to R2 - should be down"
248+
assert 0, assertmsg
249+
else:
250+
logger.info("Check Ping IPv4 from R1 to R2 missing - OK")
251+
234252
### Passwords are the same
235253
logger.info("Check Ping IPv4 from R1 to R2 = 10.255.255.2")
236-
output = ping_helper()
237-
if "100 packets transmitted, 100 received" not in output:
238-
assertmsg = "expected ping IPv4 from R1 to R2 should be ok"
239-
assert 0, assertmsg
240-
else:
241-
logger.info("Check Ping IPv4 from R1 to R2 OK")
254+
verify_same_password()
242255

243256
### Passwords are different
244257
logger.info("Modify password and send ping again, should drop")
@@ -248,14 +261,8 @@ def relink_session():
248261
ip nhrp authentication secret12
249262
""")
250263
relink_session()
251-
topotest.sleep(10, "Waiting for session to initialize")
252-
output = ping_helper()
253-
if "Network is unreachable" not in output:
254-
assertmsg = "expected ping IPv4 from R1 to R2 - should be down"
255-
assert 0, assertmsg
256-
else:
257-
logger.info("Check Ping IPv4 from R1 to R2 missing - OK")
258-
264+
verify_mismatched_password()
265+
259266
### Passwords are the same - again
260267
logger.info("Recover password and verify conectivity is back")
261268
hubrouter.vtysh_cmd("""
@@ -264,14 +271,7 @@ def relink_session():
264271
ip nhrp authentication secret
265272
""")
266273
relink_session()
267-
topotest.sleep(10, "Waiting for session to initialize")
268-
output = pingrouter.run("ping 10.255.255.2 -f -c 100")
269-
logger.info(output)
270-
if "100 packets transmitted, 100 received" not in output:
271-
assertmsg = "expected ping IPv4 from R1 to R2 should be ok"
272-
assert 0, assertmsg
273-
else:
274-
logger.info("Check Ping IPv4 from R1 to R2 OK")
274+
verify_same_password()
275275

276276
def test_route_install():
277277
"Test use of NHRP routes by other protocols (sharpd here)."

0 commit comments

Comments
 (0)