diff options
Diffstat (limited to 'zebra/rtadv.c')
| -rw-r--r-- | zebra/rtadv.c | 222 |
1 files changed, 167 insertions, 55 deletions
diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 60ac471b5a..11434edfcf 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -46,6 +46,10 @@ #include "zebra/zebra_errors.h" #include "zebra/zebra_router.h" +#ifndef VTYSH_EXTRACT_PL +#include "zebra/rtadv_clippy.c" +#endif + extern struct zebra_privs_t zserv_privs; #if defined(HAVE_RTADV) @@ -204,9 +208,12 @@ static void rtadv_send_packet(int sock, struct interface *ifp, } /* Logging of packet. */ - if (IS_ZEBRA_DEBUG_PACKET) - zlog_debug("%s(%u): Tx RA, socket %u", ifp->name, ifp->ifindex, - sock); + if (IS_ZEBRA_DEBUG_PACKET) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + + zlog_debug("%s(%s:%u): Tx RA, socket %u", ifp->name, + VRF_LOGNAME(vrf), ifp->ifindex, sock); + } /* Fill in sockaddr_in6. */ memset(&addr, 0, sizeof(struct sockaddr_in6)); @@ -227,7 +234,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp, rtadv->nd_ra_code = 0; rtadv->nd_ra_cksum = 0; - rtadv->nd_ra_curhoplimit = 64; + rtadv->nd_ra_curhoplimit = zif->rtadv.AdvCurHopLimit; /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */ rtadv->nd_ra_flags_reserved = zif->rtadv.AdvDefaultLifetime == 0 @@ -333,16 +340,6 @@ static void rtadv_send_packet(int sock, struct interface *ifp, IPV6_ADDR_COPY(&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix); -#ifdef DEBUG - { - uint8_t buf[INET6_ADDRSTRLEN]; - - zlog_debug("DEBUG %s", - inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, - buf, INET6_ADDRSTRLEN)); - } -#endif /* DEBUG */ - len += sizeof(struct nd_opt_prefix_info); } @@ -388,9 +385,11 @@ static void rtadv_send_packet(int sock, struct interface *ifp, sizeof(struct nd_opt_rdnss) + sizeof(struct in6_addr); if (len + opt_len > max_len) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + zlog_warn( - "%s(%u): Tx RA: RDNSS option would exceed MTU, omitting it", - ifp->name, ifp->ifindex); + "%s(%s:%u): Tx RA: RDNSS option would exceed MTU, omitting it", + ifp->name, VRF_LOGNAME(vrf), ifp->ifindex); goto no_more_opts; } struct nd_opt_rdnss *opt = (struct nd_opt_rdnss *)(buf + len); @@ -510,10 +509,17 @@ static int rtadv_timer(struct thread *thread) <= 0) zif->rtadv.inFastRexmit = 0; - if (IS_ZEBRA_DEBUG_SEND) + if (IS_ZEBRA_DEBUG_SEND) { + struct vrf *vrf = + vrf_lookup_by_id( + ifp->vrf_id); + zlog_debug( - "Fast RA Rexmit on interface %s", - ifp->name); + "Fast RA Rexmit on interface %s(%s:%u)", + ifp->name, + VRF_LOGNAME(vrf), + ifp->ifindex); + } rtadv_send_packet(rtadv_get_socket(zvrf), ifp, RA_ENABLE); @@ -612,9 +618,14 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len, inet_ntop(AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN); if (len < sizeof(struct nd_router_advert)) { - if (IS_ZEBRA_DEBUG_PACKET) - zlog_debug("%s(%u): Rx RA with invalid length %d from %s", - ifp->name, ifp->ifindex, len, addr_str); + if (IS_ZEBRA_DEBUG_PACKET) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + + zlog_debug( + "%s(%s:%u): Rx RA with invalid length %d from %s", + ifp->name, VRF_LOGNAME(vrf), ifp->ifindex, len, + addr_str); + } return; } @@ -622,9 +633,14 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len, rtadv_process_optional(msg + sizeof(struct nd_router_advert), len - sizeof(struct nd_router_advert), ifp, addr); - if (IS_ZEBRA_DEBUG_PACKET) - zlog_debug("%s(%u): Rx RA with non-linklocal source address from %s", - ifp->name, ifp->ifindex, addr_str); + if (IS_ZEBRA_DEBUG_PACKET) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + + zlog_debug( + "%s(%s:%u): Rx RA with non-linklocal source address from %s", + ifp->name, VRF_LOGNAME(vrf), ifp->ifindex, + addr_str); + } return; } @@ -703,9 +719,12 @@ static void rtadv_process_packet(uint8_t *buf, unsigned int len, return; } - if (IS_ZEBRA_DEBUG_PACKET) - zlog_debug("%s(%u): Rx RA/RS len %d from %s", ifp->name, - ifp->ifindex, len, addr_str); + if (IS_ZEBRA_DEBUG_PACKET) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + + zlog_debug("%s(%s:%u): Rx RA/RS len %d from %s", ifp->name, + VRF_LOGNAME(vrf), ifp->ifindex, len, addr_str); + } if (if_is_loopback(ifp) || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) @@ -718,8 +737,11 @@ static void rtadv_process_packet(uint8_t *buf, unsigned int len, /* ICMP message length check. */ if (len < sizeof(struct icmp6_hdr)) { - zlog_debug("%s(%u): Rx RA with Invalid ICMPV6 packet length %d", - ifp->name, ifp->ifindex, len); + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + + zlog_debug( + "%s(%s:%u): Rx RA with Invalid ICMPV6 packet length %d", + ifp->name, VRF_LOGNAME(vrf), ifp->ifindex, len); return; } @@ -728,15 +750,20 @@ static void rtadv_process_packet(uint8_t *buf, unsigned int len, /* ICMP message type check. */ if (icmph->icmp6_type != ND_ROUTER_SOLICIT && icmph->icmp6_type != ND_ROUTER_ADVERT) { - zlog_debug("%s(%u): Rx RA - Unwanted ICMPV6 message type %d", - ifp->name, ifp->ifindex, icmph->icmp6_type); + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + + zlog_debug("%s(%s:%u): Rx RA - Unwanted ICMPV6 message type %d", + ifp->name, VRF_LOGNAME(vrf), ifp->ifindex, + icmph->icmp6_type); return; } /* Hoplimit check. */ if (hoplimit >= 0 && hoplimit != 255) { - zlog_debug("%s(%u): Rx RA - Invalid hoplimit %d", ifp->name, - ifp->ifindex, hoplimit); + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + + zlog_debug("%s(%s:%u): Rx RA - Invalid hoplimit %d", ifp->name, + VRF_LOGNAME(vrf), ifp->ifindex, hoplimit); return; } @@ -1055,25 +1082,34 @@ static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable) unsigned int ra_interval = ra_interval_rxd; - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%u: IF %u RA %s from client %s, interval %ums", - zvrf_id(zvrf), ifindex, + if (IS_ZEBRA_DEBUG_EVENT) { + struct vrf *vrf = zvrf->vrf; + + zlog_debug("%s:%u: IF %u RA %s from client %s, interval %ums", + VRF_LOGNAME(vrf), zvrf_id(zvrf), ifindex, enable ? "enable" : "disable", zebra_route_string(client->proto), ra_interval); + } /* Locate interface and check VRF match. */ ifp = if_lookup_by_index(ifindex, zvrf->vrf->vrf_id); if (!ifp) { + struct vrf *vrf = zvrf->vrf; + flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE, - "%u: IF %u RA %s client %s - interface unknown", - zvrf_id(zvrf), ifindex, enable ? "enable" : "disable", + "%s:%u: IF %u RA %s client %s - interface unknown", + VRF_LOGNAME(vrf), zvrf_id(zvrf), ifindex, + enable ? "enable" : "disable", zebra_route_string(client->proto)); return; } if (ifp->vrf_id != zvrf_id(zvrf)) { + struct vrf *vrf = zvrf->vrf; + zlog_debug( - "%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u", - zvrf_id(zvrf), ifindex, enable ? "enable" : "disable", + "%s:%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u", + VRF_LOGNAME(vrf), zvrf_id(zvrf), ifindex, + enable ? "enable" : "disable", zebra_route_string(client->proto), ifp->vrf_id); return; } @@ -1199,6 +1235,53 @@ DEFUN (no_ipv6_nd_ra_fast_retrans, return CMD_SUCCESS; } +DEFPY (ipv6_nd_ra_hop_limit, + ipv6_nd_ra_hop_limit_cmd, + "ipv6 nd ra-hop-limit (0-255)$hopcount", + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Advertisement Hop Limit\n" + "Advertisement Hop Limit in hops (default:64)\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct zebra_if *zif = ifp->info; + + if (if_is_loopback(ifp) + || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) { + vty_out(vty, + "Cannot configure IPv6 Router Advertisements on this interface\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + zif->rtadv.AdvCurHopLimit = hopcount; + + return CMD_SUCCESS; +} + +DEFPY (no_ipv6_nd_ra_hop_limit, + no_ipv6_nd_ra_hop_limit_cmd, + "no ipv6 nd ra-hop-limit [(0-255)]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Advertisement Hop Limit\n" + "Advertisement Hop Limit in hops\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct zebra_if *zif = ifp->info; + + if (if_is_loopback(ifp) + || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) { + vty_out(vty, + "Cannot configure IPv6 Router Advertisements on this interface\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + zif->rtadv.AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT; + + return CMD_SUCCESS; +} + DEFUN (ipv6_nd_suppress_ra, ipv6_nd_suppress_ra_cmd, "ipv6 nd suppress-ra", @@ -2146,6 +2229,8 @@ static int nd_dump_vty(struct vty *vty, struct interface *ifp) vty_out(vty, " ND advertised retransmit interval is %d milliseconds\n", rtadv->AdvRetransTimer); + vty_out(vty, " ND advertised hop-count limit is %d hops\n", + rtadv->AdvCurHopLimit); vty_out(vty, " ND router advertisements sent: %d rcvd: %d\n", zif->ra_sent, zif->ra_rcvd); interval = rtadv->MaxRtrAdvInterval; @@ -2237,6 +2322,10 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp) if (!zif->rtadv.UseFastRexmit) vty_out(vty, " no ipv6 nd ra-fast-retrans\n"); + if (zif->rtadv.AdvCurHopLimit != RTADV_DEFAULT_HOPLIMIT) + vty_out(vty, " ipv6 nd ra-hop-limit %d\n", + zif->rtadv.AdvCurHopLimit); + if (zif->rtadv.AdvDefaultLifetime != -1) vty_out(vty, " ipv6 nd ra-lifetime %d\n", zif->rtadv.AdvDefaultLifetime); @@ -2329,6 +2418,13 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val) { struct rtadv *rtadv = &zvrf->rtadv; + if (IS_ZEBRA_DEBUG_EVENT) { + struct vrf *vrf = zvrf->vrf; + + zlog_debug("%s(%s) with event: %d and val: %d", __func__, + VRF_LOGNAME(vrf), event, val); + } + switch (event) { case RTADV_START: thread_add_read(zrouter.master, rtadv_read, zvrf, val, @@ -2371,20 +2467,26 @@ void rtadv_init(struct zebra_vrf *zvrf) } } -void rtadv_terminate(struct zebra_vrf *zvrf) +void rtadv_vrf_terminate(struct zebra_vrf *zvrf) { rtadv_event(zvrf, RTADV_STOP, 0); if (zvrf->rtadv.sock >= 0) { close(zvrf->rtadv.sock); zvrf->rtadv.sock = -1; - } else if (zrouter.rtadv_sock >= 0) { - close(zrouter.rtadv_sock); - zrouter.rtadv_sock = -1; } + zvrf->rtadv.adv_if_count = 0; zvrf->rtadv.adv_msec_if_count = 0; } +void rtadv_terminate(void) +{ + if (zrouter.rtadv_sock >= 0) { + close(zrouter.rtadv_sock); + zrouter.rtadv_sock = -1; + } +} + void rtadv_cmd_init(void) { hook_register(zebra_if_extra_info, nd_dump_vty); @@ -2392,6 +2494,8 @@ void rtadv_cmd_init(void) install_element(INTERFACE_NODE, &ipv6_nd_ra_fast_retrans_cmd); install_element(INTERFACE_NODE, &no_ipv6_nd_ra_fast_retrans_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_ra_hop_limit_cmd); + install_element(INTERFACE_NODE, &no_ipv6_nd_ra_hop_limit_cmd); install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd); install_element(INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd); install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_cmd); @@ -2445,10 +2549,13 @@ static int if_join_all_router(int sock, struct interface *ifp) ifp->name, ifp->ifindex, sock, safe_strerror(errno)); - if (IS_ZEBRA_DEBUG_EVENT) + if (IS_ZEBRA_DEBUG_EVENT) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + zlog_debug( - "%s(%u): Join All-Routers multicast group, socket %u", - ifp->name, ifp->ifindex, sock); + "%s(%s:%u): Join All-Routers multicast group, socket %u", + ifp->name, VRF_LOGNAME(vrf), ifp->ifindex, sock); + } return 0; } @@ -2465,17 +2572,22 @@ static int if_leave_all_router(int sock, struct interface *ifp) ret = setsockopt(sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char *)&mreq, sizeof(mreq)); - if (ret < 0) + if (ret < 0) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + flog_err_sys( EC_LIB_SOCKET, - "%s(%u): Failed to leave group, socket %u error %s", - ifp->name, ifp->ifindex, sock, safe_strerror(errno)); + "%s(%s:%u): Failed to leave group, socket %u error %s", + ifp->name, VRF_LOGNAME(vrf), ifp->ifindex, sock, + safe_strerror(errno)); + } + if (IS_ZEBRA_DEBUG_EVENT) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); - if (IS_ZEBRA_DEBUG_EVENT) zlog_debug( - "%s(%u): Leave All-Routers multicast group, socket %u", - ifp->name, ifp->ifindex, sock); - + "%s(%s:%u): Leave All-Routers multicast group, socket %u", + ifp->name, VRF_LOGNAME(vrf), ifp->ifindex, sock); + } return 0; } |
