summaryrefslogtreecommitdiff
path: root/zebra/rtadv.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/rtadv.c')
-rw-r--r--zebra/rtadv.c2389
1 files changed, 1180 insertions, 1209 deletions
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 589ecc9498..b8cf2d490a 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -45,7 +45,7 @@
extern struct zebra_privs_t zserv_privs;
-#if defined (HAVE_RTADV)
+#if defined(HAVE_RTADV)
#ifdef OPEN_BSD
#include <netinet/icmp6.h>
@@ -62,743 +62,722 @@ extern struct zebra_privs_t zserv_privs;
#define ALLNODE "ff02::1"
#define ALLROUTER "ff02::2"
-enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
- RTADV_TIMER_MSEC, RTADV_READ};
+enum rtadv_event {
+ RTADV_START,
+ RTADV_STOP,
+ RTADV_TIMER,
+ RTADV_TIMER_MSEC,
+ RTADV_READ
+};
-static void rtadv_event (struct zebra_ns *, enum rtadv_event, int);
+static void rtadv_event(struct zebra_ns *, enum rtadv_event, int);
-static int if_join_all_router (int, struct interface *);
-static int if_leave_all_router (int, struct interface *);
+static int if_join_all_router(int, struct interface *);
+static int if_leave_all_router(int, struct interface *);
-static int
-rtadv_increment_received(struct zebra_ns *zns, ifindex_t *ifindex)
+static int rtadv_increment_received(struct zebra_ns *zns, ifindex_t *ifindex)
{
- int ret = -1;
- struct interface *iface;
- struct zebra_if *zif;
-
- iface = if_lookup_by_index_per_ns (zns, *ifindex);
- if (iface && iface->info)
- {
- zif = iface->info;
- zif->ra_rcvd++;
- ret = 0;
- }
- return ret;
+ int ret = -1;
+ struct interface *iface;
+ struct zebra_if *zif;
+
+ iface = if_lookup_by_index_per_ns(zns, *ifindex);
+ if (iface && iface->info) {
+ zif = iface->info;
+ zif->ra_rcvd++;
+ ret = 0;
+ }
+ return ret;
}
-static int
-rtadv_recv_packet (struct zebra_ns *zns, int sock, u_char *buf, int buflen,
- struct sockaddr_in6 *from, ifindex_t *ifindex,
- int *hoplimit)
+static int rtadv_recv_packet(struct zebra_ns *zns, int sock, u_char *buf,
+ int buflen, struct sockaddr_in6 *from,
+ ifindex_t *ifindex, int *hoplimit)
{
- int ret;
- struct msghdr msg;
- struct iovec iov;
- struct cmsghdr *cmsgptr;
- struct in6_addr dst;
-
- char adata[1024];
-
- /* Fill in message and iovec. */
- msg.msg_name = (void *) from;
- msg.msg_namelen = sizeof (struct sockaddr_in6);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = (void *) adata;
- msg.msg_controllen = sizeof adata;
- iov.iov_base = buf;
- iov.iov_len = buflen;
-
- /* If recvmsg fail return minus value. */
- ret = recvmsg (sock, &msg, 0);
- if (ret < 0)
- return ret;
-
- for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
- cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
- {
- /* I want interface index which this packet comes from. */
- if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
- cmsgptr->cmsg_type == IPV6_PKTINFO)
- {
- struct in6_pktinfo *ptr;
-
- ptr = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
- *ifindex = ptr->ipi6_ifindex;
- memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
- }
-
- /* Incoming packet's hop limit. */
- if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
- cmsgptr->cmsg_type == IPV6_HOPLIMIT)
- {
- int *hoptr = (int *) CMSG_DATA (cmsgptr);
- *hoplimit = *hoptr;
+ int ret;
+ struct msghdr msg;
+ struct iovec iov;
+ struct cmsghdr *cmsgptr;
+ struct in6_addr dst;
+
+ char adata[1024];
+
+ /* Fill in message and iovec. */
+ msg.msg_name = (void *)from;
+ msg.msg_namelen = sizeof(struct sockaddr_in6);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (void *)adata;
+ msg.msg_controllen = sizeof adata;
+ iov.iov_base = buf;
+ iov.iov_len = buflen;
+
+ /* If recvmsg fail return minus value. */
+ ret = recvmsg(sock, &msg, 0);
+ if (ret < 0)
+ return ret;
+
+ for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
+ cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
+ /* I want interface index which this packet comes from. */
+ if (cmsgptr->cmsg_level == IPPROTO_IPV6
+ && cmsgptr->cmsg_type == IPV6_PKTINFO) {
+ struct in6_pktinfo *ptr;
+
+ ptr = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
+ *ifindex = ptr->ipi6_ifindex;
+ memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
+ }
+
+ /* Incoming packet's hop limit. */
+ if (cmsgptr->cmsg_level == IPPROTO_IPV6
+ && cmsgptr->cmsg_type == IPV6_HOPLIMIT) {
+ int *hoptr = (int *)CMSG_DATA(cmsgptr);
+ *hoplimit = *hoptr;
+ }
}
- }
- rtadv_increment_received(zns, ifindex);
- return ret;
+ rtadv_increment_received(zns, ifindex);
+ return ret;
}
#define RTADV_MSG_SIZE 4096
/* Send router advertisement packet. */
-static void
-rtadv_send_packet (int sock, struct interface *ifp)
+static void rtadv_send_packet(int sock, struct interface *ifp)
{
- struct msghdr msg;
- struct iovec iov;
- struct cmsghdr *cmsgptr;
- struct in6_pktinfo *pkt;
- struct sockaddr_in6 addr;
- static void *adata = NULL;
- unsigned char buf[RTADV_MSG_SIZE];
- struct nd_router_advert *rtadv;
- int ret;
- int len = 0;
- struct zebra_if *zif;
- struct rtadv_prefix *rprefix;
- u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
- struct listnode *node;
- u_int16_t pkt_RouterLifetime;
-
- /*
- * Allocate control message bufffer. This is dynamic because
- * CMSG_SPACE is not guaranteed not to call a function. Note that
- * the size will be different on different architectures due to
- * differing alignment rules.
- */
- if (adata == NULL)
- {
- /* XXX Free on shutdown. */
- adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
-
- if (adata == NULL)
- zlog_err("rtadv_send_packet: can't malloc control data");
- }
-
- /* Logging of packet. */
- if (IS_ZEBRA_DEBUG_PACKET)
- zlog_debug ("%s(%u): Tx RA, socket %u",
- ifp->name, ifp->ifindex, sock);
-
- /* Fill in sockaddr_in6. */
- memset (&addr, 0, sizeof (struct sockaddr_in6));
- addr.sin6_family = AF_INET6;
+ struct msghdr msg;
+ struct iovec iov;
+ struct cmsghdr *cmsgptr;
+ struct in6_pktinfo *pkt;
+ struct sockaddr_in6 addr;
+ static void *adata = NULL;
+ unsigned char buf[RTADV_MSG_SIZE];
+ struct nd_router_advert *rtadv;
+ int ret;
+ int len = 0;
+ struct zebra_if *zif;
+ struct rtadv_prefix *rprefix;
+ u_char all_nodes_addr[] = {0xff, 0x02, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1};
+ struct listnode *node;
+ u_int16_t pkt_RouterLifetime;
+
+ /*
+ * Allocate control message bufffer. This is dynamic because
+ * CMSG_SPACE is not guaranteed not to call a function. Note that
+ * the size will be different on different architectures due to
+ * differing alignment rules.
+ */
+ if (adata == NULL) {
+ /* XXX Free on shutdown. */
+ adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
+
+ if (adata == NULL)
+ zlog_err(
+ "rtadv_send_packet: can't malloc control data");
+ }
+
+ /* Logging of packet. */
+ if (IS_ZEBRA_DEBUG_PACKET)
+ zlog_debug("%s(%u): Tx RA, socket %u", ifp->name, ifp->ifindex,
+ sock);
+
+ /* Fill in sockaddr_in6. */
+ memset(&addr, 0, sizeof(struct sockaddr_in6));
+ addr.sin6_family = AF_INET6;
#ifdef SIN6_LEN
- addr.sin6_len = sizeof (struct sockaddr_in6);
+ addr.sin6_len = sizeof(struct sockaddr_in6);
#endif /* SIN6_LEN */
- addr.sin6_port = htons (IPPROTO_ICMPV6);
- IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr);
-
- /* Fetch interface information. */
- zif = ifp->info;
-
- /* Make router advertisement message. */
- rtadv = (struct nd_router_advert *) buf;
-
- rtadv->nd_ra_type = ND_ROUTER_ADVERT;
- rtadv->nd_ra_code = 0;
- rtadv->nd_ra_cksum = 0;
-
- rtadv->nd_ra_curhoplimit = 64;
-
- /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
- rtadv->nd_ra_flags_reserved =
- zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference;
- rtadv->nd_ra_flags_reserved <<= 3;
-
- if (zif->rtadv.AdvManagedFlag)
- rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
- if (zif->rtadv.AdvOtherConfigFlag)
- rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
- if (zif->rtadv.AdvHomeAgentFlag)
- rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
- /* Note that according to Neighbor Discovery (RFC 4861 [18]),
- * AdvDefaultLifetime is by default based on the value of
- * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
- * field of Router Advertisements. Given that this field is expressed
- * in seconds, a small MaxRtrAdvInterval value can result in a zero
- * value for this field. To prevent this, routers SHOULD keep
- * AdvDefaultLifetime in at least one second, even if the use of
- * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
- pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ?
- zif->rtadv.AdvDefaultLifetime :
- MAX (1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
- rtadv->nd_ra_router_lifetime = htons (pkt_RouterLifetime);
- rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime);
- rtadv->nd_ra_retransmit = htonl (0);
-
- len = sizeof (struct nd_router_advert);
-
- /* If both the Home Agent Preference and Home Agent Lifetime are set to
- * their default values specified above, this option SHOULD NOT be
- * included in the Router Advertisement messages sent by this home
- * agent. -- RFC6275, 7.4 */
- if
- (
- zif->rtadv.AdvHomeAgentFlag &&
- (zif->rtadv.HomeAgentPreference || zif->rtadv.HomeAgentLifetime != -1)
- )
- {
- struct nd_opt_homeagent_info *ndopt_hai =
- (struct nd_opt_homeagent_info *)(buf + len);
- ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
- ndopt_hai->nd_opt_hai_len = 1;
- ndopt_hai->nd_opt_hai_reserved = 0;
- ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference);
- /* 16-bit unsigned integer. The lifetime associated with the home
- * agent in units of seconds. The default value is the same as the
- * Router Lifetime, as specified in the main body of the Router
- * Advertisement. The maximum value corresponds to 18.2 hours. A
- * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
- ndopt_hai->nd_opt_hai_lifetime = htons
- (
- zif->rtadv.HomeAgentLifetime != -1 ?
- zif->rtadv.HomeAgentLifetime :
- MAX (1, pkt_RouterLifetime) /* 0 is OK for RL, but not for HAL*/
- );
- len += sizeof(struct nd_opt_homeagent_info);
- }
-
- if (zif->rtadv.AdvIntervalOption)
- {
- struct nd_opt_adv_interval *ndopt_adv =
- (struct nd_opt_adv_interval *)(buf + len);
- ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
- ndopt_adv->nd_opt_ai_len = 1;
- ndopt_adv->nd_opt_ai_reserved = 0;
- ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval);
- len += sizeof(struct nd_opt_adv_interval);
- }
-
- /* Fill in prefix. */
- for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
- {
- struct nd_opt_prefix_info *pinfo;
-
- pinfo = (struct nd_opt_prefix_info *) (buf + len);
-
- pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
- pinfo->nd_opt_pi_len = 4;
- pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;
-
- pinfo->nd_opt_pi_flags_reserved = 0;
- if (rprefix->AdvOnLinkFlag)
- pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
- if (rprefix->AdvAutonomousFlag)
- pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
- if (rprefix->AdvRouterAddressFlag)
- pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
-
- pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime);
- pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime);
- pinfo->nd_opt_pi_reserved2 = 0;
-
- IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
+ addr.sin6_port = htons(IPPROTO_ICMPV6);
+ IPV6_ADDR_COPY(&addr.sin6_addr, all_nodes_addr);
+
+ /* Fetch interface information. */
+ zif = ifp->info;
+
+ /* Make router advertisement message. */
+ rtadv = (struct nd_router_advert *)buf;
+
+ rtadv->nd_ra_type = ND_ROUTER_ADVERT;
+ rtadv->nd_ra_code = 0;
+ rtadv->nd_ra_cksum = 0;
+
+ rtadv->nd_ra_curhoplimit = 64;
+
+ /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
+ rtadv->nd_ra_flags_reserved = zif->rtadv.AdvDefaultLifetime == 0
+ ? 0
+ : zif->rtadv.DefaultPreference;
+ rtadv->nd_ra_flags_reserved <<= 3;
+
+ if (zif->rtadv.AdvManagedFlag)
+ rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
+ if (zif->rtadv.AdvOtherConfigFlag)
+ rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
+ if (zif->rtadv.AdvHomeAgentFlag)
+ rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
+ /* Note that according to Neighbor Discovery (RFC 4861 [18]),
+ * AdvDefaultLifetime is by default based on the value of
+ * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
+ * field of Router Advertisements. Given that this field is expressed
+ * in seconds, a small MaxRtrAdvInterval value can result in a zero
+ * value for this field. To prevent this, routers SHOULD keep
+ * AdvDefaultLifetime in at least one second, even if the use of
+ * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
+ pkt_RouterLifetime =
+ zif->rtadv.AdvDefaultLifetime != -1
+ ? zif->rtadv.AdvDefaultLifetime
+ : MAX(1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
+ rtadv->nd_ra_router_lifetime = htons(pkt_RouterLifetime);
+ rtadv->nd_ra_reachable = htonl(zif->rtadv.AdvReachableTime);
+ rtadv->nd_ra_retransmit = htonl(0);
+
+ len = sizeof(struct nd_router_advert);
+
+ /* If both the Home Agent Preference and Home Agent Lifetime are set to
+ * their default values specified above, this option SHOULD NOT be
+ * included in the Router Advertisement messages sent by this home
+ * agent. -- RFC6275, 7.4 */
+ if (zif->rtadv.AdvHomeAgentFlag
+ && (zif->rtadv.HomeAgentPreference
+ || zif->rtadv.HomeAgentLifetime != -1)) {
+ struct nd_opt_homeagent_info *ndopt_hai =
+ (struct nd_opt_homeagent_info *)(buf + len);
+ ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
+ ndopt_hai->nd_opt_hai_len = 1;
+ ndopt_hai->nd_opt_hai_reserved = 0;
+ ndopt_hai->nd_opt_hai_preference =
+ htons(zif->rtadv.HomeAgentPreference);
+ /* 16-bit unsigned integer. The lifetime associated with the
+ * home
+ * agent in units of seconds. The default value is the same as
+ * the
+ * Router Lifetime, as specified in the main body of the Router
+ * Advertisement. The maximum value corresponds to 18.2 hours.
+ * A
+ * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
+ ndopt_hai->nd_opt_hai_lifetime =
+ htons(zif->rtadv.HomeAgentLifetime != -1
+ ? zif->rtadv.HomeAgentLifetime
+ : MAX(1, pkt_RouterLifetime) /* 0 is OK
+ for RL,
+ but not
+ for HAL*/
+ );
+ len += sizeof(struct nd_opt_homeagent_info);
+ }
-#ifdef DEBUG
- {
- u_char buf[INET6_ADDRSTRLEN];
+ if (zif->rtadv.AdvIntervalOption) {
+ struct nd_opt_adv_interval *ndopt_adv =
+ (struct nd_opt_adv_interval *)(buf + len);
+ ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
+ ndopt_adv->nd_opt_ai_len = 1;
+ ndopt_adv->nd_opt_ai_reserved = 0;
+ ndopt_adv->nd_opt_ai_interval =
+ htonl(zif->rtadv.MaxRtrAdvInterval);
+ len += sizeof(struct nd_opt_adv_interval);
+ }
+
+ /* Fill in prefix. */
+ for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) {
+ struct nd_opt_prefix_info *pinfo;
- zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,
- buf, INET6_ADDRSTRLEN));
+ pinfo = (struct nd_opt_prefix_info *)(buf + len);
- }
+ pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
+ pinfo->nd_opt_pi_len = 4;
+ pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;
+
+ pinfo->nd_opt_pi_flags_reserved = 0;
+ if (rprefix->AdvOnLinkFlag)
+ pinfo->nd_opt_pi_flags_reserved |=
+ ND_OPT_PI_FLAG_ONLINK;
+ if (rprefix->AdvAutonomousFlag)
+ pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
+ if (rprefix->AdvRouterAddressFlag)
+ pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
+
+ pinfo->nd_opt_pi_valid_time = htonl(rprefix->AdvValidLifetime);
+ pinfo->nd_opt_pi_preferred_time =
+ htonl(rprefix->AdvPreferredLifetime);
+ pinfo->nd_opt_pi_reserved2 = 0;
+
+ IPV6_ADDR_COPY(&pinfo->nd_opt_pi_prefix,
+ &rprefix->prefix.prefix);
+
+#ifdef DEBUG
+ {
+ u_char 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);
- }
-
- /* Hardware address. */
- if (ifp->hw_addr_len != 0)
- {
- buf[len++] = ND_OPT_SOURCE_LINKADDR;
-
- /* Option length should be rounded up to next octet if
- the link address does not end on an octet boundary. */
- buf[len++] = (ifp->hw_addr_len + 9) >> 3;
-
- memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
- len += ifp->hw_addr_len;
-
- /* Pad option to end on an octet boundary. */
- memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
- len += -(ifp->hw_addr_len + 2) & 0x7;
- }
-
- /* MTU */
- if (zif->rtadv.AdvLinkMTU)
- {
- struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len);
- opt->nd_opt_mtu_type = ND_OPT_MTU;
- opt->nd_opt_mtu_len = 1;
- opt->nd_opt_mtu_reserved = 0;
- opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU);
- len += sizeof (struct nd_opt_mtu);
- }
-
- msg.msg_name = (void *) &addr;
- msg.msg_namelen = sizeof (struct sockaddr_in6);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = (void *) adata;
- msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
- msg.msg_flags = 0;
- iov.iov_base = buf;
- iov.iov_len = len;
-
- cmsgptr = ZCMSG_FIRSTHDR(&msg);
- cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
- cmsgptr->cmsg_level = IPPROTO_IPV6;
- cmsgptr->cmsg_type = IPV6_PKTINFO;
-
- pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
- memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
- pkt->ipi6_ifindex = ifp->ifindex;
-
- ret = sendmsg (sock, &msg, 0);
- if (ret < 0)
- {
- zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)",
- ifp->name, ifp->ifindex, sock, errno, safe_strerror(errno));
- }
- else
- zif->ra_sent++;
+ len += sizeof(struct nd_opt_prefix_info);
+ }
+
+ /* Hardware address. */
+ if (ifp->hw_addr_len != 0) {
+ buf[len++] = ND_OPT_SOURCE_LINKADDR;
+
+ /* Option length should be rounded up to next octet if
+ the link address does not end on an octet boundary. */
+ buf[len++] = (ifp->hw_addr_len + 9) >> 3;
+
+ memcpy(buf + len, ifp->hw_addr, ifp->hw_addr_len);
+ len += ifp->hw_addr_len;
+
+ /* Pad option to end on an octet boundary. */
+ memset(buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
+ len += -(ifp->hw_addr_len + 2) & 0x7;
+ }
+
+ /* MTU */
+ if (zif->rtadv.AdvLinkMTU) {
+ struct nd_opt_mtu *opt = (struct nd_opt_mtu *)(buf + len);
+ opt->nd_opt_mtu_type = ND_OPT_MTU;
+ opt->nd_opt_mtu_len = 1;
+ opt->nd_opt_mtu_reserved = 0;
+ opt->nd_opt_mtu_mtu = htonl(zif->rtadv.AdvLinkMTU);
+ len += sizeof(struct nd_opt_mtu);
+ }
+
+ msg.msg_name = (void *)&addr;
+ msg.msg_namelen = sizeof(struct sockaddr_in6);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (void *)adata;
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
+ msg.msg_flags = 0;
+ iov.iov_base = buf;
+ iov.iov_len = len;
+
+ cmsgptr = ZCMSG_FIRSTHDR(&msg);
+ cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+ cmsgptr->cmsg_level = IPPROTO_IPV6;
+ cmsgptr->cmsg_type = IPV6_PKTINFO;
+
+ pkt = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
+ memset(&pkt->ipi6_addr, 0, sizeof(struct in6_addr));
+ pkt->ipi6_ifindex = ifp->ifindex;
+
+ ret = sendmsg(sock, &msg, 0);
+ if (ret < 0) {
+ zlog_err("%s(%u): Tx RA failed, socket %u error %d (%s)",
+ ifp->name, ifp->ifindex, sock, errno,
+ safe_strerror(errno));
+ } else
+ zif->ra_sent++;
}
-static int
-rtadv_timer (struct thread *thread)
+static int rtadv_timer(struct thread *thread)
{
- struct zebra_ns *zns = THREAD_ARG (thread);
- struct vrf *vrf;
- struct listnode *node, *nnode;
- struct interface *ifp;
- struct zebra_if *zif;
- int period;
-
- zns->rtadv.ra_timer = NULL;
- if (zns->rtadv.adv_msec_if_count == 0)
- {
- period = 1000; /* 1 s */
- rtadv_event (zns, RTADV_TIMER, 1 /* 1 s */);
- }
- else
- {
- period = 10; /* 10 ms */
- rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
- }
-
- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
- for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp))
- {
- if (if_is_loopback (ifp) ||
- CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) ||
- ! if_is_operative (ifp))
- continue;
-
- zif = ifp->info;
-
- if (zif->rtadv.AdvSendAdvertisements)
- {
- if (zif->rtadv.inFastRexmit)
- {
- /* We assume we fast rexmit every sec so no additional vars */
- if (--zif->rtadv.NumFastReXmitsRemain <= 0)
- zif->rtadv.inFastRexmit = 0;
-
- if (IS_ZEBRA_DEBUG_SEND)
- zlog_debug("Fast RA Rexmit on interface %s", ifp->name);
-
- rtadv_send_packet (zns->rtadv.sock, ifp);
- }
- else
- {
- zif->rtadv.AdvIntervalTimer -= period;
- if (zif->rtadv.AdvIntervalTimer <= 0)
- {
- /* FIXME: using MaxRtrAdvInterval each time isn't what section
- 6.2.4 of RFC4861 tells to do. */
- zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
- rtadv_send_packet (zns->rtadv.sock, ifp);
- }
- }
- }
- }
-
- return 0;
+ struct zebra_ns *zns = THREAD_ARG(thread);
+ struct vrf *vrf;
+ struct listnode *node, *nnode;
+ struct interface *ifp;
+ struct zebra_if *zif;
+ int period;
+
+ zns->rtadv.ra_timer = NULL;
+ if (zns->rtadv.adv_msec_if_count == 0) {
+ period = 1000; /* 1 s */
+ rtadv_event(zns, RTADV_TIMER, 1 /* 1 s */);
+ } else {
+ period = 10; /* 10 ms */
+ rtadv_event(zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
+ }
+
+ RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id)
+ for (ALL_LIST_ELEMENTS(vrf->iflist, node, nnode, ifp)) {
+ if (if_is_loopback(ifp)
+ || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)
+ || !if_is_operative(ifp))
+ continue;
+
+ zif = ifp->info;
+
+ if (zif->rtadv.AdvSendAdvertisements) {
+ if (zif->rtadv.inFastRexmit) {
+ /* We assume we fast rexmit every sec so no
+ * additional vars */
+ if (--zif->rtadv.NumFastReXmitsRemain <= 0)
+ zif->rtadv.inFastRexmit = 0;
+
+ if (IS_ZEBRA_DEBUG_SEND)
+ zlog_debug(
+ "Fast RA Rexmit on interface %s",
+ ifp->name);
+
+ rtadv_send_packet(zns->rtadv.sock, ifp);
+ } else {
+ zif->rtadv.AdvIntervalTimer -= period;
+ if (zif->rtadv.AdvIntervalTimer <= 0) {
+ /* FIXME: using MaxRtrAdvInterval each
+ time isn't what section
+ 6.2.4 of RFC4861 tells to do. */
+ zif->rtadv.AdvIntervalTimer =
+ zif->rtadv.MaxRtrAdvInterval;
+ rtadv_send_packet(zns->rtadv.sock, ifp);
+ }
+ }
+ }
+ }
+
+ return 0;
}
-static void
-rtadv_process_solicit (struct interface *ifp)
+static void rtadv_process_solicit(struct interface *ifp)
{
- struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
- struct zebra_ns *zns = zvrf->zns;
+ struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
+ struct zebra_ns *zns = zvrf->zns;
- assert (zns);
- rtadv_send_packet (zns->rtadv.sock, ifp);
+ assert(zns);
+ rtadv_send_packet(zns->rtadv.sock, ifp);
}
-static void
-rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp,
- struct sockaddr_in6 *addr)
+static void rtadv_process_advert(u_char *msg, unsigned int len,
+ struct interface *ifp,
+ struct sockaddr_in6 *addr)
{
- struct nd_router_advert *radvert;
- char addr_str[INET6_ADDRSTRLEN];
- struct zebra_if *zif;
- struct prefix p;
-
- zif = ifp->info;
-
- inet_ntop (AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
-
- if (len < sizeof(struct nd_router_advert)) {
- zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
- ifp->name, ifp->ifindex, len, addr_str);
- return;
- }
- if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
- zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s",
- ifp->name, ifp->ifindex, addr_str);
- return;
- }
-
- radvert = (struct nd_router_advert *) msg;
-
- if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) &&
- (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit))
- {
- zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
- ifp->name, ifp->ifindex, addr_str);
- }
-
- if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) &&
- !zif->rtadv.AdvManagedFlag)
- {
- zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
- ifp->name, ifp->ifindex, addr_str);
- }
-
- if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) &&
- !zif->rtadv.AdvOtherConfigFlag)
- {
- zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
- ifp->name, ifp->ifindex, addr_str);
- }
-
- if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) &&
- (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime))
- {
- zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
- ifp->name, ifp->ifindex, addr_str);
- }
-
- if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) &&
- (ntohl(radvert->nd_ra_retransmit) != (unsigned int)zif->rtadv.AdvRetransTimer))
- {
- zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
- ifp->name, ifp->ifindex, addr_str);
- }
-
- /* Create entry for neighbor if not known. */
- p.family = AF_INET6;
- IPV6_ADDR_COPY (&p.u.prefix, &addr->sin6_addr);
- p.prefixlen = IPV6_MAX_PREFIXLEN;
-
- if (!nbr_connected_check(ifp, &p))
- nbr_connected_add_ipv6 (ifp, &addr->sin6_addr);
-}
+ struct nd_router_advert *radvert;
+ char addr_str[INET6_ADDRSTRLEN];
+ struct zebra_if *zif;
+ struct prefix p;
+ zif = ifp->info;
-static void
-rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex, int hoplimit,
- struct sockaddr_in6 *from, struct zebra_ns *zns)
-{
- struct icmp6_hdr *icmph;
- struct interface *ifp;
- struct zebra_if *zif;
- char addr_str[INET6_ADDRSTRLEN];
-
- inet_ntop (AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN);
-
- /* Interface search. */
- ifp = if_lookup_by_index_per_ns (zns, ifindex);
- if (ifp == NULL)
- {
- zlog_warn ("RA/RS received on unknown IF %u from %s",
- ifindex, addr_str);
- 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 (if_is_loopback (ifp) ||
- CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
- return;
-
- /* Check interface configuration. */
- zif = ifp->info;
- if (! zif->rtadv.AdvSendAdvertisements)
- return;
-
- /* ICMP message length check. */
- if (len < sizeof (struct icmp6_hdr))
- {
- zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
- ifp->name, ifp->ifindex, len);
- return;
- }
-
- icmph = (struct icmp6_hdr *) buf;
-
- /* ICMP message type check. */
- if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
- icmph->icmp6_type != ND_ROUTER_ADVERT)
- {
- zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
- ifp->name, ifp->ifindex, icmph->icmp6_type);
- return;
- }
-
- /* Hoplimit check. */
- if (hoplimit >= 0 && hoplimit != 255)
- {
- zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d",
- ifp->name, ifp->ifindex, hoplimit);
- return;
- }
-
- /* Check ICMP message type. */
- if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
- rtadv_process_solicit (ifp);
- else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
- rtadv_process_advert (buf, len, ifp, from);
-
- return;
+ inet_ntop(AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
+
+ if (len < sizeof(struct nd_router_advert)) {
+ zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
+ ifp->name, ifp->ifindex, len, addr_str);
+ return;
+ }
+ if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
+ zlog_warn(
+ "%s(%u): Rx RA with non-linklocal source address from %s",
+ ifp->name, ifp->ifindex, addr_str);
+ return;
+ }
+
+ radvert = (struct nd_router_advert *)msg;
+
+ if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit)
+ && (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit)) {
+ zlog_warn(
+ "%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
+ ifp->name, ifp->ifindex, addr_str);
+ }
+
+ if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)
+ && !zif->rtadv.AdvManagedFlag) {
+ zlog_warn(
+ "%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
+ ifp->name, ifp->ifindex, addr_str);
+ }
+
+ if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
+ && !zif->rtadv.AdvOtherConfigFlag) {
+ zlog_warn(
+ "%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
+ ifp->name, ifp->ifindex, addr_str);
+ }
+
+ if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime)
+ && (ntohl(radvert->nd_ra_reachable)
+ != zif->rtadv.AdvReachableTime)) {
+ zlog_warn(
+ "%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
+ ifp->name, ifp->ifindex, addr_str);
+ }
+
+ if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer)
+ && (ntohl(radvert->nd_ra_retransmit)
+ != (unsigned int)zif->rtadv.AdvRetransTimer)) {
+ zlog_warn(
+ "%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
+ ifp->name, ifp->ifindex, addr_str);
+ }
+
+ /* Create entry for neighbor if not known. */
+ p.family = AF_INET6;
+ IPV6_ADDR_COPY(&p.u.prefix, &addr->sin6_addr);
+ p.prefixlen = IPV6_MAX_PREFIXLEN;
+
+ if (!nbr_connected_check(ifp, &p))
+ nbr_connected_add_ipv6(ifp, &addr->sin6_addr);
}
-static int
-rtadv_read (struct thread *thread)
+
+static void rtadv_process_packet(u_char *buf, unsigned int len,
+ ifindex_t ifindex, int hoplimit,
+ struct sockaddr_in6 *from,
+ struct zebra_ns *zns)
{
- int sock;
- int len;
- u_char buf[RTADV_MSG_SIZE];
- struct sockaddr_in6 from;
- ifindex_t ifindex = 0;
- int hoplimit = -1;
- struct zebra_ns *zns = THREAD_ARG (thread);
+ struct icmp6_hdr *icmph;
+ struct interface *ifp;
+ struct zebra_if *zif;
+ char addr_str[INET6_ADDRSTRLEN];
+
+ inet_ntop(AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN);
+
+ /* Interface search. */
+ ifp = if_lookup_by_index_per_ns(zns, ifindex);
+ if (ifp == NULL) {
+ zlog_warn("RA/RS received on unknown IF %u from %s", ifindex,
+ addr_str);
+ 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 (if_is_loopback(ifp)
+ || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
+ return;
- sock = THREAD_FD (thread);
- zns->rtadv.ra_read = NULL;
+ /* Check interface configuration. */
+ zif = ifp->info;
+ if (!zif->rtadv.AdvSendAdvertisements)
+ return;
- /* Register myself. */
- rtadv_event (zns, RTADV_READ, sock);
+ /* ICMP message length check. */
+ if (len < sizeof(struct icmp6_hdr)) {
+ zlog_warn("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
+ ifp->name, ifp->ifindex, len);
+ return;
+ }
+
+ icmph = (struct icmp6_hdr *)buf;
- len = rtadv_recv_packet (zns, sock, buf, sizeof (buf), &from, &ifindex, &hoplimit);
+ /* ICMP message type check. */
+ if (icmph->icmp6_type != ND_ROUTER_SOLICIT
+ && icmph->icmp6_type != ND_ROUTER_ADVERT) {
+ zlog_warn("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
+ ifp->name, ifp->ifindex, icmph->icmp6_type);
+ return;
+ }
- if (len < 0)
- {
- zlog_warn ("RA/RS recv failed, socket %u error %s",
- sock, safe_strerror (errno));
- return len;
- }
+ /* Hoplimit check. */
+ if (hoplimit >= 0 && hoplimit != 255) {
+ zlog_warn("%s(%u): Rx RA - Invalid hoplimit %d", ifp->name,
+ ifp->ifindex, hoplimit);
+ return;
+ }
- rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from, zns);
+ /* Check ICMP message type. */
+ if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
+ rtadv_process_solicit(ifp);
+ else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
+ rtadv_process_advert(buf, len, ifp, from);
- return 0;
+ return;
}
-static int
-rtadv_make_socket (void)
+static int rtadv_read(struct thread *thread)
{
- int sock;
- int ret = 0;
- struct icmp6_filter filter;
-
- if ( zserv_privs.change (ZPRIVS_RAISE) )
- zlog_err ("rtadv_make_socket: could not raise privs, %s",
- safe_strerror (errno) );
-
- sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
-
- if ( zserv_privs.change (ZPRIVS_LOWER) )
- zlog_err ("rtadv_make_socket: could not lower privs, %s",
- safe_strerror (errno) );
-
- if (sock < 0)
- {
- close (sock);
- return -1;
- }
-
- ret = setsockopt_ipv6_pktinfo (sock, 1);
- if (ret < 0)
- {
- close (sock);
- return ret;
- }
- ret = setsockopt_ipv6_multicast_loop (sock, 0);
- if (ret < 0)
- {
- close (sock);
- return ret;
- }
- ret = setsockopt_ipv6_unicast_hops (sock, 255);
- if (ret < 0)
- {
- close (sock);
- return ret;
- }
- ret = setsockopt_ipv6_multicast_hops (sock, 255);
- if (ret < 0)
- {
- close (sock);
- return ret;
- }
- ret = setsockopt_ipv6_hoplimit (sock, 1);
- if (ret < 0)
- {
- close (sock);
- return ret;
- }
-
- ICMP6_FILTER_SETBLOCKALL(&filter);
- ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
- ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter);
-
- ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
- sizeof (struct icmp6_filter));
- if (ret < 0)
- {
- zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
- return ret;
- }
-
- return sock;
+ int sock;
+ int len;
+ u_char buf[RTADV_MSG_SIZE];
+ struct sockaddr_in6 from;
+ ifindex_t ifindex = 0;
+ int hoplimit = -1;
+ struct zebra_ns *zns = THREAD_ARG(thread);
+
+ sock = THREAD_FD(thread);
+ zns->rtadv.ra_read = NULL;
+
+ /* Register myself. */
+ rtadv_event(zns, RTADV_READ, sock);
+
+ len = rtadv_recv_packet(zns, sock, buf, sizeof(buf), &from, &ifindex,
+ &hoplimit);
+
+ if (len < 0) {
+ zlog_warn("RA/RS recv failed, socket %u error %s", sock,
+ safe_strerror(errno));
+ return len;
+ }
+
+ rtadv_process_packet(buf, (unsigned)len, ifindex, hoplimit, &from, zns);
+
+ return 0;
}
-static struct rtadv_prefix *
-rtadv_prefix_new (void)
+static int rtadv_make_socket(void)
{
- return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
+ int sock;
+ int ret = 0;
+ struct icmp6_filter filter;
+
+ if (zserv_privs.change(ZPRIVS_RAISE))
+ zlog_err("rtadv_make_socket: could not raise privs, %s",
+ safe_strerror(errno));
+
+ sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+
+ if (zserv_privs.change(ZPRIVS_LOWER))
+ zlog_err("rtadv_make_socket: could not lower privs, %s",
+ safe_strerror(errno));
+
+ if (sock < 0) {
+ close(sock);
+ return -1;
+ }
+
+ ret = setsockopt_ipv6_pktinfo(sock, 1);
+ if (ret < 0) {
+ close(sock);
+ return ret;
+ }
+ ret = setsockopt_ipv6_multicast_loop(sock, 0);
+ if (ret < 0) {
+ close(sock);
+ return ret;
+ }
+ ret = setsockopt_ipv6_unicast_hops(sock, 255);
+ if (ret < 0) {
+ close(sock);
+ return ret;
+ }
+ ret = setsockopt_ipv6_multicast_hops(sock, 255);
+ if (ret < 0) {
+ close(sock);
+ return ret;
+ }
+ ret = setsockopt_ipv6_hoplimit(sock, 1);
+ if (ret < 0) {
+ close(sock);
+ return ret;
+ }
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
+
+ ret = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
+ sizeof(struct icmp6_filter));
+ if (ret < 0) {
+ zlog_info("ICMP6_FILTER set fail: %s", safe_strerror(errno));
+ return ret;
+ }
+
+ return sock;
}
-static void
-rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
+static struct rtadv_prefix *rtadv_prefix_new(void)
{
- XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
+ return XCALLOC(MTYPE_RTADV_PREFIX, sizeof(struct rtadv_prefix));
}
-static struct rtadv_prefix *
-rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
+static void rtadv_prefix_free(struct rtadv_prefix *rtadv_prefix)
{
- struct listnode *node;
- struct rtadv_prefix *rprefix;
+ XFREE(MTYPE_RTADV_PREFIX, rtadv_prefix);
+}
- for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
- if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
- return rprefix;
- return NULL;
+static struct rtadv_prefix *rtadv_prefix_lookup(struct list *rplist,
+ struct prefix_ipv6 *p)
+{
+ struct listnode *node;
+ struct rtadv_prefix *rprefix;
+
+ for (ALL_LIST_ELEMENTS_RO(rplist, node, rprefix))
+ if (prefix_same((struct prefix *)&rprefix->prefix,
+ (struct prefix *)p))
+ return rprefix;
+ return NULL;
}
-static struct rtadv_prefix *
-rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
+static struct rtadv_prefix *rtadv_prefix_get(struct list *rplist,
+ struct prefix_ipv6 *p)
{
- struct rtadv_prefix *rprefix;
-
- rprefix = rtadv_prefix_lookup (rplist, p);
- if (rprefix)
- return rprefix;
+ struct rtadv_prefix *rprefix;
+
+ rprefix = rtadv_prefix_lookup(rplist, p);
+ if (rprefix)
+ return rprefix;
- rprefix = rtadv_prefix_new ();
- memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
- listnode_add (rplist, rprefix);
+ rprefix = rtadv_prefix_new();
+ memcpy(&rprefix->prefix, p, sizeof(struct prefix_ipv6));
+ listnode_add(rplist, rprefix);
- return rprefix;
+ return rprefix;
}
-static void
-rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
+static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp)
{
- struct rtadv_prefix *rprefix;
-
- rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix);
-
- /* Set parameters. */
- rprefix->AdvValidLifetime = rp->AdvValidLifetime;
- rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
- rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
- rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
- rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
+ struct rtadv_prefix *rprefix;
+
+ rprefix = rtadv_prefix_get(zif->rtadv.AdvPrefixList, &rp->prefix);
+
+ /* Set parameters. */
+ rprefix->AdvValidLifetime = rp->AdvValidLifetime;
+ rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
+ rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
+ rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
+ rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
}
-static int
-rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
+static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp)
{
- struct rtadv_prefix *rprefix;
-
- rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix);
- if (rprefix != NULL)
- {
- listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix);
- rtadv_prefix_free (rprefix);
- return 1;
- }
- else
- return 0;
+ struct rtadv_prefix *rprefix;
+
+ rprefix = rtadv_prefix_lookup(zif->rtadv.AdvPrefixList, &rp->prefix);
+ if (rprefix != NULL) {
+ listnode_delete(zif->rtadv.AdvPrefixList, (void *)rprefix);
+ rtadv_prefix_free(rprefix);
+ return 1;
+ } else
+ return 0;
}
-static void
-ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status)
+static void ipv6_nd_suppress_ra_set(struct interface *ifp,
+ ipv6_nd_suppress_ra_status status)
{
- struct zebra_if *zif;
- struct zebra_vrf *zvrf;
- struct zebra_ns *zns;
-
- zif = ifp->info;
- zvrf = vrf_info_lookup (ifp->vrf_id);
- zns = zvrf->zns;
-
- if (status == RA_SUPPRESS)
- {
- /* RA is currently enabled */
- if (zif->rtadv.AdvSendAdvertisements)
- {
- zif->rtadv.AdvSendAdvertisements = 0;
- zif->rtadv.AdvIntervalTimer = 0;
- zns->rtadv.adv_if_count--;
-
- if_leave_all_router (zns->rtadv.sock, ifp);
-
- if (zns->rtadv.adv_if_count == 0)
- rtadv_event (zns, RTADV_STOP, 0);
- }
- }
- else
- {
- if (! zif->rtadv.AdvSendAdvertisements)
- {
- zif->rtadv.AdvSendAdvertisements = 1;
- zif->rtadv.AdvIntervalTimer = 0;
- zns->rtadv.adv_if_count++;
-
- if (zif->rtadv.MaxRtrAdvInterval >= 1000)
- {
- /* Enable Fast RA only when RA interval is in secs */
- zif->rtadv.inFastRexmit = 1;
- zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
- }
-
- if_join_all_router (zns->rtadv.sock, ifp);
-
- if (zns->rtadv.adv_if_count == 1)
- rtadv_event (zns, RTADV_START, zns->rtadv.sock);
- }
- }
+ struct zebra_if *zif;
+ struct zebra_vrf *zvrf;
+ struct zebra_ns *zns;
+
+ zif = ifp->info;
+ zvrf = vrf_info_lookup(ifp->vrf_id);
+ zns = zvrf->zns;
+
+ if (status == RA_SUPPRESS) {
+ /* RA is currently enabled */
+ if (zif->rtadv.AdvSendAdvertisements) {
+ zif->rtadv.AdvSendAdvertisements = 0;
+ zif->rtadv.AdvIntervalTimer = 0;
+ zns->rtadv.adv_if_count--;
+
+ if_leave_all_router(zns->rtadv.sock, ifp);
+
+ if (zns->rtadv.adv_if_count == 0)
+ rtadv_event(zns, RTADV_STOP, 0);
+ }
+ } else {
+ if (!zif->rtadv.AdvSendAdvertisements) {
+ zif->rtadv.AdvSendAdvertisements = 1;
+ zif->rtadv.AdvIntervalTimer = 0;
+ zns->rtadv.adv_if_count++;
+
+ if (zif->rtadv.MaxRtrAdvInterval >= 1000) {
+ /* Enable Fast RA only when RA interval is in
+ * secs */
+ zif->rtadv.inFastRexmit = 1;
+ zif->rtadv.NumFastReXmitsRemain =
+ RTADV_NUM_FAST_REXMITS;
+ }
+
+ if_join_all_router(zns->rtadv.sock, ifp);
+
+ if (zns->rtadv.adv_if_count == 1)
+ rtadv_event(zns, RTADV_START, zns->rtadv.sock);
+ }
+ }
}
/*
@@ -808,60 +787,55 @@ ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status statu
* if the operator has explicitly enabled RA. The enable request can also
* specify a RA interval (in seconds).
*/
-void
-zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
- struct zebra_vrf *zvrf, int enable)
+void zebra_interface_radv_set(struct zserv *client, int sock, u_short length,
+ struct zebra_vrf *zvrf, int enable)
{
- struct stream *s;
- unsigned int ifindex;
- struct interface *ifp;
- struct zebra_if *zif;
- int ra_interval;
-
- s = client->ibuf;
-
- /* Get interface index and RA interval. */
- ifindex = stream_getl (s);
- ra_interval = stream_getl (s);
-
- if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
- 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_per_ns (zebra_ns_lookup (NS_DEFAULT), ifindex);
- if (!ifp)
- {
- zlog_warn("%u: IF %u RA %s client %s - interface unknown",
- zvrf_id (zvrf), ifindex, enable ? "enable" : "disable",
- zebra_route_string(client->proto));
- return;
- }
- if (ifp->vrf_id != zvrf_id (zvrf))
- {
- zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
- zvrf_id (zvrf), ifindex, enable ? "enable" : "disable",
- zebra_route_string(client->proto), ifp->vrf_id);
- return;
- }
-
- zif = ifp->info;
- if (enable)
- {
- ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
- if (ra_interval &&
- (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval)
- zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
- }
- else
- {
- if (!zif->rtadv.configured)
- {
- zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
- ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
- }
- }
+ struct stream *s;
+ unsigned int ifindex;
+ struct interface *ifp;
+ struct zebra_if *zif;
+ int ra_interval;
+
+ s = client->ibuf;
+
+ /* Get interface index and RA interval. */
+ ifindex = stream_getl(s);
+ ra_interval = stream_getl(s);
+
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
+ 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_per_ns(zebra_ns_lookup(NS_DEFAULT), ifindex);
+ if (!ifp) {
+ zlog_warn("%u: IF %u RA %s client %s - interface unknown",
+ zvrf_id(zvrf), ifindex, enable ? "enable" : "disable",
+ zebra_route_string(client->proto));
+ return;
+ }
+ if (ifp->vrf_id != zvrf_id(zvrf)) {
+ zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
+ zvrf_id(zvrf), ifindex, enable ? "enable" : "disable",
+ zebra_route_string(client->proto), ifp->vrf_id);
+ return;
+ }
+
+ zif = ifp->info;
+ if (enable) {
+ ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
+ if (ra_interval
+ && (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval)
+ zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
+ } else {
+ if (!zif->rtadv.configured) {
+ zif->rtadv.MaxRtrAdvInterval =
+ RTADV_MAX_RTR_ADV_INTERVAL;
+ ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
+ }
+ }
}
DEFUN (ipv6_nd_suppress_ra,
@@ -871,20 +845,19 @@ DEFUN (ipv6_nd_suppress_ra,
"Neighbor discovery\n"
"Suppress Router Advertisement\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;
- }
-
- ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
- zif->rtadv.configured = 0;
- return CMD_SUCCESS;
+ 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;
+ }
+
+ ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
+ zif->rtadv.configured = 0;
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_suppress_ra,
@@ -895,20 +868,19 @@ DEFUN (no_ipv6_nd_suppress_ra,
"Neighbor discovery\n"
"Suppress Router Advertisement\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;
- }
-
- ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
- zif->rtadv.configured = 1;
- return CMD_SUCCESS;
+ 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;
+ }
+
+ ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
+ zif->rtadv.configured = 1;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_ra_interval_msec,
@@ -920,33 +892,33 @@ DEFUN (ipv6_nd_ra_interval_msec,
"Router Advertisement interval in milliseconds\n"
"Router Advertisement interval in milliseconds\n")
{
- int idx_number = 4;
- VTY_DECLVAR_CONTEXT (interface, ifp);
- unsigned interval;
- struct zebra_if *zif = ifp->info;
- struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
- struct zebra_ns *zns;
-
- zns = zvrf->zns;
- interval = strtoul(argv[idx_number]->arg, NULL, 10);
- if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
- {
- vty_out (vty,
- "This ra-interval would conflict with configured ra-lifetime!\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zns->rtadv.adv_msec_if_count--;
-
- if (interval % 1000)
- zns->rtadv.adv_msec_if_count++;
-
- zif->rtadv.MaxRtrAdvInterval = interval;
- zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
- zif->rtadv.AdvIntervalTimer = 0;
-
- return CMD_SUCCESS;
+ int idx_number = 4;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ unsigned interval;
+ struct zebra_if *zif = ifp->info;
+ struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
+ struct zebra_ns *zns;
+
+ zns = zvrf->zns;
+ interval = strtoul(argv[idx_number]->arg, NULL, 10);
+ if ((zif->rtadv.AdvDefaultLifetime != -1
+ && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) {
+ vty_out(vty,
+ "This ra-interval would conflict with configured ra-lifetime!\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (zif->rtadv.MaxRtrAdvInterval % 1000)
+ zns->rtadv.adv_msec_if_count--;
+
+ if (interval % 1000)
+ zns->rtadv.adv_msec_if_count++;
+
+ zif->rtadv.MaxRtrAdvInterval = interval;
+ zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
+ zif->rtadv.AdvIntervalTimer = 0;
+
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_ra_interval,
@@ -957,33 +929,33 @@ DEFUN (ipv6_nd_ra_interval,
"Router Advertisement interval\n"
"Router Advertisement interval in seconds\n")
{
- int idx_number = 3;
- VTY_DECLVAR_CONTEXT (interface, ifp);
- unsigned interval;
- struct zebra_if *zif = ifp->info;
- struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
- struct zebra_ns *zns;
-
- zns = zvrf->zns;
- interval = strtoul(argv[idx_number]->arg, NULL, 10);
- if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
- {
- vty_out (vty,
- "This ra-interval would conflict with configured ra-lifetime!\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zns->rtadv.adv_msec_if_count--;
-
- /* convert to milliseconds */
- interval = interval * 1000;
-
- zif->rtadv.MaxRtrAdvInterval = interval;
- zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
- zif->rtadv.AdvIntervalTimer = 0;
-
- return CMD_SUCCESS;
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ unsigned interval;
+ struct zebra_if *zif = ifp->info;
+ struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
+ struct zebra_ns *zns;
+
+ zns = zvrf->zns;
+ interval = strtoul(argv[idx_number]->arg, NULL, 10);
+ if ((zif->rtadv.AdvDefaultLifetime != -1
+ && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) {
+ vty_out(vty,
+ "This ra-interval would conflict with configured ra-lifetime!\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (zif->rtadv.MaxRtrAdvInterval % 1000)
+ zns->rtadv.adv_msec_if_count--;
+
+ /* convert to milliseconds */
+ interval = interval * 1000;
+
+ zif->rtadv.MaxRtrAdvInterval = interval;
+ zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
+ zif->rtadv.AdvIntervalTimer = 0;
+
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_ra_interval,
@@ -997,22 +969,22 @@ DEFUN (no_ipv6_nd_ra_interval,
"Specify millisecond router advertisement interval\n"
"Router Advertisement interval in milliseconds\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
- struct zebra_vrf *zvrf;
- struct zebra_ns *zns;
-
- zvrf = vrf_info_lookup (ifp->vrf_id);
- zns = zvrf->zns;
-
- if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zns->rtadv.adv_msec_if_count--;
-
- zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
- zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
- zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
+ struct zebra_vrf *zvrf;
+ struct zebra_ns *zns;
+
+ zvrf = vrf_info_lookup(ifp->vrf_id);
+ zns = zvrf->zns;
+
+ if (zif->rtadv.MaxRtrAdvInterval % 1000)
+ zns->rtadv.adv_msec_if_count--;
+
+ zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
+ zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
+ zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
+
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_ra_lifetime,
@@ -1023,27 +995,26 @@ DEFUN (ipv6_nd_ra_lifetime,
"Router lifetime\n"
"Router lifetime in seconds (0 stands for a non-default gw)\n")
{
- int idx_number = 3;
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
- int lifetime;
-
- lifetime = strtoul(argv[idx_number]->arg, NULL, 10);
-
- /* The value to be placed in the Router Lifetime field
- * of Router Advertisements sent from the interface,
- * in seconds. MUST be either zero or between
- * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
- if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval))
- {
- vty_out (vty,
- "This ra-lifetime would conflict with configured ra-interval\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- zif->rtadv.AdvDefaultLifetime = lifetime;
-
- return CMD_SUCCESS;
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
+ int lifetime;
+
+ lifetime = strtoul(argv[idx_number]->arg, NULL, 10);
+
+ /* The value to be placed in the Router Lifetime field
+ * of Router Advertisements sent from the interface,
+ * in seconds. MUST be either zero or between
+ * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
+ if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval)) {
+ vty_out(vty,
+ "This ra-lifetime would conflict with configured ra-interval\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ zif->rtadv.AdvDefaultLifetime = lifetime;
+
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_ra_lifetime,
@@ -1055,12 +1026,12 @@ DEFUN (no_ipv6_nd_ra_lifetime,
"Router lifetime\n"
"Router lifetime in seconds (0 stands for a non-default gw)\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvDefaultLifetime = -1;
+ zif->rtadv.AdvDefaultLifetime = -1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_reachable_time,
@@ -1071,11 +1042,11 @@ DEFUN (ipv6_nd_reachable_time,
"Reachable time\n"
"Reachable time in milliseconds\n")
{
- int idx_number = 3;
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvReachableTime = strtoul(argv[idx_number]->arg, NULL, 10);
- return CMD_SUCCESS;
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
+ zif->rtadv.AdvReachableTime = strtoul(argv[idx_number]->arg, NULL, 10);
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_reachable_time,
@@ -1087,12 +1058,12 @@ DEFUN (no_ipv6_nd_reachable_time,
"Reachable time\n"
"Reachable time in milliseconds\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvReachableTime = 0;
+ zif->rtadv.AdvReachableTime = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_homeagent_preference,
@@ -1103,11 +1074,12 @@ DEFUN (ipv6_nd_homeagent_preference,
"Home Agent preference\n"
"preference value (default is 0, least preferred)\n")
{
- int idx_number = 3;
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
- zif->rtadv.HomeAgentPreference = strtoul(argv[idx_number]->arg, NULL, 10);
- return CMD_SUCCESS;
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
+ zif->rtadv.HomeAgentPreference =
+ strtoul(argv[idx_number]->arg, NULL, 10);
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_homeagent_preference,
@@ -1119,12 +1091,12 @@ DEFUN (no_ipv6_nd_homeagent_preference,
"Home Agent preference\n"
"preference value (default is 0, least preferred)\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.HomeAgentPreference = 0;
+ zif->rtadv.HomeAgentPreference = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_homeagent_lifetime,
@@ -1135,11 +1107,11 @@ DEFUN (ipv6_nd_homeagent_lifetime,
"Home Agent lifetime\n"
"Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
{
- int idx_number = 3;
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
- zif->rtadv.HomeAgentLifetime = strtoul(argv[idx_number]->arg, NULL, 10);
- return CMD_SUCCESS;
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
+ zif->rtadv.HomeAgentLifetime = strtoul(argv[idx_number]->arg, NULL, 10);
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_homeagent_lifetime,
@@ -1151,12 +1123,12 @@ DEFUN (no_ipv6_nd_homeagent_lifetime,
"Home Agent lifetime\n"
"Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.HomeAgentLifetime = -1;
+ zif->rtadv.HomeAgentLifetime = -1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_managed_config_flag,
@@ -1166,12 +1138,12 @@ DEFUN (ipv6_nd_managed_config_flag,
"Neighbor discovery\n"
"Managed address configuration flag\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvManagedFlag = 1;
+ zif->rtadv.AdvManagedFlag = 1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_managed_config_flag,
@@ -1182,12 +1154,12 @@ DEFUN (no_ipv6_nd_managed_config_flag,
"Neighbor discovery\n"
"Managed address configuration flag\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvManagedFlag = 0;
+ zif->rtadv.AdvManagedFlag = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_homeagent_config_flag,
@@ -1197,12 +1169,12 @@ DEFUN (ipv6_nd_homeagent_config_flag,
"Neighbor discovery\n"
"Home Agent configuration flag\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvHomeAgentFlag = 1;
+ zif->rtadv.AdvHomeAgentFlag = 1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_homeagent_config_flag,
@@ -1213,12 +1185,12 @@ DEFUN (no_ipv6_nd_homeagent_config_flag,
"Neighbor discovery\n"
"Home Agent configuration flag\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvHomeAgentFlag = 0;
+ zif->rtadv.AdvHomeAgentFlag = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_adv_interval_config_option,
@@ -1228,12 +1200,12 @@ DEFUN (ipv6_nd_adv_interval_config_option,
"Neighbor discovery\n"
"Advertisement Interval Option\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvIntervalOption = 1;
+ zif->rtadv.AdvIntervalOption = 1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_adv_interval_config_option,
@@ -1244,12 +1216,12 @@ DEFUN (no_ipv6_nd_adv_interval_config_option,
"Neighbor discovery\n"
"Advertisement Interval Option\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvIntervalOption = 0;
+ zif->rtadv.AdvIntervalOption = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_other_config_flag,
@@ -1259,12 +1231,12 @@ DEFUN (ipv6_nd_other_config_flag,
"Neighbor discovery\n"
"Other statefull configuration flag\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvOtherConfigFlag = 1;
+ zif->rtadv.AdvOtherConfigFlag = 1;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_other_config_flag,
@@ -1275,12 +1247,12 @@ DEFUN (no_ipv6_nd_other_config_flag,
"Neighbor discovery\n"
"Other statefull configuration flag\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvOtherConfigFlag = 0;
+ zif->rtadv.AdvOtherConfigFlag = 0;
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_prefix,
@@ -1300,63 +1272,70 @@ DEFUN (ipv6_nd_prefix,
"Do not use prefix for autoconfiguration\n"
"Do not use prefix for onlink determination\n")
{
- /* prelude */
- char *prefix = argv[3]->arg;
- int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN || strmatch (argv[4]->text, "infinite"));
- int routeropts = lifetimes ? argc > 6 : argc > 4;
-
- int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0;
-
- char *lifetime = NULL, *preflifetime = NULL;
- int routeraddr = 0, offlink = 0, noautoconf = 0;
- if (lifetimes)
- {
- lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg : argv[4]->text;
- preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg : argv[5]->text;
- }
- if (routeropts)
- {
- routeraddr = strmatch (argv[idx_routeropts]->text, "router-address");
- if (!routeraddr)
- {
- offlink = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "off-link"));
- noautoconf = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "no-autoconfig"));
- }
- }
-
- /* business */
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zebra_if = ifp->info;
- int ret;
- struct rtadv_prefix rp;
-
- ret = str2prefix_ipv6 (prefix, &rp.prefix);
- if (!ret)
- {
- vty_out (vty, "Malformed IPv6 prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
- rp.AdvOnLinkFlag = !offlink;
- rp.AdvAutonomousFlag = !noautoconf;
- rp.AdvRouterAddressFlag = routeraddr;
- rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
- rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
-
- if (lifetimes)
- {
- rp.AdvValidLifetime = strmatch (lifetime, "infinite") ? UINT32_MAX : strtoll (lifetime, NULL, 10);
- rp.AdvPreferredLifetime = strmatch (preflifetime, "infinite") ? UINT32_MAX : strtoll (preflifetime, NULL, 10);
- if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
- {
- vty_out (vty, "Invalid preferred lifetime\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
-
- rtadv_prefix_set (zebra_if, &rp);
-
- return CMD_SUCCESS;
+ /* prelude */
+ char *prefix = argv[3]->arg;
+ int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN
+ || strmatch(argv[4]->text, "infinite"));
+ int routeropts = lifetimes ? argc > 6 : argc > 4;
+
+ int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0;
+
+ char *lifetime = NULL, *preflifetime = NULL;
+ int routeraddr = 0, offlink = 0, noautoconf = 0;
+ if (lifetimes) {
+ lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg
+ : argv[4]->text;
+ preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg
+ : argv[5]->text;
+ }
+ if (routeropts) {
+ routeraddr =
+ strmatch(argv[idx_routeropts]->text, "router-address");
+ if (!routeraddr) {
+ offlink = (argc > idx_routeropts + 1
+ || strmatch(argv[idx_routeropts]->text,
+ "off-link"));
+ noautoconf = (argc > idx_routeropts + 1
+ || strmatch(argv[idx_routeropts]->text,
+ "no-autoconfig"));
+ }
+ }
+
+ /* business */
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zebra_if = ifp->info;
+ int ret;
+ struct rtadv_prefix rp;
+
+ ret = str2prefix_ipv6(prefix, &rp.prefix);
+ if (!ret) {
+ vty_out(vty, "Malformed IPv6 prefix\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */
+ rp.AdvOnLinkFlag = !offlink;
+ rp.AdvAutonomousFlag = !noautoconf;
+ rp.AdvRouterAddressFlag = routeraddr;
+ rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
+ rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
+
+ if (lifetimes) {
+ rp.AdvValidLifetime = strmatch(lifetime, "infinite")
+ ? UINT32_MAX
+ : strtoll(lifetime, NULL, 10);
+ rp.AdvPreferredLifetime =
+ strmatch(preflifetime, "infinite")
+ ? UINT32_MAX
+ : strtoll(preflifetime, NULL, 10);
+ if (rp.AdvPreferredLifetime > rp.AdvValidLifetime) {
+ vty_out(vty, "Invalid preferred lifetime\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
+ rtadv_prefix_set(zebra_if, &rp);
+
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_prefix,
@@ -1377,28 +1356,26 @@ DEFUN (no_ipv6_nd_prefix,
"Do not use prefix for autoconfiguration\n"
"Do not use prefix for onlink determination\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zebra_if = ifp->info;
- int ret;
- struct rtadv_prefix rp;
- char *prefix = argv[4]->arg;
-
- ret = str2prefix_ipv6 (prefix, &rp.prefix);
- if (!ret)
- {
- vty_out (vty, "Malformed IPv6 prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
-
- ret = rtadv_prefix_reset (zebra_if, &rp);
- if (!ret)
- {
- vty_out (vty, "Non-existant IPv6 prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zebra_if = ifp->info;
+ int ret;
+ struct rtadv_prefix rp;
+ char *prefix = argv[4]->arg;
+
+ ret = str2prefix_ipv6(prefix, &rp.prefix);
+ if (!ret) {
+ vty_out(vty, "Malformed IPv6 prefix\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */
+
+ ret = rtadv_prefix_reset(zebra_if, &rp);
+ if (!ret) {
+ vty_out(vty, "Non-existant IPv6 prefix\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_router_preference,
@@ -1411,22 +1388,22 @@ DEFUN (ipv6_nd_router_preference,
"Medium default router preference (default)\n"
"Low default router preference\n")
{
- int idx_high_medium_low = 3;
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
- int i = 0;
-
- while (0 != rtadv_pref_strs[i])
- {
- if (strncmp (argv[idx_high_medium_low]->arg, rtadv_pref_strs[i], 1) == 0)
- {
- zif->rtadv.DefaultPreference = i;
- return CMD_SUCCESS;
+ int idx_high_medium_low = 3;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
+ int i = 0;
+
+ while (0 != rtadv_pref_strs[i]) {
+ if (strncmp(argv[idx_high_medium_low]->arg, rtadv_pref_strs[i],
+ 1)
+ == 0) {
+ zif->rtadv.DefaultPreference = i;
+ return CMD_SUCCESS;
+ }
+ i++;
}
- i++;
- }
- return CMD_ERR_NO_MATCH;
+ return CMD_ERR_NO_MATCH;
}
DEFUN (no_ipv6_nd_router_preference,
@@ -1440,12 +1417,13 @@ DEFUN (no_ipv6_nd_router_preference,
"Medium default router preference (default)\n"
"Low default router preference\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
- zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
+ zif->rtadv.DefaultPreference =
+ RTADV_PREF_MEDIUM; /* Default per RFC4191. */
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (ipv6_nd_mtu,
@@ -1456,11 +1434,11 @@ DEFUN (ipv6_nd_mtu,
"Advertised MTU\n"
"MTU in bytes\n")
{
- int idx_number = 3;
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvLinkMTU = strtoul(argv[idx_number]->arg, NULL, 10);
- return CMD_SUCCESS;
+ int idx_number = 3;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
+ zif->rtadv.AdvLinkMTU = strtoul(argv[idx_number]->arg, NULL, 10);
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_nd_mtu,
@@ -1472,253 +1450,246 @@ DEFUN (no_ipv6_nd_mtu,
"Advertised MTU\n"
"MTU in bytes\n")
{
- VTY_DECLVAR_CONTEXT (interface, ifp);
- struct zebra_if *zif = ifp->info;
- zif->rtadv.AdvLinkMTU = 0;
- return CMD_SUCCESS;
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct zebra_if *zif = ifp->info;
+ zif->rtadv.AdvLinkMTU = 0;
+ return CMD_SUCCESS;
}
/* Write configuration about router advertisement. */
-void
-rtadv_config_write (struct vty *vty, struct interface *ifp)
+void rtadv_config_write(struct vty *vty, struct interface *ifp)
{
- struct zebra_if *zif;
- struct listnode *node;
- struct rtadv_prefix *rprefix;
- char buf[PREFIX_STRLEN];
- int interval;
-
- zif = ifp->info;
-
- if (!(if_is_loopback (ifp) ||
- CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)))
- {
- if (zif->rtadv.AdvSendAdvertisements)
- vty_out (vty, " no ipv6 nd suppress-ra\n");
- }
-
- interval = zif->rtadv.MaxRtrAdvInterval;
- if (interval % 1000)
- vty_out (vty, " ipv6 nd ra-interval msec %d\n",interval);
- else
- if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
- vty_out (vty, " ipv6 nd ra-interval %d\n",interval / 1000);
-
- if (zif->rtadv.AdvIntervalOption)
- vty_out (vty, " ipv6 nd adv-interval-option\n");
-
- if (zif->rtadv.AdvDefaultLifetime != -1)
- vty_out (vty, " ipv6 nd ra-lifetime %d\n",zif->rtadv.AdvDefaultLifetime);
-
- if (zif->rtadv.HomeAgentPreference)
- vty_out (vty, " ipv6 nd home-agent-preference %u\n",
- zif->rtadv.HomeAgentPreference);
-
- if (zif->rtadv.HomeAgentLifetime != -1)
- vty_out (vty, " ipv6 nd home-agent-lifetime %u\n",
- zif->rtadv.HomeAgentLifetime);
-
- if (zif->rtadv.AdvHomeAgentFlag)
- vty_out (vty, " ipv6 nd home-agent-config-flag\n");
-
- if (zif->rtadv.AdvReachableTime)
- vty_out (vty, " ipv6 nd reachable-time %d\n",
- zif->rtadv.AdvReachableTime);
-
- if (zif->rtadv.AdvManagedFlag)
- vty_out (vty, " ipv6 nd managed-config-flag\n");
-
- if (zif->rtadv.AdvOtherConfigFlag)
- vty_out (vty, " ipv6 nd other-config-flag\n");
-
- if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
- vty_out (vty, " ipv6 nd router-preference %s\n",
- rtadv_pref_strs[zif->rtadv.DefaultPreference]);
-
- if (zif->rtadv.AdvLinkMTU)
- vty_out (vty, " ipv6 nd mtu %d\n", zif->rtadv.AdvLinkMTU);
-
- for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
- {
- vty_out (vty, " ipv6 nd prefix %s",
- prefix2str (&rprefix->prefix, buf, sizeof(buf)));
- if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) ||
- (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME))
- {
- if (rprefix->AdvValidLifetime == UINT32_MAX)
- vty_out (vty, " infinite");
- else
- vty_out (vty, " %u", rprefix->AdvValidLifetime);
- if (rprefix->AdvPreferredLifetime == UINT32_MAX)
- vty_out (vty, " infinite");
- else
- vty_out (vty, " %u", rprefix->AdvPreferredLifetime);
+ struct zebra_if *zif;
+ struct listnode *node;
+ struct rtadv_prefix *rprefix;
+ char buf[PREFIX_STRLEN];
+ int interval;
+
+ zif = ifp->info;
+
+ if (!(if_is_loopback(ifp)
+ || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))) {
+ if (zif->rtadv.AdvSendAdvertisements)
+ vty_out(vty, " no ipv6 nd suppress-ra\n");
+ }
+
+ interval = zif->rtadv.MaxRtrAdvInterval;
+ if (interval % 1000)
+ vty_out(vty, " ipv6 nd ra-interval msec %d\n", interval);
+ else if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
+ vty_out(vty, " ipv6 nd ra-interval %d\n", interval / 1000);
+
+ if (zif->rtadv.AdvIntervalOption)
+ vty_out(vty, " ipv6 nd adv-interval-option\n");
+
+ if (zif->rtadv.AdvDefaultLifetime != -1)
+ vty_out(vty, " ipv6 nd ra-lifetime %d\n",
+ zif->rtadv.AdvDefaultLifetime);
+
+ if (zif->rtadv.HomeAgentPreference)
+ vty_out(vty, " ipv6 nd home-agent-preference %u\n",
+ zif->rtadv.HomeAgentPreference);
+
+ if (zif->rtadv.HomeAgentLifetime != -1)
+ vty_out(vty, " ipv6 nd home-agent-lifetime %u\n",
+ zif->rtadv.HomeAgentLifetime);
+
+ if (zif->rtadv.AdvHomeAgentFlag)
+ vty_out(vty, " ipv6 nd home-agent-config-flag\n");
+
+ if (zif->rtadv.AdvReachableTime)
+ vty_out(vty, " ipv6 nd reachable-time %d\n",
+ zif->rtadv.AdvReachableTime);
+
+ if (zif->rtadv.AdvManagedFlag)
+ vty_out(vty, " ipv6 nd managed-config-flag\n");
+
+ if (zif->rtadv.AdvOtherConfigFlag)
+ vty_out(vty, " ipv6 nd other-config-flag\n");
+
+ if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
+ vty_out(vty, " ipv6 nd router-preference %s\n",
+ rtadv_pref_strs[zif->rtadv.DefaultPreference]);
+
+ if (zif->rtadv.AdvLinkMTU)
+ vty_out(vty, " ipv6 nd mtu %d\n", zif->rtadv.AdvLinkMTU);
+
+ for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) {
+ vty_out(vty, " ipv6 nd prefix %s",
+ prefix2str(&rprefix->prefix, buf, sizeof(buf)));
+ if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME)
+ || (rprefix->AdvPreferredLifetime
+ != RTADV_PREFERRED_LIFETIME)) {
+ if (rprefix->AdvValidLifetime == UINT32_MAX)
+ vty_out(vty, " infinite");
+ else
+ vty_out(vty, " %u", rprefix->AdvValidLifetime);
+ if (rprefix->AdvPreferredLifetime == UINT32_MAX)
+ vty_out(vty, " infinite");
+ else
+ vty_out(vty, " %u",
+ rprefix->AdvPreferredLifetime);
+ }
+ if (!rprefix->AdvOnLinkFlag)
+ vty_out(vty, " off-link");
+ if (!rprefix->AdvAutonomousFlag)
+ vty_out(vty, " no-autoconfig");
+ if (rprefix->AdvRouterAddressFlag)
+ vty_out(vty, " router-address");
+ vty_out(vty, "\n");
}
- if (!rprefix->AdvOnLinkFlag)
- vty_out (vty, " off-link");
- if (!rprefix->AdvAutonomousFlag)
- vty_out (vty, " no-autoconfig");
- if (rprefix->AdvRouterAddressFlag)
- vty_out (vty, " router-address");
- vty_out (vty, "\n");
- }
}
-static void
-rtadv_event (struct zebra_ns *zns, enum rtadv_event event, int val)
+static void rtadv_event(struct zebra_ns *zns, enum rtadv_event event, int val)
{
- struct rtadv *rtadv = &zns->rtadv;
-
- switch (event)
- {
- case RTADV_START:
- thread_add_read(zebrad.master, rtadv_read, zns, val, &rtadv->ra_read);
- thread_add_event(zebrad.master, rtadv_timer, zns, 0, &rtadv->ra_timer);
- break;
- case RTADV_STOP:
- if (rtadv->ra_timer)
- {
- thread_cancel (rtadv->ra_timer);
- rtadv->ra_timer = NULL;
+ struct rtadv *rtadv = &zns->rtadv;
+
+ switch (event) {
+ case RTADV_START:
+ thread_add_read(zebrad.master, rtadv_read, zns, val,
+ &rtadv->ra_read);
+ thread_add_event(zebrad.master, rtadv_timer, zns, 0,
+ &rtadv->ra_timer);
+ break;
+ case RTADV_STOP:
+ if (rtadv->ra_timer) {
+ thread_cancel(rtadv->ra_timer);
+ rtadv->ra_timer = NULL;
+ }
+ if (rtadv->ra_read) {
+ thread_cancel(rtadv->ra_read);
+ rtadv->ra_read = NULL;
+ }
+ break;
+ case RTADV_TIMER:
+ thread_add_timer(zebrad.master, rtadv_timer, zns, val,
+ &rtadv->ra_timer);
+ break;
+ case RTADV_TIMER_MSEC:
+ thread_add_timer_msec(zebrad.master, rtadv_timer, zns, val,
+ &rtadv->ra_timer);
+ break;
+ case RTADV_READ:
+ thread_add_read(zebrad.master, rtadv_read, zns, val,
+ &rtadv->ra_read);
+ break;
+ default:
+ break;
}
- if (rtadv->ra_read)
- {
- thread_cancel (rtadv->ra_read);
- rtadv->ra_read = NULL;
- }
- break;
- case RTADV_TIMER:
- thread_add_timer(zebrad.master, rtadv_timer, zns, val, &rtadv->ra_timer);
- break;
- case RTADV_TIMER_MSEC:
- thread_add_timer_msec(zebrad.master, rtadv_timer, zns, val,
- &rtadv->ra_timer);
- break;
- case RTADV_READ:
- thread_add_read(zebrad.master, rtadv_read, zns, val, &rtadv->ra_read);
- break;
- default:
- break;
- }
- return;
+ return;
}
-void
-rtadv_init (struct zebra_ns *zns)
+void rtadv_init(struct zebra_ns *zns)
{
- zns->rtadv.sock = rtadv_make_socket ();
+ zns->rtadv.sock = rtadv_make_socket();
}
-void
-rtadv_terminate (struct zebra_ns *zns)
+void rtadv_terminate(struct zebra_ns *zns)
{
- rtadv_event (zns, RTADV_STOP, 0);
- if (zns->rtadv.sock >= 0)
- {
- close (zns->rtadv.sock);
- zns->rtadv.sock = -1;
- }
-
- zns->rtadv.adv_if_count = 0;
- zns->rtadv.adv_msec_if_count = 0;
+ rtadv_event(zns, RTADV_STOP, 0);
+ if (zns->rtadv.sock >= 0) {
+ close(zns->rtadv.sock);
+ zns->rtadv.sock = -1;
+ }
+
+ zns->rtadv.adv_if_count = 0;
+ zns->rtadv.adv_msec_if_count = 0;
}
-void
-rtadv_cmd_init (void)
+void rtadv_cmd_init(void)
{
- 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);
- install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
- install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
- install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_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);
+ install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
+ install_element(INTERFACE_NODE,
+ &ipv6_nd_adv_interval_config_option_cmd);
+ install_element(INTERFACE_NODE,
+ &no_ipv6_nd_adv_interval_config_option_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_prefix_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
+ install_element(INTERFACE_NODE, &ipv6_nd_mtu_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
}
-static int
-if_join_all_router (int sock, struct interface *ifp)
+static int if_join_all_router(int sock, struct interface *ifp)
{
- int ret;
+ int ret;
- struct ipv6_mreq mreq;
+ struct ipv6_mreq mreq;
- memset (&mreq, 0, sizeof (struct ipv6_mreq));
- inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
- mreq.ipv6mr_interface = ifp->ifindex;
+ memset(&mreq, 0, sizeof(struct ipv6_mreq));
+ inet_pton(AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
+ mreq.ipv6mr_interface = ifp->ifindex;
- ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
- (char *) &mreq, sizeof mreq);
- if (ret < 0)
- zlog_warn ("%s(%u): Failed to join group, socket %u error %s",
- ifp->name, ifp->ifindex, sock, safe_strerror (errno));
+ ret = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq,
+ sizeof mreq);
+ if (ret < 0)
+ zlog_warn("%s(%u): Failed to join group, socket %u error %s",
+ ifp->name, ifp->ifindex, sock, safe_strerror(errno));
- if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u",
- ifp->name, ifp->ifindex, sock);
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "%s(%u): Join All-Routers multicast group, socket %u",
+ ifp->name, ifp->ifindex, sock);
- return 0;
+ return 0;
}
-static int
-if_leave_all_router (int sock, struct interface *ifp)
+static int if_leave_all_router(int sock, struct interface *ifp)
{
- int ret;
+ int ret;
- struct ipv6_mreq mreq;
+ struct ipv6_mreq mreq;
- memset (&mreq, 0, sizeof (struct ipv6_mreq));
- inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
- mreq.ipv6mr_interface = ifp->ifindex;
+ memset(&mreq, 0, sizeof(struct ipv6_mreq));
+ inet_pton(AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
+ mreq.ipv6mr_interface = ifp->ifindex;
- ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
- (char *) &mreq, sizeof mreq);
- if (ret < 0)
- zlog_warn ("%s(%u): Failed to leave group, socket %u error %s",
- ifp->name, ifp->ifindex, sock,safe_strerror (errno));
+ ret = setsockopt(sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char *)&mreq,
+ sizeof mreq);
+ if (ret < 0)
+ zlog_warn("%s(%u): Failed to leave group, socket %u error %s",
+ ifp->name, ifp->ifindex, sock, safe_strerror(errno));
- if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u",
- ifp->name, ifp->ifindex, sock);
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "%s(%u): Leave All-Routers multicast group, socket %u",
+ ifp->name, ifp->ifindex, sock);
- return 0;
+ return 0;
}
#else
-void
-rtadv_init (struct zebra_ns *zns)
+void rtadv_init(struct zebra_ns *zns)
{
- /* Empty.*/;
+ /* Empty.*/;
}
-void
-rtadv_terminate (struct zebra_ns *zns)
+void rtadv_terminate(struct zebra_ns *zns)
{
- /* Empty.*/;
+ /* Empty.*/;
}
-void
-rtadv_cmd_init (void)
+void rtadv_cmd_init(void)
{
- /* Empty.*/;
+ /* Empty.*/;
}
#endif /* HAVE_RTADV */