summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/bfd.c9
-rw-r--r--lib/bfd.h6
-rw-r--r--lib/if.c3
-rw-r--r--lib/if.h1
-rw-r--r--lib/vrf.c9
-rw-r--r--lib/vty.c295
-rw-r--r--lib/vty.h10
7 files changed, 112 insertions, 221 deletions
diff --git a/lib/bfd.c b/lib/bfd.c
index 70cbe0f2a6..9800ed4924 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -552,7 +552,8 @@ static bool bfd_sess_address_changed(const struct bfd_session_params *bsp,
}
void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp,
- struct in_addr *src, struct in_addr *dst)
+ const struct in_addr *src,
+ const struct in_addr *dst)
{
if (!bfd_sess_address_changed(bsp, AF_INET, (struct in6_addr *)src,
(struct in6_addr *)dst))
@@ -576,10 +577,10 @@ void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp,
}
void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp,
- struct in6_addr *src, struct in6_addr *dst)
+ const struct in6_addr *src,
+ const struct in6_addr *dst)
{
- if (!bfd_sess_address_changed(bsp, AF_INET, (struct in6_addr *)src,
- (struct in6_addr *)dst))
+ if (!bfd_sess_address_changed(bsp, AF_INET6, src, dst))
return;
/* If already installed, remove the old setting. */
diff --git a/lib/bfd.h b/lib/bfd.h
index 6c0d1c177e..cc9659ff79 100644
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -124,7 +124,8 @@ void bfd_sess_free(struct bfd_session_params **bsp);
* \param dst remote address (mandatory).
*/
void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp,
- struct in_addr *src, struct in_addr *dst);
+ const struct in_addr *src,
+ const struct in_addr *dst);
/**
* Set the local and peer address of the BFD session.
@@ -138,7 +139,8 @@ void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp,
* \param dst remote address (mandatory).
*/
void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp,
- struct in6_addr *src, struct in6_addr *dst);
+ const struct in6_addr *src,
+ const struct in6_addr *dst);
/**
* Configure the BFD session interface.
diff --git a/lib/if.c b/lib/if.c
index 4ccb36d091..71d2f5d9cc 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -48,6 +48,7 @@ DEFINE_MTYPE_STATIC(LIB, IF_LINK_PARAMS, "Informational Link Parameters");
static void if_set_name(struct interface *ifp, const char *name);
static struct interface *if_lookup_by_ifindex(ifindex_t ifindex,
vrf_id_t vrf_id);
+static struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex);
static int if_cmp_func(const struct interface *, const struct interface *);
static int if_cmp_index_func(const struct interface *ifp1,
const struct interface *ifp2);
@@ -440,7 +441,7 @@ static struct interface *if_lookup_by_name_all_vrf(const char *name)
return NULL;
}
-struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex)
+static struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex)
{
struct vrf *vrf;
struct interface *ifp;
diff --git a/lib/if.h b/lib/if.h
index 1d32c2b088..506c14ff59 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -515,7 +515,6 @@ extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
extern struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex,
vrf_id_t vrf_id);
-extern struct interface *if_lookup_by_index_all_vrf(ifindex_t);
extern struct interface *if_lookup_exact_address(const void *matchaddr,
int family, vrf_id_t vrf_id);
extern struct connected *if_lookup_address(const void *matchaddr, int family,
diff --git a/lib/vrf.c b/lib/vrf.c
index 847899f0ba..aaedb63800 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -256,10 +256,8 @@ void vrf_delete(struct vrf *vrf)
* the ID mapping. Interfaces assigned to this VRF should've been
* removed already as part of the VRF going down.
*/
- if (vrf_is_user_cfged(vrf)) {
- vrf->ns_ctxt = NULL;
+ if (vrf_is_user_cfged(vrf))
return;
- }
/* Do not delete the VRF if it has interfaces configured in it. */
if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name))
@@ -541,10 +539,13 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *),
static void vrf_terminate_single(struct vrf *vrf)
{
+ int enabled = vrf_is_enabled(vrf);
+
/* Clear configured flag and invoke delete. */
UNSET_FLAG(vrf->status, VRF_CONFIGURED);
if_terminate(vrf);
- vrf_delete(vrf);
+ if (enabled)
+ vrf_delete(vrf);
}
/* Terminate VRF module. */
diff --git a/lib/vty.c b/lib/vty.c
index 5a03514be4..388af8ebaf 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -57,9 +57,12 @@
#endif
DEFINE_MTYPE_STATIC(LIB, VTY, "VTY");
+DEFINE_MTYPE_STATIC(LIB, VTY_SERV, "VTY server");
DEFINE_MTYPE_STATIC(LIB, VTY_OUT_BUF, "VTY output buffer");
DEFINE_MTYPE_STATIC(LIB, VTY_HIST, "VTY history");
+DECLARE_DLIST(vtys, struct vty, itm);
+
/* Vty events */
enum event {
VTY_SERV,
@@ -73,17 +76,31 @@ enum event {
#endif /* VTYSH */
};
-static void vty_event_serv(enum event event, int sock);
+PREDECL_DLIST(vtyservs);
+
+struct vty_serv {
+ struct vtyservs_item itm;
+
+ int sock;
+ bool vtysh;
+
+ struct thread *t_accept;
+};
+
+DECLARE_DLIST(vtyservs, struct vty_serv, itm);
+
+static void vty_event_serv(enum event event, struct vty_serv *);
static void vty_event(enum event, struct vty *);
/* Extern host structure from command.c */
extern struct host host;
-/* Vector which store each vty structure. */
-static vector vtyvec;
+/* active listeners */
+static struct vtyservs_head vty_servs[1] = {INIT_DLIST(vty_servs[0])};
-/* Vector for vtysh connections. */
-static vector vtyshvec;
+/* active connections */
+static struct vtys_head vty_sessions[1] = {INIT_DLIST(vty_sessions[0])};
+static struct vtys_head vtysh_sessions[1] = {INIT_DLIST(vtysh_sessions[0])};
/* Vty timeout value. */
static unsigned long vty_timeout_val = VTY_TIMEOUT_DEFAULT;
@@ -94,9 +111,6 @@ static char *vty_accesslist_name = NULL;
/* Vty access-calss for IPv6. */
static char *vty_ipv6_accesslist_name = NULL;
-/* VTY server thread. */
-static vector Vvty_serv_thread;
-
/* Current directory. */
static char vty_cwd[MAXPATHLEN];
@@ -266,63 +280,6 @@ done:
return len;
}
-static int vty_log_out(struct vty *vty, const char *level,
- const char *proto_str, const char *msg,
- struct timestamp_control *ctl)
-{
- int ret;
- int len;
- char buf[1024];
-
- if (!ctl->already_rendered) {
- ctl->len = quagga_timestamp(ctl->precision, ctl->buf,
- sizeof(ctl->buf));
- ctl->already_rendered = 1;
- }
- if (ctl->len + 1 >= sizeof(buf))
- return -1;
- memcpy(buf, ctl->buf, len = ctl->len);
- buf[len++] = ' ';
- buf[len] = '\0';
-
- if (level)
- ret = snprintf(buf + len, sizeof(buf) - len, "%s: %s: ", level,
- proto_str);
- else
- ret = snprintf(buf + len, sizeof(buf) - len, "%s: ", proto_str);
- if ((ret < 0) || ((size_t)(len += ret) >= sizeof(buf)))
- return -1;
-
- if (((ret = snprintf(buf + len, sizeof(buf) - len, "%s", msg)) < 0)
- || ((size_t)((len += ret) + 2) > sizeof(buf)))
- return -1;
-
- buf[len++] = '\r';
- buf[len++] = '\n';
-
- if (write(vty->wfd, buf, len) < 0) {
- if (ERRNO_IO_RETRY(errno))
- /* Kernel buffer is full, probably too much debugging
- output, so just
- drop the data and ignore. */
- return -1;
- /* Fatal I/O error. */
- vty->monitor =
- 0; /* disable monitoring to avoid infinite recursion */
- flog_err(EC_LIB_SOCKET,
- "%s: write failed to vty client fd %d, closing: %s",
- __func__, vty->fd, safe_strerror(errno));
- buffer_reset(vty->obuf);
- buffer_reset(vty->lbuf);
- /* cannot call vty_close, because a parent routine may still try
- to access the vty struct */
- vty->status = VTY_CLOSE;
- shutdown(vty->fd, SHUT_RDWR);
- return -1;
- }
- return 0;
-}
-
/* Output current time to the vty. */
void vty_time_print(struct vty *vty, int cr)
{
@@ -480,19 +437,12 @@ static int vty_command(struct vty *vty, char *buf)
cp++;
}
if (cp != NULL && *cp != '\0') {
- unsigned i;
char vty_str[VTY_BUFSIZ];
char prompt_str[VTY_BUFSIZ];
/* format the base vty info */
- snprintf(vty_str, sizeof(vty_str), "vty[??]@%s", vty->address);
-
- for (i = 0; i < vector_active(vtyvec); i++)
- if (vty == vector_slot(vtyvec, i)) {
- snprintf(vty_str, sizeof(vty_str), "vty[%d]@%s",
- i, vty->address);
- break;
- }
+ snprintf(vty_str, sizeof(vty_str), "vty[%d]@%s", vty->fd,
+ vty->address);
/* format the prompt */
snprintf(prompt_str, sizeof(prompt_str), cmd_prompt(vty->node),
@@ -1624,13 +1574,14 @@ static struct vty *vty_new_init(int vty_sock)
memset(vty->xpath, 0, sizeof(vty->xpath));
vty->private_config = false;
vty->candidate_config = vty_shared_candidate_config;
- vector_set_index(vtyvec, vty_sock, vty);
vty->status = VTY_NORMAL;
vty->lines = -1;
vty->iac = 0;
vty->iac_sb_in_progress = 0;
vty->sb_len = 0;
+ vtys_add_tail(vty_sessions, vty);
+
return vty;
}
@@ -1788,18 +1739,17 @@ struct vty *vty_stdio(void (*atclose)(int isexit))
/* Accept connection from the network. */
static int vty_accept(struct thread *thread)
{
+ struct vty_serv *vtyserv = THREAD_ARG(thread);
int vty_sock;
union sockunion su;
int ret;
unsigned int on;
- int accept_sock;
+ int accept_sock = vtyserv->sock;
struct prefix p;
struct access_list *acl = NULL;
- accept_sock = THREAD_FD(thread);
-
/* We continue hearing vty socket. */
- vty_event_serv(VTY_SERV, accept_sock);
+ vty_event_serv(VTY_SERV, vtyserv);
memset(&su, 0, sizeof(union sockunion));
@@ -1826,10 +1776,6 @@ static int vty_accept(struct thread *thread)
&& (access_list_apply(acl, &p) == FILTER_DENY)) {
zlog_info("Vty connection refused from %pSU", &su);
close(vty_sock);
-
- /* continue accepting connections */
- vty_event_serv(VTY_SERV, accept_sock);
-
return 0;
}
}
@@ -1841,10 +1787,6 @@ static int vty_accept(struct thread *thread)
&& (access_list_apply(acl, &p) == FILTER_DENY)) {
zlog_info("Vty connection refused from %pSU", &su);
close(vty_sock);
-
- /* continue accepting connections */
- vty_event_serv(VTY_SERV, accept_sock);
-
return 0;
}
}
@@ -1890,6 +1832,8 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port)
ainfo_save = ainfo;
do {
+ struct vty_serv *vtyserv;
+
if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
continue;
@@ -1915,7 +1859,11 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port)
continue;
}
- vty_event_serv(VTY_SERV, sock);
+ vtyserv = XCALLOC(MTYPE_VTY_SERV, sizeof(*vtyserv));
+ vtyserv->sock = sock;
+ vtyservs_add_tail(vty_servs, vtyserv);
+
+ vty_event_serv(VTY_SERV, vtyserv);
} while ((ainfo = ainfo->ai_next) != NULL);
freeaddrinfo(ainfo_save);
@@ -1928,6 +1876,7 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port)
/* VTY shell UNIX domain socket. */
static void vty_serv_un(const char *path)
{
+ struct vty_serv *vtyserv;
int ret;
int sock, len;
struct sockaddr_un serv;
@@ -1993,22 +1942,26 @@ static void vty_serv_un(const char *path)
}
}
- vty_event_serv(VTYSH_SERV, sock);
+ vtyserv = XCALLOC(MTYPE_VTY_SERV, sizeof(*vtyserv));
+ vtyserv->sock = sock;
+ vtyserv->vtysh = true;
+ vtyservs_add_tail(vty_servs, vtyserv);
+
+ vty_event_serv(VTYSH_SERV, vtyserv);
}
/* #define VTYSH_DEBUG 1 */
static int vtysh_accept(struct thread *thread)
{
- int accept_sock;
+ struct vty_serv *vtyserv = THREAD_ARG(thread);
+ int accept_sock = vtyserv->sock;
int sock;
int client_len;
struct sockaddr_un client;
struct vty *vty;
- accept_sock = THREAD_FD(thread);
-
- vty_event_serv(VTYSH_SERV, accept_sock);
+ vty_event_serv(VTYSH_SERV, vtyserv);
memset(&client, 0, sizeof(struct sockaddr_un));
client_len = sizeof(struct sockaddr_un);
@@ -2041,7 +1994,7 @@ static int vtysh_accept(struct thread *thread)
vty->wfd = sock;
vty->type = VTY_SHELL_SERV;
vty->node = VIEW_NODE;
- vector_set_index(vtyshvec, sock, vty);
+ vtys_add_tail(vtysh_sessions, vty);
vty_event(VTYSH_READ, vty);
@@ -2217,9 +2170,9 @@ void vty_close(struct vty *vty)
/* Unset vector. */
if (vty->fd != -1) {
if (vty->type == VTY_SHELL_SERV)
- vector_unset(vtyshvec, vty->fd);
+ vtys_del(vtysh_sessions, vty);
else
- vector_unset(vtyvec, vty->fd);
+ vtys_del(vty_sessions, vty);
}
if (vty->wfd > 0 && vty->type == VTY_FILE)
@@ -2533,52 +2486,6 @@ tmp_free_and_out:
return read_success;
}
-/* Small utility function which output log to the VTY. */
-void vty_log(const char *level, const char *proto_str, const char *msg,
- struct timestamp_control *ctl)
-{
- unsigned int i;
- struct vty *vty;
-
- if (!vtyvec)
- return;
-
- for (i = 0; i < vector_active(vtyvec); i++)
- if ((vty = vector_slot(vtyvec, i)) != NULL)
- if (vty->monitor)
- vty_log_out(vty, level, proto_str, msg, ctl);
-}
-
-/* Async-signal-safe version of vty_log for fixed strings. */
-void vty_log_fixed(char *buf, size_t len)
-{
- unsigned int i;
- struct iovec iov[2];
- char crlf[4] = "\r\n";
-
- /* vty may not have been initialised */
- if (!vtyvec)
- return;
-
- iov[0].iov_base = buf;
- iov[0].iov_len = len;
- iov[1].iov_base = crlf;
- iov[1].iov_len = 2;
-
- for (i = 0; i < vector_active(vtyvec); i++) {
- struct vty *vty;
- if (((vty = vector_slot(vtyvec, i)) != NULL) && vty->monitor)
- /* N.B. We don't care about the return code, since
- process is
- most likely just about to die anyway. */
- if (writev(vty->wfd, iov, 2) == -1) {
- fprintf(stderr, "Failure to writev: %d\n",
- errno);
- exit(-1);
- }
- }
-}
-
static void update_xpath(struct vty *vty, const char *oldpath,
const char *newpath)
{
@@ -2597,21 +2504,11 @@ static void update_xpath(struct vty *vty, const char *oldpath,
void vty_update_xpath(const char *oldpath, const char *newpath)
{
struct vty *vty;
- unsigned int i;
-
- for (i = 0; i < vector_active(vtyshvec); i++) {
- if ((vty = vector_slot(vtyshvec, i)) == NULL)
- continue;
+ frr_each (vtys, vtysh_sessions, vty)
update_xpath(vty, oldpath, newpath);
- }
-
- for (i = 0; i < vector_active(vtyvec); i++) {
- if ((vty = vector_slot(vtyvec, i)) == NULL)
- continue;
-
+ frr_each (vtys, vty_sessions, vty)
update_xpath(vty, oldpath, newpath);
- }
}
int vty_config_enter(struct vty *vty, bool private_config, bool exclusive)
@@ -2695,23 +2592,17 @@ int vty_config_node_exit(struct vty *vty)
/* Master of the threads. */
static struct thread_master *vty_master;
-static void vty_event_serv(enum event event, int sock)
+static void vty_event_serv(enum event event, struct vty_serv *vty_serv)
{
- struct thread **vty_serv_thread_ptr = NULL;
-
switch (event) {
case VTY_SERV:
- vty_serv_thread_ptr = (struct thread **)vector_get_index(
- Vvty_serv_thread, sock);
- thread_add_read(vty_master, vty_accept, NULL, sock,
- vty_serv_thread_ptr);
+ thread_add_read(vty_master, vty_accept, vty_serv,
+ vty_serv->sock, &vty_serv->t_accept);
break;
#ifdef VTYSH
case VTYSH_SERV:
- vty_serv_thread_ptr = (struct thread **)vector_get_index(
- Vvty_serv_thread, sock);
- thread_add_read(vty_master, vtysh_accept, NULL, sock,
- vty_serv_thread_ptr);
+ thread_add_read(vty_master, vtysh_accept, vty_serv,
+ vty_serv->sock, &vty_serv->t_accept);
break;
#endif /* VTYSH */
default:
@@ -2763,13 +2654,11 @@ DEFUN_NOSH (config_who,
"who",
"Display who is on vty\n")
{
- unsigned int i;
struct vty *v;
- for (i = 0; i < vector_active(vtyvec); i++)
- if ((v = vector_slot(vtyvec, i)) != NULL)
- vty_out(vty, "%svty[%d] connected from %s.\n",
- v->config ? "*" : " ", i, v->address);
+ frr_each (vtys, vty_sessions, v)
+ vty_out(vty, "%svty[%d] connected from %s.\n",
+ v->config ? "*" : " ", v->fd, v->address);
return CMD_SUCCESS;
}
@@ -3082,25 +2971,14 @@ struct cmd_node vty_node = {
/* Reset all VTY status. */
void vty_reset(void)
{
- unsigned int i;
struct vty *vty;
- struct thread *vty_serv_thread;
-
- for (i = 0; i < vector_active(vtyvec); i++)
- if ((vty = vector_slot(vtyvec, i)) != NULL) {
- buffer_reset(vty->lbuf);
- buffer_reset(vty->obuf);
- vty->status = VTY_CLOSE;
- vty_close(vty);
- }
- for (i = 0; i < vector_active(Vvty_serv_thread); i++)
- if ((vty_serv_thread = vector_slot(Vvty_serv_thread, i))
- != NULL) {
- THREAD_OFF(vty_serv_thread);
- vector_slot(Vvty_serv_thread, i) = NULL;
- close(i);
- }
+ frr_each_safe (vtys, vty_sessions, vty) {
+ buffer_reset(vty->lbuf);
+ buffer_reset(vty->obuf);
+ vty->status = VTY_CLOSE;
+ vty_close(vty);
+ }
vty_timeout_val = VTY_TIMEOUT_DEFAULT;
@@ -3151,7 +3029,7 @@ int vty_shell_serv(struct vty *vty)
void vty_init_vtysh(void)
{
- vtyvec = vector_init(VECTOR_MIN_SIZE);
+ /* currently nothing to do, but likely to have future use */
}
/* Install vty's own commands like `who' command. */
@@ -3160,16 +3038,10 @@ void vty_init(struct thread_master *master_thread, bool do_command_logging)
/* For further configuration read, preserve current directory. */
vty_save_cwd();
- vtyvec = vector_init(VECTOR_MIN_SIZE);
- vtyshvec = vector_init(VECTOR_MIN_SIZE);
-
vty_master = master_thread;
atexit(vty_stdio_atexit);
- /* Initialize server thread vector. */
- Vvty_serv_thread = vector_init(VECTOR_MIN_SIZE);
-
/* Install bgp top node. */
install_node(&vty_node);
@@ -3204,17 +3076,34 @@ void vty_init(struct thread_master *master_thread, bool do_command_logging)
void vty_terminate(void)
{
+ struct vty *vty;
+ struct vty_serv *vtyserv;
+
memset(vty_cwd, 0x00, sizeof(vty_cwd));
- if (vtyvec && Vvty_serv_thread) {
- vty_reset();
- vector_free(vtyvec);
- vector_free(Vvty_serv_thread);
- vtyvec = NULL;
- Vvty_serv_thread = NULL;
+ vty_reset();
+
+ /* default state of vty_sessions is initialized & empty. */
+ vtys_fini(vty_sessions);
+ vtys_init(vty_sessions);
+
+ /* vty_reset() doesn't close vtysh sessions */
+ frr_each_safe (vtys, vtysh_sessions, vty) {
+ buffer_reset(vty->lbuf);
+ buffer_reset(vty->obuf);
+ vty->status = VTY_CLOSE;
+ vty_close(vty);
}
- if (vtyshvec) {
- vector_free(vtyshvec);
- vtyshvec = NULL;
+
+ vtys_fini(vtysh_sessions);
+ vtys_init(vtysh_sessions);
+
+ while ((vtyserv = vtyservs_pop(vty_servs))) {
+ THREAD_OFF(vtyserv->t_accept);
+ close(vtyserv->sock);
+ XFREE(MTYPE_VTY_SERV, vtyserv);
}
+
+ vtyservs_fini(vty_servs);
+ vtyservs_init(vty_servs);
}
diff --git a/lib/vty.h b/lib/vty.h
index 70ec4fcd84..62e2518957 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -56,8 +56,12 @@ struct vty_cfg_change {
const char *value;
};
+PREDECL_DLIST(vtys);
+
/* VTY struct. */
struct vty {
+ struct vtys_item itm;
+
/* File descripter of this vty. */
int fd;
@@ -325,8 +329,6 @@ extern void vty_time_print(struct vty *, int);
extern void vty_serv_sock(const char *, unsigned short, const char *);
extern void vty_close(struct vty *);
extern char *vty_get_cwd(void);
-extern void vty_log(const char *level, const char *proto, const char *msg,
- struct timestamp_control *);
extern void vty_update_xpath(const char *oldpath, const char *newpath);
extern int vty_config_enter(struct vty *vty, bool private_config,
bool exclusive);
@@ -341,10 +343,6 @@ extern void vty_stdio_suspend(void);
extern void vty_stdio_resume(void);
extern void vty_stdio_close(void);
-/* Send a fixed-size message to all vty terminal monitors; this should be
- an async-signal-safe function. */
-extern void vty_log_fixed(char *buf, size_t len);
-
#ifdef __cplusplus
}
#endif