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); } 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_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); } } 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) 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;