version 1.1, 2012/02/21 17:26:11
|
version 1.1.1.3, 2016/11/02 10:09:10
|
Line 31
|
Line 31
|
#include "linklist.h" |
#include "linklist.h" |
#include "command.h" |
#include "command.h" |
#include "privs.h" |
#include "privs.h" |
|
#include "vrf.h" |
|
|
#include "zebra/interface.h" |
#include "zebra/interface.h" |
#include "zebra/rtadv.h" |
#include "zebra/rtadv.h" |
Line 40
|
Line 41
|
|
|
extern struct zebra_privs_t zserv_privs; |
extern struct zebra_privs_t zserv_privs; |
|
|
#if defined (HAVE_IPV6) && defined (RTADV) | #if defined (HAVE_IPV6) && defined (HAVE_RTADV) |
|
|
#ifdef OPEN_BSD |
#ifdef OPEN_BSD |
#include <netinet/icmp6.h> |
#include <netinet/icmp6.h> |
Line 62 extern struct zebra_t zebrad;
|
Line 63 extern struct zebra_t zebrad;
|
enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER, |
enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER, |
RTADV_TIMER_MSEC, RTADV_READ}; |
RTADV_TIMER_MSEC, RTADV_READ}; |
|
|
static void rtadv_event (enum rtadv_event, int); | static void rtadv_event (struct zebra_vrf *, enum rtadv_event, int); |
|
|
static int if_join_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 if_leave_all_router (int, struct interface *); |
|
|
/* Structure which hold status of router advertisement. */ |
|
struct rtadv |
|
{ |
|
int sock; |
|
|
|
int adv_if_count; |
|
int adv_msec_if_count; |
|
|
|
struct thread *ra_read; |
|
struct thread *ra_timer; |
|
}; |
|
|
|
struct rtadv *rtadv = NULL; |
|
|
|
static struct rtadv * |
|
rtadv_new (void) |
|
{ |
|
return XCALLOC (MTYPE_TMP, sizeof (struct rtadv)); |
|
} |
|
|
|
static int |
static int |
rtadv_recv_packet (int sock, u_char *buf, int buflen, |
rtadv_recv_packet (int sock, u_char *buf, int buflen, |
struct sockaddr_in6 *from, unsigned int *ifindex, | struct sockaddr_in6 *from, ifindex_t *ifindex, |
int *hoplimit) |
int *hoplimit) |
{ |
{ |
int ret; |
int ret; |
Line 163 rtadv_send_packet (int sock, struct interface *ifp)
|
Line 144 rtadv_send_packet (int sock, struct interface *ifp)
|
struct rtadv_prefix *rprefix; |
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}; |
u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; |
struct listnode *node; |
struct listnode *node; |
|
u_int16_t pkt_RouterLifetime; |
|
|
/* |
/* |
* Allocate control message bufffer. This is dynamic because |
* Allocate control message bufffer. This is dynamic because |
Line 190 rtadv_send_packet (int sock, struct interface *ifp)
|
Line 172 rtadv_send_packet (int sock, struct interface *ifp)
|
addr.sin6_len = sizeof (struct sockaddr_in6); |
addr.sin6_len = sizeof (struct sockaddr_in6); |
#endif /* SIN6_LEN */ |
#endif /* SIN6_LEN */ |
addr.sin6_port = htons (IPPROTO_ICMPV6); |
addr.sin6_port = htons (IPPROTO_ICMPV6); |
memcpy (&addr.sin6_addr, all_nodes_addr, sizeof (struct in6_addr)); | IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr); |
|
|
/* Fetch interface information. */ |
/* Fetch interface information. */ |
zif = ifp->info; |
zif = ifp->info; |
Line 215 rtadv_send_packet (int sock, struct interface *ifp)
|
Line 197 rtadv_send_packet (int sock, struct interface *ifp)
|
rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; |
rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; |
if (zif->rtadv.AdvHomeAgentFlag) |
if (zif->rtadv.AdvHomeAgentFlag) |
rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT; |
rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT; |
rtadv->nd_ra_router_lifetime = htons (zif->rtadv.AdvDefaultLifetime); | /* 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_reachable = htonl (zif->rtadv.AdvReachableTime); |
rtadv->nd_ra_retransmit = htonl (0); |
rtadv->nd_ra_retransmit = htonl (0); |
|
|
len = sizeof (struct nd_router_advert); |
len = sizeof (struct nd_router_advert); |
|
|
if (zif->rtadv.AdvHomeAgentFlag) | /* 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 *ndopt_hai = |
(struct nd_opt_homeagent_info *)(buf + len); |
(struct nd_opt_homeagent_info *)(buf + len); |
Line 229 rtadv_send_packet (int sock, struct interface *ifp)
|
Line 230 rtadv_send_packet (int sock, struct interface *ifp)
|
ndopt_hai->nd_opt_hai_len = 1; |
ndopt_hai->nd_opt_hai_len = 1; |
ndopt_hai->nd_opt_hai_reserved = 0; |
ndopt_hai->nd_opt_hai_reserved = 0; |
ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference); |
ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference); |
ndopt_hai->nd_opt_hai_lifetime = htons(zif->rtadv.HomeAgentLifetime); | /* 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); |
len += sizeof(struct nd_opt_homeagent_info); |
} |
} |
|
|
Line 267 rtadv_send_packet (int sock, struct interface *ifp)
|
Line 278 rtadv_send_packet (int sock, struct interface *ifp)
|
pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime); |
pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime); |
pinfo->nd_opt_pi_reserved2 = 0; |
pinfo->nd_opt_pi_reserved2 = 0; |
|
|
memcpy (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.u.prefix6, | IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix); |
sizeof (struct in6_addr)); | |
|
|
#ifdef DEBUG |
#ifdef DEBUG |
{ |
{ |
Line 284 rtadv_send_packet (int sock, struct interface *ifp)
|
Line 294 rtadv_send_packet (int sock, struct interface *ifp)
|
} |
} |
|
|
/* Hardware address. */ |
/* Hardware address. */ |
#ifdef HAVE_STRUCT_SOCKADDR_DL |
|
sdl = &ifp->sdl; |
|
if (sdl != NULL && sdl->sdl_alen != 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++] = (sdl->sdl_alen + 9) >> 3; |
|
|
|
memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen); |
|
len += sdl->sdl_alen; |
|
|
|
/* Pad option to end on an octet boundary. */ |
|
memset (buf + len, 0, -(sdl->sdl_alen + 2) & 0x7); |
|
len += -(sdl->sdl_alen + 2) & 0x7; |
|
} |
|
#else |
|
if (ifp->hw_addr_len != 0) |
if (ifp->hw_addr_len != 0) |
{ |
{ |
buf[len++] = ND_OPT_SOURCE_LINKADDR; |
buf[len++] = ND_OPT_SOURCE_LINKADDR; |
Line 317 rtadv_send_packet (int sock, struct interface *ifp)
|
Line 309 rtadv_send_packet (int sock, struct interface *ifp)
|
memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7); |
memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7); |
len += -(ifp->hw_addr_len + 2) & 0x7; |
len += -(ifp->hw_addr_len + 2) & 0x7; |
} |
} |
#endif /* HAVE_STRUCT_SOCKADDR_DL */ |
|
|
|
|
/* 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_name = (void *) &addr; |
msg.msg_namelen = sizeof (struct sockaddr_in6); |
msg.msg_namelen = sizeof (struct sockaddr_in6); |
msg.msg_iov = &iov; |
msg.msg_iov = &iov; |
Line 349 rtadv_send_packet (int sock, struct interface *ifp)
|
Line 351 rtadv_send_packet (int sock, struct interface *ifp)
|
static int |
static int |
rtadv_timer (struct thread *thread) |
rtadv_timer (struct thread *thread) |
{ |
{ |
|
struct zebra_vrf *zvrf = THREAD_ARG (thread); |
struct listnode *node, *nnode; |
struct listnode *node, *nnode; |
struct interface *ifp; |
struct interface *ifp; |
struct zebra_if *zif; |
struct zebra_if *zif; |
int period; |
int period; |
|
|
rtadv->ra_timer = NULL; | zvrf->rtadv.ra_timer = NULL; |
if (rtadv->adv_msec_if_count == 0) | if (zvrf->rtadv.adv_msec_if_count == 0) |
{ |
{ |
period = 1000; /* 1 s */ |
period = 1000; /* 1 s */ |
rtadv_event (RTADV_TIMER, 1 /* 1 s */); | rtadv_event (zvrf, RTADV_TIMER, 1 /* 1 s */); |
} |
} |
else |
else |
{ |
{ |
period = 10; /* 10 ms */ |
period = 10; /* 10 ms */ |
rtadv_event (RTADV_TIMER_MSEC, 10 /* 10 ms */); | rtadv_event (zvrf, RTADV_TIMER_MSEC, 10 /* 10 ms */); |
} |
} |
|
|
for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp)) | for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf->vrf_id), node, nnode, ifp)) |
{ |
{ |
if (if_is_loopback (ifp)) | if (if_is_loopback (ifp) || ! if_is_operative (ifp)) |
continue; |
continue; |
|
|
zif = ifp->info; |
zif = ifp->info; |
Line 378 rtadv_timer (struct thread *thread)
|
Line 381 rtadv_timer (struct thread *thread)
|
zif->rtadv.AdvIntervalTimer -= period; |
zif->rtadv.AdvIntervalTimer -= period; |
if (zif->rtadv.AdvIntervalTimer <= 0) |
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; |
zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval; |
rtadv_send_packet (rtadv->sock, ifp); | rtadv_send_packet (zvrf->rtadv.sock, ifp); |
} |
} |
} |
} |
} |
} |
Line 389 rtadv_timer (struct thread *thread)
|
Line 394 rtadv_timer (struct thread *thread)
|
static void |
static void |
rtadv_process_solicit (struct interface *ifp) |
rtadv_process_solicit (struct interface *ifp) |
{ |
{ |
zlog_info ("Router solicitation received on %s", ifp->name); | struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); |
|
|
rtadv_send_packet (rtadv->sock, ifp); | zlog_info ("Router solicitation received on %s vrf %u", ifp->name, zvrf->vrf_id); |
| |
| rtadv_send_packet (zvrf->rtadv.sock, ifp); |
} |
} |
|
|
static void |
static void |
Line 401 rtadv_process_advert (void)
|
Line 408 rtadv_process_advert (void)
|
} |
} |
|
|
static void |
static void |
rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int hoplimit) | rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex, |
| int hoplimit, vrf_id_t vrf_id) |
{ |
{ |
struct icmp6_hdr *icmph; |
struct icmp6_hdr *icmph; |
struct interface *ifp; |
struct interface *ifp; |
struct zebra_if *zif; |
struct zebra_if *zif; |
|
|
/* Interface search. */ |
/* Interface search. */ |
ifp = if_lookup_by_index (ifindex); | ifp = if_lookup_by_index_vrf (ifindex, vrf_id); |
if (ifp == NULL) |
if (ifp == NULL) |
{ |
{ |
zlog_warn ("Unknown interface index: %d", ifindex); | zlog_warn ("Unknown interface index: %d, vrf %u", ifindex, vrf_id); |
return; |
return; |
} |
} |
|
|
Line 464 rtadv_read (struct thread *thread)
|
Line 472 rtadv_read (struct thread *thread)
|
int len; |
int len; |
u_char buf[RTADV_MSG_SIZE]; |
u_char buf[RTADV_MSG_SIZE]; |
struct sockaddr_in6 from; |
struct sockaddr_in6 from; |
unsigned int ifindex = 0; | ifindex_t ifindex = 0; |
int hoplimit = -1; |
int hoplimit = -1; |
|
struct zebra_vrf *zvrf = THREAD_ARG (thread); |
|
|
sock = THREAD_FD (thread); |
sock = THREAD_FD (thread); |
rtadv->ra_read = NULL; | zvrf->rtadv.ra_read = NULL; |
|
|
/* Register myself. */ |
/* Register myself. */ |
rtadv_event (RTADV_READ, sock); | rtadv_event (zvrf, RTADV_READ, sock); |
|
|
len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit); |
len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit); |
|
|
Line 481 rtadv_read (struct thread *thread)
|
Line 490 rtadv_read (struct thread *thread)
|
return len; |
return len; |
} |
} |
|
|
rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit); | rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, zvrf->vrf_id); |
|
|
return 0; |
return 0; |
} |
} |
|
|
static int |
static int |
rtadv_make_socket (void) | rtadv_make_socket (vrf_id_t vrf_id) |
{ |
{ |
int sock; |
int sock; |
int ret; |
int ret; |
Line 497 rtadv_make_socket (void)
|
Line 506 rtadv_make_socket (void)
|
zlog_err ("rtadv_make_socket: could not raise privs, %s", |
zlog_err ("rtadv_make_socket: could not raise privs, %s", |
safe_strerror (errno) ); |
safe_strerror (errno) ); |
|
|
sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); | sock = vrf_socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, vrf_id); |
|
|
if ( zserv_privs.change (ZPRIVS_LOWER) ) |
if ( zserv_privs.change (ZPRIVS_LOWER) ) |
zlog_err ("rtadv_make_socket: could not lower privs, %s", |
zlog_err ("rtadv_make_socket: could not lower privs, %s", |
Line 506 rtadv_make_socket (void)
|
Line 515 rtadv_make_socket (void)
|
/* When we can't make ICMPV6 socket simply back. Router |
/* When we can't make ICMPV6 socket simply back. Router |
advertisement feature will not be supported. */ |
advertisement feature will not be supported. */ |
if (sock < 0) |
if (sock < 0) |
return -1; | { |
| close (sock); |
| return -1; |
| } |
|
|
ret = setsockopt_ipv6_pktinfo (sock, 1); |
ret = setsockopt_ipv6_pktinfo (sock, 1); |
if (ret < 0) |
if (ret < 0) |
return ret; | { |
| close (sock); |
| return ret; |
| } |
ret = setsockopt_ipv6_multicast_loop (sock, 0); |
ret = setsockopt_ipv6_multicast_loop (sock, 0); |
if (ret < 0) |
if (ret < 0) |
return ret; | { |
| close (sock); |
| return ret; |
| } |
ret = setsockopt_ipv6_unicast_hops (sock, 255); |
ret = setsockopt_ipv6_unicast_hops (sock, 255); |
if (ret < 0) |
if (ret < 0) |
return ret; | { |
| close (sock); |
| return ret; |
| } |
ret = setsockopt_ipv6_multicast_hops (sock, 255); |
ret = setsockopt_ipv6_multicast_hops (sock, 255); |
if (ret < 0) |
if (ret < 0) |
return ret; | { |
| close (sock); |
| return ret; |
| } |
ret = setsockopt_ipv6_hoplimit (sock, 1); |
ret = setsockopt_ipv6_hoplimit (sock, 1); |
if (ret < 0) |
if (ret < 0) |
return ret; | { |
| close (sock); |
| return ret; |
| } |
|
|
ICMP6_FILTER_SETBLOCKALL(&filter); |
ICMP6_FILTER_SETBLOCKALL(&filter); |
ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter); |
ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter); |
Line 538 rtadv_make_socket (void)
|
Line 565 rtadv_make_socket (void)
|
|
|
return sock; |
return sock; |
} |
} |
| |
static struct rtadv_prefix * |
static struct rtadv_prefix * |
rtadv_prefix_new (void) |
rtadv_prefix_new (void) |
{ |
{ |
Line 552 rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
|
Line 579 rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
|
} |
} |
|
|
static struct rtadv_prefix * |
static struct rtadv_prefix * |
rtadv_prefix_lookup (struct list *rplist, struct prefix *p) | rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p) |
{ |
{ |
struct listnode *node; |
struct listnode *node; |
struct rtadv_prefix *rprefix; |
struct rtadv_prefix *rprefix; |
|
|
for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix)) |
for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix)) |
if (prefix_same (&rprefix->prefix, p)) | if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p)) |
return rprefix; |
return rprefix; |
return NULL; |
return NULL; |
} |
} |
|
|
static struct rtadv_prefix * |
static struct rtadv_prefix * |
rtadv_prefix_get (struct list *rplist, struct prefix *p) | rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p) |
{ |
{ |
struct rtadv_prefix *rprefix; |
struct rtadv_prefix *rprefix; |
|
|
Line 573 rtadv_prefix_get (struct list *rplist, struct prefix *
|
Line 600 rtadv_prefix_get (struct list *rplist, struct prefix *
|
return rprefix; |
return rprefix; |
|
|
rprefix = rtadv_prefix_new (); |
rprefix = rtadv_prefix_new (); |
memcpy (&rprefix->prefix, p, sizeof (struct prefix)); | memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6)); |
listnode_add (rplist, rprefix); |
listnode_add (rplist, rprefix); |
|
|
return rprefix; |
return rprefix; |
Line 619 DEFUN (ipv6_nd_suppress_ra,
|
Line 646 DEFUN (ipv6_nd_suppress_ra,
|
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
struct zebra_if *zif; |
struct zebra_if *zif; |
|
struct zebra_vrf *zvrf; |
|
|
ifp = vty->index; |
ifp = vty->index; |
zif = ifp->info; |
zif = ifp->info; |
|
zvrf = vrf_info_lookup (ifp->vrf_id); |
|
|
if (if_is_loopback (ifp)) |
if (if_is_loopback (ifp)) |
{ |
{ |
Line 633 DEFUN (ipv6_nd_suppress_ra,
|
Line 662 DEFUN (ipv6_nd_suppress_ra,
|
{ |
{ |
zif->rtadv.AdvSendAdvertisements = 0; |
zif->rtadv.AdvSendAdvertisements = 0; |
zif->rtadv.AdvIntervalTimer = 0; |
zif->rtadv.AdvIntervalTimer = 0; |
rtadv->adv_if_count--; | zvrf->rtadv.adv_if_count--; |
|
|
if_leave_all_router (rtadv->sock, ifp); | if_leave_all_router (zvrf->rtadv.sock, ifp); |
|
|
if (rtadv->adv_if_count == 0) | if (zvrf->rtadv.adv_if_count == 0) |
rtadv_event (RTADV_STOP, 0); | rtadv_event (zvrf, RTADV_STOP, 0); |
} |
} |
|
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
Line 654 DEFUN (no_ipv6_nd_suppress_ra,
|
Line 683 DEFUN (no_ipv6_nd_suppress_ra,
|
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
struct zebra_if *zif; |
struct zebra_if *zif; |
|
struct zebra_vrf *zvrf; |
|
|
ifp = vty->index; |
ifp = vty->index; |
zif = ifp->info; |
zif = ifp->info; |
|
zvrf = vrf_info_lookup (ifp->vrf_id); |
|
|
if (if_is_loopback (ifp)) |
if (if_is_loopback (ifp)) |
{ |
{ |
Line 668 DEFUN (no_ipv6_nd_suppress_ra,
|
Line 699 DEFUN (no_ipv6_nd_suppress_ra,
|
{ |
{ |
zif->rtadv.AdvSendAdvertisements = 1; |
zif->rtadv.AdvSendAdvertisements = 1; |
zif->rtadv.AdvIntervalTimer = 0; |
zif->rtadv.AdvIntervalTimer = 0; |
rtadv->adv_if_count++; | zvrf->rtadv.adv_if_count++; |
|
|
if_join_all_router (rtadv->sock, ifp); | if_join_all_router (zvrf->rtadv.sock, ifp); |
|
|
if (rtadv->adv_if_count == 1) | if (zvrf->rtadv.adv_if_count == 1) |
rtadv_event (RTADV_START, rtadv->sock); | rtadv_event (zvrf, RTADV_START, zvrf->rtadv.sock); |
} |
} |
|
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
Line 681 DEFUN (no_ipv6_nd_suppress_ra,
|
Line 712 DEFUN (no_ipv6_nd_suppress_ra,
|
|
|
DEFUN (ipv6_nd_ra_interval_msec, |
DEFUN (ipv6_nd_ra_interval_msec, |
ipv6_nd_ra_interval_msec_cmd, |
ipv6_nd_ra_interval_msec_cmd, |
"ipv6 nd ra-interval msec MILLISECONDS", | "ipv6 nd ra-interval msec <70-1800000>", |
"Interface IPv6 config commands\n" |
"Interface IPv6 config commands\n" |
"Neighbor discovery\n" |
"Neighbor discovery\n" |
"Router Advertisement interval\n" |
"Router Advertisement interval\n" |
"Router Advertisement interval in milliseconds\n") |
"Router Advertisement interval in milliseconds\n") |
{ |
{ |
int interval; | unsigned interval; |
struct interface *ifp; | struct interface *ifp = (struct interface *) vty->index; |
struct zebra_if *zif; | struct zebra_if *zif = ifp->info; |
| struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); |
|
|
ifp = (struct interface *) vty->index; | VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000); |
zif = ifp->info; | if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) |
| { |
| vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE); |
| return CMD_WARNING; |
| } |
|
|
interval = atoi (argv[0]); |
|
|
|
if (interval <= 0) |
|
{ |
|
vty_out (vty, "Invalid Router Advertisement Interval%s", VTY_NEWLINE); |
|
return CMD_WARNING; |
|
} |
|
|
|
if (zif->rtadv.MaxRtrAdvInterval % 1000) |
if (zif->rtadv.MaxRtrAdvInterval % 1000) |
rtadv->adv_msec_if_count--; | zvrf->rtadv.adv_msec_if_count--; |
|
|
if (interval % 1000) |
if (interval % 1000) |
rtadv->adv_msec_if_count++; | zvrf->rtadv.adv_msec_if_count++; |
|
|
zif->rtadv.MaxRtrAdvInterval = interval; |
zif->rtadv.MaxRtrAdvInterval = interval; |
zif->rtadv.MinRtrAdvInterval = 0.33 * interval; |
zif->rtadv.MinRtrAdvInterval = 0.33 * interval; |
Line 717 DEFUN (ipv6_nd_ra_interval_msec,
|
Line 745 DEFUN (ipv6_nd_ra_interval_msec,
|
|
|
DEFUN (ipv6_nd_ra_interval, |
DEFUN (ipv6_nd_ra_interval, |
ipv6_nd_ra_interval_cmd, |
ipv6_nd_ra_interval_cmd, |
"ipv6 nd ra-interval SECONDS", | "ipv6 nd ra-interval <1-1800>", |
"Interface IPv6 config commands\n" |
"Interface IPv6 config commands\n" |
"Neighbor discovery\n" |
"Neighbor discovery\n" |
"Router Advertisement interval\n" |
"Router Advertisement interval\n" |
"Router Advertisement interval in seconds\n") |
"Router Advertisement interval in seconds\n") |
{ |
{ |
int interval; | unsigned interval; |
struct interface *ifp; | struct interface *ifp = (struct interface *) vty->index; |
struct zebra_if *zif; | struct zebra_if *zif = ifp->info; |
| struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); |
|
|
ifp = (struct interface *) vty->index; | VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800); |
zif = ifp->info; | if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) |
| { |
| vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE); |
| return CMD_WARNING; |
| } |
|
|
interval = atoi (argv[0]); |
|
|
|
if (interval <= 0) |
|
{ |
|
vty_out (vty, "Invalid Router Advertisement Interval%s", VTY_NEWLINE); |
|
return CMD_WARNING; |
|
} |
|
|
|
if (zif->rtadv.MaxRtrAdvInterval % 1000) |
if (zif->rtadv.MaxRtrAdvInterval % 1000) |
rtadv->adv_msec_if_count--; | zvrf->rtadv.adv_msec_if_count--; |
|
|
/* convert to milliseconds */ |
/* convert to milliseconds */ |
interval = interval * 1000; |
interval = interval * 1000; |
Line 761 DEFUN (no_ipv6_nd_ra_interval,
|
Line 786 DEFUN (no_ipv6_nd_ra_interval,
|
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
struct zebra_if *zif; |
struct zebra_if *zif; |
|
struct zebra_vrf *zvrf; |
|
|
ifp = (struct interface *) vty->index; |
ifp = (struct interface *) vty->index; |
zif = ifp->info; |
zif = ifp->info; |
|
zvrf = vrf_info_lookup (ifp->vrf_id); |
|
|
if (zif->rtadv.MaxRtrAdvInterval % 1000) |
if (zif->rtadv.MaxRtrAdvInterval % 1000) |
rtadv->adv_msec_if_count--; | zvrf->rtadv.adv_msec_if_count--; |
|
|
zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; |
zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; |
zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; |
zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; |
Line 775 DEFUN (no_ipv6_nd_ra_interval,
|
Line 802 DEFUN (no_ipv6_nd_ra_interval,
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
|
ALIAS (no_ipv6_nd_ra_interval, |
|
no_ipv6_nd_ra_interval_val_cmd, |
|
"no ipv6 nd ra-interval <1-1800>", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Router Advertisement interval\n") |
|
|
|
ALIAS (no_ipv6_nd_ra_interval, |
|
no_ipv6_nd_ra_interval_msec_val_cmd, |
|
"no ipv6 nd ra-interval msec <1-1800000>", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Router Advertisement interval\n" |
|
"Router Advertisement interval in milliseconds\n") |
|
|
DEFUN (ipv6_nd_ra_lifetime, |
DEFUN (ipv6_nd_ra_lifetime, |
ipv6_nd_ra_lifetime_cmd, |
ipv6_nd_ra_lifetime_cmd, |
"ipv6 nd ra-lifetime SECONDS", | "ipv6 nd ra-lifetime <0-9000>", |
"Interface IPv6 config commands\n" |
"Interface IPv6 config commands\n" |
"Neighbor discovery\n" |
"Neighbor discovery\n" |
"Router lifetime\n" |
"Router lifetime\n" |
"Router lifetime in seconds\n") | "Router lifetime in seconds (0 stands for a non-default gw)\n") |
{ |
{ |
int lifetime; |
int lifetime; |
struct interface *ifp; |
struct interface *ifp; |
Line 790 DEFUN (ipv6_nd_ra_lifetime,
|
Line 834 DEFUN (ipv6_nd_ra_lifetime,
|
ifp = (struct interface *) vty->index; |
ifp = (struct interface *) vty->index; |
zif = ifp->info; |
zif = ifp->info; |
|
|
lifetime = atoi (argv[0]); | VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000); |
|
|
if (lifetime < 0 || lifetime > 0xffff) | /* 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, "Invalid Router Lifetime%s", VTY_NEWLINE); | vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE); |
return CMD_WARNING; |
return CMD_WARNING; |
} |
} |
|
|
Line 817 DEFUN (no_ipv6_nd_ra_lifetime,
|
Line 865 DEFUN (no_ipv6_nd_ra_lifetime,
|
ifp = (struct interface *) vty->index; |
ifp = (struct interface *) vty->index; |
zif = ifp->info; |
zif = ifp->info; |
|
|
zif->rtadv.AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME; | zif->rtadv.AdvDefaultLifetime = -1; |
|
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
|
ALIAS (no_ipv6_nd_ra_lifetime, |
|
no_ipv6_nd_ra_lifetime_val_cmd, |
|
"no ipv6 nd ra-lifetime <0-9000>", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Router lifetime\n" |
|
"Router lifetime in seconds (0 stands for a non-default gw)\n") |
|
|
DEFUN (ipv6_nd_reachable_time, |
DEFUN (ipv6_nd_reachable_time, |
ipv6_nd_reachable_time_cmd, |
ipv6_nd_reachable_time_cmd, |
"ipv6 nd reachable-time MILLISECONDS", | "ipv6 nd reachable-time <1-3600000>", |
"Interface IPv6 config commands\n" |
"Interface IPv6 config commands\n" |
"Neighbor discovery\n" |
"Neighbor discovery\n" |
"Reachable time\n" |
"Reachable time\n" |
"Reachable time in milliseconds\n") |
"Reachable time in milliseconds\n") |
{ |
{ |
u_int32_t rtime; | struct interface *ifp = (struct interface *) vty->index; |
struct interface *ifp; | struct zebra_if *zif = ifp->info; |
struct zebra_if *zif; | VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME); |
| |
ifp = (struct interface *) vty->index; | |
zif = ifp->info; | |
| |
rtime = (u_int32_t) atol (argv[0]); | |
| |
if (rtime > RTADV_MAX_REACHABLE_TIME) | |
{ | |
vty_out (vty, "Invalid Reachable time%s", VTY_NEWLINE); | |
return CMD_WARNING; | |
} | |
| |
zif->rtadv.AdvReachableTime = rtime; | |
| |
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
Line 869 DEFUN (no_ipv6_nd_reachable_time,
|
Line 912 DEFUN (no_ipv6_nd_reachable_time,
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
|
ALIAS (no_ipv6_nd_reachable_time, |
|
no_ipv6_nd_reachable_time_val_cmd, |
|
"no ipv6 nd reachable-time <1-3600000>", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Reachable time\n" |
|
"Reachable time in milliseconds\n") |
|
|
DEFUN (ipv6_nd_homeagent_preference, |
DEFUN (ipv6_nd_homeagent_preference, |
ipv6_nd_homeagent_preference_cmd, |
ipv6_nd_homeagent_preference_cmd, |
"ipv6 nd home-agent-preference PREFERENCE", | "ipv6 nd home-agent-preference <0-65535>", |
"Interface IPv6 config commands\n" |
"Interface IPv6 config commands\n" |
"Neighbor discovery\n" |
"Neighbor discovery\n" |
"Home Agent preference\n" |
"Home Agent preference\n" |
"Home Agent preference value 0..65535\n") | "preference value (default is 0, least preferred)\n") |
{ |
{ |
u_int32_t hapref; | struct interface *ifp = (struct interface *) vty->index; |
struct interface *ifp; | struct zebra_if *zif = ifp->info; |
struct zebra_if *zif; | VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535); |
| |
ifp = (struct interface *) vty->index; | |
zif = ifp->info; | |
| |
hapref = (u_int32_t) atol (argv[0]); | |
| |
if (hapref > 65535) | |
{ | |
vty_out (vty, "Invalid Home Agent preference%s", VTY_NEWLINE); | |
return CMD_WARNING; | |
} | |
| |
zif->rtadv.HomeAgentPreference = hapref; | |
| |
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
Line 916 DEFUN (no_ipv6_nd_homeagent_preference,
|
Line 954 DEFUN (no_ipv6_nd_homeagent_preference,
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
|
ALIAS (no_ipv6_nd_homeagent_preference, |
|
no_ipv6_nd_homeagent_preference_val_cmd, |
|
"no ipv6 nd home-agent-preference <0-65535>", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Home Agent preference\n" |
|
"preference value (default is 0, least preferred)\n") |
|
|
DEFUN (ipv6_nd_homeagent_lifetime, |
DEFUN (ipv6_nd_homeagent_lifetime, |
ipv6_nd_homeagent_lifetime_cmd, |
ipv6_nd_homeagent_lifetime_cmd, |
"ipv6 nd home-agent-lifetime SECONDS", | "ipv6 nd home-agent-lifetime <0-65520>", |
"Interface IPv6 config commands\n" |
"Interface IPv6 config commands\n" |
"Neighbor discovery\n" |
"Neighbor discovery\n" |
"Home Agent lifetime\n" |
"Home Agent lifetime\n" |
"Home Agent lifetime in seconds\n") | "Home Agent lifetime in seconds (0 to track ra-lifetime)\n") |
{ |
{ |
u_int32_t ha_ltime; | struct interface *ifp = (struct interface *) vty->index; |
struct interface *ifp; | struct zebra_if *zif = ifp->info; |
struct zebra_if *zif; | VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME); |
| |
ifp = (struct interface *) vty->index; | |
zif = ifp->info; | |
| |
ha_ltime = (u_int32_t) atol (argv[0]); | |
| |
if (ha_ltime > RTADV_MAX_HALIFETIME) | |
{ | |
vty_out (vty, "Invalid Home Agent Lifetime time%s", VTY_NEWLINE); | |
return CMD_WARNING; | |
} | |
| |
zif->rtadv.HomeAgentLifetime = ha_ltime; | |
| |
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
Line 958 DEFUN (no_ipv6_nd_homeagent_lifetime,
|
Line 991 DEFUN (no_ipv6_nd_homeagent_lifetime,
|
ifp = (struct interface *) vty->index; |
ifp = (struct interface *) vty->index; |
zif = ifp->info; |
zif = ifp->info; |
|
|
zif->rtadv.HomeAgentLifetime = 0; | zif->rtadv.HomeAgentLifetime = -1; |
|
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
|
ALIAS (no_ipv6_nd_homeagent_lifetime, |
|
no_ipv6_nd_homeagent_lifetime_val_cmd, |
|
"no ipv6 nd home-agent-lifetime <0-65520>", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Home Agent lifetime\n" |
|
"Home Agent lifetime in seconds (0 to track ra-lifetime)\n") |
|
|
DEFUN (ipv6_nd_managed_config_flag, |
DEFUN (ipv6_nd_managed_config_flag, |
ipv6_nd_managed_config_flag_cmd, |
ipv6_nd_managed_config_flag_cmd, |
"ipv6 nd managed-config-flag", |
"ipv6 nd managed-config-flag", |
Line 1137 DEFUN (ipv6_nd_prefix,
|
Line 1179 DEFUN (ipv6_nd_prefix,
|
ifp = (struct interface *) vty->index; |
ifp = (struct interface *) vty->index; |
zebra_if = ifp->info; |
zebra_if = ifp->info; |
|
|
ret = str2prefix_ipv6 (argv[0], (struct prefix_ipv6 *) &rp.prefix); | ret = str2prefix_ipv6 (argv[0], &rp.prefix); |
if (!ret) |
if (!ret) |
{ |
{ |
vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); |
vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); |
return CMD_WARNING; |
return CMD_WARNING; |
} |
} |
|
apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */ |
rp.AdvOnLinkFlag = 1; |
rp.AdvOnLinkFlag = 1; |
rp.AdvAutonomousFlag = 1; |
rp.AdvAutonomousFlag = 1; |
rp.AdvRouterAddressFlag = 0; |
rp.AdvRouterAddressFlag = 0; |
Line 1151 DEFUN (ipv6_nd_prefix,
|
Line 1194 DEFUN (ipv6_nd_prefix,
|
|
|
if (argc > 1) |
if (argc > 1) |
{ |
{ |
if ((isdigit(argv[1][0])) || strncmp (argv[1], "i", 1) == 0) | if ((isdigit((unsigned char)argv[1][0])) |
| || strncmp (argv[1], "i", 1) == 0) |
{ |
{ |
if ( strncmp (argv[1], "i", 1) == 0) |
if ( strncmp (argv[1], "i", 1) == 0) |
rp.AdvValidLifetime = UINT32_MAX; |
rp.AdvValidLifetime = UINT32_MAX; |
Line 1364 DEFUN (no_ipv6_nd_prefix,
|
Line 1408 DEFUN (no_ipv6_nd_prefix,
|
ifp = (struct interface *) vty->index; |
ifp = (struct interface *) vty->index; |
zebra_if = ifp->info; |
zebra_if = ifp->info; |
|
|
ret = str2prefix_ipv6 (argv[0], (struct prefix_ipv6 *) &rp.prefix); | ret = str2prefix_ipv6 (argv[0], &rp.prefix); |
if (!ret) |
if (!ret) |
{ |
{ |
vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); |
vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); |
return CMD_WARNING; |
return CMD_WARNING; |
} |
} |
|
apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */ |
|
|
ret = rtadv_prefix_reset (zebra_if, &rp); |
ret = rtadv_prefix_reset (zebra_if, &rp); |
if (!ret) |
if (!ret) |
Line 1430 DEFUN (no_ipv6_nd_router_preference,
|
Line 1475 DEFUN (no_ipv6_nd_router_preference,
|
return CMD_SUCCESS; |
return CMD_SUCCESS; |
} |
} |
|
|
|
ALIAS (no_ipv6_nd_router_preference, |
|
no_ipv6_nd_router_preference_val_cmd, |
|
"no ipv6 nd router-preference (high|medium|low)", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Default router preference\n" |
|
"High default router preference\n" |
|
"Low default router preference\n" |
|
"Medium default router preference (default)\n") |
|
|
|
DEFUN (ipv6_nd_mtu, |
|
ipv6_nd_mtu_cmd, |
|
"ipv6 nd mtu <1-65535>", |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Advertised MTU\n" |
|
"MTU in bytes\n") |
|
{ |
|
struct interface *ifp = (struct interface *) vty->index; |
|
struct zebra_if *zif = ifp->info; |
|
VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535); |
|
return CMD_SUCCESS; |
|
} |
|
|
|
DEFUN (no_ipv6_nd_mtu, |
|
no_ipv6_nd_mtu_cmd, |
|
"no ipv6 nd mtu", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Advertised MTU\n") |
|
{ |
|
struct interface *ifp = (struct interface *) vty->index; |
|
struct zebra_if *zif = ifp->info; |
|
zif->rtadv.AdvLinkMTU = 0; |
|
return CMD_SUCCESS; |
|
} |
|
|
|
ALIAS (no_ipv6_nd_mtu, |
|
no_ipv6_nd_mtu_val_cmd, |
|
"no ipv6 nd mtu <1-65535>", |
|
NO_STR |
|
"Interface IPv6 config commands\n" |
|
"Neighbor discovery\n" |
|
"Advertised MTU\n" |
|
"MTU in bytes\n") |
|
|
/* Write configuration about router advertisement. */ |
/* Write configuration about router advertisement. */ |
void |
void |
rtadv_config_write (struct vty *vty, struct interface *ifp) |
rtadv_config_write (struct vty *vty, struct interface *ifp) |
Line 1437 rtadv_config_write (struct vty *vty, struct interface
|
Line 1530 rtadv_config_write (struct vty *vty, struct interface
|
struct zebra_if *zif; |
struct zebra_if *zif; |
struct listnode *node; |
struct listnode *node; |
struct rtadv_prefix *rprefix; |
struct rtadv_prefix *rprefix; |
u_char buf[INET6_ADDRSTRLEN]; | char buf[PREFIX_STRLEN]; |
int interval; |
int interval; |
|
|
if (! rtadv) |
|
return; |
|
|
|
zif = ifp->info; |
zif = ifp->info; |
|
|
if (! if_is_loopback (ifp)) |
if (! if_is_loopback (ifp)) |
Line 1463 rtadv_config_write (struct vty *vty, struct interface
|
Line 1553 rtadv_config_write (struct vty *vty, struct interface
|
vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000, |
vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000, |
VTY_NEWLINE); |
VTY_NEWLINE); |
|
|
if (zif->rtadv.AdvDefaultLifetime != RTADV_ADV_DEFAULT_LIFETIME) | if (zif->rtadv.AdvIntervalOption) |
| vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE); |
| |
| if (zif->rtadv.AdvDefaultLifetime != -1) |
vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime, |
vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime, |
VTY_NEWLINE); |
VTY_NEWLINE); |
|
|
|
if (zif->rtadv.HomeAgentPreference) |
|
vty_out (vty, " ipv6 nd home-agent-preference %u%s", |
|
zif->rtadv.HomeAgentPreference, VTY_NEWLINE); |
|
|
|
if (zif->rtadv.HomeAgentLifetime != -1) |
|
vty_out (vty, " ipv6 nd home-agent-lifetime %u%s", |
|
zif->rtadv.HomeAgentLifetime, VTY_NEWLINE); |
|
|
|
if (zif->rtadv.AdvHomeAgentFlag) |
|
vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE); |
|
|
if (zif->rtadv.AdvReachableTime) |
if (zif->rtadv.AdvReachableTime) |
vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime, |
vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime, |
VTY_NEWLINE); |
VTY_NEWLINE); |
Line 1482 rtadv_config_write (struct vty *vty, struct interface
|
Line 1586 rtadv_config_write (struct vty *vty, struct interface
|
rtadv_pref_strs[zif->rtadv.DefaultPreference], |
rtadv_pref_strs[zif->rtadv.DefaultPreference], |
VTY_NEWLINE); |
VTY_NEWLINE); |
|
|
|
if (zif->rtadv.AdvLinkMTU) |
|
vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE); |
|
|
for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix)) |
for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix)) |
{ |
{ |
vty_out (vty, " ipv6 nd prefix %s/%d", | vty_out (vty, " ipv6 nd prefix %s", |
inet_ntop (AF_INET6, &rprefix->prefix.u.prefix6, | prefix2str (&rprefix->prefix, buf, sizeof(buf))); |
(char *) buf, INET6_ADDRSTRLEN), | |
rprefix->prefix.prefixlen); | |
if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) || |
if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) || |
(rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME)) |
(rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME)) |
{ |
{ |
Line 1512 rtadv_config_write (struct vty *vty, struct interface
|
Line 1617 rtadv_config_write (struct vty *vty, struct interface
|
|
|
|
|
static void |
static void |
rtadv_event (enum rtadv_event event, int val) | rtadv_event (struct zebra_vrf *zvrf, enum rtadv_event event, int val) |
{ |
{ |
|
struct rtadv *rtadv = &zvrf->rtadv; |
|
|
switch (event) |
switch (event) |
{ |
{ |
case RTADV_START: |
case RTADV_START: |
if (! rtadv->ra_read) |
if (! rtadv->ra_read) |
rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, NULL, val); | rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val); |
if (! rtadv->ra_timer) |
if (! rtadv->ra_timer) |
rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer, |
rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer, |
NULL, 0); | zvrf, 0); |
break; |
break; |
case RTADV_STOP: |
case RTADV_STOP: |
if (rtadv->ra_timer) |
if (rtadv->ra_timer) |
Line 1537 rtadv_event (enum rtadv_event event, int val)
|
Line 1644 rtadv_event (enum rtadv_event event, int val)
|
break; |
break; |
case RTADV_TIMER: |
case RTADV_TIMER: |
if (! rtadv->ra_timer) |
if (! rtadv->ra_timer) |
rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, NULL, | rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zvrf, |
val); |
val); |
break; |
break; |
case RTADV_TIMER_MSEC: |
case RTADV_TIMER_MSEC: |
if (! rtadv->ra_timer) |
if (! rtadv->ra_timer) |
rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer, |
rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer, |
NULL, val); | zvrf, val); |
break; |
break; |
case RTADV_READ: |
case RTADV_READ: |
if (! rtadv->ra_read) |
if (! rtadv->ra_read) |
rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, NULL, val); | rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val); |
break; |
break; |
default: |
default: |
break; |
break; |
Line 1556 rtadv_event (enum rtadv_event event, int val)
|
Line 1663 rtadv_event (enum rtadv_event event, int val)
|
} |
} |
|
|
void |
void |
rtadv_init (void) | rtadv_init (struct zebra_vrf *zvrf) |
{ |
{ |
int sock; | zvrf->rtadv.sock = rtadv_make_socket (zvrf->vrf_id); |
| } |
|
|
sock = rtadv_make_socket (); | void |
if (sock < 0) | rtadv_terminate (struct zebra_vrf *zvrf) |
return; | { |
| rtadv_event (zvrf, RTADV_STOP, 0); |
|
|
rtadv = rtadv_new (); | if (zvrf->rtadv.sock >= 0) |
rtadv->sock = sock; | { |
| close (zvrf->rtadv.sock); |
| zvrf->rtadv.sock = -1; |
| } |
|
|
|
zvrf->rtadv.adv_if_count = 0; |
|
zvrf->rtadv.adv_msec_if_count = 0; |
|
} |
|
|
|
void |
|
rtadv_cmd_init (void) |
|
{ |
install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd); |
install_element (INTERFACE_NODE, &no_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_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_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, &no_ipv6_nd_ra_interval_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_val_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_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, &no_ipv6_nd_managed_config_flag_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd); |
Line 1584 rtadv_init (void)
|
Line 1707 rtadv_init (void)
|
install_element (INTERFACE_NODE, &no_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, &ipv6_nd_homeagent_preference_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_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, &no_ipv6_nd_adv_interval_config_option_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd); |
install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd); |
Line 1605 rtadv_init (void)
|
Line 1730 rtadv_init (void)
|
install_element (INTERFACE_NODE, &no_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, &ipv6_nd_router_preference_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd); |
install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd); |
|
install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd); |
|
install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd); |
} |
} |
|
|
static int |
static int |
Line 1651 if_leave_all_router (int sock, struct interface *ifp)
|
Line 1780 if_leave_all_router (int sock, struct interface *ifp)
|
|
|
#else |
#else |
void |
void |
rtadv_init (void) | rtadv_init (struct zebra_vrf *zvrf) |
{ |
{ |
/* Empty.*/; |
/* Empty.*/; |
} |
} |
#endif /* RTADV && HAVE_IPV6 */ | void |
| rtadv_terminate (struct zebra_vrf *zvrf) |
| { |
| /* Empty.*/; |
| } |
| void |
| rtadv_cmd_init (void) |
| { |
| /* Empty.*/; |
| } |
| #endif /* HAVE_RTADV && HAVE_IPV6 */ |