version 1.1.1.2, 2012/10/09 09:22:29
|
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 313 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 346 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 */ |
/* MTU */ |
if (zif->rtadv.AdvLinkMTU) |
if (zif->rtadv.AdvLinkMTU) |
Line 389 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_is_operative (ifp)) |
if (if_is_loopback (ifp) || ! if_is_operative (ifp)) |
continue; |
continue; |
Line 421 rtadv_timer (struct thread *thread)
|
Line 384 rtadv_timer (struct thread *thread)
|
/* FIXME: using MaxRtrAdvInterval each time isn't what section |
/* FIXME: using MaxRtrAdvInterval each time isn't what section |
6.2.4 of RFC4861 tells to do. */ |
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 431 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 443 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 506 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 523 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 539 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 548 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 580 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 661 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 675 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 696 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 710 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 732 DEFUN (ipv6_nd_ra_interval_msec,
|
Line 721 DEFUN (ipv6_nd_ra_interval_msec,
|
unsigned interval; |
unsigned interval; |
struct interface *ifp = (struct interface *) vty->index; |
struct interface *ifp = (struct interface *) vty->index; |
struct zebra_if *zif = ifp->info; |
struct zebra_if *zif = ifp->info; |
|
struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); |
|
|
VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000); |
VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000); |
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) |
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) |
Line 741 DEFUN (ipv6_nd_ra_interval_msec,
|
Line 731 DEFUN (ipv6_nd_ra_interval_msec,
|
} |
} |
|
|
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 764 DEFUN (ipv6_nd_ra_interval,
|
Line 754 DEFUN (ipv6_nd_ra_interval,
|
unsigned interval; |
unsigned interval; |
struct interface *ifp = (struct interface *) vty->index; |
struct interface *ifp = (struct interface *) vty->index; |
struct zebra_if *zif = ifp->info; |
struct zebra_if *zif = ifp->info; |
|
struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); |
|
|
VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800); |
VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800); |
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) |
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) |
Line 773 DEFUN (ipv6_nd_ra_interval,
|
Line 764 DEFUN (ipv6_nd_ra_interval,
|
} |
} |
|
|
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 795 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 1201 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 1483 DEFUN (no_ipv6_nd_router_preference,
|
Line 1477 DEFUN (no_ipv6_nd_router_preference,
|
|
|
ALIAS (no_ipv6_nd_router_preference, |
ALIAS (no_ipv6_nd_router_preference, |
no_ipv6_nd_router_preference_val_cmd, |
no_ipv6_nd_router_preference_val_cmd, |
"no ipv6 nd router-preference (high|medium|low", | "no ipv6 nd router-preference (high|medium|low)", |
NO_STR |
NO_STR |
"Interface IPv6 config commands\n" |
"Interface IPv6 config commands\n" |
"Neighbor discovery\n" |
"Neighbor discovery\n" |
Line 1536 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 1600 rtadv_config_write (struct vty *vty, struct interface
|
Line 1591 rtadv_config_write (struct vty *vty, struct interface
|
|
|
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.prefix, | 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 1628 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 1653 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 1672 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); |
Line 1777 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 */ |