if(fd >= 0 && rc < 0) {
zlog_err("unlink(babel-state): %s", safe_strerror(errno));
/* If we couldn't unlink it, it's probably stale. */
- close(fd);
- fd = -1;
+ goto fini;
}
if(fd >= 0) {
char buf[100];
zlog_err("Couldn't parse babel-state.");
}
}
- close(fd);
- fd = -1;
+ goto fini;
}
+fini:
+ if (fd >= 0)
+ close(fd);
+ return ;
}
static void
if(missed_hellos > 0) {
neigh->reach >>= missed_hellos;
neigh->hello_seqno = seqno_plus(neigh->hello_seqno, missed_hellos);
- missed_hellos = 0;
rc = 1;
}
DEFUN (bgp_evpn_advertise_default_gw_vni,
bgp_evpn_advertise_default_gw_vni_cmd,
"advertise-default-gw",
- "Advertise defualt g/w mac-ip routes in EVPN for a VNI\n")
+ "Advertise default g/w mac-ip routes in EVPN for a VNI\n")
{
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
DEFUN (bgp_evpn_advertise_default_gw,
bgp_evpn_advertise_default_gw_cmd,
"advertise-default-gw",
- "Advertise All defualt g/w mac-ip routes in EVPN\n")
+ "Advertise All default g/w mac-ip routes in EVPN\n")
{
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
int exist_cluster;
int internal_as_route;
int confed_as_route;
- int ret;
+ int ret = 0;
char new_buf[PATH_ADDPATH_STR_BUFFER];
char exist_buf[PATH_ADDPATH_STR_BUFFER];
u_int32_t new_mm_seq;
}
/* 1. Weight check. */
- new_weight = exist_weight = 0;
-
new_weight = newattr->weight;
exist_weight = existattr->weight;
Package: frr
Architecture: any
-Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute, ${misc:Depends}, libc-ares2
+Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), iproute2 | iproute, ${misc:Depends}, libc-ares2
Pre-Depends: adduser
Conflicts: zebra, zebra-pj, quagga
Replaces: zebra, zebra-pj
apt-get install git autoconf automake libtool make gawk libreadline-dev \
texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \
- python-pytest libc-ares-dev python3-dev libsystemd-dev
+ python-pytest libc-ares-dev python3-dev libsystemd-dev python-ipaddr
Get FRR, compile it and install it (from Git)
---------------------------------------------
**Reboot** or use `sysctl -p` to apply the same config to the running system
-### Install the systemd service
+### Install the systemd service (if rebooted from last step, change directory back to frr directory)
sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service
sudo install -m 644 tools/etc/default/frr /etc/default/frr
} else if (new_state == ISIS_ADJ_DOWN) {
listnode_delete(circuit->u.bc.adjdb[level - 1],
adj);
+
circuit->upadjcount[level - 1]--;
- if (circuit->upadjcount[level - 1] == 0) {
- /* Clean lsp_queue when no adj is up. */
- if (circuit->lsp_queue)
- list_delete_all_node(
- circuit->lsp_queue);
- }
+ if (circuit->upadjcount[level - 1] == 0)
+ isis_circuit_lsp_queue_clean(circuit);
+
isis_event_adjacency_state_change(adj,
new_state);
del = true;
if (adj->circuit->u.p2p.neighbor == adj)
adj->circuit->u.p2p.neighbor = NULL;
circuit->upadjcount[level - 1]--;
- if (circuit->upadjcount[level - 1] == 0) {
- /* Clean lsp_queue when no adj is up. */
- if (circuit->lsp_queue)
- list_delete_all_node(
- circuit->lsp_queue);
- }
+ if (circuit->upadjcount[level - 1] == 0)
+ isis_circuit_lsp_queue_clean(circuit);
+
isis_event_adjacency_state_change(adj,
new_state);
del = true;
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_lsp.h"
+#include "isisd/isis_lsp_hash.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
#include "isisd/isis_misc.h"
isis_circuit_prepare(circuit);
circuit->lsp_queue = list_new();
- circuit->lsp_queue_last_cleared = time(NULL);
+ circuit->lsp_hash = isis_lsp_hash_new();
+ monotime(&circuit->lsp_queue_last_cleared);
return ISIS_OK;
}
THREAD_TIMER_OFF(circuit->t_send_csnp[1]);
THREAD_TIMER_OFF(circuit->t_send_psnp[0]);
THREAD_TIMER_OFF(circuit->t_send_psnp[1]);
+ THREAD_OFF(circuit->t_send_lsp);
THREAD_OFF(circuit->t_read);
if (circuit->lsp_queue) {
- circuit->lsp_queue->del = NULL;
list_delete(circuit->lsp_queue);
circuit->lsp_queue = NULL;
}
+ if (circuit->lsp_hash) {
+ isis_lsp_hash_free(circuit->lsp_hash);
+ circuit->lsp_hash = NULL;
+ }
+
/* send one gratuitous hello to spead up convergence */
if (circuit->is_type & IS_LEVEL_1)
send_hello(circuit, IS_LEVEL_1);
isis_vty_init();
}
+
+void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit)
+{
+ if (circuit->t_send_lsp)
+ return;
+ circuit->t_send_lsp = thread_add_event(master, send_lsp, circuit, 0, NULL);
+}
+
+void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp)
+{
+ if (isis_lsp_hash_lookup(circuit->lsp_hash, lsp))
+ return;
+
+ listnode_add(circuit->lsp_queue, lsp);
+ isis_lsp_hash_add(circuit->lsp_hash, lsp);
+ isis_circuit_schedule_lsp_send(circuit);
+}
+
+void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit)
+{
+ if (!circuit->lsp_queue)
+ return;
+
+ list_delete_all_node(circuit->lsp_queue);
+ isis_lsp_hash_clean(circuit->lsp_hash);
+}
+
+void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit,
+ struct isis_lsp *lsp)
+{
+ if (!circuit->lsp_queue)
+ return;
+
+ listnode_delete(circuit->lsp_queue, lsp);
+ isis_lsp_hash_release(circuit->lsp_hash, lsp);
+}
+
+struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit)
+{
+ if (!circuit->lsp_queue)
+ return NULL;
+
+ struct listnode *node = listhead(circuit->lsp_queue);
+ if (!node)
+ return NULL;
+
+ struct isis_lsp *rv = listgetdata(node);
+
+ list_delete_node(circuit->lsp_queue, node);
+ isis_lsp_hash_release(circuit->lsp_hash, rv);
+
+ return rv;
+}
#define CIRCUIT_MAX 255
+struct isis_lsp;
+
struct password {
struct password *next;
int len;
struct thread *t_read;
struct thread *t_send_csnp[2];
struct thread *t_send_psnp[2];
+ struct thread *t_send_lsp;
struct list *lsp_queue; /* LSPs to be txed (both levels) */
- time_t lsp_queue_last_cleared; /* timestamp used to enforce transmit
+ struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */
+ struct timeval lsp_queue_last_cleared; /* timestamp used to enforce transmit
* interval;
* for scalability, use one timestamp per
* circuit, instead of one per lsp per
int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid,
bool enabled);
+void isis_circuit_schedule_lsp_send(struct isis_circuit *circuit);
+void isis_circuit_queue_lsp(struct isis_circuit *circuit, struct isis_lsp *lsp);
+void isis_circuit_lsp_queue_clean(struct isis_circuit *circuit);
+void isis_circuit_cancel_queued_lsp(struct isis_circuit *circuit,
+ struct isis_lsp *lsp);
+struct isis_lsp *isis_circuit_lsp_queue_pop(struct isis_circuit *circuit);
#endif /* _ZEBRA_ISIS_CIRCUIT_H */
#define MAX_MIN_LSP_GEN_INTERVAL 120 /* RFC 4444 says 65535 */
#define DEFAULT_MIN_LSP_GEN_INTERVAL 30
-#define MIN_LSP_TRANS_INTERVAL 5
+#define MIN_LSP_TRANS_INTERVAL 20000 /* Microseconds */
#define MIN_CSNP_INTERVAL 1
#define MAX_CSNP_INTERVAL 600
static void lsp_destroy(struct isis_lsp *lsp)
{
- struct listnode *cnode, *lnode, *lnnode;
- struct isis_lsp *lsp_in_list;
+ struct listnode *cnode;
struct isis_circuit *circuit;
if (!lsp)
return;
- if (lsp->area->circuit_list) {
- for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode,
- circuit)) {
- if (circuit->lsp_queue == NULL)
- continue;
- for (ALL_LIST_ELEMENTS(circuit->lsp_queue, lnode,
- lnnode, lsp_in_list))
- if (lsp_in_list == lsp)
- list_delete_node(circuit->lsp_queue,
- lnode);
- }
- }
+ for (ALL_LIST_ELEMENTS_RO(lsp->area->circuit_list, cnode, circuit))
+ isis_circuit_cancel_queued_lsp(circuit, lsp);
+
ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags);
ISIS_FLAGS_CLEAR_ALL(lsp->SRMflags);
if (listcount(lsp_list) > 0) {
for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
cnode, circuit)) {
- int diff =
- time(NULL)
- - circuit->lsp_queue_last_cleared;
- if (circuit->lsp_queue == NULL
- || diff < MIN_LSP_TRANS_INTERVAL)
+ if (!circuit->lsp_queue)
continue;
+
+ if (monotime_since(
+ &circuit->lsp_queue_last_cleared,
+ NULL) < MIN_LSP_TRANS_INTERVAL) {
+ continue;
+ }
+
for (ALL_LIST_ELEMENTS_RO(
lsp_list, lspnode, lsp)) {
if (circuit->upadjcount
&& ISIS_CHECK_FLAG(
lsp->SRMflags,
circuit)) {
- /* Add the lsp only if
- * it is not already in
- * lsp
- * queue */
- if (!listnode_lookup(
- circuit->lsp_queue,
- lsp)) {
- listnode_add(
- circuit->lsp_queue,
- lsp);
- thread_add_event(
- master,
- send_lsp,
- circuit,
- 0,
- NULL);
- }
+ isis_circuit_queue_lsp(circuit, lsp);
}
}
}
--- /dev/null
+/*
+ * IS-IS Rout(e)ing protocol - LSP Hash
+ *
+ * Copyright (C) 2017 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (FRR)
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <zebra.h>
+
+#include "hash.h"
+#include "jhash.h"
+
+#include "isisd/isis_memory.h"
+#include "isisd/isis_flags.h"
+#include "dict.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isis_lsp.h"
+#include "isisd/isis_lsp_hash.h"
+
+DEFINE_MTYPE_STATIC(ISISD, LSP_HASH, "ISIS LSP Hash")
+
+struct isis_lsp_hash {
+ struct hash *h;
+};
+
+static unsigned lsp_hash_key(void *lp)
+{
+ struct isis_lsp *lsp = lp;
+
+ return jhash(lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 2, 0x55aa5a5a);
+}
+
+static int lsp_hash_cmp(const void *a, const void *b)
+{
+ const struct isis_lsp *la = a, *lb = b;
+
+ return 0 == memcmp(la->hdr.lsp_id, lb->hdr.lsp_id, ISIS_SYS_ID_LEN + 2);
+}
+
+struct isis_lsp_hash *isis_lsp_hash_new(void)
+{
+ struct isis_lsp_hash *rv = XCALLOC(MTYPE_LSP_HASH, sizeof(*rv));
+
+ rv->h = hash_create(lsp_hash_key, lsp_hash_cmp, NULL);
+ return rv;
+}
+
+void isis_lsp_hash_clean(struct isis_lsp_hash *ih)
+{
+ hash_clean(ih->h, NULL);
+}
+
+void isis_lsp_hash_free(struct isis_lsp_hash *ih)
+{
+ isis_lsp_hash_clean(ih);
+ hash_free(ih->h);
+}
+
+struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
+ struct isis_lsp *lsp)
+{
+ return hash_lookup(ih->h, lsp);
+}
+
+void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp)
+{
+ struct isis_lsp *inserted;
+ inserted = hash_get(ih->h, lsp, hash_alloc_intern);
+ assert(inserted == lsp);
+}
+
+void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp)
+{
+ hash_release(ih->h, lsp);
+}
--- /dev/null
+/*
+ * IS-IS Rout(e)ing protocol - LSP Hash
+ *
+ * Copyright (C) 2017 Christian Franke
+ *
+ * This file is part of FreeRangeRouting (FRR)
+ *
+ * FRR is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRR is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef ISIS_LSP_HASH_H
+#define ISIS_LSP_HASH_H
+
+struct isis_lsp_hash;
+
+struct isis_lsp_hash *isis_lsp_hash_new(void);
+void isis_lsp_hash_clean(struct isis_lsp_hash *ih);
+void isis_lsp_hash_free(struct isis_lsp_hash *ih);
+struct isis_lsp *isis_lsp_hash_lookup(struct isis_lsp_hash *ih,
+ struct isis_lsp *lsp);
+void isis_lsp_hash_add(struct isis_lsp_hash *ih, struct isis_lsp *lsp);
+void isis_lsp_hash_release(struct isis_lsp_hash *ih, struct isis_lsp *lsp);
+#endif
{
struct isis_circuit *circuit;
struct isis_lsp *lsp;
- struct listnode *node;
int clear_srm = 1;
int retval = ISIS_OK;
circuit = THREAD_ARG(thread);
assert(circuit);
+ circuit->t_send_lsp = NULL;
- if (!circuit->lsp_queue)
+ lsp = isis_circuit_lsp_queue_pop(circuit);
+ if (!lsp)
return ISIS_OK;
-
- node = listhead(circuit->lsp_queue);
-
- /*
- * Handle case where there are no LSPs on the queue. This can
- * happen, for instance, if an adjacency goes down before this
- * thread gets a chance to run.
- */
- if (!node)
- return ISIS_OK;
-
- /*
- * Delete LSP from lsp_queue. If it's still in queue, it is assumed
- * as 'transmit pending', but send_lsp may never be called again.
- * Retry will happen because SRM flag will not be cleared.
- */
- lsp = listgetdata(node);
- list_delete_node(circuit->lsp_queue, node);
-
/* Set the last-cleared time if the queue is empty. */
/* TODO: Is is possible that new lsps keep being added to the queue
* that the queue is never empty? */
- if (list_isempty(circuit->lsp_queue))
- circuit->lsp_queue_last_cleared = time(NULL);
+ if (list_isempty(circuit->lsp_queue)) {
+ monotime(&circuit->lsp_queue_last_cleared);
+ } else {
+ isis_circuit_schedule_lsp_send(circuit);
+ }
if (circuit->state != C_STATE_UP || circuit->is_passive == 1)
goto out;
isisd/isis_events.c \
isisd/isis_flags.c \
isisd/isis_lsp.c \
+ isisd/isis_lsp_hash.c \
isisd/isis_memory.c \
isisd/isis_misc.c \
isisd/isis_mt.c \
isisd/isis_events.h \
isisd/isis_flags.h \
isisd/isis_lsp.h \
+ isisd/isis_lsp_hash.h \
isisd/isis_memory.h \
isisd/isis_misc.h \
isisd/isis_mt.h \
switch (a->source.type) {
case HELLO_LINK:
- if (strcmp(a->source.link.ia->iface->name,
- b->source.link.ia->iface->name) < 0)
+ if (if_cmp_name_func((char *)a->source.link.ia->iface->name,
+ (char *)b->source.link.ia->iface->name) < 0)
return (-1);
- if (strcmp(a->source.link.ia->iface->name,
- b->source.link.ia->iface->name) > 0)
+ if (if_cmp_name_func((char *)a->source.link.ia->iface->name,
+ (char *)b->source.link.ia->iface->name) > 0)
return (1);
return (ldp_addrcmp(a->source.link.ia->af,
&a->source.link.src_addr, &b->source.link.src_addr));
static __inline int
iface_compare(const struct iface *a, const struct iface *b)
{
- return (strcmp(a->name, b->name));
+ return (if_cmp_name_func((char *)a->name, (char *)b->name));
}
struct iface *
static __inline int
l2vpn_if_compare(const struct l2vpn_if *a, const struct l2vpn_if *b)
{
- return (strcmp(a->ifname, b->ifname));
+ return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname));
}
struct l2vpn_if *
static __inline int
l2vpn_pw_compare(const struct l2vpn_pw *a, const struct l2vpn_pw *b)
{
- return (strcmp(a->ifname, b->ifname));
+ return (if_cmp_name_func((char *)a->ifname, (char *)b->ifname));
}
struct l2vpn_pw *
int ldp_debug_config_write(struct vty *);
int ldp_vty_mpls_ldp (struct vty *, const char *);
int ldp_vty_address_family (struct vty *, const char *, const char *);
-int ldp_vty_disc_holdtime(struct vty *, const char *, const char *, long);
-int ldp_vty_disc_interval(struct vty *, const char *, const char *, long);
+int ldp_vty_disc_holdtime(struct vty *, const char *, enum hello_type, long);
+int ldp_vty_disc_interval(struct vty *, const char *, enum hello_type, long);
int ldp_vty_targeted_hello_accept(struct vty *, const char *, const char *);
int ldp_vty_nbr_session_holdtime(struct vty *, const char *, struct in_addr, long);
int ldp_vty_af_session_holdtime(struct vty *, const char *, long);
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, const char *);
int ldp_vty_clear_nbr(struct vty *, const char *);
int ldp_vty_debug(struct vty *, const char *, const char *, const char *, const char *);
-int ldp_vty_show_binding(struct vty *, const char *, const char *, const char *);
+int ldp_vty_show_binding(struct vty *, const char *, const char *, int,
+ const char *, unsigned long, unsigned long, const char *, const char *);
int ldp_vty_show_discovery(struct vty *, const char *, const char *, const char *);
int ldp_vty_show_interface(struct vty *, const char *, const char *);
int ldp_vty_show_capabilities(struct vty *, const char *);
-int ldp_vty_show_neighbor(struct vty *, int, const char *, const char *);
-int ldp_vty_show_atom_binding(struct vty *, const char *);
-int ldp_vty_show_atom_vc(struct vty *, const char *);
+int ldp_vty_show_neighbor(struct vty *, const char *, int, const char *, const char *);
+int ldp_vty_show_atom_binding(struct vty *, const char *, unsigned long,
+ unsigned long, const char *);
+int ldp_vty_show_atom_vc(struct vty *, const char *, const char *,
+ const char *, const char *);
int ldp_vty_show_debugging(struct vty *);
void ldp_vty_init(void);
return CMD_SUCCESS;
}
-DEFPY (ldp_discovery_holdtime,
- ldp_discovery_holdtime_cmd,
- "[no] discovery <hello|targeted-hello>$hello_type holdtime (1-65535)$holdtime",
+DEFPY (ldp_discovery_link_holdtime,
+ ldp_discovery_link_holdtime_cmd,
+ "[no] discovery hello holdtime (1-65535)$holdtime",
NO_STR
"Configure discovery parameters\n"
"LDP Link Hellos\n"
+ "Hello holdtime\n"
+ "Time (seconds) - 65535 implies infinite\n")
+{
+ return (ldp_vty_disc_holdtime(vty, no, HELLO_LINK, holdtime));
+}
+
+DEFPY (ldp_discovery_targeted_holdtime,
+ ldp_discovery_targeted_holdtime_cmd,
+ "[no] discovery targeted-hello holdtime (1-65535)$holdtime",
+ NO_STR
+ "Configure discovery parameters\n"
"LDP Targeted Hellos\n"
"Hello holdtime\n"
"Time (seconds) - 65535 implies infinite\n")
{
- return (ldp_vty_disc_holdtime(vty, no, hello_type, holdtime));
+ return (ldp_vty_disc_holdtime(vty, no, HELLO_TARGETED, holdtime));
}
-DEFPY (ldp_discovery_interval,
- ldp_discovery_interval_cmd,
- "[no] discovery <hello|targeted-hello>$hello_type interval (1-65535)$interval",
+DEFPY (ldp_discovery_link_interval,
+ ldp_discovery_link_interval_cmd,
+ "[no] discovery hello interval (1-65535)$interval",
NO_STR
"Configure discovery parameters\n"
"LDP Link Hellos\n"
+ "Hello interval\n"
+ "Time (seconds)\n")
+{
+ return (ldp_vty_disc_interval(vty, no, HELLO_LINK, interval));
+}
+
+DEFPY (ldp_discovery_targeted_interval,
+ ldp_discovery_targeted_interval_cmd,
+ "[no] discovery targeted-hello interval (1-65535)$interval",
+ NO_STR
+ "Configure discovery parameters\n"
"LDP Targeted Hellos\n"
"Hello interval\n"
"Time (seconds)\n")
{
- return (ldp_vty_disc_interval(vty, no, hello_type, interval));
+ return (ldp_vty_disc_interval(vty, no, HELLO_TARGETED, interval));
}
DEFPY (ldp_dual_stack_transport_connection_prefer_ipv4,
DEFPY (ldp_show_mpls_ldp_binding,
ldp_show_mpls_ldp_binding_cmd,
- "show mpls ldp [<ipv4|ipv6>]$af binding [detail]$detail [json]$json",
+ "show mpls ldp [<ipv4|ipv6>]$af binding\
+ [<A.B.C.D/M|X:X::X:X/M>$prefix [longer-prefixes$longer_prefixes]]\
+ [{\
+ neighbor A.B.C.D$nbr\
+ |local-label (0-1048575)$local_label\
+ |remote-label (0-1048575)$remote_label\
+ }]\
+ [detail]$detail [json]$json",
"Show running system information\n"
"MPLS information\n"
"Label Distribution Protocol\n"
"IPv4 Address Family\n"
"IPv6 Address Family\n"
"Label Information Base (LIB) information\n"
+ "Destination prefix (IPv4)\n"
+ "Destination prefix (IPv6)\n"
+ "Include longer matches\n"
+ "Display labels from LDP neighbor\n"
+ "Neighbor LSR-ID\n"
+ "Match locally assigned label values\n"
+ "Locally assigned label value\n"
+ "Match remotely assigned label values\n"
+ "Remotely assigned label value\n"
"Show detailed information\n"
JSON_STR)
{
- return (ldp_vty_show_binding(vty, af, detail, json));
+ if (!local_label_str)
+ local_label = NO_LABEL;
+ if (!remote_label_str)
+ remote_label = NO_LABEL;
+ return (ldp_vty_show_binding(vty, af, prefix_str, !!longer_prefixes,
+ nbr_str, local_label, remote_label, detail, json));
}
DEFPY (ldp_show_mpls_ldp_discovery,
DEFPY (ldp_show_mpls_ldp_neighbor,
ldp_show_mpls_ldp_neighbor_cmd,
- "show mpls ldp neighbor [detail]$detail [json]$json",
+ "show mpls ldp neighbor [A.B.C.D]$lsr_id [detail]$detail [json]$json",
"Show running system information\n"
"MPLS information\n"
"Label Distribution Protocol\n"
"Neighbor information\n"
+ "Neighbor LSR-ID\n"
"Show detailed information\n"
JSON_STR)
{
- return (ldp_vty_show_neighbor(vty, 0, detail, json));
+ return (ldp_vty_show_neighbor(vty, lsr_id_str, 0, detail, json));
}
DEFPY (ldp_show_mpls_ldp_neighbor_capabilities,
ldp_show_mpls_ldp_neighbor_capabilities_cmd,
- "show mpls ldp neighbor capabilities [json]$json",
+ "show mpls ldp neighbor [A.B.C.D]$lsr_id capabilities [json]$json",
"Show running system information\n"
"MPLS information\n"
"Label Distribution Protocol\n"
"Neighbor information\n"
+ "Neighbor LSR-ID\n"
"Display neighbor capability information\n"
JSON_STR)
{
- return (ldp_vty_show_neighbor(vty, 1, NULL, json));
+ return (ldp_vty_show_neighbor(vty, lsr_id_str, 1, NULL, json));
}
DEFPY (ldp_show_l2vpn_atom_binding,
ldp_show_l2vpn_atom_binding_cmd,
- "show l2vpn atom binding [json]$json",
+ "show l2vpn atom binding\
+ [{\
+ A.B.C.D$peer\
+ |local-label (16-1048575)$local_label\
+ |remote-label (16-1048575)$remote_label\
+ }]\
+ [json]$json",
"Show running system information\n"
"Show information about Layer2 VPN\n"
"Show Any Transport over MPLS information\n"
"Show AToM label binding information\n"
+ "Destination address of the VC\n"
+ "Match locally assigned label values\n"
+ "Locally assigned label value\n"
+ "Match remotely assigned label values\n"
+ "Remotely assigned label value\n"
JSON_STR)
{
- return (ldp_vty_show_atom_binding(vty, json));
+ if (!local_label_str)
+ local_label = NO_LABEL;
+ if (!remote_label_str)
+ remote_label = NO_LABEL;
+ return (ldp_vty_show_atom_binding(vty, peer_str, local_label,
+ remote_label, json));
}
DEFPY (ldp_show_l2vpn_atom_vc,
ldp_show_l2vpn_atom_vc_cmd,
- "show l2vpn atom vc [json]$json",
+ "show l2vpn atom vc\
+ [{\
+ A.B.C.D$peer\
+ |interface IFNAME$ifname\
+ |vc-id (1-4294967295)$vcid\
+ }]\
+ [json]$json",
"Show running system information\n"
"Show information about Layer2 VPN\n"
"Show Any Transport over MPLS information\n"
"Show AToM virtual circuit information\n"
+ "Destination address of the VC\n"
+ "Local interface of the pseudowire\n"
+ "Interface's name\n"
+ "VC ID\n"
+ "VC ID\n"
JSON_STR)
{
- return (ldp_vty_show_atom_vc(vty, json));
+ return (ldp_vty_show_atom_vc(vty, peer_str, ifname, vcid_str, json));
}
DEFUN_NOSH (ldp_show_debugging_mpls_ldp,
install_element(LDP_NODE, &ldp_address_family_cmd);
install_element(LDP_NODE, &no_ldp_address_family_cmd);
- install_element(LDP_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_NODE, &ldp_discovery_targeted_holdtime_cmd);
+ install_element(LDP_NODE, &ldp_discovery_link_interval_cmd);
+ install_element(LDP_NODE, &ldp_discovery_targeted_interval_cmd);
install_element(LDP_NODE, &ldp_dual_stack_transport_connection_prefer_ipv4_cmd);
install_element(LDP_NODE, &ldp_dual_stack_cisco_interop_cmd);
install_element(LDP_NODE, &ldp_neighbor_password_cmd);
install_element(LDP_NODE, &ldp_neighbor_ttl_security_cmd);
install_element(LDP_NODE, &ldp_router_id_cmd);
- install_element(LDP_IPV4_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_IPV4_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_IPV4_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_holdtime_cmd);
+ install_element(LDP_IPV4_NODE, &ldp_discovery_link_interval_cmd);
+ install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_interval_cmd);
install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_hello_accept_cmd);
install_element(LDP_IPV4_NODE, &ldp_discovery_transport_address_ipv4_cmd);
install_element(LDP_IPV4_NODE, &ldp_label_local_advertise_cmd);
install_element(LDP_IPV4_NODE, &ldp_neighbor_ipv4_targeted_cmd);
install_element(LDP_IPV4_NODE, &ldp_exit_address_family_cmd);
- install_element(LDP_IPV6_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_IPV6_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_IPV6_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_holdtime_cmd);
+ install_element(LDP_IPV6_NODE, &ldp_discovery_link_interval_cmd);
+ install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_interval_cmd);
install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_hello_accept_cmd);
install_element(LDP_IPV6_NODE, &ldp_discovery_transport_address_ipv6_cmd);
install_element(LDP_IPV6_NODE, &ldp_label_local_advertise_cmd);
install_element(LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd);
install_element(LDP_IPV6_NODE, &ldp_exit_address_family_cmd);
- install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_link_interval_cmd);
- install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_holdtime_cmd);
- install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_interval_cmd);
+ install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_holdtime_cmd);
+ install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_link_interval_cmd);
install_element(LDP_L2VPN_NODE, &ldp_bridge_cmd);
install_element(LDP_L2VPN_NODE, &ldp_mtu_cmd);
ldp_af_iface_config_write(vty, af);
+ vty_out(vty, " !\n");
vty_out(vty, " exit-address-family\n");
}
return (CMD_SUCCESS);
}
-int
-ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
- const char *hello_type_str, long secs)
+int ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
+ enum hello_type hello_type, long secs)
{
struct ldpd_af_conf *af_conf;
struct iface *iface;
struct iface_af *ia;
int af;
- enum hello_type hello_type;
-
- if (hello_type_str[0] == 'h')
- hello_type = HELLO_LINK;
- else
- hello_type = HELLO_TARGETED;
switch (vty->node) {
case LDP_NODE:
int
ldp_vty_disc_interval(struct vty *vty, const char *negate,
- const char *hello_type_str, long secs)
+ enum hello_type hello_type, long secs)
{
struct ldpd_af_conf *af_conf;
struct iface *iface;
struct iface_af *ia;
int af;
- enum hello_type hello_type;
-
- if (hello_type_str[0] == 'h')
- hello_type = HELLO_LINK;
- else
- hello_type = HELLO_TARGETED;
switch (vty->node) {
case LDP_NODE:
int family;
union ldpd_addr addr;
uint8_t prefixlen;
- int capabilities;
int detail;
int json;
+ union {
+ struct {
+ struct in_addr lsr_id;
+ int capabilities;
+ } neighbor;
+ struct {
+ struct prefix prefix;
+ int longer_prefixes;
+ struct in_addr neighbor;
+ uint32_t local_label;
+ uint32_t remote_label;
+ } lib;
+ struct {
+ struct in_addr peer;
+ uint32_t local_label;
+ uint32_t remote_label;
+ char ifname[IFNAMSIZ];
+ uint32_t vcid;
+ } l2vpn;
+ };
};
#define LDPBUFSIZ 65535
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_LIB_BEGIN:
+ rt = imsg->data;
+
+ if (params->lib.remote_label != NO_LABEL &&
+ params->lib.remote_label != rt->remote_label)
+ return (0);
+ /* FALLTHROUGH */
case IMSG_CTL_SHOW_LIB_RCVD:
rt = imsg->data;
!rt->no_downstream)
break;
- if (params->family != AF_UNSPEC && params->family != rt->af)
- break;
-
snprintf(dstnet, sizeof(dstnet), "%s/%d",
log_addr(rt->af, &rt->prefix), rt->prefixlen);
show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
{
struct ctl_rt *rt = NULL;
- char dstnet[BUFSIZ];
+ static char dstnet[BUFSIZ];
static int upstream, downstream;
size_t buflen;
static char sent_buffer[LDPBUFSIZ];
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_LIB_BEGIN:
- case IMSG_CTL_SHOW_LIB_SENT:
- case IMSG_CTL_SHOW_LIB_RCVD:
- case IMSG_CTL_SHOW_LIB_END:
rt = imsg->data;
- if (params->family != AF_UNSPEC && params->family != rt->af)
- return (0);
- break;
- default:
- break;
- }
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_LIB_BEGIN:
upstream = 0;
downstream = 0;
sent_buffer[0] = '\0';
rcvd_buffer[0] = '\0';
-
snprintf(dstnet, sizeof(dstnet), "%s/%d",
log_addr(rt->af, &rt->prefix), rt->prefixlen);
-
- vty_out (vty, "%s\n", dstnet);
- vty_out (vty, "%-8sLocal binding: label: %s\n", "",
- log_label(rt->local_label));
break;
case IMSG_CTL_SHOW_LIB_SENT:
+ rt = imsg->data;
+
upstream = 1;
buflen = strlen(sent_buffer);
snprintf(sent_buffer + buflen, LDPBUFSIZ - buflen,
"%12s%s:0\n", "", inet_ntoa(rt->nexthop));
break;
case IMSG_CTL_SHOW_LIB_RCVD:
+ rt = imsg->data;
downstream = 1;
buflen = strlen(rcvd_buffer);
snprintf(rcvd_buffer + buflen, LDPBUFSIZ - buflen,
rt->in_use ? " (in use)" : "");
break;
case IMSG_CTL_SHOW_LIB_END:
+ rt = imsg->data;
+
+ if (params->lib.remote_label != NO_LABEL &&
+ !downstream)
+ break;
+ vty_out(vty, "%s\n", dstnet);
+ vty_out(vty, "%-8sLocal binding: label: %s\n", "",
+ log_label(rt->local_label));
if (upstream) {
vty_out (vty, "%-8sAdvertised to:\n", "");
vty_out(vty, "%s", sent_buffer);
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_LIB_BEGIN:
- case IMSG_CTL_SHOW_LIB_SENT:
- case IMSG_CTL_SHOW_LIB_RCVD:
- case IMSG_CTL_SHOW_LIB_END:
rt = imsg->data;
- if (params->family != AF_UNSPEC && params->family != rt->af)
- return (0);
- break;
- default:
- break;
- }
- switch (imsg->hdr.type) {
- case IMSG_CTL_SHOW_LIB_BEGIN:
snprintf(dstnet, sizeof(dstnet), "%s/%d",
log_addr(rt->af, &rt->prefix), rt->prefixlen);
json_object_object_add(json, dstnet, json_lib_entry);
break;
case IMSG_CTL_SHOW_LIB_SENT:
+ rt = imsg->data;
+
json_adv_label = json_object_new_object();
json_object_string_add(json_adv_label, "neighborId",
inet_ntoa(rt->nexthop));
json_object_array_add(json_adv_labels, json_adv_label);
break;
case IMSG_CTL_SHOW_LIB_RCVD:
+ rt = imsg->data;
+
json_remote_label = json_object_new_object();
json_object_string_add(json_remote_label, "neighborId",
inet_ntoa(rt->nexthop));
}
static int
-ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+ldp_vty_dispatch_iface(struct vty *vty, struct imsg *imsg,
struct show_params *params, json_object *json)
{
int ret;
- switch (cmd) {
- case SHOW_IFACE:
+ if (params->json)
+ ret = show_interface_msg_json(imsg, params, json);
+ else
+ ret = show_interface_msg(vty, imsg, params);
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_disc(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ int ret;
+
+ if (params->detail) {
if (params->json)
- ret = show_interface_msg_json(imsg, params, json);
+ ret = show_discovery_detail_msg_json(imsg, params,
+ json);
else
- ret = show_interface_msg(vty, imsg, params);
- break;
- case SHOW_DISC:
- if (params->detail) {
- if (params->json)
- ret = show_discovery_detail_msg_json(imsg,
- params, json);
- else
- ret = show_discovery_detail_msg(vty, imsg,
- params);
- } else {
- if (params->json)
- ret = show_discovery_msg_json(imsg, params,
- json);
- else
- ret = show_discovery_msg(vty, imsg, params);
+ ret = show_discovery_detail_msg(vty, imsg, params);
+ } else {
+ if (params->json)
+ ret = show_discovery_msg_json(imsg, params, json);
+ else
+ ret = show_discovery_msg(vty, imsg, params);
+ }
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_nbr(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ static bool filtered = false;
+ struct ctl_nbr *nbr;
+ int ret;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_NBR:
+ filtered = false;
+ nbr = imsg->data;
+
+ if (params->neighbor.lsr_id.s_addr != INADDR_ANY &&
+ params->neighbor.lsr_id.s_addr != nbr->id.s_addr) {
+ filtered = true;
+ return (0);
}
break;
- case SHOW_NBR:
- if (params->capabilities) {
- if (params->json)
- ret = show_nbr_capabilities_msg_json(imsg,
- params, json);
- else
- ret = show_nbr_capabilities_msg(vty, imsg,
- params);
- } else if (params->detail) {
- if (params->json)
- ret = show_nbr_detail_msg_json(imsg, params,
- json);
- else
- ret = show_nbr_detail_msg(vty, imsg, params);
- } else {
- if (params->json)
- ret = show_nbr_msg_json(imsg, params, json);
- else
- ret = show_nbr_msg(vty, imsg, params);
- }
+ case IMSG_CTL_SHOW_NBR_DISC:
+ case IMSG_CTL_SHOW_NBR_END:
+ if (filtered)
+ return (0);
break;
- case SHOW_LIB:
- if (params->detail) {
- if (params->json)
- ret = show_lib_detail_msg_json(imsg, params,
- json);
- else
- ret = show_lib_detail_msg(vty, imsg, params);
- } else {
- if (params->json)
- ret = show_lib_msg_json(imsg, params, json);
- else
- ret = show_lib_msg(vty, imsg, params);
- }
+ default:
break;
- case SHOW_L2VPN_PW:
+ }
+
+ if (params->neighbor.capabilities) {
+ if (params->json)
+ ret = show_nbr_capabilities_msg_json(imsg, params,
+ json);
+ else
+ ret = show_nbr_capabilities_msg(vty, imsg, params);
+ } else if (params->detail) {
+ if (params->json)
+ ret = show_nbr_detail_msg_json(imsg, params, json);
+ else
+ ret = show_nbr_detail_msg(vty, imsg, params);
+ } else {
if (params->json)
- ret = show_l2vpn_pw_msg_json(imsg, params, json);
+ ret = show_nbr_msg_json(imsg, params, json);
else
- ret = show_l2vpn_pw_msg(vty, imsg, params);
+ ret = show_nbr_msg(vty, imsg, params);
+ }
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_lib(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ static bool filtered = false;
+ struct ctl_rt *rt = NULL;
+ struct prefix prefix;
+ int ret;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB_BEGIN:
+ filtered = false;
break;
- case SHOW_L2VPN_BINDING:
+ case IMSG_CTL_SHOW_LIB_SENT:
+ case IMSG_CTL_SHOW_LIB_RCVD:
+ case IMSG_CTL_SHOW_LIB_END:
+ if (filtered)
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB_BEGIN:
+ case IMSG_CTL_SHOW_LIB_SENT:
+ case IMSG_CTL_SHOW_LIB_RCVD:
+ case IMSG_CTL_SHOW_LIB_END:
+ rt = imsg->data;
+
+ if (params->family != AF_UNSPEC && params->family != rt->af) {
+ filtered = true;
+ return (0);
+ }
+
+ prefix.family = rt->af;
+ prefix.prefixlen = rt->prefixlen;
+ memcpy(&prefix.u.val, &rt->prefix, sizeof(prefix.u.val));
+ if (params->lib.prefix.family != AF_UNSPEC) {
+ if (!params->lib.longer_prefixes &&
+ !prefix_same(¶ms->lib.prefix, &prefix)) {
+ filtered = true;
+ return (0);
+ } else if (params->lib.longer_prefixes &&
+ !prefix_match(¶ms->lib.prefix, &prefix)) {
+ filtered = true;
+ return (0);
+ }
+ }
+
+ if (params->lib.local_label != NO_LABEL &&
+ params->lib.local_label != rt->local_label) {
+ filtered = true;
+ return (0);
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB_SENT:
+ case IMSG_CTL_SHOW_LIB_RCVD:
+ if (params->lib.neighbor.s_addr != INADDR_ANY &&
+ params->lib.neighbor.s_addr != rt->nexthop.s_addr)
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_LIB_RCVD:
+ if (params->lib.remote_label != NO_LABEL &&
+ params->lib.remote_label != rt->remote_label)
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ if (params->detail) {
if (params->json)
- ret = show_l2vpn_binding_msg_json(imsg, params, json);
+ ret = show_lib_detail_msg_json(imsg, params, json);
else
- ret = show_l2vpn_binding_msg(vty, imsg, params);
+ ret = show_lib_detail_msg(vty, imsg, params);
+ } else {
+ if (params->json)
+ ret = show_lib_msg_json(imsg, params, json);
+ else
+ ret = show_lib_msg(vty, imsg, params);
+ }
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_l2vpn_pw(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ struct ctl_pw *pw;
+ int ret;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_L2VPN_PW:
+ pw = imsg->data;
+ if (params->l2vpn.peer.s_addr != INADDR_ANY &&
+ params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
+ return (0);
+ if (params->l2vpn.ifname[0] != '\0' &&
+ strcmp(params->l2vpn.ifname, pw->ifname))
+ return (0);
+ if (params->l2vpn.vcid && params->l2vpn.vcid != pw->pwid)
+ return (0);
break;
default:
- return (0);
+ break;
}
+ if (params->json)
+ ret = show_l2vpn_pw_msg_json(imsg, params, json);
+ else
+ ret = show_l2vpn_pw_msg(vty, imsg, params);
+
+ return (ret);
+}
+
+static int
+ldp_vty_dispatch_l2vpn_binding(struct vty *vty, struct imsg *imsg,
+ struct show_params *params, json_object *json)
+{
+ struct ctl_pw *pw;
+ int ret;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_L2VPN_BINDING:
+ pw = imsg->data;
+ if (params->l2vpn.peer.s_addr != INADDR_ANY &&
+ params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
+ return (0);
+ if (params->l2vpn.local_label != NO_LABEL &&
+ params->l2vpn.local_label != pw->local_label)
+ return (0);
+ if (params->l2vpn.remote_label != NO_LABEL &&
+ params->l2vpn.remote_label != pw->remote_label)
+ return (0);
+ break;
+ default:
+ break;
+ }
+
+ if (params->json)
+ ret = show_l2vpn_binding_msg_json(imsg, params, json);
+ else
+ ret = show_l2vpn_binding_msg(vty, imsg, params);
+
return (ret);
}
+static int
+ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+ struct show_params *params, json_object *json)
+{
+ switch (cmd) {
+ case SHOW_IFACE:
+ return (ldp_vty_dispatch_iface(vty, imsg, params, json));
+ case SHOW_DISC:
+ return (ldp_vty_dispatch_disc(vty, imsg, params, json));
+ case SHOW_NBR:
+ return (ldp_vty_dispatch_nbr(vty, imsg, params, json));
+ case SHOW_LIB:
+ return (ldp_vty_dispatch_lib(vty, imsg, params, json));
+ case SHOW_L2VPN_PW:
+ return (ldp_vty_dispatch_l2vpn_pw(vty, imsg, params, json));
+ case SHOW_L2VPN_BINDING:
+ return (ldp_vty_dispatch_l2vpn_binding(vty, imsg, params,
+ json));
+ default:
+ return (0);
+ }
+}
+
static int
ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd,
struct show_params *params)
}
int
-ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, const char *json)
+ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *prefix,
+ int longer_prefixes, const char *neighbor, unsigned long local_label,
+ unsigned long remote_label, const char *detail, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
params.family = af;
params.detail = (detail) ? 1 : 0;
params.json = (json) ? 1 : 0;
+ if (prefix) {
+ (void)str2prefix(prefix, ¶ms.lib.prefix);
+ params.lib.longer_prefixes = longer_prefixes;
+ }
+ if (neighbor &&
+ (inet_pton(AF_INET, neighbor, ¶ms.lib.neighbor) != 1 ||
+ bad_addr_v4(params.lib.neighbor))) {
+ vty_out (vty, "%% Malformed address\n");
+ return (CMD_SUCCESS);
+ }
+ params.lib.local_label = local_label;
+ params.lib.remote_label = remote_label;
if (!params.detail && !params.json)
vty_out (vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF",
}
int
-ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, const char *json)
+ldp_vty_show_neighbor(struct vty *vty, const char *lsr_id, int capabilities,
+ const char *detail, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
return (CMD_WARNING);
memset(¶ms, 0, sizeof(params));
- params.capabilities = capabilities;
params.detail = (detail) ? 1 : 0;
params.json = (json) ? 1 : 0;
+ params.neighbor.capabilities = capabilities;
+ if (lsr_id &&
+ (inet_pton(AF_INET, lsr_id, ¶ms.neighbor.lsr_id) != 1 ||
+ bad_addr_v4(params.neighbor.lsr_id))) {
+ vty_out (vty, "%% Malformed address\n");
+ return (CMD_SUCCESS);
+ }
- if (params.capabilities)
+ if (params.neighbor.capabilities)
params.detail = 1;
if (!params.detail && !params.json)
}
int
-ldp_vty_show_atom_binding(struct vty *vty, const char *json)
+ldp_vty_show_atom_binding(struct vty *vty, const char *peer,
+ unsigned long local_label, unsigned long remote_label, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
memset(¶ms, 0, sizeof(params));
params.json = (json) ? 1 : 0;
+ if (peer &&
+ (inet_pton(AF_INET, peer, ¶ms.l2vpn.peer) != 1 ||
+ bad_addr_v4(params.l2vpn.peer))) {
+ vty_out (vty, "%% Malformed address\n");
+ return (CMD_SUCCESS);
+ }
+ params.l2vpn.local_label = local_label;
+ params.l2vpn.remote_label = remote_label;
imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, ¶ms));
}
int
-ldp_vty_show_atom_vc(struct vty *vty, const char *json)
+ldp_vty_show_atom_vc(struct vty *vty, const char *peer, const char *ifname,
+ const char *vcid, const char *json)
{
struct imsgbuf ibuf;
struct show_params params;
memset(¶ms, 0, sizeof(params));
params.json = (json) ? 1 : 0;
+ if (peer &&
+ (inet_pton(AF_INET, peer, ¶ms.l2vpn.peer) != 1 ||
+ bad_addr_v4(params.l2vpn.peer))) {
+ vty_out (vty, "%% Malformed address\n");
+ return (CMD_SUCCESS);
+ }
+ if (ifname)
+ strlcpy(params.l2vpn.ifname, ifname,
+ sizeof(params.l2vpn.ifname));
+ if (vcid)
+ params.l2vpn.vcid = atoi(vcid);
if (!params.json) {
/* header */
frr_preinit(&ldpd_di, argc, argv);
frr_opt_add("LEn:", longopts,
" --ctl_socket Override ctl socket path\n"
- "-n, --instance Instance id\n");
+ " -n, --instance Instance id\n");
while (1) {
int opt;
start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
{
char *argv[3];
- int argc = 0;
+ int argc = 0, nullfd;
pid_t pid;
switch (pid = fork()) {
return (pid);
}
+ nullfd = open("/dev/null", O_RDONLY | O_NOCTTY);
+ dup2(nullfd, 0);
+ dup2(nullfd, 1);
+ dup2(nullfd, 2);
+ close(nullfd);
+
if (dup2(fd_async, LDPD_FD_ASYNC) == -1)
fatal("cannot setup imsg async fd");
if (dup2(fd_sync, LDPD_FD_SYNC) == -1)
/* Clean the stack. */
memset(W, 0, 256);
memset(S, 0, 32);
- t0 = t1 = 0;
+ memset(&t0, 0, sizeof(t0));
+ memset(&t1, 0, sizeof(t0));
}
static unsigned char PAD[64] = {
u_int16_t expected_cmd)
{
struct stream *s;
- u_int16_t size;
+ u_int16_t size = -1;
u_char marker;
u_char version;
vrf_id_t vrf_id;
vty_out(vty, "debug ospf6 route intra-area\n");
if (IS_OSPF6_DEBUG_ROUTE(INTER))
vty_out(vty, "debug ospf6 route inter-area\n");
+ if (IS_OSPF6_DEBUG_ROUTE(MEMORY))
+ vty_out(vty, "debug ospf6 route memory\n");
+
return 0;
}
struct ospf_area_range *range = rn->info;
if (range->specifics != 0)
- ospf_delete_discard_route(area->ospf->new_table,
+ ospf_delete_discard_route(area->ospf, area->ospf->new_table,
(struct prefix_ipv4 *)&rn->p);
ospf_area_range_free(range);
if (CHECK_FLAG(range->flags,
OSPF_AREA_RANGE_ADVERTISE)) {
if (range->specifics)
- ospf_add_discard_route(
+ ospf_add_discard_route(ospf,
ospf->new_table, area,
(struct prefix_ipv4
*)&rn->p);
else
- ospf_delete_discard_route(
+ ospf_delete_discard_route(ospf,
ospf->new_table,
(struct prefix_ipv4
*)&rn->p);
{
struct listnode *node, *nnode;
struct ospf_interface *oi;
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
- if (!(ospf = ospf_lookup()))
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (!ospf)
return NULL;
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
{
struct listnode *node, *nnode;
struct ospf_interface *oi;
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
- if (!(ospf = ospf_lookup()))
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (!ospf)
return NULL;
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
struct ospf_interface *oi;
struct registered_opaque_type *r;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
/* Check if this interface is indeed ready for type 9 */
struct ospf *ospf;
struct ospf_area *area;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
struct registered_opaque_type *r;
struct ospf *ospf;
struct registered_opaque_type *r;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Can type 11 be originated? */
if (!ospf_apiserver_is_ready_type11(ospf))
struct ospf *ospf;
struct ospf_area *area;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Get request sequence number */
seqnum = msg_get_seq(msg);
struct ospf *ospf;
- ospf = ospf_lookup();
+ if (oi && oi->ospf)
+ ospf = oi->ospf;
+ else
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
assert(ospf);
/* Create a stream for internal opaque LSA */
new->area = area;
new->oi = oi;
+ new->vrf_id = ospf->vrf_id;
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, newlsa, length);
int ready = 0;
int rc = 0;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Extract opaque LSA data from message */
omsg = (struct msg_originate_request *)STREAM_DATA(msg->s);
case OSPF_OPAQUE_AS_LSA: {
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Increment counters? XXX */
{
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Install this LSA into LSDB. */
struct ospf_lsa *new = NULL;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
apiserv = lookup_apiserver_by_lsa(lsa);
int rc = 0;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Extract opaque LSA from message */
* the LSDB until it is finally handled by the maxage remover thread.
* Therefore, the lookup function below may return non-NULL result.
*/
- old = ospf_lsa_lookup(area, dmsg->lsa_type, id, ospf->router_id);
+ old = ospf_lsa_lookup(ospf, area, dmsg->lsa_type, id, ospf->router_id);
if (!old) {
zlog_warn(
"ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB",
struct ospf *ospf;
struct ospf_area *area;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
assert(ospf);
/* Set parameter struct. */
/* Remove route from zebra. */
if (or->type == OSPF_DESTINATION_NETWORK)
- ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+ ospf_zebra_delete(ospf,
+ (struct prefix_ipv4 *)&rn->p,
or);
ospf_route_free(or);
return 1;
}
-static int ospf_ase_compare_tables(struct route_table *new_external_route,
+static int ospf_ase_compare_tables(struct ospf *ospf,
+ struct route_table *new_external_route,
struct route_table *old_external_route)
{
struct route_node *rn, *new_rn;
if ((or = rn->info)) {
if (!(new_rn = route_node_lookup(new_external_route,
&rn->p)))
- ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+ ospf_zebra_delete(ospf,
+ (struct prefix_ipv4 *)&rn->p,
or);
else
route_unlock_node(new_rn);
if ((or = rn->info) != NULL)
if (!ospf_ase_route_match_same(old_external_route,
&rn->p, or))
- ospf_zebra_add((struct prefix_ipv4 *)&rn->p,
+ ospf_zebra_add(ospf,
+ (struct prefix_ipv4 *)&rn->p,
or);
return 0;
/* Compare old and new external routing table and install the
difference info zebra/kernel */
- ospf_ase_compare_tables(ospf->new_external_route,
+ ospf_ase_compare_tables(ospf, ospf->new_external_route,
ospf->old_external_route);
/* Delete old external routing table */
}
/* install changes to zebra */
- ospf_ase_compare_tables(ospf->new_external_route, tmp_old);
+ ospf_ase_compare_tables(ospf, ospf->new_external_route, tmp_old);
/* update ospf->old_external_route table */
if (rn && rn->info)
bfd_info = (struct bfd_info *)params->bfd_info;
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
- zlog_debug("%s nbr (%s) with BFD",
+ zlog_debug("%s nbr (%s) with BFD. OSPF vrf %s",
bfd_get_command_dbg_str(command),
- inet_ntoa(nbr->src));
+ inet_ntoa(nbr->src),
+ ospf_vrf_id_to_name(oi->ospf->vrf_id));
bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name,
- 0, 0, command, 0, VRF_DEFAULT);
+ 0, 0, command, 0, oi->ospf->vrf_id);
}
/*
/* Send the client registration */
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
- /* Replay the neighbor, if BFD is enabled in BGP */
+ /* Replay the neighbor, if BFD is enabled in OSPF */
for (ALL_LIST_ELEMENTS(om->ospf, node, onode, ospf)) {
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) {
if ((nbrs = oi->nbrs) == NULL)
DEBUG_STR
OSPF_STR)
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
- if ((ospf = ospf_lookup()) == NULL)
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL)
return CMD_SUCCESS;
return show_debugging_ospf_common(vty, ospf);
char str[16];
memset(str, 0, 16);
- if ((ospf = ospf_lookup()) == NULL)
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL)
return CMD_SUCCESS;
if (ospf->instance)
}
/* Check LSA is related to external info. */
-struct external_info *ospf_external_info_check(struct ospf_lsa *lsa)
+struct external_info *ospf_external_info_check(struct ospf *ospf,
+ struct ospf_lsa *lsa)
{
struct as_external_lsa *al;
struct prefix_ipv4 p;
redist_on =
is_prefix_default(&p)
? vrf_bitmap_check(zclient->default_information,
- VRF_DEFAULT)
+ ospf->vrf_id)
: (zclient->mi_redist[AFI_IP][type].enabled
|| vrf_bitmap_check(
zclient->redist[AFI_IP][type],
- VRF_DEFAULT));
+ ospf->vrf_id));
// Pending: check for MI above.
if (redist_on) {
struct list *ext_list;
ospf_translated_nssa_refresh(ospf, NULL, new);
return;
}
- ei = ospf_external_info_check(new);
+ ei = ospf_external_info_check(ospf, new);
if (ei)
ospf_external_lsa_refresh(ospf, new, ei,
LSA_REFRESH_FORCE);
extern void ospf_lsa_flush_area(struct ospf_lsa *, struct ospf_area *);
extern void ospf_lsa_flush_as(struct ospf *, struct ospf_lsa *);
extern void ospf_lsa_flush(struct ospf *, struct ospf_lsa *);
-extern struct external_info *ospf_external_info_check(struct ospf_lsa *);
+extern struct external_info *ospf_external_info_check(struct ospf *,
+ struct ospf_lsa *);
extern void ospf_lsdb_init(struct ospf_lsdb *);
oi->ospf = ospf;
QOBJ_REG(oi, ospf_interface);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf interface %s vrf %s id %u created",
+ __PRETTY_FUNCTION__, ifp->name,
+ ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
+
return oi;
}
list_free(oi->ls_ack);
list_free(oi->ls_ack_direct.ls_ack);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf interface %s vrf %s id %u deleted",
+ __PRETTY_FUNCTION__, oi->ifp->name,
+ ospf_vrf_id_to_name(oi->ifp->vrf_id),
+ oi->ifp->vrf_id);
+
ospf_delete_from_if(oi->ifp, oi);
listnode_delete(oi->ospf->oiflist, oi);
struct ospf *ospf;
struct ospf_interface *oi;
- if ((ospf = ospf_lookup()) == NULL)
+ if (!oic)
+ return NULL;
+
+ ospf = oic->ospf;
+ if (ospf == NULL)
return NULL;
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
}
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_vl_new(): creating pseudo zebra interface");
+ zlog_debug("ospf_vl_new(): creating pseudo zebra interface vrf id %u",
+ ospf->vrf_id);
snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count);
- vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), VRF_DEFAULT);
+ vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), ospf->vrf_id);
/*
* if_create sets ZEBRA_INTERFACE_LINKDETECTION
* virtual links don't need this.
void ospf_if_init()
{
/* Initialize Zebra interface data structure. */
- om->iflist = vrf_iflist(VRF_DEFAULT);
hook_register_prio(if_add, 0, ospf_if_new_hook);
hook_register_prio(if_del, 0, ospf_if_delete_hook);
}
monotime(&new->tv_recv);
new->tv_orig = new->tv_recv;
new->refresh_list = -1;
+ new->vrf_id = VRF_DEFAULT;
return new;
}
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = area->ospf->vrf_id;
/* Copy LSA data to store, discard stream. */
new->data = ospf_lsa_data_new(length);
new->area = oi->area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = oi->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
new = ospf_lsa_new();
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = area->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
new = ospf_lsa_new();
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = area->ospf->vrf_id;
/* Copy LSA to store. */
new->data = ospf_lsa_data_new(length);
new->area = NULL;
SET_FLAG(new->flags,
OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
+ new->vrf_id = ospf->vrf_id;
/* Copy LSA data to store, discard stream. */
new->data = ospf_lsa_data_new(length);
void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct listnode *node, *nnode;
- struct ospf_lsa *lsa;
+ struct ospf_lsa *lsa = NULL;
struct ospf_area *area;
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
if (area->external_routing == OSPF_AREA_NSSA) {
- if (!(lsa = ospf_lsa_lookup(area, OSPF_AS_NSSA_LSA,
- p->prefix,
- ospf->router_id))) {
+ lsa = ospf_lsa_lookup(ospf, area,
+ OSPF_AS_NSSA_LSA, p->prefix,
+ ospf->router_id);
+ if (!lsa) {
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
zlog_debug(
"LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
{
struct route_node *rn;
- struct prefix_ptr lsa_prefix;
+ struct prefix lsa_prefix;
+ memset(&lsa_prefix, 0, sizeof(struct prefix));
lsa_prefix.family = 0;
- lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
- lsa_prefix.prefix = (uintptr_t)lsa;
+ lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
+ lsa_prefix.u.ptr = (uintptr_t)lsa;
if ((rn = route_node_lookup(ospf->maxage_lsa,
(struct prefix *)&lsa_prefix))) {
rn); /* unlock node because lsa is deleted */
}
route_unlock_node(rn); /* route_node_lookup */
+ } else {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: lsa %s is not found in maxage db.",
+ __PRETTY_FUNCTION__, dump_lsa_key(lsa));
}
}
*/
void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
{
- struct prefix_ptr lsa_prefix;
+ struct prefix lsa_prefix;
struct route_node *rn;
/* When we saw a MaxAge LSA flooded to us, we put it on the list
return;
}
+ memset(&lsa_prefix, 0, sizeof(struct prefix));
lsa_prefix.family = 0;
- lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
- lsa_prefix.prefix = (uintptr_t)lsa;
+ lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
+ lsa_prefix.u.ptr = (uintptr_t)lsa;
if ((rn = route_node_get(ospf->maxage_lsa,
(struct prefix *)&lsa_prefix))
SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
}
} else {
- zlog_err("Unable to allocate memory for maxage lsa\n");
+ zlog_err("Unable to allocate memory for maxage lsa %s\n",
+ dump_lsa_key(lsa));
assert(0);
}
return lsa;
}
-struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *area, u_int32_t type,
- struct in_addr id, struct in_addr adv_router)
+struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *area,
+ u_int32_t type, struct in_addr id,
+ struct in_addr adv_router)
{
- struct ospf *ospf = ospf_lookup();
- assert(ospf);
+ if (!ospf)
+ return NULL;
switch (type) {
case OSPF_ROUTER_LSA:
* they two were forming a unique LSA-ID.
*/
- match = ospf_lsa_lookup(area, lsah->type, lsah->id, lsah->adv_router);
+ match = ospf_lsa_lookup(area->ospf, area, lsah->type, lsah->id,
+ lsah->adv_router);
if (match == NULL)
if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA)
*/
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
break;
- ei = ospf_external_info_check(lsa);
+ ei = ospf_external_info_check(ospf, lsa);
if (ei)
new = ospf_external_lsa_refresh(ospf, lsa, ei,
LSA_REFRESH_FORCE);
/* For Type-9 Opaque-LSAs */
struct ospf_interface *oi;
+
+ /* VRF Id */
+ vrf_id_t vrf_id;
};
/* OSPF LSA Link Type. */
struct external_info *);
extern int ospf_external_lsa_originate_timer(struct thread *);
extern int ospf_default_originate_timer(struct thread *);
-extern struct ospf_lsa *ospf_lsa_lookup(struct ospf_area *, u_int32_t,
- struct in_addr, struct in_addr);
+extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *,
+ u_int32_t, struct in_addr,
+ struct in_addr);
extern struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *, u_int32_t,
struct in_addr);
extern struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *,
/* Library inits. */
debug_init();
- vrf_init(NULL, NULL, NULL, NULL);
+ ospf_vrf_init();
access_list_init();
prefix_list_init();
if (ret < 0)
zlog_warn("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
top->fd, safe_strerror(errno));
-
+#ifndef GNU_LINUX
+ /* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send
+ * packet out of ifindex. Below would be used Non Linux system.
+ */
ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
if (ret < 0)
zlog_warn(
"ifindex %u): %s",
top->fd, inet_ntoa(p->u.prefix4), ifindex,
safe_strerror(errno));
+#endif
return ret;
}
-int ospf_sock_init(void)
+int ospf_bind_vrfdevice(struct ospf *ospf, int ospf_sock)
+{
+ int ret = 0;
+
+#ifdef SO_BINDTODEVICE
+
+ if (ospf && ospf->vrf_id != VRF_DEFAULT &&
+ ospf->vrf_id != VRF_UNKNOWN) {
+ ret = setsockopt(ospf_sock, SOL_SOCKET, SO_BINDTODEVICE,
+ ospf->name,
+ strlen(ospf->name));
+ if (ret < 0) {
+ int save_errno = errno;
+
+ zlog_warn("%s: Could not setsockopt SO_BINDTODEVICE %s",
+ __PRETTY_FUNCTION__,
+ safe_strerror(save_errno));
+ } else {
+ zlog_debug("%s: Bind socket %d to vrf %s id %u device",
+ __PRETTY_FUNCTION__, ospf_sock,
+ ospf->name, ospf->vrf_id);
+ }
+ }
+#endif
+ return ret;
+}
+
+int ospf_sock_init(struct ospf *ospf)
{
int ospf_sock;
int ret, hincl = 1;
int bufsize = (8 * 1024 * 1024);
- if (ospfd_privs.change(ZPRIVS_RAISE))
+ if (ospfd_privs.change(ZPRIVS_RAISE)) {
zlog_err("ospf_sock_init: could not raise privs, %s",
safe_strerror(errno));
+ }
ospf_sock = socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
if (ospf_sock < 0) {
int save_errno = errno;
+
if (ospfd_privs.change(ZPRIVS_LOWER))
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
exit(1);
}
+ ret = ospf_bind_vrfdevice(ospf, ospf_sock);
+ if (ret < 0)
+ goto out;
+
#ifdef IP_HDRINCL
/* we will include IP header with packet */
ret = setsockopt(ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl,
sizeof(hincl));
if (ret < 0) {
int save_errno = errno;
- if (ospfd_privs.change(ZPRIVS_LOWER))
- zlog_err("ospf_sock_init: could not lower privs, %s",
- safe_strerror(errno));
+
zlog_warn("Can't set IP_HDRINCL option for fd %d: %s",
ospf_sock, safe_strerror(save_errno));
+ goto out;
}
#elif defined(IPTOS_PREC_INTERNETCONTROL)
#warning "IP_HDRINCL not available on this system"
ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL);
if (ret < 0) {
int save_errno = errno;
- if (ospfd_privs.change(ZPRIVS_LOWER))
- zlog_err("ospf_sock_init: could not lower privs, %s",
- safe_strerror(errno));
+
zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos,
ospf_sock, safe_strerror(save_errno));
close(ospf_sock); /* Prevent sd leak. */
- return ret;
+ goto out;
}
#else /* !IPTOS_PREC_INTERNETCONTROL */
#warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
if (ret < 0)
zlog_warn("Can't set pktinfo option for fd %d", ospf_sock);
+ setsockopt_so_sendbuf(ospf_sock, bufsize);
+ setsockopt_so_recvbuf(ospf_sock, bufsize);
+
+ ospf->fd = ospf_sock;
+out:
if (ospfd_privs.change(ZPRIVS_LOWER)) {
zlog_err("ospf_sock_init: could not lower privs, %s",
safe_strerror(errno));
}
-
- setsockopt_so_sendbuf(ospf_sock, bufsize);
- setsockopt_so_recvbuf(ospf_sock, bufsize);
-
- return ospf_sock;
+ return ret;
}
extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
-extern int ospf_sock_init(void);
+extern int ospf_sock_init(struct ospf *ospf);
+extern int ospf_bind_vrfdevice(struct ospf *, int);
#endif /* _ZEBRA_OSPF_NETWORK_H */
listnode_add(new->area->opaque_lsa_self, oipt);
break;
case OSPF_OPAQUE_AS_LSA:
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(new->vrf_id);
if (new->area != NULL && (top = new->area->ospf) == NULL) {
free_opaque_info_per_type((void *)oipt);
oipt = NULL;
"Type-10 Opaque-LSA: Reference to AREA is missing?");
break;
case OSPF_OPAQUE_AS_LSA:
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if ((area = lsa->area) != NULL && (top = area->ospf) == NULL) {
zlog_warn(
"Type-11 Opaque-LSA: Reference to OSPF is missing?");
}
break;
case OSPF_OPAQUE_AS_LSA:
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if (lsa->area != NULL && (top = lsa->area->ospf) == NULL) {
/* Above conditions must have passed. */
zlog_warn("ospf_opaque_lsa_install: Sonmething wrong?");
struct ospf_opaque_functab *functab;
struct ospf_lsa *new = NULL;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(lsa->vrf_id);
if ((functab = ospf_opaque_functab_lookup(lsa)) == NULL
|| functab->lsa_refresher == NULL) {
void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
u_char lsa_type, u_char opaque_type)
{
- struct ospf *top;
+ struct ospf *top = NULL;
struct ospf_area dummy, *area = NULL;
struct ospf_interface *oi = NULL;
/* Generate a dummy lsa to be passed for a lookup function. */
lsa = pseudo_lsa(oi, area, lsa_type, opaque_type);
+ lsa->vrf_id = top->vrf_id;
if ((oipt = lookup_opaque_info_by_type(lsa)) == NULL) {
struct ospf_opaque_functab *functab;
lsa.oi = oi;
lsa.area = area;
lsa.data = &lsah;
+ lsa.vrf_id = VRF_DEFAULT;
lsah.type = lsa_type;
tmp = SET_OPAQUE_LSID(opaque_type, 0); /* Opaque-ID is unused here. */
ospf_ls_retransmit_delete_nbr_area(lsa->area, lsa);
break;
case OSPF_OPAQUE_AS_LSA:
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
top = lsa0->area->ospf;
ospf_ls_retransmit_delete_nbr_as(top, lsa);
struct ospf_lsa *lsa;
struct ospf *top;
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa0->vrf_id);
if ((oipt = lookup_opaque_info_by_type(lsa0)) == NULL
|| (oipi = lookup_opaque_info_by_id(oipt, lsa0)) == NULL) {
#define OSPF_WRITE_IPHL_SHIFT 2
int pkt_count = 0;
+#ifdef GNU_LINUX
+ unsigned char cmsgbuf[64] = {};
+ struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
+ struct in_pktinfo *pi;
+#endif
+
ospf->t_write = NULL;
node = listhead(ospf->oi_write_q);
msg.msg_namelen = sizeof(sa_dst);
msg.msg_iov = iov;
msg.msg_iovlen = 2;
+
iov[0].iov_base = (char *)&iph;
iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
iov[1].iov_base = STREAM_PNT(op->s);
iov[1].iov_len = op->length;
-/* Sadly we can not rely on kernels to fragment packets because of either
- * IP_HDRINCL and/or multicast destination being set.
- */
+#ifdef GNU_LINUX
+ msg.msg_control = (caddr_t)cm;
+ cm->cmsg_level = SOL_IP;
+ cm->cmsg_type = IP_PKTINFO;
+ cm->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+ pi = (struct in_pktinfo *)CMSG_DATA(cm);
+ pi->ipi_ifindex = oi->ifp->ifindex;
+
+ msg.msg_controllen = cm->cmsg_len;
+#endif
+
+ /* Sadly we can not rely on kernels to fragment packets
+ * because of either IP_HDRINCL and/or multicast
+ * destination being set.
+ */
+
#ifdef WANT_OSPF_WRITE_FRAGMENT
if (op->length > maxdatasize)
ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize,
}
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("Packet %s [Hello:RECV]: Options %s",
+ zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s",
inet_ntoa(ospfh->router_id),
- ospf_options_dump(hello->options));
+ ospf_options_dump(hello->options),
+ ospf_vrf_id_to_name(oi->ospf->vrf_id));
/* Compare options. */
#define REJECT_IF_TBIT_ON 1 /* XXX */
}
/* Search proper LSA in LSDB. */
- find = ospf_lsa_lookup(oi->area, ls_type, ls_id, adv_router);
+ find = ospf_lsa_lookup(oi->ospf, oi->area, ls_type, ls_id,
+ adv_router);
if (find == NULL) {
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq);
list_delete(ls_upd);
/* Create OSPF LSA instance. */
lsa = ospf_lsa_new();
+ lsa->vrf_id = oi->ospf->vrf_id;
/* We may wish to put some error checking if type NSSA comes in
and area not in NSSA mode */
switch (lsah->type) {
*/
lsas = ospf_ls_upd_list_lsa(nbr, s, oi, size);
+ if (lsas == NULL)
+ return;
#define DISCARD_LSA(L, N) \
{ \
if (IS_DEBUG_OSPF_EVENT) \
lsa = ospf_lsa_new();
lsa->data = (struct lsa_header *)STREAM_PNT(s);
+ lsa->vrf_id = oi->ospf->vrf_id;
/* lsah = (struct lsa_header *) STREAM_PNT (s); */
size -= OSPF_LSA_HEADER_SIZE;
return;
}
-static struct stream *ospf_recv_packet(int fd, struct interface **ifp,
+static struct stream *ospf_recv_packet(struct ospf *ospf, int fd,
+ struct interface **ifp,
struct stream *ibuf)
{
int ret;
ifindex = getsockopt_ifindex(AF_INET, &msgh);
- *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
+ *ifp = if_lookup_by_index(ifindex, ospf->vrf_id);
if (ret != ip_len) {
zlog_warn(
struct ip *iph;
struct ospf_header *ospfh;
u_int16_t length;
- struct interface *ifp;
+ struct interface *ifp = NULL;
struct connected *c;
/* first of all get interface pointer. */
thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
stream_reset(ospf->ibuf);
- if (!(ibuf = ospf_recv_packet(ospf->fd, &ifp, ospf->ibuf)))
+ ibuf = ospf_recv_packet(ospf, ospf->fd, &ifp, ospf->ibuf);
+ if (ibuf == NULL)
return -1;
/* This raw packet is known to be at least as big as its IP header. */
ifindex
retrieval but do not. */
c = if_lookup_address((void *)&iph->ip_src, AF_INET,
- VRF_DEFAULT);
+ ospf->vrf_id);
if (c)
ifp = c->ifp;
if (ifp == NULL)
op->dst.s_addr = addr;
+ if (IS_DEBUG_OSPF_EVENT) {
+ if (oi->ospf->vrf_id)
+ zlog_debug("%s: Hello Tx interface %s ospf vrf %s id %u",
+ __PRETTY_FUNCTION__, oi->ifp->name,
+ ospf_vrf_id_to_name(oi->ospf->vrf_id),
+ oi->ospf->vrf_id);
+ }
/* Add packet to the top of the interface output queue, so that they
* can't get delayed by things like long queues of LS Update packets
*/
* punt-to-CPU set on them. This may overload the CPU control path that
* can be avoided if the MAC was known apriori.
*/
-#define OSPF_PING_NBR_STR_MAX (8 + 40 + 20)
+#define OSPF_PING_NBR_STR_MAX (BUFSIZ)
void ospf_proactively_arp(struct ospf_neighbor *nbr)
{
char ping_nbr[OSPF_PING_NBR_STR_MAX];
- char *str_ptr;
int ret;
if (!nbr || !nbr->oi || !nbr->oi->ifp)
return;
- str_ptr = strcpy(ping_nbr, "ping -c 1 -I ");
- str_ptr = strcat(str_ptr, nbr->oi->ifp->name);
- str_ptr = strcat(str_ptr, " ");
- str_ptr = strcat(str_ptr, inet_ntoa(nbr->address.u.prefix4));
- str_ptr = strcat(str_ptr, " > /dev/null 2>&1 &");
+ snprintf(ping_nbr, sizeof(ping_nbr),
+ "ping -c 1 -I %s %s > /dev/null 2>&1 &",
+ nbr->oi->ifp->name, inet_ntoa(nbr->address.u.prefix4));
+
ret = system(ping_nbr);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("Executed %s %s", ping_nbr,
/* If Area address is not null and exist, retrieve corresponding
* structure */
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
zlog_info("RI-> Initialize Router Info for %s scope within area %s",
OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS",
inet_ntoa(OspfRI.area_id));
"LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance",
lsa_type, inet_ntoa(lsa_id));
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Set opaque-LSA header fields. */
lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
new->area = OspfRI.area; /* Area must be null if the Opaque type is AS
scope, fulfill otherwise */
+ if (new->area && new->area->ospf)
+ new->vrf_id = new->area->ospf->vrf_id;
+ else
+ new->vrf_id = VRF_DEFAULT;
+
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, lsah, length);
stream_free(s);
struct ospf *top;
struct ospf_area *area;
int rc = -1;
+ vrf_id_t vrf_id = VRF_DEFAULT;
/* First check if the area is known if flooding scope is Area */
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
return rc;
}
OspfRI.area = area;
+ if (area->ospf)
+ vrf_id = area->ospf->vrf_id;
}
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
"ospf_router_info_lsa_originate1: ospf_router_info_lsa_new() ?");
return rc;
}
+ new->vrf_id = vrf_id;
/* Get ospf info */
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(vrf_id);
+ if (top == NULL) {
+ zlog_debug("%s: ospf instance not found for vrf id %u",
+ __PRETTY_FUNCTION__, vrf_id);
+ return rc;
+ }
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
+ new->vrf_id = lsa->vrf_id;
/* Install this LSA into LSDB. */
/* Given "lsa" will be freed in the next function. */
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(lsa->vrf_id);
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_router_info_lsa_refresh: ospf_lsa_install() ?");
ospf_lsa_unlock(&new);
if (CHECK_FLAG(OspfRI.flags, RIFLG_LSA_ENGAGED) && (opcode == REORIGINATE_THIS_LSA))
opcode = REFRESH_THIS_LSA;
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if ((OspfRI.scope == OSPF_OPAQUE_AREA_LSA) && (OspfRI.area == NULL)) {
zlog_warn(
"ospf_router_info_lsa_schedule(): Router Info is Area scope flooding but area is not set");
XFREE(MTYPE_OSPF_PATH, op);
}
-void ospf_route_delete(struct route_table *rt)
+void ospf_route_delete(struct ospf *ospf, struct route_table *rt)
{
struct route_node *rn;
struct ospf_route * or ;
for (rn = route_top(rt); rn; rn = route_next(rn))
if ((or = rn->info) != NULL) {
if (or->type == OSPF_DESTINATION_NETWORK)
- ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+ ospf_zebra_delete(ospf,
+ (struct prefix_ipv4 *)&rn->p,
or);
else if (or->type == OSPF_DESTINATION_DISCARD)
- ospf_zebra_delete_discard(
+ ospf_zebra_delete_discard(ospf,
(struct prefix_ipv4 *)&rn->p);
}
}
/* delete routes generated from AS-External routes if there is a inter/intra
* area route
*/
-static void ospf_route_delete_same_ext(struct route_table *external_routes,
+static void ospf_route_delete_same_ext(struct ospf *ospf,
+ struct route_table *external_routes,
struct route_table *routes)
{
struct route_node *rn, *ext_rn;
if ((ext_rn = route_node_lookup(external_routes,
(struct prefix *)p))) {
if (ext_rn->info) {
- ospf_zebra_delete(p, ext_rn->info);
+ ospf_zebra_delete(ospf, p,
+ ext_rn->info);
ospf_route_free(ext_rn->info);
ext_rn->info = NULL;
}
}
/* rt: Old, cmprt: New */
-static void ospf_route_delete_uniq(struct route_table *rt,
+static void ospf_route_delete_uniq(struct ospf *ospf, struct route_table *rt,
struct route_table *cmprt)
{
struct route_node *rn;
cmprt,
(struct prefix_ipv4 *)&rn
->p))
- ospf_zebra_delete(
+ ospf_zebra_delete(ospf,
(struct prefix_ipv4
*)&rn->p,
or);
cmprt,
(struct prefix_ipv4 *)&rn
->p))
- ospf_zebra_delete_discard(
+ ospf_zebra_delete_discard(ospf,
(struct prefix_ipv4
*)&rn->p);
}
/* Delete old routes. */
if (ospf->old_table)
- ospf_route_delete_uniq(ospf->old_table, rt);
+ ospf_route_delete_uniq(ospf, ospf->old_table, rt);
if (ospf->old_external_route)
- ospf_route_delete_same_ext(ospf->old_external_route, rt);
+ ospf_route_delete_same_ext(ospf, ospf->old_external_route, rt);
/* Install new routes. */
for (rn = route_top(rt); rn; rn = route_next(rn))
if (!ospf_route_match_same(
ospf->old_table,
(struct prefix_ipv4 *)&rn->p, or))
- ospf_zebra_add(
+ ospf_zebra_add(ospf,
(struct prefix_ipv4 *)&rn->p,
or);
} else if (or->type == OSPF_DESTINATION_DISCARD)
if (!ospf_route_match_same(
ospf->old_table,
(struct prefix_ipv4 *)&rn->p, or))
- ospf_zebra_add_discard(
+ ospf_zebra_add_discard(ospf,
(struct prefix_ipv4 *)&rn->p);
}
}
}
}
-int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area,
+int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt,
+ struct ospf_area *area,
struct prefix_ipv4 *p)
{
struct route_node *rn;
new_or->path_type = OSPF_PATH_INTER_AREA;
rn->info = new_or;
- ospf_zebra_add_discard(p);
+ ospf_zebra_add_discard(ospf, p);
return 1;
}
-void ospf_delete_discard_route(struct route_table *rt, struct prefix_ipv4 *p)
+void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt,
+ struct prefix_ipv4 *p)
{
struct route_node *rn;
struct ospf_route * or ;
route_unlock_node(rn);
/* remove the discard entry from the rib */
- ospf_zebra_delete_discard(p);
+ ospf_zebra_delete_discard(ospf, p);
return;
}
extern struct ospf_path *ospf_path_lookup(struct list *, struct ospf_path *);
extern struct ospf_route *ospf_route_new(void);
extern void ospf_route_free(struct ospf_route *);
-extern void ospf_route_delete(struct route_table *);
+extern void ospf_route_delete(struct ospf *, struct route_table *);
extern void ospf_route_table_free(struct route_table *);
extern void ospf_route_install(struct ospf *, struct route_table *);
extern void ospf_route_subst_nexthops(struct ospf_route *, struct list *);
extern void ospf_prune_unreachable_networks(struct route_table *);
extern void ospf_prune_unreachable_routers(struct route_table *);
-extern int ospf_add_discard_route(struct route_table *, struct ospf_area *,
- struct prefix_ipv4 *);
-extern void ospf_delete_discard_route(struct route_table *,
+extern int ospf_add_discard_route(struct ospf *, struct route_table *,
+ struct ospf_area *, struct prefix_ipv4 *);
+extern void ospf_delete_discard_route(struct ospf *, struct route_table *,
struct prefix_ipv4 *);
extern int ospf_route_match_same(struct route_table *, struct prefix_ipv4 *,
struct ospf_route *);
{
struct ospf *ospf;
int type;
+ struct listnode *n1 = NULL;
/* If OSPF instatnce does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
+ if (listcount(om->ospf) == 0)
return;
- /* Update route-map */
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (!red_list)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP_NAME(red)
- && strcmp(ROUTEMAP_NAME(red), name) == 0) {
- /* Keep old route-map. */
- struct route_map *old = ROUTEMAP(red);
-
- /* Update route-map. */
- ROUTEMAP(red) = route_map_lookup_by_name(
- ROUTEMAP_NAME(red));
-
- /* No update for this distribute type. */
- if (old == NULL && ROUTEMAP(red) == NULL)
- continue;
-
- ospf_distribute_list_update(ospf, type,
- red->instance);
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ /* Update route-map */
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP_NAME(red)
+ && strcmp(ROUTEMAP_NAME(red), name) == 0) {
+ /* Keep old route-map. */
+ struct route_map *old = ROUTEMAP(red);
+
+ /* Update route-map. */
+ ROUTEMAP(red) = route_map_lookup_by_name(
+ ROUTEMAP_NAME(red));
+
+ /* No update for this distribute type. */
+ if (old == NULL && ROUTEMAP(red) == NULL)
+ continue;
+
+ ospf_distribute_list_update(ospf, type,
+ red->instance);
+ }
}
}
}
{
struct ospf *ospf;
int type;
-
- /* If OSPF instatnce does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
- return;
-
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (!red_list)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
- && !strcmp(ROUTEMAP_NAME(red), name)) {
- ospf_distribute_list_update(ospf, type,
- red->instance);
+ struct listnode *n1 = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
+ && !strcmp(ROUTEMAP_NAME(red), name)) {
+ ospf_distribute_list_update(ospf, type,
+ red->instance);
+ }
}
}
}
if (type == RMAP_OSPF) {
ei = object;
- ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT);
+ ifp = if_lookup_by_name_all_vrf((char *)rule);
if (ifp == NULL || ifp->ifindex != ei->ifindex)
return RMAP_NOMATCH;
{
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Check whether the instance identifier is valid */
if (smux_header_generic(v, name, length, exact, var_len, write_method)
struct ospf_area *area;
int len;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
struct listnode *node;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
struct ospf_area *area;
int len;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
oid *offset;
int offsetlen;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
#define OSPF_LSDB_ENTRY_OFFSET (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
memset(&router_id, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (exact) {
/* Area ID + Range Network. */
return NULL;
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
struct ospf_nbr_nbma *nbr_nbma;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
return NULL;
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
struct listnode *node;
struct ospf_snmp_if *osif;
struct ospf_interface *oi = NULL;
- struct ospf *ospf = ospf_lookup();
+ struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS_RO(ospf_snmp_iflist, node, osif)) {
if (ifaddr->s_addr) {
{
struct ospf_snmp_if *osif;
struct listnode *nn;
- struct ospf *ospf = ospf_lookup();
+ struct ospf *ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
struct ospf_interface *oi = NULL;
if (ospf == NULL)
memset(&ifaddr, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
memset(&ifaddr, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
struct ospf_neighbor *min = NULL;
struct ospf *ospf = ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, nn, oi)) {
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
struct ospf_neighbor *nbr;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (!ospf)
return NULL;
memset(&neighbor, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
struct ospf_lsa *lsa;
struct ospf *ospf;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (exact) {
if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
return NULL;
memset(&router_id, 0, sizeof(struct in_addr));
/* Check OSPF instance. */
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL)
return NULL;
* of candidates with any vertices not already on the list. If a lower-cost
* path is found to a vertex already on the candidate list, store the new cost.
*/
-static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
+static void ospf_spf_next(struct vertex *v, struct ospf *ospf,
+ struct ospf_area *area,
struct pqueue *candidate)
{
struct ospf_lsa *w_lsa = NULL;
inet_ntoa(l->link_id));
}
- w_lsa = ospf_lsa_lookup(area, OSPF_ROUTER_LSA,
+ w_lsa = ospf_lsa_lookup(ospf, area,
+ OSPF_ROUTER_LSA,
l->link_id, l->link_id);
if (w_lsa) {
if (IS_DEBUG_OSPF_EVENT)
#endif
/* Calculating the shortest-path tree for an area. */
-static void ospf_spf_calculate(struct ospf_area *area,
+static void ospf_spf_calculate(struct ospf *ospf, struct ospf_area *area,
struct route_table *new_table,
struct route_table *new_rtrs)
{
for (;;) {
/* RFC2328 16.1. (2). */
- ospf_spf_next(v, area, candidate);
+ ospf_spf_next(v, ospf, area, candidate);
/* RFC2328 16.1. (3). */
/* If at this step the candidate list is empty, the shortest-
if (ospf->backbone && ospf->backbone == area)
continue;
- ospf_spf_calculate(area, new_table, new_rtrs);
+ ospf_spf_calculate(ospf, area, new_table, new_rtrs);
areas_processed++;
}
/* SPF for backbone, if required */
if (ospf->backbone) {
- ospf_spf_calculate(ospf->backbone, new_table, new_rtrs);
+ ospf_spf_calculate(ospf, ospf->backbone, new_table, new_rtrs);
areas_processed++;
}
ospf_ase_calculate_timer_add(ospf);
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf install new route, vrf %s id %u new_table count %lu",
+ __PRETTY_FUNCTION__,
+ ospf_vrf_id_to_name(ospf->vrf_id),
+ ospf->vrf_id, new_table->count);
/* Update routing table. */
monotime(&start_time);
ospf_route_install(ospf, new_table);
else {
lp->flags = INTER_AS | FLOOD_AREA;
lp->area = ospf_area_lookup_by_area_id(
- ospf_lookup(),
+ ospf_lookup_by_vrf_id(VRF_DEFAULT),
OspfMplsTE.interas_areaid);
}
}
}
/* Create new opaque-LSA. */
-static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf_area *area,
+static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf,
+ struct ospf_area *area,
struct mpls_te_link *lp)
{
struct stream *s;
tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_INTER_AS_LSA, lp->instance);
lsa_id.s_addr = htonl(tmp);
- struct ospf *top = ospf_lookup();
+ if (!ospf)
+ return NULL;
- lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
+ lsa_header_set(s, options, lsa_type, lsa_id, ospf->router_id);
} else {
options |= LSA_OPTIONS_GET(area); /* Get area default option */
options |= LSA_OPTIONS_NSSA_GET(area);
return new;
}
+ new->vrf_id = ospf->vrf_id;
+ if (area && area->ospf)
+ new->vrf_id = area->ospf->vrf_id;
new->area = area;
SET_FLAG(new->flags, OSPF_LSA_SELF);
memcpy(new->data, lsah, length);
static int ospf_mpls_te_lsa_originate1(struct ospf_area *area,
struct mpls_te_link *lp)
{
- struct ospf_lsa *new;
+ struct ospf_lsa *new = NULL;
int rc = -1;
/* Create new Opaque-LSA/MPLS-TE instance. */
- if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
+ new = ospf_mpls_te_lsa_new(area->ospf, area, lp);
+ if (new == NULL) {
zlog_warn(
"ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
return rc;
int rc = -1;
/* Create new Opaque-LSA/Inter-AS instance. */
- if ((new = ospf_mpls_te_lsa_new(NULL, lp)) == NULL) {
+ new = ospf_mpls_te_lsa_new(top, NULL, lp);
+ if (new == NULL) {
zlog_warn(
"ospf_mpls_te_lsa_originate2: ospf_router_info_lsa_new() ?");
return rc;
}
+ new->vrf_id = top->vrf_id;
/* Install this LSA into LSDB. */
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
ospf_opaque_lsa_flush_schedule(lsa);
return NULL;
}
-
+ top = ospf_lookup_by_vrf_id(lsa->vrf_id);
/* Create new Opaque-LSA/MPLS-TE instance. */
- if ((new = ospf_mpls_te_lsa_new(area, lp)) == NULL) {
+ new = ospf_mpls_te_lsa_new(top, area, lp);
+ if (new == NULL) {
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
return NULL;
}
* ospf_lookup() to get ospf instance */
if (area)
top = area->ospf;
- else
- top = ospf_lookup();
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
zlog_warn("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
memset(&lsa, 0, sizeof(lsa));
memset(&lsah, 0, sizeof(lsah));
- top = ospf_lookup();
+ top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
/* Check if the pseudo link is ready to flood */
if (!(CHECK_FLAG(lp->flags, LPFLG_LSA_ACTIVE))
DEFUN (show_ip_ospf_mpls_te_link,
show_ip_ospf_mpls_te_link_cmd,
- "show ip ospf mpls-te interface [INTERFACE]",
+ "show ip ospf [vrf <NAME|all>] mpls-te interface [INTERFACE]",
SHOW_STR
IP_STR
OSPF_STR
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"MPLS-TE information\n"
"Interface information\n"
"Interface name\n")
{
int idx_interface = 5;
struct interface *ifp;
- struct listnode *node, *nnode;
-
+ struct listnode *node, *nnode, *n1;
+ char *vrf_name = NULL;
+ bool all_vrf;
+ int inst = 0;
+ int idx_vrf = 0;
+ struct ospf *ospf = NULL;
+
+ if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+ vrf_name = argv[idx_vrf + 1]->arg;
+ all_vrf = strmatch(vrf_name, "all");
+ }
+
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id),
+ node, nnode, ifp))
+ show_mpls_te_link_sub(vty, ifp);
+ }
+ return CMD_SUCCESS;
+ }
+ ospf = ospf_lookup_by_inst_name (inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node,
+ nnode, ifp))
+ show_mpls_te_link_sub(vty, ifp);
+ return CMD_SUCCESS;
+ }
/* Show All Interfaces. */
if (argc == 5) {
- for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode,
- ifp))
- show_mpls_te_link_sub(vty, ifp);
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node,
+ nnode, ifp))
+ show_mpls_te_link_sub(vty, ifp);
+ }
}
/* Interface name is specified. */
else {
- if ((ifp = if_lookup_by_name(argv[idx_interface]->arg,
- VRF_DEFAULT))
- == NULL)
+ ifp = if_lookup_by_name_all_vrf(argv[idx_interface]->arg);
+ if (ifp == NULL)
vty_out(vty, "No such interface name\n");
else
show_mpls_te_link_sub(vty, ifp);
return i;
}
+#define OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) \
+ if (argv_find(argv, argc, "vrf", &idx_vrf)) { \
+ vrf_name = argv[idx_vrf + 1]->arg; \
+ all_vrf = strmatch(vrf_name, "all"); \
+ }
+
+static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty,
+ struct cmd_token *argv[],
+ const int argc,
+ uint32_t enable,
+ u_short *instance)
+{
+ struct ospf *ospf = NULL;
+ int idx_vrf = 0;
+ const char *vrf_name = NULL;
+
+ if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+ vrf_name = argv[idx_vrf + 1]->arg;
+ if (enable) {
+ if (argc > 4)
+ *instance = strtoul(argv[2]->arg, NULL, 10);
+ /* Allocate VRF aware instance */
+ ospf = ospf_get(*instance, vrf_name);
+ } else {
+ if (argc > 5)
+ *instance = strtoul(argv[3]->arg, NULL, 10);
+ ospf = ospf_lookup_by_inst_name(*instance, vrf_name);
+ }
+ } else {
+ if (enable) {
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (!ospf)
+ vty_out(vty,
+ "There isn't active ospf instance\n");
+ if (argc > 2)
+ *instance = strtoul(argv[2]->arg, NULL, 10);
+ } else {
+ if (argc > 3)
+ *instance = strtoul(argv[3]->arg, NULL, 10);
+ ospf = ospf_lookup_instance(*instance);
+ }
+ }
+ return ospf;
+}
+
+#ifndef VTYSH_EXTRACT_PL
+#include "ospf_vty_clippy.c"
+#endif
+
DEFUN_NOSH (router_ospf,
router_ospf_cmd,
- "router ospf [(1-65535)]",
+ "router ospf [{(1-65535)|vrf NAME}]",
"Enable a routing process\n"
"Start OSPF configuration\n"
- "Instance ID\n")
+ "Instance ID\n"
+ VRF_CMD_HELP_STR)
{
- struct ospf *ospf;
- u_short instance = 0;
+ struct ospf *ospf = NULL;
int ret = CMD_SUCCESS;
+ u_short instance = 0;
- ospf = ospf_lookup();
- if (!ospf) {
- vty_out(vty, "There isn't active ospf instance \n");
+ ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance);
+ if (!ospf)
return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (argc > 2)
- instance = strtoul(argv[2]->arg, NULL, 10);
/* The following logic to set the vty qobj index is in place to be able
to ignore the commands which dont belong to this instance. */
VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
ret = CMD_NOT_MY_INSTANCE;
} else {
+ if (ospf->vrf_id != VRF_UNKNOWN)
+ ospf->oi_running = 1;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("Config command 'router ospf %d' received",
- instance);
- ospf->oi_running = 1;
+ zlog_debug("Config command 'router ospf %d' received, vrf %s id %d oi_running %u",
+ instance, ospf->name ? ospf->name : "NIL",
+ ospf->vrf_id, ospf->oi_running);
VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
ospf_router_id_update(ospf);
}
DEFUN (no_router_ospf,
no_router_ospf_cmd,
- "no router ospf [(1-65535)]",
+ "no router ospf [{(1-65535)|vrf NAME}]",
NO_STR
"Enable a routing process\n"
"Start OSPF configuration\n"
- "Instance ID\n")
+ "Instance ID\n"
+ VRF_CMD_HELP_STR)
{
struct ospf *ospf;
u_short instance = 0;
- if (argc > 3)
- instance = strtoul(argv[3]->arg, NULL, 10);
-
- ospf = ospf_lookup_instance(instance);
- if (ospf == NULL)
- return CMD_NOT_MY_INSTANCE;
-
+ ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 0, &instance);
+ if (ospf == NULL) {
+ if (instance)
+ return CMD_NOT_MY_INSTANCE;
+ else
+ return CMD_WARNING;
+ }
ospf_finish(ospf);
return CMD_SUCCESS;
}
-DEFUN (ospf_router_id,
+DEFPY (ospf_router_id,
ospf_router_id_cmd,
"ospf router-id A.B.C.D",
"OSPF specific commands\n"
"OSPF router-id in IP address format\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
- int idx_ipv4 = 2;
+
struct listnode *node;
struct ospf_area *area;
- struct in_addr router_id;
- int ret;
-
- ret = inet_aton(argv[idx_ipv4]->arg, &router_id);
- if (!ret) {
- vty_out(vty, "Please specify Router ID by A.B.C.D\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
ospf->router_id_static = router_id;
return CMD_SUCCESS;
}
-DEFUN (no_ospf_router_id,
+DEFPY (no_ospf_router_id,
no_ospf_router_id_cmd,
"no ospf router-id [A.B.C.D]",
NO_STR
struct listnode *node;
struct ospf_area *area;
+ if (router_id_str) {
+ if (!IPV4_ADDR_SAME(&ospf->router_id_static, &router_id)) {
+ vty_out(vty, "%% OSPF router-id doesn't match\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
ospf->router_id_static.s_addr = 0;
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
ospf->passive_interface_default = newval;
- for (ALL_LIST_ELEMENTS_RO(om->iflist, ln, ifp)) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), ln, ifp)) {
if (ifp && OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
passive_interface))
UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), passive_interface);
return CMD_SUCCESS;
}
- ifp = if_get_by_name(argv[1]->arg, VRF_DEFAULT);
+ ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id);
+ if (ifp == NULL) {
+ vty_out(vty, "interface %s not found.\n",
+ (char *)argv[1]->arg);
+ return CMD_WARNING;
+ }
params = IF_DEF_PARAMS(ifp);
return CMD_SUCCESS;
}
- ifp = if_get_by_name(argv[2]->arg, VRF_DEFAULT);
+ ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id);
+ if (ifp == NULL) {
+ vty_out(vty, "interface %s not found.\n",
+ (char *)argv[1]->arg);
+ return CMD_WARNING;
+ }
params = IF_DEF_PARAMS(ifp);
return CMD_SUCCESS;
ospf->ref_bandwidth = refbw;
- for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
ospf_if_recalculate_output_cost(ifp);
return CMD_SUCCESS;
vty_out(vty,
" Please ensure reference bandwidth is consistent across all routers\n");
- for (ALL_LIST_ELEMENTS(om->iflist, node, nnode, ifp))
+ for (ALL_LIST_ELEMENTS(vrf_iflist(ospf->vrf_id), node, nnode, ifp))
ospf_if_recalculate_output_cost(ifp);
return CMD_SUCCESS;
DEFUN (show_ip_ospf,
show_ip_ospf_cmd,
- "show ip ospf [json]",
+ "show ip ospf [vrf <NAME|all>] [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
+ if (listcount(om->ospf) == 0)
return CMD_SUCCESS;
- return (show_ip_ospf_common(vty, ospf, uj));
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_common(vty, ospf, uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if ((ospf == NULL) || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ /* Display default ospf (instance 0) info */
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ show_ip_ospf_common(vty, ospf, uj);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance,
if (argc == iface_argv) {
/* Show All Interfaces.*/
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id),
+ node, ifp)) {
if (ospf_oi_count(ifp)) {
if (use_json)
json_interface_sub =
} else {
/* Interface name is specified. */
if ((ifp = if_lookup_by_name(argv[iface_argv]->arg,
- VRF_DEFAULT))
+ ospf->vrf_id))
== NULL) {
if (use_json)
json_object_boolean_true_add(json,
DEFUN (show_ip_ospf_interface,
show_ip_ospf_interface_cmd,
- "show ip ospf interface [INTERFACE] [json]",
+ "show ip ospf [vrf <NAME|all>] interface [INTERFACE] [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Interface information\n"
"Interface name\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (uj)
argc--;
- return show_ip_ospf_interface_common(vty, ospf, argc, argv, 4, uj);
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_interface_common(vty,
+ ospf, argc,
+ argv, 6,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_interface_common(vty, ospf,
+ argc, argv, 6, uj);
+
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_interface_common(vty, ospf,
+ argc, argv, 4, uj);
+ }
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_interface,
if (use_json)
json = json_object_new_object();
- else
- show_ip_ospf_neighbour_header(vty);
if (ospf->instance) {
if (use_json)
DEFUN (show_ip_ospf_neighbor,
show_ip_ospf_neighbor_cmd,
- "show ip ospf neighbor [json]",
+ "show ip ospf [vrf <NAME|all>] neighbor [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Neighbor list\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_neighbor_common(vty, ospf, uj);
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_common(vty, ospf,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_neighbor_common(vty, ospf, uj);
+
+ return ret;
}
if (!ospf->oi_running)
return CMD_SUCCESS;
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
return show_ip_ospf_neighbor_common(vty, ospf, uj);
}
if (use_json) {
json = json_object_new_object();
json_neighbor_sub = json_object_new_object();
- } else
- show_ip_ospf_neighbour_header(vty);
+ }
if (ospf->instance) {
if (use_json)
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
+ if (ospf->name) {
+ if (use_json) {
+ json_object_int_add(json, "vrfId",
+ (ospf->vrf_id == VRF_UNKNOWN)
+ ? -1 : ospf->vrf_id);
+ json_object_string_add(json, "vrfName",
+ (ospf->vrf_id == VRF_DEFAULT)
+ ? "Default" : ospf->name);
+ } else {
+ vty_out(vty, "\nOSPF vrf: %s\n\n",
+ ospf->vrf_id == VRF_DEFAULT
+ ? "Default" : ospf->name);
+ }
+ }
+
+
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
struct listnode *nbr_node;
struct ospf_nbr_nbma *nbr_nbma;
DEFUN (show_ip_ospf_neighbor_all,
show_ip_ospf_neighbor_all_cmd,
- "show ip ospf neighbor all [json]",
+ "show ip ospf [vrf <NAME|all>] neighbor all [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Neighbor list\n"
"include down status neighbor\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_neighbor_all_common(vty, ospf, uj);
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_all_common(vty,
+ ospf,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_neighbor_all_common(vty, ospf, uj);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_all,
if (use_json)
json = json_object_new_object();
- else
- show_ip_ospf_neighbour_header(vty);
if (ospf->instance) {
if (use_json)
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
- ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT);
+ /*ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);*/
+ ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg);
if (!ifp) {
if (use_json)
json_object_boolean_true_add(json, "noSuchIface");
struct ospf *ospf;
int idx_ifname = 4;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ int ret = CMD_SUCCESS;
+ struct interface *ifp = NULL;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
- return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj);
+ ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg);
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ if (!ifp || ifp->vrf_id != ospf->vrf_id)
+ continue;
+ ret = show_ip_ospf_neighbor_int_common(vty, ospf,
+ idx_ifname, argv, uj);
+ }
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_int,
u_short instance = 0;
u_char uj = use_json(argc, argv);
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
instance = strtoul(argv[idx_number]->arg, NULL, 10);
ospf = ospf_lookup_instance(instance);
if (ospf == NULL)
if (!ospf->oi_running)
return CMD_SUCCESS;
+ if (!uj)
+ show_ip_ospf_neighbour_header(vty);
+
return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj);
}
JSON_STR)
{
struct ospf *ospf;
- int idx_router_id = 4;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ int ret = CMD_SUCCESS;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv, uj);
+ }
- return show_ip_ospf_neighbor_id_common(vty, ospf, idx_router_id, argv, uj);
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_id,
DEFUN (show_ip_ospf_neighbor_detail,
show_ip_ospf_neighbor_detail_cmd,
- "show ip ospf neighbor detail [json]",
+ "show ip ospf [vrf <NAME|all>] neighbor detail [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Neighbor list\n"
"detail of all neighbors\n"
JSON_STR)
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_neighbor_detail_common(vty, ospf, uj);
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_detail_common(vty,
+ ospf,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_neighbor_detail_common(vty, ospf, uj);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_detail,
DEFUN (show_ip_ospf_neighbor_detail_all,
show_ip_ospf_neighbor_detail_all_cmd,
- "show ip ospf neighbor detail all [json]",
+ "show ip ospf [vrf <NAME|all>] neighbor detail all [json]",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Neighbor list\n"
"detail of all neighbors\n"
"include down status neighbor\n"
{
struct ospf *ospf;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj);
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_detail_all_common(vty,
+ ospf,
+ uj);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_neighbor_detail_all_common(vty, ospf, uj);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_detail_all,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
- ifp = if_lookup_by_name(argv[arg_base]->arg, VRF_DEFAULT);
+ ifp = if_lookup_by_name_all_vrf(argv[arg_base]->arg);
if (!ifp) {
if (!use_json)
vty_out(vty, "No such interface.\n");
JSON_STR)
{
struct ospf *ospf;
- int idx_ifname = 4;
u_char uj = use_json(argc, argv);
+ struct listnode *node = NULL;
+ int ret = CMD_SUCCESS;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0,
+ argv, uj);
+ }
- return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname, argv, uj);
+ return ret;
}
DEFUN (show_ip_ospf_instance_neighbor_int_detail,
DEFUN (show_ip_ospf_database_max,
show_ip_ospf_database_max_cmd,
- "show ip ospf database <max-age|self-originate>",
+ "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Database summary\n"
"LSAs in MaxAge list\n"
"Self-originated link states\n")
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv));
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_database_common(vty, ospf,
+ idx_vrf ? 2
+ : 0, argc,
+ argv);
+ }
+ } else {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = (show_ip_ospf_database_common(vty, ospf, idx_vrf ?
+ 2 : 0, argc, argv));
+ }
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv);
+ }
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_database,
show_ip_ospf_instance_database_cmd,
- "show ip ospf [(1-65535)] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
+ "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
+ VRF_CMD_HELP_STR
"Database summary\n"
OSPF_LSA_TYPES_DESC
"Link State ID (as an IP address)\n"
{
struct ospf *ospf;
u_short instance = 0;
-
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
int idx = 0;
+
if (argv_find(argv, argc, "(1-65535)", &idx)) {
instance = strtoul(argv[idx]->arg, NULL, 10);
ospf = ospf_lookup_instance(instance);
if (ospf == NULL)
return CMD_NOT_MY_INSTANCE;
- } else {
- ospf = ospf_lookup();
+ if (!ospf->oi_running)
+ return CMD_SUCCESS;
+
+ return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0,
+ argc, argv));
+ } else if (argv_find(argv, argc, "vrf", &idx)) {
+ vrf_name = argv[++idx]->arg;
+ all_vrf = strmatch(vrf_name, "all");
}
- if (!ospf || !ospf->oi_running)
- return CMD_SUCCESS;
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = (show_ip_ospf_database_common(vty, ospf,
+ idx ? 2 : 0,
+ argc, argv));
+ }
+ } else {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if ((ospf == NULL) || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = (show_ip_ospf_database_common(vty, ospf, idx ? 2 :
+ 0, argc, argv));
+ }
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv));
+ }
- return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, argc,
- argv));
+ return ret;
}
DEFUN (show_ip_ospf_instance_database_max,
DEFUN (show_ip_ospf_instance_database_type_adv_router,
show_ip_ospf_instance_database_type_adv_router_cmd,
- "show ip ospf [(1-65535)] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
+ "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
SHOW_STR
IP_STR
"OSPF information\n"
"Instance ID\n"
+ VRF_CMD_HELP_STR
"Database summary\n"
OSPF_LSA_TYPES_DESC
"Advertising Router link states\n"
"Advertising Router (as an IP address)\n"
"Self-originated link states\n")
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
u_short instance = 0;
- int idx = 0;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx = 0, idx_vrf = 0;
if (argv_find(argv, argc, "(1-65535)", &idx)) {
instance = strtoul(argv[idx]->arg, NULL, 10);
ospf = ospf_lookup_instance(instance);
if (ospf == NULL)
return CMD_NOT_MY_INSTANCE;
- } else
- ospf = ospf_lookup();
+ if (!ospf->oi_running)
+ return CMD_SUCCESS;
+ return (show_ip_ospf_database_type_adv_router_common(vty, ospf,
+ idx ? 1 : 0,
+ argc,
+ argv));
+ }
- if (!ospf || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return (show_ip_ospf_database_type_adv_router_common(
- vty, ospf, idx ? 1 : 0, argc, argv));
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_database_type_adv_router_common(vty,
+ ospf, idx ? 1 : 0, argc, argv);
+ }
+ } else {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if ((ospf == NULL) || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_database_type_adv_router_common(vty,
+ ospf, idx ? 1 : 0, argc, argv);
+ }
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_database_type_adv_router_common(vty, ospf,
+ idx ? 1 : 0,
+ argc, argv);
+ }
+ return ret;
+ /*return (show_ip_ospf_database_type_adv_router_common(
+ vty, ospf, idx ? 1 : 0, argc, argv));*/
}
DEFUN (ip_ospf_authentication_args,
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx = 0;
- u_int32_t cost;
+ u_int32_t cost = OSPF_OUTPUT_COST_DEFAULT;
struct in_addr addr;
struct ospf_if_params *params;
params = IF_DEF_PARAMS(ifp);
// get arguments
char *coststr = NULL, *ifaddr = NULL;
- coststr = argv_find(argv, argc, "(1-65535)", &idx) ? argv[idx]->arg
- : NULL;
- ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
+ argv_find(argv, argc, "(1-65535)", &idx);
+ coststr = argv[idx]->arg;
cost = strtol(coststr, NULL, 10);
+ ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
if (ifaddr) {
if (!inet_aton(ifaddr, &addr)) {
vty_out(vty,
/* Update timer values in neighbor structure. */
if (nbr_str) {
- struct ospf *ospf;
- if ((ospf = ospf_lookup())) {
+ struct ospf *ospf = NULL;
+
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ if (ospf) {
oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
if (oi)
ospf_nbr_timer_update(oi);
/* Update timer values in neighbor structure. */
if (argc == 1) {
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
- if ((ospf = ospf_lookup())) {
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ if (ospf) {
oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
if (oi)
ospf_nbr_timer_update(oi);
int format, ret;
struct in_addr area_id;
struct in_addr addr;
- struct ospf_if_params *params;
+ struct ospf_if_params *params = NULL;
struct route_node *rn;
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
u_short instance = 0;
char *areaid;
argv_find(argv, argc, "area", &idx);
areaid = argv[idx + 1]->arg;
- ospf = ospf_lookup_instance(instance);
+ if (ifp->vrf_id && !instance)
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ else
+ ospf = ospf_lookup_instance(instance);
+
if (ospf == NULL) {
params = IF_DEF_PARAMS(ifp);
if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
UNSET_IF_PARAM(params, if_area);
- ospf_interface_area_unset(ifp);
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ ospf_interface_area_unset(ospf, ifp);
ospf->if_ospf_cli_count--;
}
return CMD_NOT_MY_INSTANCE;
}
/* enable ospf on this interface with area_id */
- SET_IF_PARAM(params, if_area);
- params->if_area = area_id;
- params->if_area_id_fmt = format;
- ospf_interface_area_set(ifp);
+ if (params) {
+ SET_IF_PARAM(params, if_area);
+ params->if_area = area_id;
+ params->if_area_id_fmt = format;
+ }
+ ospf_interface_area_set(ospf, ifp);
ospf->if_ospf_cli_count++;
return CMD_SUCCESS;
if (argv_find(argv, argc, "(1-65535)", &idx))
instance = strtol(argv[idx]->arg, NULL, 10);
- ospf = ospf_lookup_instance(instance);
+ if (ifp->vrf_id && !instance)
+ ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+ else
+ ospf = ospf_lookup_instance(instance);
+
if (ospf == NULL)
return CMD_NOT_MY_INSTANCE;
ospf_if_update_params((ifp), (addr));
}
- ospf_interface_area_unset(ifp);
+ ospf_interface_area_unset(ospf, ifp);
ospf->if_ospf_cli_count--;
return CMD_SUCCESS;
}
int idx_number = 3;
unsigned int seconds;
- if (argc != 1) {
+ if (argc < 4) {
vty_out(vty, "%% Must supply stub-router period");
return CMD_WARNING_CONFIG_FAILED;
}
int idx_number = 3;
unsigned int seconds;
- if (argc != 1) {
+ if (argc < 4) {
vty_out(vty, "%% Must supply stub-router shutdown period");
return CMD_WARNING_CONFIG_FAILED;
}
return;
}
-static void show_ip_ospf_route_network(struct vty *vty, struct route_table *rt)
+static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
+ struct route_table *rt)
{
struct route_node *rn;
struct ospf_route * or ;
for (ALL_LIST_ELEMENTS(or->paths, pnode, pnnode,
path)) {
if (if_lookup_by_index(path->ifindex,
- VRF_DEFAULT)) {
+ ospf->vrf_id)) {
if (path->nexthop.s_addr == 0)
vty_out(vty,
"%24s directly attached to %s\n",
"",
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
else
vty_out(vty,
"%24s via %s, %s\n",
path->nexthop),
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
}
}
}
vty_out(vty, "\n");
}
-static void show_ip_ospf_route_router(struct vty *vty, struct route_table *rtrs)
+static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
+ struct route_table *rtrs)
{
struct route_node *rn;
struct ospf_route * or ;
for (ALL_LIST_ELEMENTS_RO(or->paths, pnode,
path)) {
if (if_lookup_by_index(path->ifindex,
- VRF_DEFAULT)) {
+ ospf->vrf_id)) {
if (path->nexthop.s_addr == 0)
vty_out(vty,
"%24s directly attached to %s\n",
"",
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
else
vty_out(vty,
"%24s via %s, %s\n",
path->nexthop),
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
}
}
}
vty_out(vty, "\n");
}
-static void show_ip_ospf_route_external(struct vty *vty, struct route_table *rt)
+static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
+ struct route_table *rt)
{
struct route_node *rn;
struct ospf_route *er;
for (ALL_LIST_ELEMENTS(er->paths, pnode, pnnode,
path)) {
if (if_lookup_by_index(path->ifindex,
- VRF_DEFAULT)) {
+ ospf->vrf_id)) {
if (path->nexthop.s_addr == 0)
vty_out(vty,
"%24s directly attached to %s\n",
"",
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
else
vty_out(vty,
"%24s via %s, %s\n",
path->nexthop),
ifindex2ifname(
path->ifindex,
- VRF_DEFAULT));
+ ospf->vrf_id));
}
}
}
show_ip_ospf_route_network (vty, ospf->new_table); */
/* Show Router routes. */
- show_ip_ospf_route_router(vty, ospf->new_rtrs);
+ show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs);
vty_out(vty, "\n");
DEFUN (show_ip_ospf_border_routers,
show_ip_ospf_border_routers_cmd,
- "show ip ospf border-routers",
+ "show ip ospf [vrf <NAME|all>] border-routers",
SHOW_STR
IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
"Show all the ABR's and ASBR's\n")
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_border_routers_common(vty, ospf);
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+
+ ret = show_ip_ospf_border_routers_common(vty,
+ ospf);
+ }
+ } else {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+
+ ret = show_ip_ospf_border_routers_common(vty, ospf);
+ }
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ ret = show_ip_ospf_border_routers_common(vty, ospf);
+ }
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_border_routers,
}
/* Show Network routes. */
- show_ip_ospf_route_network(vty, ospf->new_table);
+ show_ip_ospf_route_network(vty, ospf, ospf->new_table);
/* Show Router routes. */
- show_ip_ospf_route_router(vty, ospf->new_rtrs);
+ show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs);
/* Show AS External routes. */
- show_ip_ospf_route_external(vty, ospf->old_external_route);
+ show_ip_ospf_route_external(vty, ospf, ospf->old_external_route);
vty_out(vty, "\n");
DEFUN (show_ip_ospf_route,
show_ip_ospf_route_cmd,
- "show ip ospf route",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "OSPF routing table\n")
-{
- struct ospf *ospf;
+ "show ip ospf [vrf <NAME|all>] route",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "OSPF routing table\n")
+{
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ char *vrf_name = NULL;
+ bool all_vrf = FALSE;
+ int ret = CMD_SUCCESS;
+ int inst = 0;
+ int idx_vrf = 0;
- if ((ospf = ospf_lookup()) == NULL || !ospf->oi_running)
- return CMD_SUCCESS;
+ OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
- return show_ip_ospf_route_common(vty, ospf);
+ /* vrf input is provided could be all or specific vrf*/
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_route_common(vty, ospf);
+ }
+ return ret;
+ }
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ } else {
+ /* Display default ospf (instance 0) info */
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+ if (ospf == NULL || !ospf->oi_running)
+ return CMD_SUCCESS;
+ }
+
+ if (ospf)
+ ret = show_ip_ospf_route_common(vty, ospf);
+
+ return ret;
}
DEFUN (show_ip_ospf_instance_route,
return show_ip_ospf_route_common(vty, ospf);
}
+
+DEFUN (show_ip_ospf_vrfs,
+ show_ip_ospf_vrfs_cmd,
+ "show ip ospf vrfs [json]",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ "Show OSPF VRFs \n"
+ JSON_STR)
+{
+ u_char uj = use_json(argc, argv);
+ json_object *json = NULL;
+ json_object *json_vrfs = NULL;
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+ int count = 0;
+ static char header[] = "Name Id RouterId ";
+
+ if (uj) {
+ json = json_object_new_object();
+ json_vrfs = json_object_new_object();
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ json_object *json_vrf = NULL;
+ const char *name = NULL;
+ int vrf_id_ui = 0;
+
+ count++;
+
+ if (!uj && count == 1)
+ vty_out(vty, "%s\n", header);
+ if (uj)
+ json_vrf = json_object_new_object();
+
+ if (ospf->vrf_id == 0)
+ name = VRF_DEFAULT_NAME;
+ else
+ name = ospf->name;
+
+ vrf_id_ui = (ospf->vrf_id == VRF_UNKNOWN) ? -1 : ospf->vrf_id;
+
+ if (uj) {
+ json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
+ json_object_string_add(json_vrf, "routerId",
+ inet_ntoa(ospf->router_id));
+
+ json_object_object_add(json_vrfs, name, json_vrf);
+
+ } else {
+ vty_out(vty, "%-25s %-5d %-16s \n",
+ name, ospf->vrf_id, inet_ntoa(ospf->router_id));
+ }
+ }
+
+ if (uj) {
+ json_object_object_add(json, "vrfs", json_vrfs);
+ json_object_int_add(json, "totalVrfs", count);
+
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
+ JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ if (count)
+ vty_out(vty, "\nTotal number of OSPF VRFs (including default): %d\n",
+ count);
+ }
+
+ return CMD_SUCCESS;
+}
+
const char *ospf_abr_type_str[] = {"unknown", "standard", "ibm", "cisco",
"shortcut"};
"virtual-link", /* should never be used. */
"loopback"};
-/* Configuration write function for ospfd. */
-static int config_write_interface(struct vty *vty)
+static int config_write_interface_one(struct vty *vty, struct ospf *ospf)
{
struct listnode *n1, *n2;
struct interface *ifp;
struct crypt_key *ck;
- int write = 0;
struct route_node *rn = NULL;
struct ospf_if_params *params;
- struct ospf *ospf = ospf_lookup();
+ int write = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), n1, ifp)) {
+ struct vrf *vrf = NULL;
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), n1, ifp)) {
if (memcmp(ifp->name, "VLINK", 5) == 0)
continue;
if (ifp->ifindex == IFINDEX_DELETED)
continue;
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
+
vty_frame(vty, "!\n");
- vty_frame(vty, "interface %s\n", ifp->name);
+ if (ifp->vrf_id == VRF_DEFAULT || vrf == NULL)
+ vty_frame(vty, "interface %s\n", ifp->name);
+ else
+ vty_frame(vty, "interface %s vrf %s\n",
+ ifp->name, vrf->name);
if (ifp->desc)
vty_out(vty, " description %s\n", ifp->desc);
if (params->type != ospf_default_iftype(ifp)) {
vty_out(vty, " ip ospf network %s",
ospf_int_type_str
- [params->type]);
+ [params->type]);
if (params != IF_DEF_PARAMS(ifp))
vty_out(vty, " %s",
inet_ntoa(
- rn->p.u.prefix4));
+ rn->p.u.prefix4));
vty_out(vty, "\n");
}
}
const char *auth_str;
/* Translation tables are not that much help
- here due to syntax
- of the simple option */
+ * here due to syntax
+ * of the simple option */
switch (params->auth_type) {
case OSPF_AUTH_NULL:
}
/* Cryptographic Authentication Key print. */
- for (ALL_LIST_ELEMENTS_RO(params->auth_crypt, n2, ck)) {
- vty_out(vty,
- " ip ospf message-digest-key %d md5 %s",
- ck->key_id, ck->auth_key);
- if (params != IF_DEF_PARAMS(ifp))
- vty_out(vty, " %s",
- inet_ntoa(rn->p.u.prefix4));
- vty_out(vty, "\n");
+ if (params && params->auth_crypt) {
+ for (ALL_LIST_ELEMENTS_RO(params->auth_crypt,
+ n2, ck)) {
+ vty_out(vty,
+ " ip ospf message-digest-key %d md5 %s",
+ ck->key_id, ck->auth_key);
+ if (params != IF_DEF_PARAMS(ifp))
+ vty_out(vty, " %s",
+ inet_ntoa(rn->p.u.prefix4));
+ vty_out(vty, "\n");
+ }
}
/* Interface Output Cost print. */
- if (OSPF_IF_PARAM_CONFIGURED(params, output_cost_cmd)) {
+ if (OSPF_IF_PARAM_CONFIGURED(params,
+ output_cost_cmd)) {
vty_out(vty, " ip ospf cost %u",
params->output_cost_cmd);
if (params != IF_DEF_PARAMS(ifp))
/* Router Dead Interval print. */
if (OSPF_IF_PARAM_CONFIGURED(params, v_wait)
&& params->v_wait
- != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
+ != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT) {
vty_out(vty, " ip ospf dead-interval ");
/* fast hello ? */
/* Router Priority print. */
if (OSPF_IF_PARAM_CONFIGURED(params, priority)
&& params->priority
- != OSPF_ROUTER_PRIORITY_DEFAULT) {
+ != OSPF_ROUTER_PRIORITY_DEFAULT) {
vty_out(vty, " ip ospf priority %u",
params->priority);
if (params != IF_DEF_PARAMS(ifp))
if (OSPF_IF_PARAM_CONFIGURED(params,
retransmit_interval)
&& params->retransmit_interval
- != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
+ != OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
vty_out(vty, " ip ospf retransmit-interval %u",
params->retransmit_interval);
if (params != IF_DEF_PARAMS(ifp))
/* Transmit Delay print. */
if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay)
&& params->transmit_delay
- != OSPF_TRANSMIT_DELAY_DEFAULT) {
+ != OSPF_TRANSMIT_DELAY_DEFAULT) {
vty_out(vty, " ip ospf transmit-delay %u",
params->transmit_delay);
if (params != IF_DEF_PARAMS(ifp))
size_t buflen = MAX(strlen("4294967295"),
strlen("255.255.255.255"));
char buf[buflen];
- area_id2str(buf, sizeof(buf), ¶ms->if_area,
+
+ area_id2str(buf, sizeof(buf),
+ ¶ms->if_area,
params->if_area_id_fmt);
vty_out(vty, " area %s", buf);
if (params != IF_DEF_PARAMS(ifp))
vty_endframe(vty, NULL);
}
+ return write;
+}
+
+/* Configuration write function for ospfd. */
+static int config_write_interface(struct vty *vty)
+{
+ int write = 0;
+ struct ospf *ospf = NULL;
+ struct listnode *node = NULL;
+
+ /* Traverse all ospf [vrf] instances */
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf))
+ write += config_write_interface_one(vty, ospf);
return write;
}
return 0;
}
-/* OSPF configuration write function. */
-static int ospf_config_write(struct vty *vty)
+static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
{
- struct ospf *ospf;
struct interface *ifp;
struct ospf_interface *oi;
- struct listnode *node;
+ struct listnode *node = NULL;
int write = 0;
- ospf = ospf_lookup();
- if (ospf != NULL && ospf->oi_running) {
- /* `router ospf' print. */
- if (ospf->instance)
- vty_out(vty, "router ospf %d\n", ospf->instance);
- else
- vty_out(vty, "router ospf\n");
+ /* `router ospf' print. */
+ if (ospf->instance && ospf->name) {
+ vty_out(vty, "router ospf %d vrf %s\n",
+ ospf->instance, ospf->name);
+ } else if (ospf->instance) {
+ vty_out(vty, "router ospf %d\n",
+ ospf->instance);
+ } else if (ospf->name) {
+ vty_out(vty, "router ospf vrf %s\n",
+ ospf->name);
+ } else
+ vty_out(vty, "router ospf\n");
+ if (!ospf->networks) {
write++;
+ return write;
+ }
- if (!ospf->networks)
- return write;
-
- /* Router ID print. */
- if (ospf->router_id_static.s_addr != 0)
- vty_out(vty, " ospf router-id %s\n",
- inet_ntoa(ospf->router_id_static));
-
- /* ABR type print. */
- if (ospf->abr_type != OSPF_ABR_DEFAULT)
- vty_out(vty, " ospf abr-type %s\n",
- ospf_abr_type_str[ospf->abr_type]);
-
- /* log-adjacency-changes flag print. */
- if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
- if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
- vty_out(vty, " log-adjacency-changes detail\n");
- else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES)
- vty_out(vty, " log-adjacency-changes\n");
- } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) {
- vty_out(vty, " no log-adjacency-changes\n");
- }
+ /* Router ID print. */
+ if (ospf->router_id_static.s_addr != 0)
+ vty_out(vty, " ospf router-id %s\n",
+ inet_ntoa(ospf->router_id_static));
- /* RFC1583 compatibility flag print -- Compatible with CISCO
- * 12.1. */
- if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
- vty_out(vty, " compatible rfc1583\n");
+ /* ABR type print. */
+ if (ospf->abr_type != OSPF_ABR_DEFAULT)
+ vty_out(vty, " ospf abr-type %s\n",
+ ospf_abr_type_str[ospf->abr_type]);
- /* auto-cost reference-bandwidth configuration. */
- if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) {
- vty_out(vty,
- "! Important: ensure reference bandwidth "
- "is consistent across all routers\n");
- vty_out(vty, " auto-cost reference-bandwidth %d\n",
- ospf->ref_bandwidth);
- }
+ /* log-adjacency-changes flag print. */
+ if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
+ if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
+ vty_out(vty, " log-adjacency-changes detail\n");
+ else if (!DFLT_OSPF_LOG_ADJACENCY_CHANGES)
+ vty_out(vty, " log-adjacency-changes\n");
+ } else if (DFLT_OSPF_LOG_ADJACENCY_CHANGES) {
+ vty_out(vty, " no log-adjacency-changes\n");
+ }
- /* SPF timers print. */
- if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT
- || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT
- || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
- vty_out(vty, " timers throttle spf %d %d %d\n",
- ospf->spf_delay, ospf->spf_holdtime,
- ospf->spf_max_holdtime);
-
- /* LSA timers print. */
- if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL)
- vty_out(vty, " timers throttle lsa all %d\n",
- ospf->min_ls_interval);
- if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL)
- vty_out(vty, " timers lsa min-arrival %d\n",
- ospf->min_ls_arrival);
-
- /* Write multiplier print. */
- if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT)
- vty_out(vty, " ospf write-multiplier %d\n",
- ospf->write_oi_count);
-
- /* Max-metric router-lsa print */
- config_write_stub_router(vty, ospf);
-
- /* SPF refresh parameters print. */
- if (ospf->lsa_refresh_interval
- != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
- vty_out(vty, " refresh timer %d\n",
- ospf->lsa_refresh_interval);
-
- /* Redistribute information print. */
- config_write_ospf_redistribute(vty, ospf);
-
- /* passive-interface print. */
- if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
- vty_out(vty, " passive-interface default\n");
-
- for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
- if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
- passive_interface)
- && IF_DEF_PARAMS(ifp)->passive_interface
- != ospf->passive_interface_default) {
- vty_out(vty, " %spassive-interface %s\n",
- IF_DEF_PARAMS(ifp)->passive_interface
- ? ""
- : "no ",
- ifp->name);
- }
- for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
- if (!OSPF_IF_PARAM_CONFIGURED(oi->params,
- passive_interface))
- continue;
- if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp),
- passive_interface)) {
- if (oi->params->passive_interface
- == IF_DEF_PARAMS(oi->ifp)
- ->passive_interface)
- continue;
- } else if (oi->params->passive_interface
- == ospf->passive_interface_default)
- continue;
+ /* RFC1583 compatibility flag print -- Compatible with CISCO
+ * 12.1. */
+ if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
+ vty_out(vty, " compatible rfc1583\n");
- vty_out(vty, " %spassive-interface %s %s\n",
- oi->params->passive_interface ? "" : "no ",
- oi->ifp->name,
- inet_ntoa(oi->address->u.prefix4));
- }
+ /* auto-cost reference-bandwidth configuration. */
+ if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) {
+ vty_out(vty,
+ "! Important: ensure reference bandwidth "
+ "is consistent across all routers\n");
+ vty_out(vty, " auto-cost reference-bandwidth %d\n",
+ ospf->ref_bandwidth);
+ }
- /* Network area print. */
- config_write_network_area(vty, ospf);
+ /* SPF timers print. */
+ if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT
+ || ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT
+ || ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
+ vty_out(vty, " timers throttle spf %d %d %d\n",
+ ospf->spf_delay, ospf->spf_holdtime,
+ ospf->spf_max_holdtime);
+
+ /* LSA timers print. */
+ if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL)
+ vty_out(vty, " timers throttle lsa all %d\n",
+ ospf->min_ls_interval);
+ if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL)
+ vty_out(vty, " timers lsa min-arrival %d\n",
+ ospf->min_ls_arrival);
- /* Area config print. */
- config_write_ospf_area(vty, ospf);
+ /* Write multiplier print. */
+ if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT)
+ vty_out(vty, " ospf write-multiplier %d\n",
+ ospf->write_oi_count);
- /* static neighbor print. */
- config_write_ospf_nbr_nbma(vty, ospf);
+ /* Max-metric router-lsa print */
+ config_write_stub_router(vty, ospf);
- /* Virtual-Link print. */
- config_write_virtual_link(vty, ospf);
+ /* SPF refresh parameters print. */
+ if (ospf->lsa_refresh_interval
+ != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
+ vty_out(vty, " refresh timer %d\n",
+ ospf->lsa_refresh_interval);
- /* Default metric configuration. */
- config_write_ospf_default_metric(vty, ospf);
+ /* Redistribute information print. */
+ config_write_ospf_redistribute(vty, ospf);
- /* Distribute-list and default-information print. */
- config_write_ospf_distribute(vty, ospf);
+ /* passive-interface print. */
+ if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
+ vty_out(vty, " passive-interface default\n");
- /* Distance configuration. */
- config_write_ospf_distance(vty, ospf);
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
+ if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp),
+ passive_interface)
+ && IF_DEF_PARAMS(ifp)->passive_interface
+ != ospf->passive_interface_default) {
+ vty_out(vty, " %spassive-interface %s\n",
+ IF_DEF_PARAMS(ifp)->passive_interface
+ ? ""
+ : "no ",
+ ifp->name);
+ }
+ for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
+ if (!OSPF_IF_PARAM_CONFIGURED(oi->params,
+ passive_interface))
+ continue;
+ if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp),
+ passive_interface)) {
+ if (oi->params->passive_interface
+ == IF_DEF_PARAMS(oi->ifp)
+ ->passive_interface)
+ continue;
+ } else if (oi->params->passive_interface
+ == ospf->passive_interface_default)
+ continue;
- ospf_opaque_config_write_router(vty, ospf);
+ vty_out(vty, " %spassive-interface %s %s\n",
+ oi->params->passive_interface ? "" : "no ",
+ oi->ifp->name,
+ inet_ntoa(oi->address->u.prefix4));
}
+ /* Network area print. */
+ config_write_network_area(vty, ospf);
+
+ /* Area config print. */
+ config_write_ospf_area(vty, ospf);
+
+ /* static neighbor print. */
+ config_write_ospf_nbr_nbma(vty, ospf);
+
+ /* Virtual-Link print. */
+ config_write_virtual_link(vty, ospf);
+
+ /* Default metric configuration. */
+ config_write_ospf_default_metric(vty, ospf);
+
+ /* Distribute-list and default-information print. */
+ config_write_ospf_distribute(vty, ospf);
+
+ /* Distance configuration. */
+ config_write_ospf_distance(vty, ospf);
+
+ ospf_opaque_config_write_router(vty, ospf);
+
+ write++;
+ return write;
+}
+
+/* OSPF configuration write function. */
+static int ospf_config_write(struct vty *vty)
+{
+ struct ospf *ospf;
+ struct listnode *ospf_node = NULL;
+ int write = 0;
+
+ if (listcount(om->ospf) == 0)
+ return write;
+
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, ospf_node, ospf)) {
+ if (ospf->oi_running)
+ write += ospf_config_write_one(vty, ospf);
+ }
return write;
}
install_element(VIEW_NODE, &show_ip_ospf_instance_route_cmd);
install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd);
+
+ /* "show ip ospf vrfs" commands. */
+ install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd);
}
{
int idx_ifname = 4;
struct interface *ifp;
- struct listnode *node;
+ struct listnode *node, *n1;
+ struct ospf *ospf = NULL;
if (argc == 4) /* Clear all the ospfv2 interfaces. */
{
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
- ospf_interface_clear(ifp);
- } else /* Interface name is specified. */
- {
- if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
- VRF_DEFAULT))
- == NULL)
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id),
+ node, ifp))
+ ospf_interface_clear(ifp);
+ }
+ } else {
+ /* Interface name is specified. */
+ ifp = if_lookup_by_name_all_vrf(argv[idx_ifname]->arg);
+ if (ifp == NULL)
vty_out(vty, "No such interface name\n");
else
ospf_interface_clear(ifp);
DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table")
DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute")
+DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments")
DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
static int ospf_router_id_update_zebra(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
struct prefix router_id;
zebra_router_id_update_read(zclient->ibuf, &router_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(&router_id, buf, sizeof(buf));
- zlog_debug("Zebra rcvd: router id update %s", buf);
+ zlog_debug("Zebra rcvd: router id update %s vrf %s id %u",
+ buf, ospf_vrf_id_to_name(vrf_id), vrf_id);
}
router_id_zebra = router_id.u.prefix4;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
if (ospf != NULL)
ospf_router_id_update(ospf);
-
+ else {
+ if (IS_DEBUG_OSPF_EVENT) {
+ char buf[PREFIX2STR_BUFFER];
+
+ prefix2str(&router_id, buf, sizeof(buf));
+ zlog_debug("%s: ospf instance not found for vrf %s id %u router_id %s",
+ __PRETTY_FUNCTION__,
+ ospf_vrf_id_to_name(vrf_id), vrf_id, buf);
+ }
+ }
return 0;
}
static int ospf_interface_add(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
- struct interface *ifp;
+ struct interface *ifp = NULL;
+ struct ospf *ospf = NULL;
ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
+ if (ifp == NULL)
+ return 0;
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
- "Zebra: interface add %s[%u] index %d flags %llx metric %d mtu %d",
- ifp->name, ifp->vrf_id, ifp->ifindex,
+ "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
+ ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+ ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
assert(ifp->info);
IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
}
- ospf_if_update(NULL, ifp);
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
+ if (!ospf)
+ return 0;
+
+ ospf_if_update(ospf, ifp);
hook_call(ospf_if_update, ifp);
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
zlog_debug(
- "Zebra: interface delete %s[%u] index %d flags %llx metric %d mtu %d",
- ifp->name, ifp->vrf_id, ifp->ifindex,
+ "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
+ ifp->name, ospf_vrf_id_to_name(ifp->vrf_id),
+ ifp->vrf_id, ifp->ifindex,
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
hook_call(ospf_if_delete, ifp);
/* And look it up. */
return if_lookup_by_name_len(
- ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), VRF_DEFAULT);
+ ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ), vrf_id);
}
static int ospf_interface_state_up(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct connected *c;
+ struct ospf *ospf = NULL;
+
c = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
char buf[PREFIX2STR_BUFFER];
prefix2str(c->address, buf, sizeof(buf));
- zlog_debug("Zebra: interface %s address add %s", c->ifp->name,
- buf);
+ zlog_debug("Zebra: interface %s address add %s vrf %s id %u",
+ c->ifp->name, buf, ospf_vrf_id_to_name(vrf_id),
+ vrf_id);
}
- ospf_if_update(NULL, c->ifp);
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
+ if (!ospf)
+ return 0;
+
+ ospf_if_update(ospf, c->ifp);
hook_call(ospf_if_update, c->ifp);
return 0;
}
+/* VRF update for an interface. */
+static int ospf_interface_vrf_update(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct interface *ifp = NULL;
+ vrf_id_t new_vrf_id;
+
+ ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
+ &new_vrf_id);
+ if (!ifp)
+ return 0;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u",
+ __PRETTY_FUNCTION__, ifp->name, vrf_id,
+ ospf_vrf_id_to_name(new_vrf_id), new_vrf_id);
+
+ /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/
+ if_update_to_new_vrf(ifp, new_vrf_id);
+
+ return 0;
+}
-void ospf_zebra_add(struct prefix_ipv4 *p, struct ospf_route * or)
+void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
+ struct ospf_route *or)
{
struct zapi_route api;
struct zapi_nexthop *api_nh;
u_char distance;
struct ospf_path *path;
struct listnode *node;
- struct ospf *ospf = ospf_lookup();
int count = 0;
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
}
/* Distance value. */
- distance = ospf_distance_apply(p, or);
+ distance = ospf_distance_apply(ospf, p, or);
if (distance) {
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
api.distance = distance;
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
}
-void ospf_zebra_delete(struct prefix_ipv4 *p, struct ospf_route * or)
+void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
+ struct ospf_route *or)
{
struct zapi_route api;
- struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
}
-void ospf_zebra_add_discard(struct prefix_ipv4 *p)
+void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct zapi_route api;
- struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
inet_ntoa(p->prefix), p->prefixlen);
}
-void ospf_zebra_delete_discard(struct prefix_ipv4 *p)
+void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct zapi_route api;
- struct ospf *ospf = ospf_lookup();
memset(&api, 0, sizeof(api));
- api.vrf_id = VRF_DEFAULT;
+ api.vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance;
api.safi = SAFI_UNICAST;
}
-int ospf_is_type_redistributed(int type, u_short instance)
+int ospf_is_type_redistributed(struct ospf *ospf, int type, u_short instance)
{
return (DEFAULT_ROUTE_TYPE(type)
? vrf_bitmap_check(zclient->default_information,
- VRF_DEFAULT)
+ ospf->vrf_id)
: ((instance
&& redist_check_instance(
&zclient->mi_redist[AFI_IP][type],
|| (!instance
&& vrf_bitmap_check(
zclient->redist[AFI_IP][type],
- VRF_DEFAULT))));
+ ospf->vrf_id))));
}
int ospf_redistribute_set(struct ospf *ospf, int type, u_short instance,
struct ospf_redist *red;
red = ospf_redist_lookup(ospf, type, instance);
- if (ospf_is_type_redistributed(type, instance)) {
+ if (ospf_is_type_redistributed(ospf, type, instance)) {
if (mtype != red->dmetric.type) {
red->dmetric.type = mtype;
force = LSA_REFRESH_FORCE;
ospf_external_add(type, instance);
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
- instance, VRF_DEFAULT);
+ instance, ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
- zlog_debug("Redistribute[%s][%d]: Start Type[%d], Metric[%d]",
- ospf_redist_string(type), instance,
+ zlog_debug("Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]",
+ ospf_redist_string(type), instance, ospf->vrf_id,
metric_type(ospf, type, instance),
metric_value(ospf, type, instance));
if (type == zclient->redist_default && instance == zclient->instance)
return CMD_SUCCESS;
- if (!ospf_is_type_redistributed(type, instance))
+ if (!ospf_is_type_redistributed(ospf, type, instance))
return CMD_SUCCESS;
zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type,
- instance, VRF_DEFAULT);
+ instance, ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
- zlog_debug("Redistribute[%s][%d]: Stop",
- ospf_redist_string(type), instance);
+ zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
+ ospf_redist_string(type), instance, ospf->vrf_id);
ospf_redist_del(ospf, type, instance);
ospf_external_add(DEFAULT_ROUTE, 0);
- if (ospf_is_type_redistributed(DEFAULT_ROUTE, 0)) {
+ if (ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) {
/* if ospf->default_originate changes value, is calling
ospf_external_lsa_refresh_default sufficient to implement
the change? */
}
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient,
- VRF_DEFAULT);
+ ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
int ospf_redistribute_default_unset(struct ospf *ospf)
{
- if (!ospf_is_type_redistributed(DEFAULT_ROUTE, 0))
+ if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
return CMD_SUCCESS;
ospf->default_originate = DEFAULT_ORIGINATE_NONE;
ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient,
- VRF_DEFAULT);
+ ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Redistribute[DEFAULT]: Stop");
struct ospf *ospf;
int i;
- ospf = ospf_lookup();
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
if (ospf == NULL)
return 0;
struct external_info *ei;
struct route_table *rt;
struct ospf_lsa *lsa;
- int type, default_refresh = 0;
- struct ospf *ospf;
+ int type, default_refresh = 0, arg_type;
+ struct ospf *ospf = NULL;
+ void **arg = THREAD_ARG (thread);
+
+ ospf = (struct ospf *)arg[0];
+ arg_type = (int)(intptr_t)arg[1];
- ospf = ospf_lookup();
if (ospf == NULL)
return 0;
zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
+ if (IS_DEBUG_OSPF_EVENT) {
+ zlog_debug("%s: ospf distribute-list update arg_type %d vrf %s id %d",
+ __PRETTY_FUNCTION__, arg_type,
+ ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id);
+ }
+
/* foreach all external info. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
struct list *ext_list;
}
if (default_refresh)
ospf_external_lsa_refresh_default(ospf);
+
+ XFREE(MTYPE_OSPF_DIST_ARGS, arg);
return 0;
}
/* Update distribute-list and set timer to apply access-list. */
-void ospf_distribute_list_update(struct ospf *ospf, uintptr_t type,
+void ospf_distribute_list_update(struct ospf *ospf, int type,
u_short instance)
{
struct route_table *rt;
struct ospf_external *ext;
+ void **args = XCALLOC(MTYPE_OSPF_DIST_ARGS, sizeof(void *)*2);
+
+ args[0] = ospf;
+ args[1] = (void *)((ptrdiff_t) type);
/* External info does not exist. */
ext = ospf_external_lookup(type, instance);
/* Set timer. */
ospf->t_distribute_update = NULL;
thread_add_timer_msec(master, ospf_distribute_list_update_timer,
- (void *)type, ospf->min_ls_interval,
+ (void **)args, ospf->min_ls_interval,
&ospf->t_distribute_update);
}
int type;
int abr_inv = 0;
struct ospf_area *area;
- struct listnode *node;
+ struct listnode *node, *n1;
/* If OSPF instance does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
+ if (listcount(om->ospf) == 0)
return;
- /* Update distribute-list, and apply filter. */
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (red_list)
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP(red)) {
- /* if route-map is not NULL it may be
- * using this access list */
- ospf_distribute_list_update(
- ospf, type, red->instance);
+ /* Iterate all ospf [VRF] instances */
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ /* Update distribute-list, and apply filter. */
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (red_list)
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP(red)) {
+ /* if route-map is not NULL it may be
+ * using this access list */
+ ospf_distribute_list_update(
+ ospf,
+ type, red->instance);
+ }
}
- }
-
- /* There is place for route-map for default-information
- * (ZEBRA_ROUTE_MAX),
- * but no distribute list. */
- if (type == ZEBRA_ROUTE_MAX)
- break;
-
- if (DISTRIBUTE_NAME(ospf, type)) {
- /* Keep old access-list for distribute-list. */
- struct access_list *old = DISTRIBUTE_LIST(ospf, type);
- /* Update access-list for distribute-list. */
- DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
- AFI_IP, DISTRIBUTE_NAME(ospf, type));
-
- /* No update for this distribute type. */
- if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
- continue;
-
- /* Schedule distribute-list update timer. */
- if (DISTRIBUTE_LIST(ospf, type) == NULL
- || strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
- == 0)
- ospf_distribute_list_update(ospf, type, 0);
+ /* There is place for route-map for default-information
+ * (ZEBRA_ROUTE_MAX),
+ * but no distribute list. */
+ if (type == ZEBRA_ROUTE_MAX)
+ break;
+
+ if (DISTRIBUTE_NAME(ospf, type)) {
+ /* Keep old access-list for distribute-list. */
+ struct access_list *old = DISTRIBUTE_LIST(ospf,
+ type);
+
+ /* Update access-list for distribute-list. */
+ DISTRIBUTE_LIST(ospf, type) = access_list_lookup(
+ AFI_IP, DISTRIBUTE_NAME(ospf, type));
+
+ /* No update for this distribute type. */
+ if (old == NULL && DISTRIBUTE_LIST(ospf, type) == NULL)
+ continue;
+
+ /* Schedule distribute-list update timer. */
+ if (DISTRIBUTE_LIST(ospf, type) == NULL
+ || strcmp(DISTRIBUTE_NAME(ospf, type), access->name)
+ == 0)
+ ospf_distribute_list_update(ospf, type, 0);
+ }
}
- }
- /* Update Area access-list. */
- for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
- if (EXPORT_NAME(area)) {
- EXPORT_LIST(area) = NULL;
- abr_inv++;
- }
+ /* Update Area access-list. */
+ for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+ if (EXPORT_NAME(area)) {
+ EXPORT_LIST(area) = NULL;
+ abr_inv++;
+ }
- if (IMPORT_NAME(area)) {
- IMPORT_LIST(area) = NULL;
- abr_inv++;
+ if (IMPORT_NAME(area)) {
+ IMPORT_LIST(area) = NULL;
+ abr_inv++;
+ }
}
- }
- /* Schedule ABR tasks -- this will be changed -- takada. */
- if (IS_OSPF_ABR(ospf) && abr_inv)
- ospf_schedule_abr_task(ospf);
+ /* Schedule ABR tasks -- this will be changed -- takada. */
+ if (IS_OSPF_ABR(ospf) && abr_inv)
+ ospf_schedule_abr_task(ospf);
+ }
}
/* If prefix-list is updated, do some updates. */
void ospf_prefix_list_update(struct prefix_list *plist)
{
- struct ospf *ospf;
+ struct ospf *ospf = NULL;
int type;
int abr_inv = 0;
struct ospf_area *area;
- struct listnode *node;
+ struct listnode *node, *n1;
/* If OSPF instatnce does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
+ if (listcount(om->ospf) == 0)
return;
- /* Update all route-maps which are used as redistribution filters.
- * They might use prefix-list.
- */
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (red_list)
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP(red)) {
- /* if route-map is not NULL it may be
- * using this prefix list */
- ospf_distribute_list_update(
- ospf, type, red->instance);
+ /* Iterate all ospf [VRF] instances */
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+
+ /* Update all route-maps which are used
+ * as redistribution filters.
+ * They might use prefix-list.
+ */
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (red_list) {
+ for (ALL_LIST_ELEMENTS_RO(red_list,
+ node, red)) {
+ if (ROUTEMAP(red)) {
+ /* if route-map is not NULL
+ * it may be using
+ * this prefix list */
+ ospf_distribute_list_update(
+ ospf, type,
+ red->instance);
+ }
}
}
- }
+ }
- /* Update area filter-lists. */
- for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
- /* Update filter-list in. */
- if (PREFIX_NAME_IN(area))
- if (strcmp(PREFIX_NAME_IN(area),
- prefix_list_name(plist))
- == 0) {
- PREFIX_LIST_IN(area) = prefix_list_lookup(
- AFI_IP, PREFIX_NAME_IN(area));
- abr_inv++;
- }
+ /* Update area filter-lists. */
+ for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+ /* Update filter-list in. */
+ if (PREFIX_NAME_IN(area))
+ if (strcmp(PREFIX_NAME_IN(area),
+ prefix_list_name(plist)) == 0) {
+ PREFIX_LIST_IN(area) =
+ prefix_list_lookup(
+ AFI_IP,
+ PREFIX_NAME_IN(area));
+ abr_inv++;
+ }
- /* Update filter-list out. */
- if (PREFIX_NAME_OUT(area))
- if (strcmp(PREFIX_NAME_OUT(area),
- prefix_list_name(plist))
- == 0) {
- PREFIX_LIST_IN(area) = prefix_list_lookup(
- AFI_IP, PREFIX_NAME_OUT(area));
- abr_inv++;
- }
- }
+ /* Update filter-list out. */
+ if (PREFIX_NAME_OUT(area))
+ if (strcmp(PREFIX_NAME_OUT(area),
+ prefix_list_name(plist)) == 0) {
+ PREFIX_LIST_IN(area) =
+ prefix_list_lookup(
+ AFI_IP,
+ PREFIX_NAME_OUT(area));
+ abr_inv++;
+ }
+ }
- /* Schedule ABR task. */
- if (IS_OSPF_ABR(ospf) && abr_inv)
- ospf_schedule_abr_task(ospf);
+ /* Schedule ABR task. */
+ if (IS_OSPF_ABR(ospf) && abr_inv)
+ ospf_schedule_abr_task(ospf);
+ }
}
static struct ospf_distance *ospf_distance_new(void)
}
}
-u_char ospf_distance_apply(struct prefix_ipv4 *p, struct ospf_route * or)
+u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
+ struct ospf_route *or)
{
- struct ospf *ospf;
- ospf = ospf_lookup();
if (ospf == NULL)
return 0;
return 0;
}
+void ospf_zebra_vrf_register(struct ospf *ospf)
+{
+ if (!zclient || zclient->sock < 0 || !ospf)
+ return;
+
+ if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Register VRF %s id %u",
+ __PRETTY_FUNCTION__,
+ ospf_vrf_id_to_name(ospf->vrf_id),
+ ospf->vrf_id);
+ zclient_send_reg_requests(zclient, ospf->vrf_id);
+ }
+}
+
+void ospf_zebra_vrf_deregister(struct ospf *ospf)
+{
+ if (!zclient || zclient->sock < 0 || !ospf)
+ return;
+
+ if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: De-Register VRF %s id %u",
+ __PRETTY_FUNCTION__,
+ ospf_vrf_id_to_name(ospf->vrf_id),
+ ospf->vrf_id);
+ /* Deregister for router-id, interfaces,
+ * redistributed routes. */
+ zclient_send_dereg_requests(zclient, ospf->vrf_id);
+ }
+}
static void ospf_zebra_connected(struct zclient *zclient)
{
/* Send the client registration */
zclient->interface_address_add = ospf_interface_address_add;
zclient->interface_address_delete = ospf_interface_address_delete;
zclient->interface_link_params = ospf_interface_link_params;
+ zclient->interface_vrf_update = ospf_interface_vrf_update;
zclient->redistribute_route_add = ospf_zebra_read_route;
zclient->redistribute_route_del = ospf_zebra_read_route;
};
/* Prototypes */
-extern void ospf_zebra_add(struct prefix_ipv4 *, struct ospf_route *);
-extern void ospf_zebra_delete(struct prefix_ipv4 *, struct ospf_route *);
+extern void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *,
+ struct ospf_route *);
+extern void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *,
+ struct ospf_route *);
-extern void ospf_zebra_add_discard(struct prefix_ipv4 *);
-extern void ospf_zebra_delete_discard(struct prefix_ipv4 *);
+extern void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *);
+extern void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *);
extern int ospf_redistribute_check(struct ospf *, struct external_info *,
int *);
extern int ospf_distribute_check_connected(struct ospf *,
struct external_info *);
-extern void ospf_distribute_list_update(struct ospf *, uintptr_t, u_short);
+extern void ospf_distribute_list_update(struct ospf *, int, u_short);
-extern int ospf_is_type_redistributed(int, u_short);
+extern int ospf_is_type_redistributed(struct ospf *, int, u_short);
extern void ospf_distance_reset(struct ospf *);
-extern u_char ospf_distance_apply(struct prefix_ipv4 *, struct ospf_route *);
+extern u_char ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *,
+ struct ospf_route *);
extern struct ospf_external *ospf_external_lookup(u_char, u_short);
extern struct ospf_external *ospf_external_add(u_char, u_short);
extern void ospf_external_del(u_char, u_short);
extern int ospf_distance_unset(struct vty *, struct ospf *, const char *,
const char *, const char *);
extern void ospf_zebra_init(struct thread_master *, u_short);
+extern void ospf_zebra_vrf_register(struct ospf *ospf);
+extern void ospf_zebra_vrf_deregister(struct ospf *ospf);
DECLARE_HOOK(ospf_if_update, (struct interface * ifp), (ifp))
DECLARE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp))
extern struct zclient *zclient;
extern struct in_addr router_id_zebra;
+extern struct zebra_privs_t ospfd_privs;
static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
else
router_id = router_id_zebra;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Router-ID[OLD:%s]: Update to %s",
+ inet_ntoa(ospf->router_id),
+ inet_ntoa(router_id_old));
if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
ospf_router_lsa_update(ospf);
/* update ospf_interface's */
- for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp))
ospf_if_update(ospf, ifp);
}
}
}
/* Allocate new ospf structure. */
-static struct ospf *ospf_new(u_short instance)
+static struct ospf *ospf_new(u_short instance, const char *name)
{
int i;
+ struct vrf *vrf = NULL;
struct ospf *new = XCALLOC(MTYPE_OSPF_TOP, sizeof(struct ospf));
new->router_id.s_addr = htonl(0);
new->router_id_static.s_addr = htonl(0);
+ if (name) {
+ new->vrf_id = VRF_UNKNOWN;
+ /* Freed in ospf_finish_final */
+ new->name = XSTRDUP(MTYPE_OSPF_TOP, name);
+ vrf = vrf_lookup_by_name(new->name);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: Create new ospf instance with vrf_name %s vrf_id %d",
+ __PRETTY_FUNCTION__, name, new->vrf_id);
+ if (vrf)
+ ospf_vrf_link(new, vrf);
+ } else {
+ new->vrf_id = VRF_DEFAULT;
+ vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ ospf_vrf_link(new, vrf);
+ }
+ ospf_zebra_vrf_register(new);
+
new->abr_type = OSPF_ABR_DEFAULT;
new->oiflist = list_new();
new->vlinks = list_new();
new->lsa_refresh_interval, &new->t_lsa_refresher);
new->lsa_refresher_started = monotime(NULL);
- if ((new->fd = ospf_sock_init()) < 0) {
+ if ((ospf_sock_init(new)) < 0) {
zlog_err(
"ospf_new: fatal error: ospf_sock_init was unable to open "
"a socket");
return new;
}
-struct ospf *ospf_lookup()
-{
- if (listcount(om->ospf) == 0)
- return NULL;
-
- return listgetdata((struct listnode *)listhead(om->ospf));
-}
-
struct ospf *ospf_lookup_instance(u_short instance)
{
struct ospf *ospf;
listnode_delete(om->ospf, ospf);
}
-struct ospf *ospf_get()
+struct ospf *ospf_lookup_by_inst_name(u_short instance, const char *name)
+{
+ struct ospf *ospf = NULL;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) {
+ if ((ospf->instance == instance) &&
+ ((ospf->name == NULL && name == NULL) ||
+ (ospf->name && name && strcmp(ospf->name, name) == 0)))
+ return ospf;
+ }
+ return NULL;
+}
+
+struct ospf *ospf_get(u_short instance, const char *name)
{
struct ospf *ospf;
- ospf = ospf_lookup();
+ /* vrf name provided call inst and name based api
+ * in case of no name pass default ospf instance */
+ if (name)
+ ospf = ospf_lookup_by_inst_name(instance, name);
+ else
+ ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
if (ospf == NULL) {
- ospf = ospf_new(0);
+ ospf = ospf_new(instance, name);
ospf_add(ospf);
if (ospf->router_id_static.s_addr == 0)
ospf = ospf_lookup_instance(instance);
if (ospf == NULL) {
- ospf = ospf_new(instance);
+ ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/);
ospf_add(ospf);
- if (ospf->router_id_static.s_addr == 0)
+ if (ospf->router_id_static.s_addr == 0) {
+ if (vrf_lookup_by_id(ospf->vrf_id))
+ ospf_router_id_update(ospf);
+ else {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf VRF (id %d) is not active yet, skip router id update"
+ , __PRETTY_FUNCTION__,
+ ospf->vrf_id);
+ }
ospf_router_id_update(ospf);
+ }
ospf_opaque_type11_lsa_init(ospf);
}
return ospf;
}
+struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id)
+{
+ struct vrf *vrf = NULL;
+
+ vrf = vrf_lookup_by_id(vrf_id);
+ if (!vrf)
+ return NULL;
+ return (vrf->info) ? (struct ospf *)vrf->info : NULL;
+
+}
+
+/* It should only be used when processing incoming info update from zebra.
+ * Other situations, it is not sufficient to lookup the ospf instance by
+ * vrf_name only without using the instance number.
+ */
+static struct ospf *ospf_lookup_by_name(const char *vrf_name)
+{
+ struct ospf *ospf = NULL;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
+ if ((ospf->name == NULL && vrf_name == NULL)
+ || (ospf->name && vrf_name &&
+ strcmp(ospf->name, vrf_name) == 0))
+ return ospf;
+ return NULL;
+}
+
/* Handle the second half of deferred shutdown. This is called either
* from the deferred-shutdown timer thread, or directly through
* ospf_deferred_shutdown_check.
struct listnode *node, *nnode;
int i;
u_short instance = 0;
+ struct vrf *vrf = NULL;
QOBJ_UNREG(ospf);
list_delete(ospf->vlinks);
/* Remove any ospf interface config params */
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(ospf->vrf_id), node, ifp)) {
struct ospf_if_params *params;
params = IF_DEF_PARAMS(ifp);
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
ospf_if_free(oi);
+ /* De-Register VRF */
+ ospf_zebra_vrf_deregister(ospf);
+
/* Clear static neighbors */
for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
if ((nbr_nbma = rn->info)) {
if (ospf->old_table)
ospf_route_table_free(ospf->old_table);
if (ospf->new_table) {
- ospf_route_delete(ospf->new_table);
+ ospf_route_delete(ospf, ospf->new_table);
ospf_route_table_free(ospf->new_table);
}
if (ospf->old_rtrs)
if (ospf->new_rtrs)
ospf_rtrs_free(ospf->new_rtrs);
if (ospf->new_external_route) {
- ospf_route_delete(ospf->new_external_route);
+ ospf_route_delete(ospf, ospf->new_external_route);
ospf_route_table_free(ospf->new_external_route);
}
if (ospf->old_external_route) {
- ospf_route_delete(ospf->old_external_route);
+ ospf_route_delete(ospf, ospf->old_external_route);
ospf_route_table_free(ospf->old_external_route);
}
if (ospf->external_lsas) {
ospf_delete(ospf);
+ if (ospf->name) {
+ vrf = vrf_lookup_by_name(ospf->name);
+ if (vrf)
+ ospf_vrf_unlink(ospf, vrf);
+ XFREE(MTYPE_OSPF_TOP, ospf->name);
+ } else {
+ vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ if (vrf)
+ ospf_vrf_unlink(ospf, vrf);
+ }
+
XFREE(MTYPE_OSPF_TOP, ospf);
if (!CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
struct external_info *ei;
struct ospf_external *ext;
- if (ospf_is_type_redistributed(ZEBRA_ROUTE_CONNECT, 0))
+ if (ospf_is_type_redistributed(ospf, ZEBRA_ROUTE_CONNECT, 0))
if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0))
&& EXTERNAL_INFO(ext)) {
for (rn = route_top(EXTERNAL_INFO(ext)); rn;
*
* Otherwise, doesn't do anything different to ospf_if_update for now
*/
-void ospf_interface_area_set(struct interface *ifp)
+void ospf_interface_area_set(struct ospf *ospf, struct interface *ifp)
{
- struct ospf *ospf = ospf_get();
+ if (!ospf)
+ return;
ospf_if_update(ospf, ifp);
/* if_update does a update_redistributed */
return;
}
-void ospf_interface_area_unset(struct interface *ifp)
+void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
{
struct route_node *rn_oi;
- struct ospf *ospf;
- ospf = ospf_lookup();
if (!ospf)
return; /* Ospf not ready yet */
/* Find interfaces that may need to be removed. */
for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
rn_oi = route_next(rn_oi)) {
- struct ospf_interface *oi;
+ struct ospf_interface *oi = NULL;
if ((oi = rn_oi->info) == NULL)
continue;
ospf_router_id_update(area->ospf);
/* Get target interface. */
- for (ALL_LIST_ELEMENTS_RO(om->iflist, node, ifp))
+ for (ALL_LIST_ELEMENTS_RO(vrf_iflist(area->ospf->vrf_id), node, ifp))
ospf_network_run_interface(area->ospf, ifp, p, area);
}
void ospf_if_update(struct ospf *ospf, struct interface *ifp)
{
+
if (!ospf)
- ospf = ospf_lookup();
+ return;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
+ __PRETTY_FUNCTION__, ifp->name, ifp->vrf_id,
+ ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
+ inet_ntoa(ospf->router_id));
/* OSPF must be ready. */
if (!ospf_is_ready(ospf))
om->ospf = list_new();
om->master = master;
}
+
+/* Link OSPF instance to VRF. */
+void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf)
+{
+ ospf->vrf_id = vrf->vrf_id;
+ if (vrf->info != (void *)ospf)
+ vrf->info = (void *)ospf;
+}
+
+/* Unlink OSPF instance from VRF. */
+void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf)
+{
+ if (vrf->info == (void *)ospf)
+ vrf->info = NULL;
+ ospf->vrf_id = VRF_UNKNOWN;
+}
+
+/* This is hook function for vrf create called as part of vrf_init */
+static int ospf_vrf_new(struct vrf *vrf)
+{
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: VRF Created: %s(%d)", __PRETTY_FUNCTION__,
+ vrf->name, vrf->vrf_id);
+
+ return 0;
+}
+
+/* This is hook function for vrf delete call as part of vrf_init */
+static int ospf_vrf_delete(struct vrf *vrf)
+{
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: VRF Deletion: %s(%d)", __PRETTY_FUNCTION__,
+ vrf->name, vrf->vrf_id);
+
+ return 0;
+}
+
+/* Enable OSPF VRF instance */
+static int ospf_vrf_enable(struct vrf *vrf)
+{
+ struct ospf *ospf = NULL;
+ vrf_id_t old_vrf_id = VRF_DEFAULT;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: VRF %s id %d enabled",
+ __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
+
+ ospf = ospf_lookup_by_name(vrf->name);
+ if (ospf) {
+ old_vrf_id = ospf->vrf_id;
+ /* We have instance configured, link to VRF and make it "up". */
+ ospf_vrf_link(ospf, vrf);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf linked to vrf %s vrf_id %d (old id %d)",
+ __PRETTY_FUNCTION__, vrf->name, ospf->vrf_id,
+ old_vrf_id);
+
+ if (old_vrf_id != ospf->vrf_id) {
+ if (ospfd_privs.change(ZPRIVS_RAISE)) {
+ zlog_err("ospf_sock_init: could not raise privs, %s",
+ safe_strerror(errno));
+ }
+ if (ospf_bind_vrfdevice(ospf, ospf->fd) < 0)
+ return 0;
+ if (ospfd_privs.change(ZPRIVS_LOWER)) {
+ zlog_err("ospf_sock_init: could not lower privs, %s",
+ safe_strerror(errno));
+ }
+
+ ospf->oi_running = 1;
+ ospf_router_id_update(ospf);
+ }
+ }
+
+ return 0;
+}
+
+/* Disable OSPF VRF instance */
+static int ospf_vrf_disable(struct vrf *vrf)
+{
+ struct ospf *ospf = NULL;
+ vrf_id_t old_vrf_id = VRF_UNKNOWN;
+
+ if (vrf->vrf_id == VRF_DEFAULT)
+ return 0;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: VRF %s id %d disabled.",
+ __PRETTY_FUNCTION__, vrf->name, vrf->vrf_id);
+
+ ospf = ospf_lookup_by_name(vrf->name);
+ if (ospf) {
+ old_vrf_id = ospf->vrf_id;
+
+ /* We have instance configured, unlink
+ * from VRF and make it "down".
+ */
+ ospf_vrf_unlink(ospf, vrf);
+ ospf->oi_running = 0;
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ospf old_vrf_id %d unlinked",
+ __PRETTY_FUNCTION__, old_vrf_id);
+ }
+
+ /* Note: This is a callback, the VRF will be deleted by the caller. */
+ return 0;
+}
+
+void ospf_vrf_init(void)
+{
+ vrf_init(ospf_vrf_new, ospf_vrf_enable,
+ ospf_vrf_disable, ospf_vrf_delete);
+}
+
+void ospf_vrf_terminate(void)
+{
+ vrf_terminate();
+}
+
+const char *ospf_vrf_id_to_name(vrf_id_t vrf_id)
+{
+ struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+ return vrf ? vrf->name : "NIL";
+}
#include "filter.h"
#include "log.h"
+#include "vrf.h"
#include "ospf_memory.h"
#include "ospf_dump_api.h"
/* OSPF thread master. */
struct thread_master *master;
- /* Zebra interface list. */
- struct list *iflist;
/* Redistributed external information. */
struct list *external[ZEBRA_ROUTE_MAX + 1];
struct in_addr router_id; /* Configured automatically. */
struct in_addr router_id_static; /* Configured manually. */
+ vrf_id_t vrf_id; /* VRF Id */
+ char *name; /* VRF name */
+
/* ABR/ASBR internal flags. */
u_char flags;
#define OSPF_FLAG_ABR 0x0001
/* Prototypes. */
extern const char *ospf_redist_string(u_int route_type);
-extern struct ospf *ospf_lookup(void);
extern struct ospf *ospf_lookup_instance(u_short);
-extern struct ospf *ospf_get(void);
+extern struct ospf *ospf_get(u_short instance, const char *name);
extern struct ospf *ospf_get_instance(u_short);
+extern struct ospf *ospf_lookup_by_inst_name(u_short instance,
+ const char *name);
+extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
extern void ospf_finish(struct ospf *);
extern void ospf_router_id_update(struct ospf *ospf);
extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr,
extern void ospf_area_add_if(struct ospf_area *, struct ospf_interface *);
extern void ospf_area_del_if(struct ospf_area *, struct ospf_interface *);
-extern void ospf_interface_area_set(struct interface *);
-extern void ospf_interface_area_unset(struct interface *);
+extern void ospf_interface_area_set(struct ospf *, struct interface *);
+extern void ospf_interface_area_unset(struct ospf *, struct interface *);
extern void ospf_route_map_init(void);
extern void ospf_master_init(struct thread_master *master);
-
+extern void ospf_vrf_init(void);
+extern void ospf_vrf_terminate(void);
+extern void ospf_vrf_link(struct ospf *ospf, struct vrf *vrf);
+extern void ospf_vrf_unlink(struct ospf *ospf, struct vrf *vrf);
+const char *ospf_vrf_id_to_name(vrf_id_t vrf_id);
#endif /* _ZEBRA_OSPFD_H */
# end
endif
+ospfd/ospf_vty_clippy.c: $(CLIPPY_DEPS)
+ospfd/ospf_vty.$(OBJEXT): ospfd/ospf_vty_clippy.c
+
noinst_HEADERS += \
ospfd/ospf_abr.h \
ospfd/ospf_apiserver.h \
}
if (up != NULL)
- up = hash_get(pnc->upstream_hash, up, hash_alloc_intern);
+ hash_get(pnc->upstream_hash, up, hash_alloc_intern);
if (pnc && CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID)) {
memcpy(out_pnc, pnc, sizeof(struct pim_nexthop_cache));
return (lines_to_add, lines_to_del)
+
+def vtysh_config_available():
+ """
+ Return False if no frr daemon is running or some other vtysh session is
+ in 'configuration terminal' mode which will prevent us from making any
+ configuration changes.
+ """
+
+ try:
+ cmd = ['/usr/bin/vtysh', '-c', 'conf t']
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip()
+
+ if 'VTY configuration is locked by other VTY' in output:
+ print output
+ log.error("'%s' returned\n%s\n" % (' '.join(cmd), output))
+ return False
+
+ except subprocess.CalledProcessError as e:
+ msg = "vtysh could not connect with any frr daemons"
+ print msg
+ log.error(msg)
+ return False
+
+ return True
+
+
if __name__ == '__main__':
# Command line options
parser = argparse.ArgumentParser(description='Dynamically apply diff in frr configs')
elif args.reload:
+ # We will not be able to do anything, go ahead and exit(1)
+ if not vtysh_config_available():
+ sys.exit(1)
+
log.debug('New Frr Config\n%s', newconf.get_lines())
# This looks a little odd but we have to do this twice...here is why
return CMD_SUCCESS;
}
-DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd, "router ospf [(1-65535)]",
+DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd,
+ "router ospf [(1-65535)] [vrf NAME]",
"Enable a routing process\n"
"Start OSPF configuration\n"
- "Instance ID\n")
+ "Instance ID\n"
+ VRF_CMD_HELP_STR)
{
vty->node = OSPF_NODE;
return CMD_SUCCESS;
prefix->u.prefix6 = addr->ipv6;
break;
default:
+ memset(prefix, 0, sizeof(*prefix));
zlog_warn("%s: unknown address family %d", __func__, af);
break;
}