From 201f6271de2c5b428c6390ee445c9b38dd3550fc Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 17 May 2017 18:30:43 -0400 Subject: [PATCH 1/4] nhrpd: Fix some missing newlines Signed-off-by: Donald Sharp --- nhrpd/nhrp_vty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index 9b8463fb54..940b3ddfd7 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -206,7 +206,7 @@ DEFUN(nhrp_event_socket, nhrp_event_socket_cmd, NHRP_STR "Event Manager commands\n" "Event Manager unix socket path\n" - "Unix path for the socket") + "Unix path for the socket\n") { evmgr_set_socket(argv[3]->arg); return CMD_SUCCESS; @@ -218,7 +218,7 @@ DEFUN(no_nhrp_event_socket, no_nhrp_event_socket_cmd, NHRP_STR "Event Manager commands\n" "Event Manager unix socket path\n" - "Unix path for the socket") + "Unix path for the socket\n") { evmgr_set_socket(NULL); return CMD_SUCCESS; From d258c885bdc4e4a8141668fd94db1e24b5b8588a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 17 May 2017 18:31:02 -0400 Subject: [PATCH 2/4] nhrpd: Fix crash in 'no nhrp event socket..' command Signed-off-by: Donald Sharp --- nhrpd/nhrp_event.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nhrpd/nhrp_event.c b/nhrpd/nhrp_event.c index da86c585a4..8a3f820f76 100644 --- a/nhrpd/nhrp_event.c +++ b/nhrpd/nhrp_event.c @@ -215,9 +215,12 @@ void evmgr_init(void) void evmgr_set_socket(const char *socket) { - if (nhrp_event_socket_path) + if (nhrp_event_socket_path) { free((char *) nhrp_event_socket_path); - nhrp_event_socket_path = strdup(socket); + nhrp_event_socket_path = NULL; + } + if (socket) + nhrp_event_socket_path = strdup(socket); evmgr_connection_error(&evmgr_connection); } From 55fd6ee9ca49301ddfe5f2e3af11cfa89eebdeef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Wed, 17 May 2017 18:36:07 -0400 Subject: [PATCH 3/4] nhrp: improve CIE prefix length handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RFC2332 states that prefix length MUST be 0xff for unique bindings. However, it seems at least some Cisco firmwares use host prefix length instead (which on wire level makes sense). Relax the handling of prefix length to treat all value longer than address length as 0xff. Additionally treat 0x00 the same way too, this is required by the RFC. This also fixes the prefix length address family to be checked against protocol address. Signed-off-by: Timo Teräs --- nhrpd/nhrp_nhs.c | 2 +- nhrpd/nhrp_peer.c | 11 ++++++++--- nhrpd/nhrp_shortcut.c | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c index b926a8d7b2..76c591fd79 100644 --- a/nhrpd/nhrp_nhs.c +++ b/nhrpd/nhrp_nhs.c @@ -189,7 +189,7 @@ static int nhrp_reg_send_req(struct thread *t) hdr->flags |= htons(NHRP_FLAG_REGISTRATION_NAT); ext = nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS); cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, &nifp->nbma, &if_ad->addr); - cie->prefix_length = 8 * sockunion_get_addrlen(&nifp->nbma); + cie->prefix_length = 8 * sockunion_get_addrlen(&if_ad->addr); nhrp_ext_complete(zb, ext); nhrp_packet_complete(zb, hdr); diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 5f1e43a608..d9e8627a14 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -386,11 +386,12 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p) struct nhrp_extension_header *ext; struct nhrp_cache *c; union sockunion cie_nbma, cie_proto, *proto_addr, *nbma_addr, *nbma_natoa; - int holdtime, natted = 0; + int holdtime, prefix_len, hostprefix_len, natted = 0; size_t paylen; void *pay; debugf(NHRP_DEBUG_COMMON, "Parsing and replying to Registration Req"); + hostprefix_len = 8 * sockunion_get_addrlen(&p->if_ad->addr); if (!sockunion_same(&p->src_nbma, &p->peer->vc->remote.nbma)) natted = 1; @@ -412,13 +413,17 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p) zbuf_init(&payload, pay, paylen, paylen); while ((cie = nhrp_cie_pull(&payload, hdr, &cie_nbma, &cie_proto)) != NULL) { - if (cie->prefix_length != 0xff && !(p->hdr->flags & htons(NHRP_FLAG_REGISTRATION_UNIQUE))) { + prefix_len = cie->prefix_length; + if (prefix_len == 0 || prefix_len >= hostprefix_len) + prefix_len = hostprefix_len; + + if (prefix_len != hostprefix_len && !(p->hdr->flags & htons(NHRP_FLAG_REGISTRATION_UNIQUE))) { cie->code = NHRP_CODE_BINDING_NON_UNIQUE; continue; } /* We currently support only unique prefix registrations */ - if (cie->prefix_length != 0xff) { + if (prefix_len != hostprefix_len) { cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED; continue; } diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index 4a6cbce31f..4faa9d7863 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -228,7 +228,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, void *ar prefix.prefixlen = cie->prefix_length; /* Sanity check prefix length */ - if (prefix.prefixlen >= 8*prefix_blen(&prefix)) { + if (prefix.prefixlen >= 8*prefix_blen(&prefix) || prefix.prefixlen == 0) { prefix.prefixlen = 8*prefix_blen(&prefix); } else if (nhrp_route_address(NULL, &pp->dst_proto, &route_prefix, NULL) == NHRP_ROUTE_NBMA_NEXTHOP) { if (prefix.prefixlen < route_prefix.prefixlen) From 37dc8ab5b6d39b41cd964c2a3d84a1872b7f44b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Thu, 18 May 2017 12:00:22 +0300 Subject: [PATCH 4/4] nhrpd: announce ipv6 routes to zebra MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Timo Teräs --- nhrpd/nhrp_route.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 69c55e3058..7f8cad6e92 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -86,7 +86,6 @@ void nhrp_route_update_nhrp(const struct prefix *p, struct interface *ifp) void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix *p, struct interface *ifp, const union sockunion *nexthop, uint32_t mtu) { - struct in_addr *nexthop_ipv4; int flags = 0; if (zclient->sock < 0) @@ -109,6 +108,7 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix SET_FLAG(flags, ZEBRA_FLAG_INTERNAL); if (p->family == AF_INET) { + struct in_addr *nexthop_ipv4; struct zapi_ipv4 api; memset(&api, 0, sizeof(api)); @@ -118,7 +118,6 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); if (nexthop) { - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); nexthop_ipv4 = (struct in_addr *) sockunion_get_addr(nexthop); api.nexthop_num = 1; api.nexthop = &nexthop_ipv4; @@ -147,6 +146,45 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix zapi_ipv4_route( add ? ZEBRA_IPV4_ROUTE_ADD : ZEBRA_IPV4_ROUTE_DELETE, zclient, (struct prefix_ipv4 *) p, &api); + } else if (p->family == AF_INET6) { + struct in6_addr *nexthop_ipv6; + struct zapi_ipv6 api; + + memset(&api, 0, sizeof(api)); + api.flags = flags; + api.type = ZEBRA_ROUTE_NHRP; + api.safi = SAFI_UNICAST; + + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + if (nexthop) { + nexthop_ipv6 = (struct in6_addr *) sockunion_get_addr(nexthop); + api.nexthop_num = 1; + api.nexthop = &nexthop_ipv6; + } + if (ifp) { + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = 1; + api.ifindex = &ifp->ifindex; + } + if (mtu) { + SET_FLAG(api.message, ZAPI_MESSAGE_MTU); + api.mtu = mtu; + } + + if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) { + char buf[2][INET6_ADDRSTRLEN]; + zlog_debug("Zebra send: IPv6 route %s %s/%d nexthop %s metric %u" + " count %d dev %s", + add ? "add" : "del", + inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), + p->prefixlen, + nexthop ? inet_ntop(AF_INET6, api.nexthop[0], buf[1], sizeof(buf[1])) : "", + api.metric, api.nexthop_num, ifp->name); + } + + zapi_ipv6_route( + add ? ZEBRA_IPV6_ROUTE_ADD : ZEBRA_IPV6_ROUTE_DELETE, + zclient, (struct prefix_ipv6 *) p, NULL, &api); } }